[glib] Add extension point for adding metadata for local files
- From: Alexander Larsson <alexl src gnome org>
- To: svn-commits-list gnome org
- Subject: [glib] Add extension point for adding metadata for local files
- Date: Tue, 23 Jun 2009 11:07:13 -0400 (EDT)
commit 7662c86611bf44175f18ec6eb66f159040ac73c5
Author: Alexander Larsson <alexl redhat com>
Date: Thu Jun 18 09:05:27 2009 +0200
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.
gio/glocalfile.c | 75 +++++++++++++++++++++---------
gio/glocalfileenumerator.c | 2 +
gio/glocalfileinfo.c | 108 +++++++++++++++++++++++++++++++++++++++-----
gio/glocalfileinfo.h | 3 +
gio/gvfs.h | 26 +++++++++--
5 files changed, 175 insertions(+), 39 deletions(-)
---
diff --git a/gio/glocalfile.c b/gio/glocalfile.c
index 8ac6014..1f956a5 100644
--- a/gio/glocalfile.c
+++ b/gio/glocalfile.c
@@ -110,7 +110,7 @@
static void g_local_file_file_iface_init (GFileIface *iface);
static GFileAttributeInfoList *local_writable_attributes = NULL;
-static GFileAttributeInfoList *local_writable_namespaces = NULL;
+static /* GFileAttributeInfoList * */ gsize local_writable_namespaces = 0;
struct _GLocalFile
{
@@ -201,24 +201,6 @@ g_local_file_class_init (GLocalFileClass *klass)
#endif
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
@@ -1204,6 +1186,8 @@ g_local_file_query_info (GFile *file,
matcher, flags, &parent_info,
error);
+
+ _g_local_file_info_free_parent_info (&parent_info);
g_free (basename);
g_file_attribute_matcher_unref (matcher);
@@ -1224,7 +1208,38 @@ g_local_file_query_writable_namespaces (GFile *file,
GCancellable *cancellable,
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
@@ -1409,7 +1424,9 @@ g_local_file_delete (GFile *file,
GError **error)
{
GLocalFile *local = G_LOCAL_FILE (file);
-
+ GVfsClass *class;
+ GVfs *vfs;
+
if (g_remove (local->filename) == -1)
{
int errsv = errno;
@@ -1426,7 +1443,12 @@ g_local_file_delete (GFile *file,
g_strerror (errsv));
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;
}
@@ -2176,7 +2198,9 @@ g_local_file_move (GFile *source,
char *backup_name;
int res;
off_t source_size;
-
+ GVfsClass *class;
+ GVfs *vfs;
+
if (!G_IS_LOCAL_FILE (source) ||
!G_IS_LOCAL_FILE (destination))
{
@@ -2294,6 +2318,11 @@ g_local_file_move (GFile *source,
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 */
if (progress_callback)
progress_callback (source_size, source_size, progress_callback_data);
diff --git a/gio/glocalfileenumerator.c b/gio/glocalfileenumerator.c
index eda7b03..e39c050 100644
--- a/gio/glocalfileenumerator.c
+++ b/gio/glocalfileenumerator.c
@@ -116,6 +116,8 @@ g_local_file_enumerator_finalize (GObject *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_file_attribute_matcher_unref (local->matcher);
if (local->dir)
diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c
index 95ccf2e..c6d4be0 100644
--- a/gio/glocalfileinfo.c
+++ b/gio/glocalfileinfo.c
@@ -60,6 +60,7 @@
#include <glib/gstdio.h>
#include <gfileattribute-priv.h>
+#include <gvfs.h>
#include "glibintl.h"
@@ -791,7 +792,9 @@ _g_local_file_info_get_parent_info (const char *dir,
*/
struct stat statbuf;
int res;
-
+
+ parent_info->extra_data = NULL;
+ parent_info->free_extra_data = NULL;
parent_info->writable = FALSE;
parent_info->is_sticky = 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
get_access_rights (GFileAttributeMatcher *attribute_matcher,
GFileInfo *info,
@@ -1417,6 +1428,9 @@ _g_local_file_info_get (const char *basename,
#ifdef G_OS_WIN32
DWORD dos_attributes;
#endif
+ char *symlink_target;
+ GVfs *vfs;
+ GVfsClass *class;
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);
#endif
-#ifdef S_ISLNK
- if (is_symlink &&
- g_file_attribute_matcher_matches (attribute_matcher,
- G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET))
+ symlink_target = NULL;
+ if (is_symlink)
{
- char *link = read_link (path);
- g_file_info_set_symlink_target (info, link);
- g_free (link);
+ symlink_target = read_link (path);
+ if (symlink_target &&
+ 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,
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,
G_FILE_ATTRIBUTE_THUMBNAIL_PATH))
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_free (symlink_target);
+
return info;
}
@@ -2126,6 +2164,8 @@ _g_local_file_info_set_attribute (char *filename,
GError **error)
{
GFileAttributeValue value = { 0 };
+ GVfsClass *class;
+ GVfs *vfs;
_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)
return set_selinux_context (filename, &value, error);
#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,
_("Setting attribute %s not supported"), attribute);
return FALSE;
@@ -2190,6 +2259,8 @@ _g_local_file_info_set_attributes (char *filename,
GFileAttributeStatus status;
#endif
gboolean res;
+ GVfsClass *class;
+ GVfs *vfs;
/* Handles setting multiple specified data in a single set, and takes care
of ordering restrictions when setting attributes */
@@ -2310,5 +2381,20 @@ _g_local_file_info_set_attributes (char *filename,
}
#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;
}
diff --git a/gio/glocalfileinfo.h b/gio/glocalfileinfo.h
index 29ccfc0..82ad746 100644
--- a/gio/glocalfileinfo.h
+++ b/gio/glocalfileinfo.h
@@ -39,6 +39,8 @@ typedef struct
gboolean has_trash_dir;
int owner;
dev_t device;
+ gpointer extra_data;
+ GDestroyNotify free_extra_data;
} GLocalParentFileInfo;
#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,
GFileAttributeMatcher *attribute_matcher,
GLocalParentFileInfo *parent_info);
+void _g_local_file_info_free_parent_info (GLocalParentFileInfo *parent_info);
GFileInfo *_g_local_file_info_get (const char *basename,
const char *path,
GFileAttributeMatcher *attribute_matcher,
diff --git a/gio/gvfs.h b/gio/gvfs.h
index bb8fd80..be0156f 100644
--- a/gio/gvfs.h
+++ b/gio/gvfs.h
@@ -75,6 +75,27 @@ struct _GVfsClass
/*< private >*/
/* 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_reserved2) (void);
void (*_g_reserved3) (void);
@@ -82,11 +103,6 @@ struct _GVfsClass
void (*_g_reserved5) (void);
void (*_g_reserved6) (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;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]