mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-05-31 09:50:05 +02:00
Add extension point for adding metadata for local files
This adds a local_file_add_info vfunc to GVfs that vfs implementations can override to add metadata for local files.
This commit is contained in:
parent
9a6146f54c
commit
7662c86611
@ -110,7 +110,7 @@
|
|||||||
static void g_local_file_file_iface_init (GFileIface *iface);
|
static void g_local_file_file_iface_init (GFileIface *iface);
|
||||||
|
|
||||||
static GFileAttributeInfoList *local_writable_attributes = NULL;
|
static GFileAttributeInfoList *local_writable_attributes = NULL;
|
||||||
static GFileAttributeInfoList *local_writable_namespaces = NULL;
|
static /* GFileAttributeInfoList * */ gsize local_writable_namespaces = 0;
|
||||||
|
|
||||||
struct _GLocalFile
|
struct _GLocalFile
|
||||||
{
|
{
|
||||||
@ -201,24 +201,6 @@ g_local_file_class_init (GLocalFileClass *klass)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
local_writable_attributes = list;
|
local_writable_attributes = list;
|
||||||
|
|
||||||
/* Writable namespaces: */
|
|
||||||
|
|
||||||
list = g_file_attribute_info_list_new ();
|
|
||||||
|
|
||||||
#ifdef HAVE_XATTR
|
|
||||||
g_file_attribute_info_list_add (list,
|
|
||||||
"xattr",
|
|
||||||
G_FILE_ATTRIBUTE_TYPE_STRING,
|
|
||||||
G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE |
|
|
||||||
G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED);
|
|
||||||
g_file_attribute_info_list_add (list,
|
|
||||||
"xattr-sys",
|
|
||||||
G_FILE_ATTRIBUTE_TYPE_STRING,
|
|
||||||
G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
local_writable_namespaces = list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1204,6 +1186,8 @@ g_local_file_query_info (GFile *file,
|
|||||||
matcher, flags, &parent_info,
|
matcher, flags, &parent_info,
|
||||||
error);
|
error);
|
||||||
|
|
||||||
|
|
||||||
|
_g_local_file_info_free_parent_info (&parent_info);
|
||||||
g_free (basename);
|
g_free (basename);
|
||||||
|
|
||||||
g_file_attribute_matcher_unref (matcher);
|
g_file_attribute_matcher_unref (matcher);
|
||||||
@ -1224,7 +1208,38 @@ g_local_file_query_writable_namespaces (GFile *file,
|
|||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
return g_file_attribute_info_list_ref (local_writable_namespaces);
|
GFileAttributeInfoList *list;
|
||||||
|
GVfsClass *class;
|
||||||
|
GVfs *vfs;
|
||||||
|
|
||||||
|
if (g_once_init_enter (&local_writable_namespaces))
|
||||||
|
{
|
||||||
|
/* Writable namespaces: */
|
||||||
|
|
||||||
|
list = g_file_attribute_info_list_new ();
|
||||||
|
|
||||||
|
#ifdef HAVE_XATTR
|
||||||
|
g_file_attribute_info_list_add (list,
|
||||||
|
"xattr",
|
||||||
|
G_FILE_ATTRIBUTE_TYPE_STRING,
|
||||||
|
G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE |
|
||||||
|
G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED);
|
||||||
|
g_file_attribute_info_list_add (list,
|
||||||
|
"xattr-sys",
|
||||||
|
G_FILE_ATTRIBUTE_TYPE_STRING,
|
||||||
|
G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vfs = g_vfs_get_default ();
|
||||||
|
class = G_VFS_GET_CLASS (vfs);
|
||||||
|
if (class->add_writable_namespaces)
|
||||||
|
class->add_writable_namespaces (vfs, list);
|
||||||
|
|
||||||
|
g_once_init_leave (&local_writable_namespaces, (gsize)list);
|
||||||
|
}
|
||||||
|
list = (GFileAttributeInfoList *)local_writable_namespaces;
|
||||||
|
|
||||||
|
return g_file_attribute_info_list_ref (list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -1409,7 +1424,9 @@ g_local_file_delete (GFile *file,
|
|||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GLocalFile *local = G_LOCAL_FILE (file);
|
GLocalFile *local = G_LOCAL_FILE (file);
|
||||||
|
GVfsClass *class;
|
||||||
|
GVfs *vfs;
|
||||||
|
|
||||||
if (g_remove (local->filename) == -1)
|
if (g_remove (local->filename) == -1)
|
||||||
{
|
{
|
||||||
int errsv = errno;
|
int errsv = errno;
|
||||||
@ -1426,7 +1443,12 @@ g_local_file_delete (GFile *file,
|
|||||||
g_strerror (errsv));
|
g_strerror (errsv));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vfs = g_vfs_get_default ();
|
||||||
|
class = G_VFS_GET_CLASS (vfs);
|
||||||
|
if (class->local_file_removed)
|
||||||
|
class->local_file_removed (vfs, local->filename);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2176,7 +2198,9 @@ g_local_file_move (GFile *source,
|
|||||||
char *backup_name;
|
char *backup_name;
|
||||||
int res;
|
int res;
|
||||||
off_t source_size;
|
off_t source_size;
|
||||||
|
GVfsClass *class;
|
||||||
|
GVfs *vfs;
|
||||||
|
|
||||||
if (!G_IS_LOCAL_FILE (source) ||
|
if (!G_IS_LOCAL_FILE (source) ||
|
||||||
!G_IS_LOCAL_FILE (destination))
|
!G_IS_LOCAL_FILE (destination))
|
||||||
{
|
{
|
||||||
@ -2294,6 +2318,11 @@ g_local_file_move (GFile *source,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vfs = g_vfs_get_default ();
|
||||||
|
class = G_VFS_GET_CLASS (vfs);
|
||||||
|
if (class->local_file_moved)
|
||||||
|
class->local_file_moved (vfs, local_source->filename, local_destination->filename);
|
||||||
|
|
||||||
/* Make sure we send full copied size */
|
/* Make sure we send full copied size */
|
||||||
if (progress_callback)
|
if (progress_callback)
|
||||||
progress_callback (source_size, source_size, progress_callback_data);
|
progress_callback (source_size, source_size, progress_callback_data);
|
||||||
|
@ -116,6 +116,8 @@ g_local_file_enumerator_finalize (GObject *object)
|
|||||||
|
|
||||||
local = G_LOCAL_FILE_ENUMERATOR (object);
|
local = G_LOCAL_FILE_ENUMERATOR (object);
|
||||||
|
|
||||||
|
if (local->got_parent_info)
|
||||||
|
_g_local_file_info_free_parent_info (&local->parent_info);
|
||||||
g_free (local->filename);
|
g_free (local->filename);
|
||||||
g_file_attribute_matcher_unref (local->matcher);
|
g_file_attribute_matcher_unref (local->matcher);
|
||||||
if (local->dir)
|
if (local->dir)
|
||||||
|
@ -60,6 +60,7 @@
|
|||||||
|
|
||||||
#include <glib/gstdio.h>
|
#include <glib/gstdio.h>
|
||||||
#include <gfileattribute-priv.h>
|
#include <gfileattribute-priv.h>
|
||||||
|
#include <gvfs.h>
|
||||||
|
|
||||||
#include "glibintl.h"
|
#include "glibintl.h"
|
||||||
|
|
||||||
@ -791,7 +792,9 @@ _g_local_file_info_get_parent_info (const char *dir,
|
|||||||
*/
|
*/
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
parent_info->extra_data = NULL;
|
||||||
|
parent_info->free_extra_data = NULL;
|
||||||
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->has_trash_dir = FALSE;
|
||||||
@ -833,6 +836,14 @@ _g_local_file_info_get_parent_info (const char *dir,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_g_local_file_info_free_parent_info (GLocalParentFileInfo *parent_info)
|
||||||
|
{
|
||||||
|
if (parent_info->extra_data &&
|
||||||
|
parent_info->free_extra_data)
|
||||||
|
parent_info->free_extra_data (parent_info->extra_data);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_access_rights (GFileAttributeMatcher *attribute_matcher,
|
get_access_rights (GFileAttributeMatcher *attribute_matcher,
|
||||||
GFileInfo *info,
|
GFileInfo *info,
|
||||||
@ -1417,6 +1428,9 @@ _g_local_file_info_get (const char *basename,
|
|||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
DWORD dos_attributes;
|
DWORD dos_attributes;
|
||||||
#endif
|
#endif
|
||||||
|
char *symlink_target;
|
||||||
|
GVfs *vfs;
|
||||||
|
GVfsClass *class;
|
||||||
|
|
||||||
info = g_file_info_new ();
|
info = g_file_info_new ();
|
||||||
|
|
||||||
@ -1514,16 +1528,15 @@ _g_local_file_info_get (const char *basename,
|
|||||||
g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_DOS_IS_SYSTEM, TRUE);
|
g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_DOS_IS_SYSTEM, TRUE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef S_ISLNK
|
symlink_target = NULL;
|
||||||
if (is_symlink &&
|
if (is_symlink)
|
||||||
g_file_attribute_matcher_matches (attribute_matcher,
|
|
||||||
G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET))
|
|
||||||
{
|
{
|
||||||
char *link = read_link (path);
|
symlink_target = read_link (path);
|
||||||
g_file_info_set_symlink_target (info, link);
|
if (symlink_target &&
|
||||||
g_free (link);
|
g_file_attribute_matcher_matches (attribute_matcher,
|
||||||
|
G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET))
|
||||||
|
g_file_info_set_symlink_target (info, symlink_target);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (g_file_attribute_matcher_matches (attribute_matcher,
|
if (g_file_attribute_matcher_matches (attribute_matcher,
|
||||||
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME))
|
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME))
|
||||||
@ -1689,9 +1702,34 @@ _g_local_file_info_get (const char *basename,
|
|||||||
if (g_file_attribute_matcher_matches (attribute_matcher,
|
if (g_file_attribute_matcher_matches (attribute_matcher,
|
||||||
G_FILE_ATTRIBUTE_THUMBNAIL_PATH))
|
G_FILE_ATTRIBUTE_THUMBNAIL_PATH))
|
||||||
get_thumbnail_attributes (path, info);
|
get_thumbnail_attributes (path, info);
|
||||||
|
|
||||||
|
vfs = g_vfs_get_default ();
|
||||||
|
class = G_VFS_GET_CLASS (vfs);
|
||||||
|
if (class->local_file_add_info)
|
||||||
|
{
|
||||||
|
const char *extra_target;
|
||||||
|
|
||||||
|
extra_target = path;
|
||||||
|
if (!(flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS) &&
|
||||||
|
is_symlink &&
|
||||||
|
!symlink_broken &&
|
||||||
|
symlink_target != NULL)
|
||||||
|
extra_target = symlink_target;
|
||||||
|
|
||||||
|
class->local_file_add_info (vfs,
|
||||||
|
extra_target,
|
||||||
|
statbuf.st_dev,
|
||||||
|
attribute_matcher,
|
||||||
|
info,
|
||||||
|
NULL,
|
||||||
|
&parent_info->extra_data,
|
||||||
|
&parent_info->free_extra_data);
|
||||||
|
}
|
||||||
|
|
||||||
g_file_info_unset_attribute_mask (info);
|
g_file_info_unset_attribute_mask (info);
|
||||||
|
|
||||||
|
g_free (symlink_target);
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2126,6 +2164,8 @@ _g_local_file_info_set_attribute (char *filename,
|
|||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GFileAttributeValue value = { 0 };
|
GFileAttributeValue value = { 0 };
|
||||||
|
GVfsClass *class;
|
||||||
|
GVfs *vfs;
|
||||||
|
|
||||||
_g_file_attribute_value_set_from_pointer (&value, type, value_p, FALSE);
|
_g_file_attribute_value_set_from_pointer (&value, type, value_p, FALSE);
|
||||||
|
|
||||||
@ -2166,7 +2206,36 @@ _g_local_file_info_set_attribute (char *filename,
|
|||||||
else if (strcmp (attribute, G_FILE_ATTRIBUTE_SELINUX_CONTEXT) == 0)
|
else if (strcmp (attribute, G_FILE_ATTRIBUTE_SELINUX_CONTEXT) == 0)
|
||||||
return set_selinux_context (filename, &value, error);
|
return set_selinux_context (filename, &value, error);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
vfs = g_vfs_get_default ();
|
||||||
|
class = G_VFS_GET_CLASS (vfs);
|
||||||
|
if (class->local_file_set_attributes)
|
||||||
|
{
|
||||||
|
GFileInfo *info;
|
||||||
|
|
||||||
|
info = g_file_info_new ();
|
||||||
|
g_file_info_set_attribute (info,
|
||||||
|
attribute,
|
||||||
|
type,
|
||||||
|
value_p);
|
||||||
|
if (!class->local_file_set_attributes (vfs, filename,
|
||||||
|
info,
|
||||||
|
flags, cancellable,
|
||||||
|
error))
|
||||||
|
{
|
||||||
|
g_object_unref (info);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_file_info_get_attribute_status (info, attribute) == G_FILE_ATTRIBUTE_STATUS_SET)
|
||||||
|
{
|
||||||
|
g_object_unref (info);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref (info);
|
||||||
|
}
|
||||||
|
|
||||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||||
_("Setting attribute %s not supported"), attribute);
|
_("Setting attribute %s not supported"), attribute);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -2190,6 +2259,8 @@ _g_local_file_info_set_attributes (char *filename,
|
|||||||
GFileAttributeStatus status;
|
GFileAttributeStatus status;
|
||||||
#endif
|
#endif
|
||||||
gboolean res;
|
gboolean res;
|
||||||
|
GVfsClass *class;
|
||||||
|
GVfs *vfs;
|
||||||
|
|
||||||
/* Handles setting multiple specified data in a single set, and takes care
|
/* Handles setting multiple specified data in a single set, and takes care
|
||||||
of ordering restrictions when setting attributes */
|
of ordering restrictions when setting attributes */
|
||||||
@ -2310,5 +2381,20 @@ _g_local_file_info_set_attributes (char *filename,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
vfs = g_vfs_get_default ();
|
||||||
|
class = G_VFS_GET_CLASS (vfs);
|
||||||
|
if (class->local_file_set_attributes)
|
||||||
|
{
|
||||||
|
if (!class->local_file_set_attributes (vfs, filename,
|
||||||
|
info,
|
||||||
|
flags, cancellable,
|
||||||
|
error))
|
||||||
|
{
|
||||||
|
res = FALSE;
|
||||||
|
/* Don't set error multiple times */
|
||||||
|
error = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,8 @@ typedef struct
|
|||||||
gboolean has_trash_dir;
|
gboolean has_trash_dir;
|
||||||
int owner;
|
int owner;
|
||||||
dev_t device;
|
dev_t device;
|
||||||
|
gpointer extra_data;
|
||||||
|
GDestroyNotify free_extra_data;
|
||||||
} GLocalParentFileInfo;
|
} GLocalParentFileInfo;
|
||||||
|
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
@ -53,6 +55,7 @@ gboolean _g_local_file_has_trash_dir (const char *dirname,
|
|||||||
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);
|
||||||
|
void _g_local_file_info_free_parent_info (GLocalParentFileInfo *parent_info);
|
||||||
GFileInfo *_g_local_file_info_get (const char *basename,
|
GFileInfo *_g_local_file_info_get (const char *basename,
|
||||||
const char *path,
|
const char *path,
|
||||||
GFileAttributeMatcher *attribute_matcher,
|
GFileAttributeMatcher *attribute_matcher,
|
||||||
|
26
gio/gvfs.h
26
gio/gvfs.h
@ -75,6 +75,27 @@ struct _GVfsClass
|
|||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
/* Padding for future expansion */
|
/* Padding for future expansion */
|
||||||
|
void (* local_file_add_info) (GVfs *vfs,
|
||||||
|
const char *filename,
|
||||||
|
guint64 device,
|
||||||
|
GFileAttributeMatcher *attribute_matcher,
|
||||||
|
GFileInfo *info,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
gpointer *extra_data,
|
||||||
|
GDestroyNotify *free_extra_data);
|
||||||
|
void (* add_writable_namespaces) (GVfs *vfs,
|
||||||
|
GFileAttributeInfoList *list);
|
||||||
|
gboolean (* local_file_set_attributes) (GVfs *vfs,
|
||||||
|
const char *filename,
|
||||||
|
GFileInfo *info,
|
||||||
|
GFileQueryInfoFlags flags,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error);
|
||||||
|
void (* local_file_removed) (GVfs *vfs,
|
||||||
|
const char *filename);
|
||||||
|
void (* local_file_moved) (GVfs *vfs,
|
||||||
|
const char *source,
|
||||||
|
const char *dest);
|
||||||
void (*_g_reserved1) (void);
|
void (*_g_reserved1) (void);
|
||||||
void (*_g_reserved2) (void);
|
void (*_g_reserved2) (void);
|
||||||
void (*_g_reserved3) (void);
|
void (*_g_reserved3) (void);
|
||||||
@ -82,11 +103,6 @@ struct _GVfsClass
|
|||||||
void (*_g_reserved5) (void);
|
void (*_g_reserved5) (void);
|
||||||
void (*_g_reserved6) (void);
|
void (*_g_reserved6) (void);
|
||||||
void (*_g_reserved7) (void);
|
void (*_g_reserved7) (void);
|
||||||
void (*_g_reserved8) (void);
|
|
||||||
void (*_g_reserved9) (void);
|
|
||||||
void (*_g_reserved10) (void);
|
|
||||||
void (*_g_reserved11) (void);
|
|
||||||
void (*_g_reserved12) (void);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GType g_vfs_get_type (void) G_GNUC_CONST;
|
GType g_vfs_get_type (void) G_GNUC_CONST;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user