mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 23:16:14 +01:00
Correctly implement can_trash by actually looking for a trash dir, not
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. svn path=/trunk/; revision=6679
This commit is contained in:
parent
15f3867833
commit
c5a10d2650
@ -1,3 +1,11 @@
|
|||||||
|
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.
|
||||||
|
|
||||||
2008-03-10 Matthias Clasen <mclasen@redhat.com>
|
2008-03-10 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
* === Released 2.16.1 ===
|
* === Released 2.16.1 ===
|
||||||
|
@ -1576,6 +1576,79 @@ escape_trash_name (char *name)
|
|||||||
return g_string_free (str, FALSE);
|
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
|
static gboolean
|
||||||
g_local_file_trash (GFile *file,
|
g_local_file_trash (GFile *file,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
|
@ -781,6 +781,7 @@ _g_local_file_info_get_parent_info (const char *dir,
|
|||||||
|
|
||||||
parent_info->writable = FALSE;
|
parent_info->writable = FALSE;
|
||||||
parent_info->is_sticky = FALSE;
|
parent_info->is_sticky = FALSE;
|
||||||
|
parent_info->has_trash_dir = FALSE;
|
||||||
parent_info->device = 0;
|
parent_info->device = 0;
|
||||||
|
|
||||||
if (g_file_attribute_matcher_matches (attribute_matcher, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME) ||
|
if (g_file_attribute_matcher_matches (attribute_matcher, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME) ||
|
||||||
@ -806,6 +807,10 @@ _g_local_file_info_get_parent_info (const char *dir,
|
|||||||
#endif
|
#endif
|
||||||
parent_info->owner = statbuf.st_uid;
|
parent_info->owner = statbuf.st_uid;
|
||||||
parent_info->device = statbuf.st_dev;
|
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 @@ get_access_rights (GFileAttributeMatcher *attribute_matcher,
|
|||||||
g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE,
|
g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE,
|
||||||
writable);
|
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))
|
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,
|
g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH,
|
||||||
writable);
|
writable && parent_info->has_trash_dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,10 +35,13 @@ G_BEGIN_DECLS
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
gboolean writable;
|
gboolean writable;
|
||||||
gboolean is_sticky;
|
gboolean is_sticky;
|
||||||
|
gboolean has_trash_dir;
|
||||||
int owner;
|
int owner;
|
||||||
dev_t device;
|
dev_t device;
|
||||||
} GLocalParentFileInfo;
|
} 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,
|
void _g_local_file_info_get_parent_info (const char *dir,
|
||||||
GFileAttributeMatcher *attribute_matcher,
|
GFileAttributeMatcher *attribute_matcher,
|
||||||
GLocalParentFileInfo *parent_info);
|
GLocalParentFileInfo *parent_info);
|
||||||
|
Loading…
Reference in New Issue
Block a user