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 GSList * gtk_file_system_unix_list_roots (GtkFileSystem *file_system);
88 static GtkFileInfo * gtk_file_system_unix_get_root_info (GtkFileSystem *file_system,
89 const GtkFilePath *path,
90 GtkFileInfoType types,
92 static GtkFileFolder *gtk_file_system_unix_get_folder (GtkFileSystem *file_system,
93 const GtkFilePath *path,
94 GtkFileInfoType types,
96 static gboolean gtk_file_system_unix_create_folder (GtkFileSystem *file_system,
97 const GtkFilePath *path,
100 static void gtk_file_system_unix_volume_free (GtkFileSystem *file_system,
101 GtkFileSystemVolume *volume);
102 static GtkFilePath *gtk_file_system_unix_volume_get_base_path (GtkFileSystem *file_system,
103 GtkFileSystemVolume *volume);
104 static gboolean gtk_file_system_unix_volume_get_is_mounted (GtkFileSystem *file_system,
105 GtkFileSystemVolume *volume);
106 static gboolean gtk_file_system_unix_volume_mount (GtkFileSystem *file_system,
107 GtkFileSystemVolume *volume,
109 static gchar * gtk_file_system_unix_volume_get_display_name (GtkFileSystem *file_system,
110 GtkFileSystemVolume *volume);
111 static GdkPixbuf * gtk_file_system_unix_volume_render_icon (GtkFileSystem *file_system,
112 GtkFileSystemVolume *volume,
117 static gboolean gtk_file_system_unix_get_parent (GtkFileSystem *file_system,
118 const GtkFilePath *path,
119 GtkFilePath **parent,
121 static GtkFilePath * gtk_file_system_unix_make_path (GtkFileSystem *file_system,
122 const GtkFilePath *base_path,
123 const gchar *display_name,
125 static gboolean gtk_file_system_unix_parse (GtkFileSystem *file_system,
126 const GtkFilePath *base_path,
128 GtkFilePath **folder,
132 static gchar * gtk_file_system_unix_path_to_uri (GtkFileSystem *file_system,
133 const GtkFilePath *path);
134 static gchar * gtk_file_system_unix_path_to_filename (GtkFileSystem *file_system,
135 const GtkFilePath *path);
136 static GtkFilePath *gtk_file_system_unix_uri_to_path (GtkFileSystem *file_system,
138 static GtkFilePath *gtk_file_system_unix_filename_to_path (GtkFileSystem *file_system,
139 const gchar *filename);
141 static GdkPixbuf *gtk_file_system_unix_render_icon (GtkFileSystem *file_system,
142 const GtkFilePath *path,
147 static gboolean gtk_file_system_unix_add_bookmark (GtkFileSystem *file_system,
148 const GtkFilePath *path,
150 static gboolean gtk_file_system_unix_remove_bookmark (GtkFileSystem *file_system,
151 const GtkFilePath *path,
153 static GSList * gtk_file_system_unix_list_bookmarks (GtkFileSystem *file_system);
155 static GType gtk_file_folder_unix_get_type (void);
156 static void gtk_file_folder_unix_class_init (GtkFileFolderUnixClass *class);
157 static void gtk_file_folder_unix_iface_init (GtkFileFolderIface *iface);
158 static void gtk_file_folder_unix_init (GtkFileFolderUnix *impl);
159 static void gtk_file_folder_unix_finalize (GObject *object);
161 static GtkFileInfo *gtk_file_folder_unix_get_info (GtkFileFolder *folder,
162 const GtkFilePath *path,
164 static gboolean gtk_file_folder_unix_list_children (GtkFileFolder *folder,
168 static gchar * filename_from_path (const GtkFilePath *path);
169 static GtkFilePath *filename_to_path (const gchar *filename);
171 static gboolean filename_is_root (const char *filename);
172 static GtkFileInfo *filename_get_info (const gchar *filename,
173 GtkFileInfoType types,
180 gtk_file_system_unix_get_type (void)
182 static GType file_system_unix_type = 0;
184 if (!file_system_unix_type)
186 static const GTypeInfo file_system_unix_info =
188 sizeof (GtkFileSystemUnixClass),
189 NULL, /* base_init */
190 NULL, /* base_finalize */
191 (GClassInitFunc) gtk_file_system_unix_class_init,
192 NULL, /* class_finalize */
193 NULL, /* class_data */
194 sizeof (GtkFileSystemUnix),
196 (GInstanceInitFunc) gtk_file_system_unix_init,
199 static const GInterfaceInfo file_system_info =
201 (GInterfaceInitFunc) gtk_file_system_unix_iface_init, /* interface_init */
202 NULL, /* interface_finalize */
203 NULL /* interface_data */
206 file_system_unix_type = g_type_register_static (G_TYPE_OBJECT,
208 &file_system_unix_info, 0);
209 g_type_add_interface_static (file_system_unix_type,
210 GTK_TYPE_FILE_SYSTEM,
214 return file_system_unix_type;
218 * gtk_file_system_unix_new:
220 * Creates a new #GtkFileSystemUnix object. #GtkFileSystemUnix
221 * implements the #GtkFileSystem interface with direct access to
222 * the filesystem using Unix/Linux API calls
224 * Return value: the new #GtkFileSystemUnix object
227 gtk_file_system_unix_new (void)
229 return g_object_new (GTK_TYPE_FILE_SYSTEM_UNIX, NULL);
233 gtk_file_system_unix_class_init (GtkFileSystemUnixClass *class)
235 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
237 system_parent_class = g_type_class_peek_parent (class);
239 gobject_class->finalize = gtk_file_system_unix_finalize;
243 gtk_file_system_unix_iface_init (GtkFileSystemIface *iface)
245 iface->list_volumes = gtk_file_system_unix_list_volumes;
246 iface->list_roots = gtk_file_system_unix_list_roots;
247 iface->get_folder = gtk_file_system_unix_get_folder;
248 iface->get_root_info = gtk_file_system_unix_get_root_info;
249 iface->create_folder = gtk_file_system_unix_create_folder;
250 iface->volume_free = gtk_file_system_unix_volume_free;
251 iface->volume_get_base_path = gtk_file_system_unix_volume_get_base_path;
252 iface->volume_get_is_mounted = gtk_file_system_unix_volume_get_is_mounted;
253 iface->volume_mount = gtk_file_system_unix_volume_mount;
254 iface->volume_get_display_name = gtk_file_system_unix_volume_get_display_name;
255 iface->volume_render_icon = gtk_file_system_unix_volume_render_icon;
256 iface->get_parent = gtk_file_system_unix_get_parent;
257 iface->make_path = gtk_file_system_unix_make_path;
258 iface->parse = gtk_file_system_unix_parse;
259 iface->path_to_uri = gtk_file_system_unix_path_to_uri;
260 iface->path_to_filename = gtk_file_system_unix_path_to_filename;
261 iface->uri_to_path = gtk_file_system_unix_uri_to_path;
262 iface->filename_to_path = gtk_file_system_unix_filename_to_path;
263 iface->render_icon = gtk_file_system_unix_render_icon;
264 iface->add_bookmark = gtk_file_system_unix_add_bookmark;
265 iface->remove_bookmark = gtk_file_system_unix_remove_bookmark;
266 iface->list_bookmarks = gtk_file_system_unix_list_bookmarks;
270 gtk_file_system_unix_init (GtkFileSystemUnix *system_unix)
275 gtk_file_system_unix_finalize (GObject *object)
277 system_parent_class->finalize (object);
281 gtk_file_system_unix_list_volumes (GtkFileSystem *file_system)
283 return g_slist_append (NULL, gtk_file_path_new_dup ("/"));
287 gtk_file_system_unix_list_roots (GtkFileSystem *file_system)
289 return g_slist_append (NULL, gtk_file_path_new_dup ("/"));
293 gtk_file_system_unix_get_root_info (GtkFileSystem *file_system,
294 const GtkFilePath *path,
295 GtkFileInfoType types,
298 const gchar *filename = gtk_file_path_get_string (path);
300 g_return_val_if_fail (strcmp (filename, "/") == 0, NULL);
302 return filename_get_info ("/", types, error);
305 static GtkFileFolder *
306 gtk_file_system_unix_get_folder (GtkFileSystem *file_system,
307 const GtkFilePath *path,
308 GtkFileInfoType types,
311 GtkFileFolderUnix *folder_unix;
314 filename = filename_from_path (path);
315 g_return_val_if_fail (filename != NULL, NULL);
317 folder_unix = g_object_new (GTK_TYPE_FILE_FOLDER_UNIX, NULL);
318 folder_unix->filename = filename;
319 folder_unix->types = types;
321 return GTK_FILE_FOLDER (folder_unix);
325 gtk_file_system_unix_create_folder (GtkFileSystem *file_system,
326 const GtkFilePath *path,
332 filename = filename_from_path (path);
333 g_return_val_if_fail (filename != NULL, FALSE);
335 result = mkdir (filename, 0777) != 0;
339 gchar *filename_utf8 = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
341 GTK_FILE_SYSTEM_ERROR,
342 GTK_FILE_SYSTEM_ERROR_NONEXISTENT,
343 _("error creating directory '%s': %s"),
344 filename_utf8 ? filename_utf8 : "???",
346 g_free (filename_utf8);
355 gtk_file_system_unix_volume_free (GtkFileSystem *file_system,
356 GtkFileSystemVolume *volume)
360 path = (GtkFilePath *) volume;
361 gtk_file_path_free (path);
365 gtk_file_system_unix_volume_get_base_path (GtkFileSystem *file_system,
366 GtkFileSystemVolume *volume)
368 return gtk_file_path_new_dup ("/");
372 gtk_file_system_unix_volume_get_is_mounted (GtkFileSystem *file_system,
373 GtkFileSystemVolume *volume)
379 gtk_file_system_unix_volume_mount (GtkFileSystem *file_system,
380 GtkFileSystemVolume *volume,
384 GTK_FILE_SYSTEM_ERROR,
385 GTK_FILE_SYSTEM_ERROR_FAILED,
386 _("This file system does not support mounting"));
391 gtk_file_system_unix_volume_get_display_name (GtkFileSystem *file_system,
392 GtkFileSystemVolume *volume)
394 return g_strdup (_("Filesystem")); /* Same as Nautilus */
398 gtk_file_system_unix_volume_render_icon (GtkFileSystem *file_system,
399 GtkFileSystemVolume *volume,
404 return NULL; /* FIXME: We need a hard disk icon or something */
408 gtk_file_system_unix_get_parent (GtkFileSystem *file_system,
409 const GtkFilePath *path,
410 GtkFilePath **parent,
413 gchar *filename = filename_from_path (path);
414 g_return_val_if_fail (filename != NULL, FALSE);
416 if (filename_is_root (filename))
422 gchar *parent_filename = g_path_get_dirname (filename);
423 *parent = filename_to_path (parent_filename);
424 g_free (parent_filename);
433 gtk_file_system_unix_make_path (GtkFileSystem *file_system,
434 const GtkFilePath *base_path,
435 const gchar *display_name,
438 gchar *base_filename;
440 gchar *full_filename;
441 GError *tmp_error = NULL;
444 base_filename = filename_from_path (base_path);
445 g_return_val_if_fail (base_filename != NULL, NULL);
447 filename = g_filename_from_utf8 (display_name, -1, NULL, NULL, &tmp_error);
451 GTK_FILE_SYSTEM_ERROR,
452 GTK_FILE_SYSTEM_ERROR_BAD_FILENAME,
456 g_error_free (tmp_error);
457 g_free (base_filename);
462 full_filename = g_build_filename (base_filename, filename, NULL);
463 result = filename_to_path (full_filename);
464 g_free (base_filename);
466 g_free (full_filename);
471 /* If this was a publically exported function, it should return
472 * a dup'ed result, but we make it modify-in-place for efficiency
473 * here, and because it works for us.
476 canonicalize_filename (gchar *filename)
479 gboolean last_was_slash = FALSE;
486 if (*p == G_DIR_SEPARATOR)
489 *q++ = G_DIR_SEPARATOR;
491 last_was_slash = TRUE;
495 if (last_was_slash && *p == '.')
497 if (*(p + 1) == G_DIR_SEPARATOR ||
500 if (*(p + 1) == '\0')
505 else if (*(p + 1) == '.' &&
506 (*(p + 2) == G_DIR_SEPARATOR ||
509 if (q > filename + 1)
512 while (q > filename + 1 &&
513 *(q - 1) != G_DIR_SEPARATOR)
517 if (*(p + 2) == '\0')
525 last_was_slash = FALSE;
531 last_was_slash = FALSE;
538 if (q > filename + 1 && *(q - 1) == G_DIR_SEPARATOR)
545 gtk_file_system_unix_parse (GtkFileSystem *file_system,
546 const GtkFilePath *base_path,
548 GtkFilePath **folder,
554 gboolean result = FALSE;
556 base_filename = filename_from_path (base_path);
557 g_return_val_if_fail (base_filename != NULL, FALSE);
559 last_slash = strrchr (str, G_DIR_SEPARATOR);
562 *folder = gtk_file_path_copy (base_path);
563 *file_part = g_strdup (str);
570 GError *tmp_error = NULL;
572 if (last_slash == str)
573 folder_part = g_strdup ("/");
575 folder_part = g_filename_from_utf8 (str, last_slash - str,
576 NULL, NULL, &tmp_error);
581 GTK_FILE_SYSTEM_ERROR,
582 GTK_FILE_SYSTEM_ERROR_BAD_FILENAME,
585 g_error_free (tmp_error);
589 if (folder_part[0] == G_DIR_SEPARATOR)
590 folder_path = folder_part;
593 folder_path = g_build_filename (base_filename, folder_part, NULL);
594 g_free (folder_part);
597 canonicalize_filename (folder_path);
599 *folder = filename_to_path (folder_path);
600 *file_part = g_strdup (last_slash + 1);
602 g_free (folder_path);
608 g_free (base_filename);
614 gtk_file_system_unix_path_to_uri (GtkFileSystem *file_system,
615 const GtkFilePath *path)
617 return g_filename_to_uri (gtk_file_path_get_string (path), NULL, NULL);
621 gtk_file_system_unix_path_to_filename (GtkFileSystem *file_system,
622 const GtkFilePath *path)
624 return g_strdup (gtk_file_path_get_string (path));
628 gtk_file_system_unix_uri_to_path (GtkFileSystem *file_system,
631 gchar *filename = g_filename_from_uri (uri, NULL, NULL);
633 return gtk_file_path_new_steal (filename);
639 gtk_file_system_unix_filename_to_path (GtkFileSystem *file_system,
640 const gchar *filename)
642 return gtk_file_path_new_dup (filename);
646 gtk_file_system_unix_render_icon (GtkFileSystem *file_system,
647 const GtkFilePath *path,
652 /* FIXME: Implement this */
654 GTK_FILE_SYSTEM_ERROR,
655 GTK_FILE_SYSTEM_ERROR_FAILED,
656 _("This file system does not support icons"));
661 gtk_file_system_unix_add_bookmark (GtkFileSystem *file_system,
662 const GtkFilePath *path,
665 /* FIXME: Implement as a really simple ~/.gtk-bookmarks */
667 GTK_FILE_SYSTEM_ERROR,
668 GTK_FILE_SYSTEM_ERROR_FAILED,
669 _("This file system does not support bookmarks"));
674 gtk_file_system_unix_remove_bookmark (GtkFileSystem *file_system,
675 const GtkFilePath *path,
678 /* FIXME: Implement as a really simple ~/.gtk-bookmarks */
680 GTK_FILE_SYSTEM_ERROR,
681 GTK_FILE_SYSTEM_ERROR_FAILED,
682 _("This file system does not support bookmarks"));
687 gtk_file_system_unix_list_bookmarks (GtkFileSystem *file_system)
689 /* FIXME: Implement as a really simple ~/.gtk-bookmarks */
697 gtk_file_folder_unix_get_type (void)
699 static GType file_folder_unix_type = 0;
701 if (!file_folder_unix_type)
703 static const GTypeInfo file_folder_unix_info =
705 sizeof (GtkFileFolderUnixClass),
706 NULL, /* base_init */
707 NULL, /* base_finalize */
708 (GClassInitFunc) gtk_file_folder_unix_class_init,
709 NULL, /* class_finalize */
710 NULL, /* class_data */
711 sizeof (GtkFileFolderUnix),
713 (GInstanceInitFunc) gtk_file_folder_unix_init,
716 static const GInterfaceInfo file_folder_info =
718 (GInterfaceInitFunc) gtk_file_folder_unix_iface_init, /* interface_init */
719 NULL, /* interface_finalize */
720 NULL /* interface_data */
723 file_folder_unix_type = g_type_register_static (G_TYPE_OBJECT,
725 &file_folder_unix_info, 0);
726 g_type_add_interface_static (file_folder_unix_type,
727 GTK_TYPE_FILE_FOLDER,
731 return file_folder_unix_type;
735 gtk_file_folder_unix_class_init (GtkFileFolderUnixClass *class)
737 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
739 folder_parent_class = g_type_class_peek_parent (class);
741 gobject_class->finalize = gtk_file_folder_unix_finalize;
745 gtk_file_folder_unix_iface_init (GtkFileFolderIface *iface)
747 iface->get_info = gtk_file_folder_unix_get_info;
748 iface->list_children = gtk_file_folder_unix_list_children;
752 gtk_file_folder_unix_init (GtkFileFolderUnix *impl)
757 gtk_file_folder_unix_finalize (GObject *object)
759 GtkFileFolderUnix *folder_unix = GTK_FILE_FOLDER_UNIX (object);
761 g_free (folder_unix->filename);
763 folder_parent_class->finalize (object);
767 gtk_file_folder_unix_get_info (GtkFileFolder *folder,
768 const GtkFilePath *path,
771 GtkFileFolderUnix *folder_unix = GTK_FILE_FOLDER_UNIX (folder);
776 filename = filename_from_path (path);
777 g_return_val_if_fail (filename != NULL, NULL);
779 dirname = g_path_get_dirname (filename);
780 g_return_val_if_fail (strcmp (dirname, folder_unix->filename) == 0, NULL);
783 info = filename_get_info (filename, folder_unix->types, error);
791 gtk_file_folder_unix_list_children (GtkFileFolder *folder,
795 GtkFileFolderUnix *folder_unix = GTK_FILE_FOLDER_UNIX (folder);
796 GError *tmp_error = NULL;
801 dir = g_dir_open (folder_unix->filename, 0, &tmp_error);
805 GTK_FILE_SYSTEM_ERROR,
806 GTK_FILE_SYSTEM_ERROR_NONEXISTENT,
810 g_error_free (tmp_error);
817 const gchar *filename = g_dir_read_name (dir);
823 fullname = g_build_filename (folder_unix->filename, filename, NULL);
824 *children = g_slist_prepend (*children, filename_to_path (fullname));
830 *children = g_slist_reverse (*children);
836 filename_get_info (const gchar *filename,
837 GtkFileInfoType types,
842 GtkFileIconType icon_type = GTK_FILE_ICON_REGULAR;
846 /* If stat fails, try to fall back to lstat to catch broken links
848 if (stat (filename, &statbuf) != 0 &&
849 lstat (filename, &statbuf) != 0)
851 gchar *filename_utf8 = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
853 GTK_FILE_SYSTEM_ERROR,
854 GTK_FILE_SYSTEM_ERROR_NONEXISTENT,
855 _("error getting information for '%s': %s"),
856 filename_utf8 ? filename_utf8 : "???",
858 g_free (filename_utf8);
863 info = gtk_file_info_new ();
865 if (filename_is_root (filename))
867 if (types & GTK_FILE_INFO_DISPLAY_NAME)
868 gtk_file_info_set_display_name (info, "/");
870 if (types & GTK_FILE_INFO_IS_HIDDEN)
871 gtk_file_info_set_is_hidden (info, FALSE);
875 gchar *basename = g_path_get_basename (filename);
877 if (types & GTK_FILE_INFO_DISPLAY_NAME)
879 gchar *display_name = g_filename_to_utf8 (basename, -1, NULL, NULL, NULL);
881 display_name = g_strescape (basename, NULL);
883 gtk_file_info_set_display_name (info, display_name);
885 g_free (display_name);
888 if (types & GTK_FILE_INFO_IS_HIDDEN)
890 gtk_file_info_set_is_hidden (info, basename[0] == '.');
896 if (types & GTK_FILE_INFO_IS_FOLDER)
898 gtk_file_info_set_is_folder (info, S_ISDIR (statbuf.st_mode));
902 if (types & GTK_FILE_INFO_ICON)
904 if (S_ISBLK (statbuf.st_mode))
905 icon_type = GTK_FILE_ICON_BLOCK_DEVICE;
906 else if (S_ISLNK (statbuf.st_mode))
907 icon_type = GTK_FILE_ICON_BROKEN_SYMBOLIC_LINK;
908 else if (S_ISCHR (statbuf.st_mode))
909 icon_type = GTK_FILE_ICON_CHARACTER_DEVICE;
910 else if (S_ISDIR (statbuf.st_mode))
911 icon_type = GTK_FILE_ICON_DIRECTORY;
912 else if (S_ISFIFO (statbuf.st_mode))
913 icon_type = GTK_FILE_ICON_FIFO;
914 else if (S_ISSOCK (statbuf.st_mode))
915 icon_type = GTK_FILE_ICON_SOCKET;
917 gtk_file_info_set_icon_type (info, icon_type);
920 if ((types & GTK_FILE_INFO_MIME_TYPE) ||
921 ((types & GTK_FILE_INFO_ICON) && icon_type == GTK_FILE_ICON_REGULAR))
923 if (types & GTK_FILE_INFO_MIME_TYPE)
926 const char *mime_type = xdg_mime_get_mime_type_for_file (filename);
927 gtk_file_info_set_mime_type (info, mime_type);
930 if ((types & GTK_FILE_INFO_ICON) && icon_type == GTK_FILE_ICON_REGULAR &&
931 (statbuf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) &&
932 (strcmp (mime_type, XDG_MIME_TYPE_UNKNOWN) == 0 ||
933 strcmp (mime_type, "application/x-executable") == 0 ||
934 strcmp (mime_type, "application/x-shellscript") == 0))
935 gtk_file_info_set_icon_type (info, GTK_FILE_ICON_EXECUTABLE);
939 if (types & GTK_FILE_INFO_MODIFICATION_TIME)
941 gtk_file_info_set_modification_time (info, statbuf.st_mtime);
944 if (types & GTK_FILE_INFO_SIZE)
946 gtk_file_info_set_size (info, (gint64)statbuf.st_size);
953 filename_from_path (const GtkFilePath *path)
955 return g_strdup (gtk_file_path_get_string (path));
959 filename_to_path (const char *filename)
961 return gtk_file_path_new_dup (filename);
965 filename_is_root (const char *filename)
967 const gchar *after_root;
969 after_root = g_path_skip_root (filename);
971 return (after_root != NULL && *after_root == '\0');