glib r6679 - trunk/gio
- From: alexl svn gnome org
- To: svn-commits-list gnome org
- Subject: glib r6679 - trunk/gio
- Date: Tue, 11 Mar 2008 14:48:29 +0000 (GMT)
Author: alexl
Date: Tue Mar 11 14:48:28 2008
New Revision: 6679
URL: http://svn.gnome.org/viewvc/glib?rev=6679&view=rev
Log:
2008-03-11 Alexander Larsson <alexl redhat com>
* glocalfile.c:
* glocalfileinfo.[ch]:
Correctly implement can_trash by actually
looking for a trash dir, not just assuming
one exists.
Modified:
trunk/gio/ChangeLog
trunk/gio/glocalfile.c
trunk/gio/glocalfileinfo.c
trunk/gio/glocalfileinfo.h
Modified: trunk/gio/glocalfile.c
==============================================================================
--- trunk/gio/glocalfile.c (original)
+++ trunk/gio/glocalfile.c Tue Mar 11 14:48:28 2008
@@ -1576,6 +1576,79 @@
return g_string_free (str, FALSE);
}
+gboolean
+_g_local_file_has_trash_dir (const char *dirname, dev_t dir_dev)
+{
+ static gsize home_dev = 0;
+ char *topdir, *globaldir, *trashdir, *tmpname;
+ uid_t uid;
+ char uid_str[32];
+ struct stat global_stat, trash_stat;
+ gboolean res;
+ int statres;
+
+ if (g_once_init_enter (&home_dev))
+ {
+ gsize setup_value = 0;
+ struct stat home_stat;
+
+ g_stat (g_get_home_dir (), &home_stat);
+ setup_value = home_stat.st_dev;
+ g_once_init_leave (&home_dev, setup_value);
+ }
+
+ /* Assume we can trash to the home */
+ if (dir_dev == (dev_t)home_dev)
+ return TRUE;
+
+ topdir = find_mountpoint_for (dirname, dir_dev);
+ if (topdir == NULL)
+ return FALSE;
+
+ globaldir = g_build_filename (topdir, ".Trash", NULL);
+ statres = g_lstat (globaldir, &global_stat);
+ if (g_lstat (globaldir, &global_stat) == 0 &&
+ S_ISDIR (global_stat.st_mode) &&
+ (global_stat.st_mode & S_ISVTX) != 0)
+ {
+ /* got a toplevel sysadmin created dir, assume we
+ * can trash to it (we should be able to create a dir)
+ * This fails for the FAT case where the ownership of
+ * that dir would be wrong though..
+ */
+ g_free (globaldir);
+ g_free (topdir);
+ return TRUE;
+ }
+ g_free (globaldir);
+
+ /* No global trash dir, or it failed the tests, fall back to $topdir/.Trash-$uid */
+ uid = geteuid ();
+ g_snprintf (uid_str, sizeof (uid_str), "%lu", (unsigned long) uid);
+
+ tmpname = g_strdup_printf (".Trash-%s", uid_str);
+ trashdir = g_build_filename (topdir, tmpname, NULL);
+ g_free (tmpname);
+
+ if (g_lstat (trashdir, &trash_stat) == 0)
+ {
+ g_free (topdir);
+ g_free (trashdir);
+ return
+ S_ISDIR (trash_stat.st_mode) &&
+ trash_stat.st_uid == uid;
+ }
+ g_free (trashdir);
+
+ /* User specific trash didn't exist, can we create it? */
+ res = g_access (topdir, W_OK) == 0;
+
+ g_free (topdir);
+
+ return res;
+}
+
+
static gboolean
g_local_file_trash (GFile *file,
GCancellable *cancellable,
Modified: trunk/gio/glocalfileinfo.c
==============================================================================
--- trunk/gio/glocalfileinfo.c (original)
+++ trunk/gio/glocalfileinfo.c Tue Mar 11 14:48:28 2008
@@ -781,6 +781,7 @@
parent_info->writable = FALSE;
parent_info->is_sticky = FALSE;
+ parent_info->has_trash_dir = FALSE;
parent_info->device = 0;
if (g_file_attribute_matcher_matches (attribute_matcher, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME) ||
@@ -806,6 +807,10 @@
#endif
parent_info->owner = statbuf.st_uid;
parent_info->device = statbuf.st_dev;
+ /* No need to find trash dir if its not writable anyway */
+ if (parent_info->writable &&
+ g_file_attribute_matcher_matches (attribute_matcher, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH))
+ parent_info->has_trash_dir = _g_local_file_has_trash_dir (dir, statbuf.st_dev);
}
}
}
@@ -863,10 +868,9 @@
g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE,
writable);
- /* TODO: This means we can move it, but we should also look for a trash dir */
if (g_file_attribute_matcher_matches (attribute_matcher, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH))
- g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH,
- writable);
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH,
+ writable && parent_info->has_trash_dir);
}
}
Modified: trunk/gio/glocalfileinfo.h
==============================================================================
--- trunk/gio/glocalfileinfo.h (original)
+++ trunk/gio/glocalfileinfo.h Tue Mar 11 14:48:28 2008
@@ -35,10 +35,13 @@
typedef struct {
gboolean writable;
gboolean is_sticky;
+ gboolean has_trash_dir;
int owner;
dev_t device;
} GLocalParentFileInfo;
+gboolean _g_local_file_has_trash_dir (const char *dirname,
+ dev_t dir_dev);
void _g_local_file_info_get_parent_info (const char *dir,
GFileAttributeMatcher *attribute_matcher,
GLocalParentFileInfo *parent_info);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]