1 /* GTK - The GIMP Toolkit
2 * gtkfilesystemunix.c: Default implementation of GtkFileSystem for UNIX-like systems
3 * Copyright (C) 2003, Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
21 #include "gtkfilesystem.h"
22 #include "gtkfilesystemunix.h"
25 #define XDG_PREFIX _gtk_xdg
26 #include "xdgmime/xdgmime.h"
31 #include <sys/types.h>
34 typedef struct _GtkFileSystemUnixClass GtkFileSystemUnixClass;
36 #define GTK_FILE_SYSTEM_UNIX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_FILE_SYSTEM_UNIX, GtkFileSystemUnixClass))
37 #define GTK_IS_FILE_SYSTEM_UNIX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_FILE_SYSTEM_UNIX))
38 #define GTK_FILE_SYSTEM_UNIX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_FILE_SYSTEM_UNIX, GtkFileSystemUnixClass))
40 struct _GtkFileSystemUnixClass
42 GObjectClass parent_class;
45 struct _GtkFileSystemUnix
47 GObject parent_instance;
50 /* Simple stub for our returned volumes */
55 #define GTK_TYPE_FILE_FOLDER_UNIX (gtk_file_folder_unix_get_type ())
56 #define GTK_FILE_FOLDER_UNIX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILE_FOLDER_UNIX, GtkFileFolderUnix))
57 #define GTK_IS_FILE_FOLDER_UNIX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FILE_FOLDER_UNIX))
58 #define GTK_FILE_FOLDER_UNIX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_FILE_FOLDER_UNIX, GtkFileFolderUnixClass))
59 #define GTK_IS_FILE_FOLDER_UNIX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_FILE_FOLDER_UNIX))
60 #define GTK_FILE_FOLDER_UNIX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_FILE_FOLDER_UNIX, GtkFileFolderUnixClass))
62 typedef struct _GtkFileFolderUnix GtkFileFolderUnix;
63 typedef struct _GtkFileFolderUnixClass GtkFileFolderUnixClass;
65 struct _GtkFileFolderUnixClass
67 GObjectClass parent_class;
70 struct _GtkFileFolderUnix
72 GObject parent_instance;
74 GtkFileInfoType types;
78 static GObjectClass *system_parent_class;
79 static GObjectClass *folder_parent_class;
81 static void gtk_file_system_unix_class_init (GtkFileSystemUnixClass *class);
82 static void gtk_file_system_unix_iface_init (GtkFileSystemIface *iface);
83 static void gtk_file_system_unix_init (GtkFileSystemUnix *impl);
84 static void gtk_file_system_unix_finalize (GObject *object);
86 static GSList * gtk_file_system_unix_list_volumes (GtkFileSystem *file_system);
87 static GtkFileSystemVolume *gtk_file_system_unix_get_volume_for_path (GtkFileSystem *file_system,
88 const GtkFilePath *path);
90 static GtkFileFolder *gtk_file_system_unix_get_folder (GtkFileSystem *file_system,
91 const GtkFilePath *path,
92 GtkFileInfoType types,
94 static gboolean gtk_file_system_unix_create_folder (GtkFileSystem *file_system,
95 const GtkFilePath *path,
98 static void gtk_file_system_unix_volume_free (GtkFileSystem *file_system,
99 GtkFileSystemVolume *volume);
100 static GtkFilePath *gtk_file_system_unix_volume_get_base_path (GtkFileSystem *file_system,
101 GtkFileSystemVolume *volume);
102 static gboolean gtk_file_system_unix_volume_get_is_mounted (GtkFileSystem *file_system,
103 GtkFileSystemVolume *volume);
104 static gboolean gtk_file_system_unix_volume_mount (GtkFileSystem *file_system,
105 GtkFileSystemVolume *volume,
107 static gchar * gtk_file_system_unix_volume_get_display_name (GtkFileSystem *file_system,
108 GtkFileSystemVolume *volume);
109 static GdkPixbuf * gtk_file_system_unix_volume_render_icon (GtkFileSystem *file_system,
110 GtkFileSystemVolume *volume,
115 static gboolean gtk_file_system_unix_get_parent (GtkFileSystem *file_system,
116 const GtkFilePath *path,
117 GtkFilePath **parent,
119 static GtkFilePath * gtk_file_system_unix_make_path (GtkFileSystem *file_system,
120 const GtkFilePath *base_path,
121 const gchar *display_name,
123 static gboolean gtk_file_system_unix_parse (GtkFileSystem *file_system,
124 const GtkFilePath *base_path,
126 GtkFilePath **folder,
130 static gchar * gtk_file_system_unix_path_to_uri (GtkFileSystem *file_system,
131 const GtkFilePath *path);
132 static gchar * gtk_file_system_unix_path_to_filename (GtkFileSystem *file_system,
133 const GtkFilePath *path);
134 static GtkFilePath *gtk_file_system_unix_uri_to_path (GtkFileSystem *file_system,
136 static GtkFilePath *gtk_file_system_unix_filename_to_path (GtkFileSystem *file_system,
137 const gchar *filename);
139 static GdkPixbuf *gtk_file_system_unix_render_icon (GtkFileSystem *file_system,
140 const GtkFilePath *path,
145 static gboolean gtk_file_system_unix_add_bookmark (GtkFileSystem *file_system,
146 const GtkFilePath *path,
148 static gboolean gtk_file_system_unix_remove_bookmark (GtkFileSystem *file_system,
149 const GtkFilePath *path,
151 static GSList * gtk_file_system_unix_list_bookmarks (GtkFileSystem *file_system);
153 static GType gtk_file_folder_unix_get_type (void);
154 static void gtk_file_folder_unix_class_init (GtkFileFolderUnixClass *class);
155 static void gtk_file_folder_unix_iface_init (GtkFileFolderIface *iface);
156 static void gtk_file_folder_unix_init (GtkFileFolderUnix *impl);
157 static void gtk_file_folder_unix_finalize (GObject *object);
159 static GtkFileInfo *gtk_file_folder_unix_get_info (GtkFileFolder *folder,
160 const GtkFilePath *path,
162 static gboolean gtk_file_folder_unix_list_children (GtkFileFolder *folder,
166 static gchar * filename_from_path (const GtkFilePath *path);
167 static GtkFilePath *filename_to_path (const gchar *filename);
169 static gboolean filename_is_root (const char *filename);
170 static GtkFileInfo *filename_get_info (const gchar *filename,
171 GtkFileInfoType types,
178 gtk_file_system_unix_get_type (void)
180 static GType file_system_unix_type = 0;
182 if (!file_system_unix_type)
184 static const GTypeInfo file_system_unix_info =
186 sizeof (GtkFileSystemUnixClass),
187 NULL, /* base_init */
188 NULL, /* base_finalize */
189 (GClassInitFunc) gtk_file_system_unix_class_init,
190 NULL, /* class_finalize */
191 NULL, /* class_data */
192 sizeof (GtkFileSystemUnix),
194 (GInstanceInitFunc) gtk_file_system_unix_init,
197 static const GInterfaceInfo file_system_info =
199 (GInterfaceInitFunc) gtk_file_system_unix_iface_init, /* interface_init */
200 NULL, /* interface_finalize */
201 NULL /* interface_data */
204 file_system_unix_type = g_type_register_static (G_TYPE_OBJECT,
206 &file_system_unix_info, 0);
207 g_type_add_interface_static (file_system_unix_type,
208 GTK_TYPE_FILE_SYSTEM,
212 return file_system_unix_type;
216 * gtk_file_system_unix_new:
218 * Creates a new #GtkFileSystemUnix object. #GtkFileSystemUnix
219 * implements the #GtkFileSystem interface with direct access to
220 * the filesystem using Unix/Linux API calls
222 * Return value: the new #GtkFileSystemUnix object
225 gtk_file_system_unix_new (void)
227 return g_object_new (GTK_TYPE_FILE_SYSTEM_UNIX, NULL);
231 gtk_file_system_unix_class_init (GtkFileSystemUnixClass *class)
233 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
235 system_parent_class = g_type_class_peek_parent (class);
237 gobject_class->finalize = gtk_file_system_unix_finalize;
241 gtk_file_system_unix_iface_init (GtkFileSystemIface *iface)
243 iface->list_volumes = gtk_file_system_unix_list_volumes;
244 iface->get_volume_for_path = gtk_file_system_unix_get_volume_for_path;
245 iface->get_folder = gtk_file_system_unix_get_folder;
246 iface->create_folder = gtk_file_system_unix_create_folder;
247 iface->volume_free = gtk_file_system_unix_volume_free;
248 iface->volume_get_base_path = gtk_file_system_unix_volume_get_base_path;
249 iface->volume_get_is_mounted = gtk_file_system_unix_volume_get_is_mounted;
250 iface->volume_mount = gtk_file_system_unix_volume_mount;
251 iface->volume_get_display_name = gtk_file_system_unix_volume_get_display_name;
252 iface->volume_render_icon = gtk_file_system_unix_volume_render_icon;
253 iface->get_parent = gtk_file_system_unix_get_parent;
254 iface->make_path = gtk_file_system_unix_make_path;
255 iface->parse = gtk_file_system_unix_parse;
256 iface->path_to_uri = gtk_file_system_unix_path_to_uri;
257 iface->path_to_filename = gtk_file_system_unix_path_to_filename;
258 iface->uri_to_path = gtk_file_system_unix_uri_to_path;
259 iface->filename_to_path = gtk_file_system_unix_filename_to_path;
260 iface->render_icon = gtk_file_system_unix_render_icon;
261 iface->add_bookmark = gtk_file_system_unix_add_bookmark;
262 iface->remove_bookmark = gtk_file_system_unix_remove_bookmark;
263 iface->list_bookmarks = gtk_file_system_unix_list_bookmarks;
267 gtk_file_system_unix_init (GtkFileSystemUnix *system_unix)
272 gtk_file_system_unix_finalize (GObject *object)
274 system_parent_class->finalize (object);
277 /* Returns our single root volume */
278 static GtkFileSystemVolume *
279 get_root_volume (void)
281 return (GtkFileSystemVolume *) gtk_file_path_new_dup ("/");
285 gtk_file_system_unix_list_volumes (GtkFileSystem *file_system)
287 return g_slist_append (NULL, get_root_volume ());
290 static GtkFileSystemVolume *
291 gtk_file_system_unix_get_volume_for_path (GtkFileSystem *file_system,
292 const GtkFilePath *path)
294 return get_root_volume ();
297 static GtkFileFolder *
298 gtk_file_system_unix_get_folder (GtkFileSystem *file_system,
299 const GtkFilePath *path,
300 GtkFileInfoType types,
303 GtkFileFolderUnix *folder_unix;
306 filename = filename_from_path (path);
307 g_return_val_if_fail (filename != NULL, NULL);
309 folder_unix = g_object_new (GTK_TYPE_FILE_FOLDER_UNIX, NULL);
310 folder_unix->filename = filename;
311 folder_unix->types = types;
313 return GTK_FILE_FOLDER (folder_unix);
317 gtk_file_system_unix_create_folder (GtkFileSystem *file_system,
318 const GtkFilePath *path,
324 filename = filename_from_path (path);
325 g_return_val_if_fail (filename != NULL, FALSE);
327 result = mkdir (filename, 0777) != 0;
331 gchar *filename_utf8 = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
333 GTK_FILE_SYSTEM_ERROR,
334 GTK_FILE_SYSTEM_ERROR_NONEXISTENT,
335 _("error creating directory '%s': %s"),
336 filename_utf8 ? filename_utf8 : "???",
338 g_free (filename_utf8);
347 gtk_file_system_unix_volume_free (GtkFileSystem *file_system,
348 GtkFileSystemVolume *volume)
352 path = (GtkFilePath *) volume;
353 gtk_file_path_free (path);
357 gtk_file_system_unix_volume_get_base_path (GtkFileSystem *file_system,
358 GtkFileSystemVolume *volume)
360 return gtk_file_path_new_dup ("/");
364 gtk_file_system_unix_volume_get_is_mounted (GtkFileSystem *file_system,
365 GtkFileSystemVolume *volume)
371 gtk_file_system_unix_volume_mount (GtkFileSystem *file_system,
372 GtkFileSystemVolume *volume,
376 GTK_FILE_SYSTEM_ERROR,
377 GTK_FILE_SYSTEM_ERROR_FAILED,
378 _("This file system does not support mounting"));
383 gtk_file_system_unix_volume_get_display_name (GtkFileSystem *file_system,
384 GtkFileSystemVolume *volume)
386 return g_strdup (_("Filesystem")); /* Same as Nautilus */
390 gtk_file_system_unix_volume_render_icon (GtkFileSystem *file_system,
391 GtkFileSystemVolume *volume,
396 return NULL; /* FIXME: We need a hard disk icon or something */
400 gtk_file_system_unix_get_parent (GtkFileSystem *file_system,
401 const GtkFilePath *path,
402 GtkFilePath **parent,
405 gchar *filename = filename_from_path (path);
406 g_return_val_if_fail (filename != NULL, FALSE);
408 if (filename_is_root (filename))
414 gchar *parent_filename = g_path_get_dirname (filename);
415 *parent = filename_to_path (parent_filename);
416 g_free (parent_filename);
425 gtk_file_system_unix_make_path (GtkFileSystem *file_system,
426 const GtkFilePath *base_path,
427 const gchar *display_name,
430 gchar *base_filename;
432 gchar *full_filename;
433 GError *tmp_error = NULL;
436 base_filename = filename_from_path (base_path);
437 g_return_val_if_fail (base_filename != NULL, NULL);
439 filename = g_filename_from_utf8 (display_name, -1, NULL, NULL, &tmp_error);
443 GTK_FILE_SYSTEM_ERROR,
444 GTK_FILE_SYSTEM_ERROR_BAD_FILENAME,
448 g_error_free (tmp_error);
449 g_free (base_filename);
454 full_filename = g_build_filename (base_filename, filename, NULL);
455 result = filename_to_path (full_filename);
456 g_free (base_filename);
458 g_free (full_filename);
463 /* If this was a publically exported function, it should return
464 * a dup'ed result, but we make it modify-in-place for efficiency
465 * here, and because it works for us.
468 canonicalize_filename (gchar *filename)
471 gboolean last_was_slash = FALSE;
478 if (*p == G_DIR_SEPARATOR)
481 *q++ = G_DIR_SEPARATOR;
483 last_was_slash = TRUE;
487 if (last_was_slash && *p == '.')
489 if (*(p + 1) == G_DIR_SEPARATOR ||
492 if (*(p + 1) == '\0')
497 else if (*(p + 1) == '.' &&
498 (*(p + 2) == G_DIR_SEPARATOR ||
501 if (q > filename + 1)
504 while (q > filename + 1 &&
505 *(q - 1) != G_DIR_SEPARATOR)
509 if (*(p + 2) == '\0')
517 last_was_slash = FALSE;
523 last_was_slash = FALSE;
530 if (q > filename + 1 && *(q - 1) == G_DIR_SEPARATOR)
537 gtk_file_system_unix_parse (GtkFileSystem *file_system,
538 const GtkFilePath *base_path,
540 GtkFilePath **folder,
546 gboolean result = FALSE;
548 base_filename = filename_from_path (base_path);
549 g_return_val_if_fail (base_filename != NULL, FALSE);
551 last_slash = strrchr (str, G_DIR_SEPARATOR);
554 *folder = gtk_file_path_copy (base_path);
555 *file_part = g_strdup (str);
562 GError *tmp_error = NULL;
564 if (last_slash == str)
565 folder_part = g_strdup ("/");
567 folder_part = g_filename_from_utf8 (str, last_slash - str,
568 NULL, NULL, &tmp_error);
573 GTK_FILE_SYSTEM_ERROR,
574 GTK_FILE_SYSTEM_ERROR_BAD_FILENAME,
577 g_error_free (tmp_error);
581 if (folder_part[0] == G_DIR_SEPARATOR)
582 folder_path = folder_part;
585 folder_path = g_build_filename (base_filename, folder_part, NULL);
586 g_free (folder_part);
589 canonicalize_filename (folder_path);
591 *folder = filename_to_path (folder_path);
592 *file_part = g_strdup (last_slash + 1);
594 g_free (folder_path);
600 g_free (base_filename);
606 gtk_file_system_unix_path_to_uri (GtkFileSystem *file_system,
607 const GtkFilePath *path)
609 return g_filename_to_uri (gtk_file_path_get_string (path), NULL, NULL);
613 gtk_file_system_unix_path_to_filename (GtkFileSystem *file_system,
614 const GtkFilePath *path)
616 return g_strdup (gtk_file_path_get_string (path));
620 gtk_file_system_unix_uri_to_path (GtkFileSystem *file_system,
623 gchar *filename = g_filename_from_uri (uri, NULL, NULL);
625 return gtk_file_path_new_steal (filename);
631 gtk_file_system_unix_filename_to_path (GtkFileSystem *file_system,
632 const gchar *filename)
634 return gtk_file_path_new_dup (filename);
638 gtk_file_system_unix_render_icon (GtkFileSystem *file_system,
639 const GtkFilePath *path,
644 /* FIXME: Implement this */
646 GTK_FILE_SYSTEM_ERROR,
647 GTK_FILE_SYSTEM_ERROR_FAILED,
648 _("This file system does not support icons"));
653 gtk_file_system_unix_add_bookmark (GtkFileSystem *file_system,
654 const GtkFilePath *path,
657 /* FIXME: Implement as a really simple ~/.gtk-bookmarks */
659 GTK_FILE_SYSTEM_ERROR,
660 GTK_FILE_SYSTEM_ERROR_FAILED,
661 _("This file system does not support bookmarks"));
666 gtk_file_system_unix_remove_bookmark (GtkFileSystem *file_system,
667 const GtkFilePath *path,
670 /* FIXME: Implement as a really simple ~/.gtk-bookmarks */
672 GTK_FILE_SYSTEM_ERROR,
673 GTK_FILE_SYSTEM_ERROR_FAILED,
674 _("This file system does not support bookmarks"));
679 gtk_file_system_unix_list_bookmarks (GtkFileSystem *file_system)
681 /* FIXME: Implement as a really simple ~/.gtk-bookmarks */
689 gtk_file_folder_unix_get_type (void)
691 static GType file_folder_unix_type = 0;
693 if (!file_folder_unix_type)
695 static const GTypeInfo file_folder_unix_info =
697 sizeof (GtkFileFolderUnixClass),
698 NULL, /* base_init */
699 NULL, /* base_finalize */
700 (GClassInitFunc) gtk_file_folder_unix_class_init,
701 NULL, /* class_finalize */
702 NULL, /* class_data */
703 sizeof (GtkFileFolderUnix),
705 (GInstanceInitFunc) gtk_file_folder_unix_init,
708 static const GInterfaceInfo file_folder_info =
710 (GInterfaceInitFunc) gtk_file_folder_unix_iface_init, /* interface_init */
711 NULL, /* interface_finalize */
712 NULL /* interface_data */
715 file_folder_unix_type = g_type_register_static (G_TYPE_OBJECT,
717 &file_folder_unix_info, 0);
718 g_type_add_interface_static (file_folder_unix_type,
719 GTK_TYPE_FILE_FOLDER,
723 return file_folder_unix_type;
727 gtk_file_folder_unix_class_init (GtkFileFolderUnixClass *class)
729 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
731 folder_parent_class = g_type_class_peek_parent (class);
733 gobject_class->finalize = gtk_file_folder_unix_finalize;
737 gtk_file_folder_unix_iface_init (GtkFileFolderIface *iface)
739 iface->get_info = gtk_file_folder_unix_get_info;
740 iface->list_children = gtk_file_folder_unix_list_children;
744 gtk_file_folder_unix_init (GtkFileFolderUnix *impl)
749 gtk_file_folder_unix_finalize (GObject *object)
751 GtkFileFolderUnix *folder_unix = GTK_FILE_FOLDER_UNIX (object);
753 g_free (folder_unix->filename);
755 folder_parent_class->finalize (object);
759 gtk_file_folder_unix_get_info (GtkFileFolder *folder,
760 const GtkFilePath *path,
763 GtkFileFolderUnix *folder_unix = GTK_FILE_FOLDER_UNIX (folder);
768 filename = filename_from_path (path);
769 g_return_val_if_fail (filename != NULL, NULL);
771 dirname = g_path_get_dirname (filename);
772 g_return_val_if_fail (strcmp (dirname, folder_unix->filename) == 0, NULL);
775 info = filename_get_info (filename, folder_unix->types, error);
783 gtk_file_folder_unix_list_children (GtkFileFolder *folder,
787 GtkFileFolderUnix *folder_unix = GTK_FILE_FOLDER_UNIX (folder);
788 GError *tmp_error = NULL;
793 dir = g_dir_open (folder_unix->filename, 0, &tmp_error);
797 GTK_FILE_SYSTEM_ERROR,
798 GTK_FILE_SYSTEM_ERROR_NONEXISTENT,
802 g_error_free (tmp_error);
809 const gchar *filename = g_dir_read_name (dir);
815 fullname = g_build_filename (folder_unix->filename, filename, NULL);
816 *children = g_slist_prepend (*children, filename_to_path (fullname));
822 *children = g_slist_reverse (*children);
828 filename_get_info (const gchar *filename,
829 GtkFileInfoType types,
834 GtkFileIconType icon_type = GTK_FILE_ICON_REGULAR;
838 /* If stat fails, try to fall back to lstat to catch broken links
840 if (stat (filename, &statbuf) != 0 &&
841 lstat (filename, &statbuf) != 0)
843 gchar *filename_utf8 = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
845 GTK_FILE_SYSTEM_ERROR,
846 GTK_FILE_SYSTEM_ERROR_NONEXISTENT,
847 _("error getting information for '%s': %s"),
848 filename_utf8 ? filename_utf8 : "???",
850 g_free (filename_utf8);
855 info = gtk_file_info_new ();
857 if (filename_is_root (filename))
859 if (types & GTK_FILE_INFO_DISPLAY_NAME)
860 gtk_file_info_set_display_name (info, "/");
862 if (types & GTK_FILE_INFO_IS_HIDDEN)
863 gtk_file_info_set_is_hidden (info, FALSE);
867 gchar *basename = g_path_get_basename (filename);
869 if (types & GTK_FILE_INFO_DISPLAY_NAME)
871 gchar *display_name = g_filename_to_utf8 (basename, -1, NULL, NULL, NULL);
873 display_name = g_strescape (basename, NULL);
875 gtk_file_info_set_display_name (info, display_name);
877 g_free (display_name);
880 if (types & GTK_FILE_INFO_IS_HIDDEN)
882 gtk_file_info_set_is_hidden (info, basename[0] == '.');
888 if (types & GTK_FILE_INFO_IS_FOLDER)
890 gtk_file_info_set_is_folder (info, S_ISDIR (statbuf.st_mode));
894 if (types & GTK_FILE_INFO_ICON)
896 if (S_ISBLK (statbuf.st_mode))
897 icon_type = GTK_FILE_ICON_BLOCK_DEVICE;
898 else if (S_ISLNK (statbuf.st_mode))
899 icon_type = GTK_FILE_ICON_BROKEN_SYMBOLIC_LINK;
900 else if (S_ISCHR (statbuf.st_mode))
901 icon_type = GTK_FILE_ICON_CHARACTER_DEVICE;
902 else if (S_ISDIR (statbuf.st_mode))
903 icon_type = GTK_FILE_ICON_DIRECTORY;
904 else if (S_ISFIFO (statbuf.st_mode))
905 icon_type = GTK_FILE_ICON_FIFO;
906 else if (S_ISSOCK (statbuf.st_mode))
907 icon_type = GTK_FILE_ICON_SOCKET;
909 gtk_file_info_set_icon_type (info, icon_type);
912 if ((types & GTK_FILE_INFO_MIME_TYPE) ||
913 ((types & GTK_FILE_INFO_ICON) && icon_type == GTK_FILE_ICON_REGULAR))
915 if (types & GTK_FILE_INFO_MIME_TYPE)
918 const char *mime_type = xdg_mime_get_mime_type_for_file (filename);
919 gtk_file_info_set_mime_type (info, mime_type);
922 if ((types & GTK_FILE_INFO_ICON) && icon_type == GTK_FILE_ICON_REGULAR &&
923 (statbuf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) &&
924 (strcmp (mime_type, XDG_MIME_TYPE_UNKNOWN) == 0 ||
925 strcmp (mime_type, "application/x-executable") == 0 ||
926 strcmp (mime_type, "application/x-shellscript") == 0))
927 gtk_file_info_set_icon_type (info, GTK_FILE_ICON_EXECUTABLE);
931 if (types & GTK_FILE_INFO_MODIFICATION_TIME)
933 gtk_file_info_set_modification_time (info, statbuf.st_mtime);
936 if (types & GTK_FILE_INFO_SIZE)
938 gtk_file_info_set_size (info, (gint64)statbuf.st_size);
945 filename_from_path (const GtkFilePath *path)
947 return g_strdup (gtk_file_path_get_string (path));
951 filename_to_path (const char *filename)
953 return gtk_file_path_new_dup (filename);
957 filename_is_root (const char *filename)
959 const gchar *after_root;
961 after_root = g_path_skip_root (filename);
963 return (after_root != NULL && *after_root == '\0');