From 617d1132bef45889283325fa28f6d5a9e3085135 Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Nov 18 2009 14:05:08 +0000 Subject: - Update to 1.5.1 - AFC: temporarily disable setting file modification times --- diff --git a/.cvsignore b/.cvsignore index a3de04a..2333f99 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -gvfs-1.4.0.tar.bz2 +gvfs-1.5.1.tar.bz2 diff --git a/0001-Add-AFC-backend.patch b/0001-Add-AFC-backend.patch deleted file mode 100644 index 144ee50..0000000 --- a/0001-Add-AFC-backend.patch +++ /dev/null @@ -1,2238 +0,0 @@ -From 8675a60e030fc91292d19cfd2cd9a6d74dd1776f Mon Sep 17 00:00:00 2001 -From: Bastien Nocera -Date: Thu, 6 Aug 2009 22:55:47 +0100 -Subject: [PATCH] Add AFC backend - -Add a backend based on libiphone to access data on Apple's iPhone, -and iPod Touch. - -Code by: -Patrick Walton -Martin Szulecki -Nikias Bassen -Bastien Nocera ---- - configure.ac | 26 +- - daemon/Makefile.am | 23 + - daemon/afc.mount.in | 7 + - daemon/gvfsbackendafc.c | 1228 ++++++++++++++++++++ - daemon/gvfsbackendafc.h | 37 + - monitor/Makefile.am | 6 +- - monitor/afc/Makefile.am | 49 + - monitor/afc/afc.monitor | 5 + - monitor/afc/afcvolume.c | 353 ++++++ - monitor/afc/afcvolume.h | 44 + - monitor/afc/afcvolumemonitor.c | 224 ++++ - monitor/afc/afcvolumemonitor.h | 39 + - monitor/afc/afcvolumemonitordaemon.c | 31 + - .../org.gtk.Private.AfcVolumeMonitor.service.in | 4 + - 14 files changed, 2074 insertions(+), 2 deletions(-) - create mode 100644 daemon/afc.mount.in - create mode 100644 daemon/gvfsbackendafc.c - create mode 100644 daemon/gvfsbackendafc.h - create mode 100644 monitor/afc/Makefile.am - create mode 100644 monitor/afc/afc.monitor - create mode 100644 monitor/afc/afcvolume.c - create mode 100644 monitor/afc/afcvolume.h - create mode 100644 monitor/afc/afcvolumemonitor.c - create mode 100644 monitor/afc/afcvolumemonitor.h - create mode 100644 monitor/afc/afcvolumemonitordaemon.c - create mode 100644 monitor/afc/org.gtk.Private.AfcVolumeMonitor.service.in - -diff --git a/configure.ac b/configure.ac -index 9bfb8ad..6b3838c 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -324,6 +324,28 @@ AC_SUBST(CDDA_CFLAGS) - - AM_CONDITIONAL(USE_CDDA, [test "$msg_cdda" = "yes"]) - -+dnl ************************************************* -+dnl *** Check if we should build with AFC backend *** -+dnl ************************************************* -+AC_ARG_ENABLE(afc, [ --disable-afc build without AFC backend]) -+msg_afc=no -+AFC_LIBS= -+AFC_CFLAGS= -+ -+if test "x$enable_afc" != "xno" -a "x$msg_gudev" = "xyes" ; then -+ PKG_CHECK_EXISTS(libiphone-1.0 >= 0.9.2, msg_afc=yes) -+ -+ if test "x$msg_afc" = "xyes"; then -+ PKG_CHECK_MODULES(AFC, libiphone-1.0 gudev-1.0) -+ AC_DEFINE(HAVE_AFC, 1, [Define to 1 if AFC is going to be built]) -+ fi -+fi -+ -+AC_SUBST(AFC_LIBS) -+AC_SUBST(AFC_CFLAGS) -+ -+AM_CONDITIONAL(USE_AFC, [test "$msg_afc" = "yes"]) -+ - dnl ***************************************************** - dnl *** Check if we should build with obexftp backend *** - dnl ***************************************************** -@@ -695,6 +717,7 @@ monitor/proxy/Makefile - monitor/hal/Makefile - monitor/gdu/Makefile - monitor/gphoto2/Makefile -+monitor/afc/Makefile - gconf/Makefile - programs/Makefile - test/Makefile -@@ -712,7 +735,8 @@ echo " - FUSE support: $msg_fuse - CDDA support: $msg_cdda - Gphoto2 support: $msg_gphoto2 -- archive support: $msg_archive -+ archive support: $msg_archive -+ AFC support: $msg_afc - GConf support: $msg_gconf - DNS-SD support: $msg_avahi - Build HAL volume monitor: $msg_hal (with fast init path: $have_hal_fast_init) -diff --git a/daemon/Makefile.am b/daemon/Makefile.am -index a03eba1..cf68391 100644 ---- a/daemon/Makefile.am -+++ b/daemon/Makefile.am -@@ -101,6 +101,12 @@ mount_DATA += archive.mount - libexec_PROGRAMS += gvfsd-archive - endif - -+mount_in_files += afc.mount.in -+if USE_AFC -+mount_DATA += afc.mount -+libexec_PROGRAMS += gvfsd-afc -+endif -+ - EXTRA_DIST = gvfs-daemon.service.in $(mount_in_files) obexftp-marshal.list - - DISTCLEANFILES = gvfs-daemon.service $(mount_DATA) -@@ -442,3 +448,20 @@ gvfsd_dav_LDADD = $(libraries) $(HTTP_LIBS) - if HAVE_AVAHI - gvfsd_dav_LDADD += $(top_builddir)/common/libgvfscommon-dnssd.la - endif -+ -+gvfsd_afc_SOURCES = \ -+ gvfsbackendafc.c gvfsbackendafc.h \ -+ daemon-main.c daemon-main.h \ -+ daemon-main-generic.c -+ -+gvfsd_afc_CPPFLAGS = \ -+ -DBACKEND_HEADER=gvfsbackendafc.h \ -+ -DDEFAULT_BACKEND_TYPE=afc \ -+ -DMAX_JOB_THREADS=1 \ -+ $(AFC_CFLAGS) \ -+ -DBACKEND_TYPES='"afc", G_VFS_TYPE_BACKEND_AFC,' -+ -+gvfsd_afc_LDADD = \ -+ $(libraries) \ -+ $(AFC_LIBS) -+ -diff --git a/daemon/afc.mount.in b/daemon/afc.mount.in -new file mode 100644 -index 0000000..727d833 ---- /dev/null -+++ b/daemon/afc.mount.in -@@ -0,0 +1,7 @@ -+[Mount] -+Type=afc -+Exec=@libexecdir@/gvfsd-afc -+AutoMount=false -+Scheme=afc -+DefaultPort=1 -+ -diff --git a/daemon/gvfsbackendafc.c b/daemon/gvfsbackendafc.c -new file mode 100644 -index 0000000..d30ede8 ---- /dev/null -+++ b/daemon/gvfsbackendafc.c -@@ -0,0 +1,1228 @@ -+/* -+ * gvfs/daemon/gvfsbackendafc.c -+ * -+ * Copyright (c) 2008 Patrick Walton -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+#include -+ -+#include "gvfsbackendafc.h" -+#include "gvfsjobopenforread.h" -+#include "gvfsjobread.h" -+#include "gvfsjobseekread.h" -+#include "gvfsjobopenforwrite.h" -+#include "gvfsjobwrite.h" -+#include "gvfsjobseekwrite.h" -+#include "gvfsjobsetdisplayname.h" -+#include "gvfsjobqueryinfo.h" -+#include "gvfsjobqueryfsinfo.h" -+#include "gvfsjobqueryattributes.h" -+#include "gvfsjobenumerate.h" -+#include "gvfsdaemonprotocol.h" -+#include "gvfsdaemonutils.h" -+ -+#define G_VFS_BACKEND_AFC_MAX_FILE_SIZE G_MAXINT64 -+int g_blocksize = 4096; /* assume this is the default block size */ -+ -+struct _GVfsBackendAfc { -+ GVfsBackend backend; -+ -+ GUdevClient *client; -+ -+ char uuid[41]; -+ char *service; -+ char *model; -+ gboolean connected; -+ -+ iphone_device_t dev; -+ afc_client_t afc_cli; -+}; -+ -+struct afc_error_mapping { -+ afc_error_t from; -+ GIOErrorEnum to; -+}; -+ -+static struct afc_error_mapping afc_error_to_g_io_error[] = { -+ { AFC_E_UNKNOWN_ERROR , G_IO_ERROR_FAILED }, -+ { AFC_E_OP_HEADER_INVALID , G_IO_ERROR_FAILED }, -+ { AFC_E_NO_RESOURCES , G_IO_ERROR_TOO_MANY_OPEN_FILES }, -+ { AFC_E_READ_ERROR , G_IO_ERROR_NOT_DIRECTORY }, -+ { AFC_E_WRITE_ERROR , G_IO_ERROR_FAILED }, -+ { AFC_E_UNKNOWN_PACKET_TYPE , G_IO_ERROR_FAILED }, -+ { AFC_E_INVALID_ARGUMENT , G_IO_ERROR_INVALID_ARGUMENT }, -+ { AFC_E_OBJECT_NOT_FOUND , G_IO_ERROR_NOT_FOUND }, -+ { AFC_E_OBJECT_IS_DIR , G_IO_ERROR_IS_DIRECTORY }, -+ { AFC_E_DIR_NOT_EMPTY , G_IO_ERROR_NOT_EMPTY }, -+ { AFC_E_PERM_DENIED , G_IO_ERROR_PERMISSION_DENIED }, -+ { AFC_E_SERVICE_NOT_CONNECTED , G_IO_ERROR_HOST_NOT_FOUND }, -+ { AFC_E_OP_TIMEOUT , G_IO_ERROR_TIMED_OUT }, -+ { AFC_E_TOO_MUCH_DATA , G_IO_ERROR_FAILED }, -+ { AFC_E_END_OF_DATA , G_IO_ERROR_FAILED }, -+ { AFC_E_OP_NOT_SUPPORTED , G_IO_ERROR_NOT_SUPPORTED }, -+ { AFC_E_OBJECT_EXISTS , G_IO_ERROR_EXISTS }, -+ { AFC_E_OBJECT_BUSY , G_IO_ERROR_BUSY }, -+ { AFC_E_NO_SPACE_LEFT , G_IO_ERROR_NO_SPACE }, -+ { AFC_E_OP_WOULD_BLOCK , G_IO_ERROR_WOULD_BLOCK }, -+ { AFC_E_IO_ERROR , G_IO_ERROR_FAILED }, -+ { AFC_E_OP_INTERRUPTED , G_IO_ERROR_CANCELLED }, -+ { AFC_E_OP_IN_PROGRESS , G_IO_ERROR_PENDING }, -+ { AFC_E_INTERNAL_ERROR , G_IO_ERROR_FAILED }, -+ { AFC_E_NOT_ENOUGH_DATA , G_IO_ERROR_CLOSED }, -+ { AFC_E_MUX_ERROR , G_IO_ERROR_FAILED }, -+ { -1 } -+}; -+ -+/** -+ * Tries to convert the AFC error value into a GIOError. -+ * -+ * @param client AFC client to retrieve status value from. -+ * -+ * @return errno value. -+ */ -+static GIOErrorEnum -+g_io_error_from_afc_error (afc_error_t error) -+{ -+ GIOErrorEnum res = G_IO_ERROR_FAILED; -+ int i = 0; gboolean found = FALSE; -+ -+ while (afc_error_to_g_io_error[i++].from != -1) -+ { -+ if (afc_error_to_g_io_error[i].from == error) -+ { -+ res = afc_error_to_g_io_error[i++].to; -+ found = TRUE; -+ break; -+ } -+ } -+ -+ if (!found) -+ g_warning ("Unknown AFC error (%d).\n", error); -+ -+ return res; -+} -+ -+G_DEFINE_TYPE(GVfsBackendAfc, g_vfs_backend_afc, G_VFS_TYPE_BACKEND) -+ -+static void -+g_vfs_backend_afc_close_connection (GVfsBackendAfc *self) -+{ -+ if (self->connected) -+ { -+ afc_client_free (self->afc_cli); -+ g_free (self->model); -+ self->model = NULL; -+ iphone_device_free (self->dev); -+ } -+ self->connected = FALSE; -+} -+ -+static int -+g_vfs_backend_afc_check (afc_error_t cond, GVfsJob *job) -+{ -+ GIOErrorEnum error; -+ -+ if (G_LIKELY(cond == AFC_E_SUCCESS)) -+ return 0; -+ -+ error = g_io_error_from_afc_error (cond); -+ switch (cond) -+ { -+ case AFC_E_INTERNAL_ERROR: -+ g_vfs_job_failed (job, G_IO_ERROR, error, -+ _("Internal Apple File Control error")); -+ break; -+ case AFC_E_OBJECT_NOT_FOUND: -+ g_vfs_job_failed (job, G_IO_ERROR, error, -+ _("File does not exist")); -+ case AFC_E_DIR_NOT_EMPTY: -+ g_vfs_job_failed (job, G_IO_ERROR, error, -+ _("The directory is not empty")); -+ break; -+ case AFC_E_OP_TIMEOUT: -+ g_vfs_job_failed (job, G_IO_ERROR, error, -+ _("The device did not respond")); -+ break; -+ case AFC_E_NOT_ENOUGH_DATA: -+ g_vfs_job_failed (job, G_IO_ERROR, error, -+ _("The connection was interrupted")); -+ break; -+ case AFC_E_MUX_ERROR: -+ g_vfs_job_failed (job, G_IO_ERROR, error, -+ _("Invalid Apple File Control data received")); -+ break; -+ default: -+ g_vfs_job_failed (job, G_IO_ERROR, error, -+ _("Unhandled Apple File Control error (%d)"), cond); -+ break; -+ } -+ -+ return 1; -+} -+ -+static int -+g_vfs_backend_lockdownd_check (lockdownd_error_t cond, GVfsJob *job) -+{ -+ if (G_LIKELY(cond == LOCKDOWN_E_SUCCESS)) -+ return 0; -+ -+ switch (cond) -+ { -+ case LOCKDOWN_E_INVALID_ARG: -+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, -+ _("Lockdown Error: Invalid Argument")); -+ break; -+ default: -+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_FAILED, -+ _("Unhandled Lockdown error (%d)"), cond); -+ break; -+ } -+ -+ return 1; -+} -+ -+static int -+g_vfs_backend_iphone_check (iphone_error_t cond, GVfsJob *job) -+{ -+ if (G_LIKELY(cond == IPHONE_E_SUCCESS)) -+ return 0; -+ -+ switch (cond) -+ { -+ case IPHONE_E_INVALID_ARG: -+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, -+ _("iPhone Device Error: Invalid Argument")); -+ break; -+ case IPHONE_E_NO_DEVICE: -+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_FAILED, -+ _("iPhone Device Error: No device found. Make sure usbmuxd is set up correctly.")); -+ default: -+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_FAILED, -+ _("Unhandled iPhone Device error (%d)"), cond); -+ break; -+ } -+ -+ return 1; -+} -+ -+static void -+_uevent_cb (GUdevClient *client, -+ const gchar *action, -+ GUdevDevice *device, -+ gpointer user_data) -+{ -+ GVfsBackendAfc *afc_backend = G_VFS_BACKEND_AFC (user_data); -+ const char *uuid; -+ -+ g_return_if_fail (afc_backend->uuid != NULL); -+ -+ if (g_str_equal (action, "remove") == FALSE) -+ return; -+ uuid = g_udev_device_get_property (device, "ID_SERIAL_SHORT"); -+ if (uuid == NULL || -+ g_str_equal (uuid, afc_backend->uuid) == FALSE) -+ return; -+ -+ g_print ("Shutting down AFC backend for device uuid %s\n", afc_backend->uuid); -+ -+ g_vfs_backend_afc_close_connection (afc_backend); -+ -+ /* TODO: need a cleaner way to force unmount ourselves */ -+ exit (1); -+} -+ -+/* Callback for mounting. */ -+static void -+g_vfs_backend_afc_mount (GVfsBackend *backend, -+ GVfsJobMount *job, -+ GMountSpec *spec, -+ GMountSource *src, -+ gboolean automounting) -+{ -+ const char *str; -+ char *tmp; -+ char *display_name; -+ int port, virtual_port; -+ GMountSpec *real_spec; -+ GVfsBackendAfc *self; -+ int retries; -+ iphone_error_t err; -+ lockdownd_client_t lockdown_cli = NULL; -+ const gchar * const subsystems[] = { "usb", NULL }; -+ -+ self = G_VFS_BACKEND_AFC(backend); -+ self->connected = FALSE; -+ self->client = g_udev_client_new (subsystems); -+ g_signal_connect (G_OBJECT (self->client), "uevent", -+ G_CALLBACK (_uevent_cb), self); -+ -+ /* setup afc */ -+ -+ str = g_mount_spec_get(spec, "host"); -+ if (G_UNLIKELY(str == NULL)) -+ { -+ g_vfs_job_failed (G_VFS_JOB (job), -+ G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, -+ _("Invalid mount spec")); -+ return; -+ } -+ if (G_UNLIKELY(sscanf(str, "%40s", &self->uuid) < 1)) -+ { -+ g_vfs_job_failed (G_VFS_JOB(job), G_IO_ERROR, G_IO_ERROR_FAILED, -+ _("Invalid AFC location: must be in the form of " -+ "afc://uuid:port-number")); -+ return; -+ } -+ -+ str = g_mount_spec_get (spec, "port"); -+ if (str == NULL) -+ virtual_port = 1; -+ else -+ virtual_port = atoi (str); -+ -+ /* set a generic display name */ -+ if (virtual_port >= 2) -+ { -+ self->service = g_strdup_printf ("com.apple.afc%d", virtual_port); -+ display_name = g_strdup_printf (_("Service %d on Apple Mobile Device"), -+ virtual_port); -+ } -+ else -+ { -+ self->service = g_strdup ("com.apple.afc"); -+ display_name = g_strdup_printf (_("Apple Mobile Device")); -+ } -+ -+ g_vfs_backend_set_display_name (G_VFS_BACKEND(self), display_name); -+ g_free (display_name); -+ -+ real_spec = g_mount_spec_new ("afc"); -+ tmp = g_strdup_printf ("%40s", &self->uuid); -+ g_mount_spec_set (real_spec, "host", tmp); -+ g_free (tmp); -+ -+ /* INFO: Don't ever set the DefaultPort again or everything goes crazy */ -+ if (virtual_port != 1) -+ { -+ tmp = g_strdup_printf ("%d", virtual_port); -+ g_mount_spec_set (real_spec, "port", tmp); -+ g_free (tmp); -+ } -+ -+ g_vfs_backend_set_mount_spec (G_VFS_BACKEND(self), real_spec); -+ g_mount_spec_unref (real_spec); -+ -+ retries = 0; -+ do { -+ err = iphone_get_device_by_uuid(&self->dev, self->uuid); -+ if (err == IPHONE_E_SUCCESS) -+ break; -+ g_usleep (G_USEC_PER_SEC); -+ } while (retries++ < 10); -+ -+ if (G_UNLIKELY(g_vfs_backend_iphone_check(err, G_VFS_JOB(job)))) -+ goto out_destroy_service; -+ if (G_UNLIKELY(g_vfs_backend_lockdownd_check (lockdownd_client_new (self->dev, -+ &lockdown_cli), -+ G_VFS_JOB(job)))) -+ { -+ goto out_destroy_dev; -+ } -+ -+ /* try to use pretty device name */ -+ if (LOCKDOWN_E_SUCCESS == lockdownd_get_device_name (lockdown_cli, &display_name)) -+ { -+ if (display_name) -+ { -+ if (virtual_port >= 2) -+ { -+ /* translators: -+ * This is the device name, with the service being browsed in brackets, eg.: -+ * Alan Smithee's iPhone (Service 2 on Apple Mobile Device */ -+ g_vfs_backend_set_display_name (G_VFS_BACKEND(self), -+ g_strdup_printf (_("%s (%s)"), display_name, self->service)); -+ } -+ else -+ { -+ g_vfs_backend_set_display_name (G_VFS_BACKEND(self), display_name); -+ } -+ g_free (display_name); -+ } -+ } -+ -+ if (G_UNLIKELY(g_vfs_backend_lockdownd_check (lockdownd_start_service (lockdown_cli, -+ self->service, &port), -+ G_VFS_JOB(job)))) -+ { -+ goto out_destroy_lockdown; -+ } -+ if (G_UNLIKELY(g_vfs_backend_afc_check (afc_client_new (self->dev, -+ port, &self->afc_cli), -+ G_VFS_JOB(job)))) -+ { -+ goto out_destroy_lockdown; -+ } -+ -+ /* set correct fd icon spec name depending on device model */ -+ self->model = afc_get_device_info_field (self->afc_cli, "Model"); -+ if (G_UNLIKELY(self->model == NULL)) -+ goto out_destroy_afc; -+ -+ if (strstr(self->model, "iPod") != NULL) -+ { -+ g_vfs_backend_set_icon_name (G_VFS_BACKEND(self), "multimedia-player-apple-ipod-touch"); -+ } -+ else -+ { -+ g_vfs_backend_set_icon_name (G_VFS_BACKEND(self), "phone-apple-iphone"); -+ } -+ -+ /* lockdown connection is not needed anymore */ -+ lockdownd_client_free (lockdown_cli); -+ -+ self->connected = TRUE; -+ g_vfs_job_succeeded (G_VFS_JOB(job)); -+ return; -+ -+out_destroy_afc: -+ afc_client_free (self->afc_cli); -+ -+out_destroy_lockdown: -+ lockdownd_client_free (lockdown_cli); -+ -+out_destroy_dev: -+ iphone_device_free (self->dev); -+ -+out_destroy_service: -+ g_free (self->service); -+ g_free(self->model); -+} -+ -+static void -+g_vfs_backend_afc_unmount (GVfsBackend *backend, -+ GVfsJobUnmount *job, -+ GMountUnmountFlags flags, -+ GMountSource *mount_source) -+{ -+ GVfsBackendAfc *self; -+ -+ /* FIXME: check on G_MOUNT_UNMOUNT_FORCE flag */ -+ self = G_VFS_BACKEND_AFC (backend); -+ g_vfs_backend_afc_close_connection (self); -+ g_vfs_job_succeeded (G_VFS_JOB(job)); -+} -+ -+/* Callback to open an existing file for reading. */ -+static void -+g_vfs_backend_afc_open_for_read (GVfsBackend *backend, -+ GVfsJobOpenForRead *job, -+ const char *path) -+{ -+ uint64_t fd = 0; -+ GVfsBackendAfc *self; -+ -+ self = G_VFS_BACKEND_AFC(backend); -+ g_return_if_fail (self->connected); -+ -+ if (G_UNLIKELY(g_vfs_backend_afc_check (afc_file_open (self->afc_cli, -+ path, AFC_FOPEN_RDONLY, &fd), -+ G_VFS_JOB(job)))) -+ { -+ return; -+ } -+ -+ g_vfs_job_open_for_read_set_handle (job, GUINT_TO_POINTER((gulong) fd)); -+ g_vfs_job_open_for_read_set_can_seek (job, TRUE); -+ g_vfs_job_succeeded (G_VFS_JOB(job)); -+ -+ return; -+} -+ -+/* Callback to open a nonexistent file for writing. */ -+static void -+g_vfs_backend_afc_create (GVfsBackend *backend, -+ GVfsJobOpenForWrite *job, -+ const char *path, -+ GFileCreateFlags flags) -+{ -+ uint64_t fd = 0; -+ GVfsBackendAfc *self; -+ -+ self = G_VFS_BACKEND_AFC(backend); -+ g_return_if_fail (self->connected); -+ -+ if (G_UNLIKELY(g_vfs_backend_afc_check (afc_file_open (self->afc_cli, -+ path, AFC_FOPEN_RW, &fd), -+ G_VFS_JOB(job)))) -+ { -+ return; -+ } -+ -+ g_vfs_job_open_for_write_set_handle (job, GUINT_TO_POINTER((gulong)fd)); -+ g_vfs_job_open_for_write_set_can_seek (job, TRUE); -+ g_vfs_job_succeeded (G_VFS_JOB(job)); -+ -+ return; -+} -+ -+/* Callback to open a possibly-existing file for writing. */ -+static void -+g_vfs_backend_afc_append_to (GVfsBackend *backend, -+ GVfsJobOpenForWrite *job, -+ const char *path, -+ GFileCreateFlags flags) -+{ -+ uint64_t fd = 0; -+ uint64_t off = 0; -+ GVfsBackendAfc *self; -+ -+ self = G_VFS_BACKEND_AFC(backend); -+ g_return_if_fail (self->connected); -+ -+ if (G_UNLIKELY(g_vfs_backend_afc_check (afc_file_open (self->afc_cli, -+ path, AFC_FOPEN_RW, &fd), -+ G_VFS_JOB(job)))) -+ { -+ return; -+ } -+ -+ if (G_UNLIKELY(g_vfs_backend_afc_check (afc_file_seek (self->afc_cli, -+ fd, 0, SEEK_END), -+ G_VFS_JOB(job)))) -+ { -+ return; -+ } -+ -+ if (G_UNLIKELY(g_vfs_backend_afc_check (afc_file_tell (self->afc_cli, -+ fd, &off), -+ G_VFS_JOB(job)))) -+ { -+ return; -+ } -+ -+ g_vfs_job_open_for_write_set_handle (job, GUINT_TO_POINTER((gulong)fd)); -+ g_vfs_job_open_for_write_set_can_seek (job, TRUE); -+ g_vfs_job_open_for_write_set_initial_offset (job, off); -+ g_vfs_job_succeeded (G_VFS_JOB(job)); -+ -+ return; -+} -+ -+static void -+g_vfs_backend_afc_replace (GVfsBackend *backend, -+ GVfsJobOpenForWrite *job, -+ const char *filename, -+ const char *etag, -+ gboolean make_backup, -+ GFileCreateFlags flags) -+{ -+ uint64_t fd = 0; -+ GVfsBackendAfc *self; -+ -+ self = G_VFS_BACKEND_AFC(backend); -+ g_return_if_fail(self->connected); -+ -+ if (make_backup) -+ { -+ /* FIXME: implement! */ -+ g_vfs_job_failed (G_VFS_JOB (job), -+ G_IO_ERROR, -+ G_IO_ERROR_CANT_CREATE_BACKUP, -+ _("Backups are not yet supported.")); -+ return; -+ } -+ -+ if (G_UNLIKELY(g_vfs_backend_afc_check (afc_file_open (self->afc_cli, -+ filename, AFC_FOPEN_WR, &fd), -+ G_VFS_JOB(job)))) -+ { -+ return; -+ } -+ -+ g_vfs_job_open_for_write_set_handle (job, GUINT_TO_POINTER((gulong)fd)); -+ g_vfs_job_open_for_write_set_can_seek (job, TRUE); -+ g_vfs_job_succeeded (G_VFS_JOB(job)); -+ -+ return; -+} -+ -+/* Callback to close a file that was previously opened for reading. */ -+static void -+g_vfs_backend_afc_close_read (GVfsBackend *backend, -+ GVfsJobCloseRead *job, -+ GVfsBackendHandle handle) -+{ -+ GVfsBackendAfc *self; -+ uint64_t fd = 0; -+ -+ fd = GPOINTER_TO_UINT(handle); -+ g_return_if_fail (fd != 0); -+ -+ self = G_VFS_BACKEND_AFC(backend); -+ -+ if (self->connected) -+ afc_file_close (self->afc_cli, fd); -+ -+ g_vfs_job_succeeded (G_VFS_JOB(job)); -+} -+ -+static void -+g_vfs_backend_afc_close_write (GVfsBackend *backend, -+ GVfsJobCloseWrite *job, -+ GVfsBackendHandle handle) -+{ -+ GVfsBackendAfc *self; -+ uint64_t fd = 0; -+ -+ fd = GPOINTER_TO_UINT(handle); -+ g_return_if_fail (fd != 0); -+ -+ self = G_VFS_BACKEND_AFC(backend); -+ -+ if (self->connected) -+ afc_file_close(self->afc_cli, fd); -+ -+ g_vfs_job_succeeded (G_VFS_JOB(job)); -+} -+ -+static void -+g_vfs_backend_afc_read (GVfsBackend *backend, -+ GVfsJobRead *job, -+ GVfsBackendHandle handle, -+ char *buffer, -+ gsize req) -+{ -+ guint32 nread = 0; -+ GVfsBackendAfc *self; -+ uint64_t fd = 0; -+ -+ fd = GPOINTER_TO_UINT(handle); -+ g_return_if_fail (fd != 0); -+ -+ self = G_VFS_BACKEND_AFC(backend); -+ g_return_if_fail (self->connected); -+ -+ if (req > 0 && -+ G_UNLIKELY(g_vfs_backend_afc_check (afc_file_read (self->afc_cli, -+ fd, buffer, req, &nread), -+ G_VFS_JOB(job)))) -+ { -+ return; -+ } -+ -+ g_vfs_job_read_set_size (job, nread); -+ g_vfs_job_succeeded (G_VFS_JOB(job)); -+} -+ -+static void -+g_vfs_backend_afc_write (GVfsBackend *backend, -+ GVfsJobWrite *job, -+ GVfsBackendHandle handle, -+ char *buffer, -+ gsize sz) -+{ -+ guint32 nwritten = 0; -+ GVfsBackendAfc *self; -+ uint64_t fd = 0; -+ -+ fd = GPOINTER_TO_UINT(handle); -+ g_return_if_fail (fd != 0); -+ -+ self = G_VFS_BACKEND_AFC(backend); -+ g_return_if_fail (self->connected); -+ -+ if (sz > 0 && -+ G_UNLIKELY(g_vfs_backend_afc_check(afc_file_write (self->afc_cli, -+ fd, buffer, sz, &nwritten), -+ G_VFS_JOB(job)))) -+ { -+ return; -+ } -+ -+ g_vfs_job_write_set_written_size (job, nwritten); -+ g_vfs_job_succeeded (G_VFS_JOB(job)); -+} -+ -+static int -+g_vfs_backend_afc_seek (GVfsBackendAfc *self, -+ GVfsJob *job, -+ GVfsBackendHandle handle, -+ goffset offset, -+ GSeekType type) -+{ -+ int afc_seek_type; -+ uint64_t fd = 0; -+ -+ switch (type) -+ { -+ case G_SEEK_SET: -+ afc_seek_type = SEEK_SET; -+ break; -+ case G_SEEK_CUR: -+ afc_seek_type = SEEK_CUR; -+ break; -+ case G_SEEK_END: -+ afc_seek_type = SEEK_END; -+ break; -+ default: -+ g_vfs_job_failed(job, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, -+ _("Invalid seek type")); -+ return 1; -+ } -+ -+ fd = GPOINTER_TO_UINT(handle); -+ -+ if (G_UNLIKELY(g_vfs_backend_afc_check (afc_file_seek (self->afc_cli, -+ fd, offset, afc_seek_type), -+ job))) -+ { -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static void -+g_vfs_backend_afc_seek_on_read (GVfsBackend *backend, -+ GVfsJobSeekRead *job, -+ GVfsBackendHandle handle, -+ goffset offset, -+ GSeekType type) -+{ -+ GVfsBackendAfc *self; -+ -+ g_return_if_fail (handle != NULL); -+ -+ self = G_VFS_BACKEND_AFC(backend); -+ g_return_if_fail (self->connected); -+ -+ if (!g_vfs_backend_afc_seek (self, G_VFS_JOB(job), handle, offset, type)) -+ { -+ g_vfs_job_seek_read_set_offset (job, offset); -+ g_vfs_job_succeeded (G_VFS_JOB(job)); -+ } -+} -+ -+static void -+g_vfs_backend_afc_seek_on_write (GVfsBackend *backend, -+ GVfsJobSeekWrite *job, -+ GVfsBackendHandle handle, -+ goffset offset, -+ GSeekType type) -+{ -+ GVfsBackendAfc *self; -+ -+ g_return_if_fail (handle != NULL); -+ -+ self = G_VFS_BACKEND_AFC(backend); -+ g_return_if_fail (self->connected); -+ -+ if (!g_vfs_backend_afc_seek (self, G_VFS_JOB(job), handle, offset, type)) -+ { -+ g_vfs_job_seek_write_set_offset (job, offset); -+ g_vfs_job_succeeded (G_VFS_JOB(job)); -+ } -+} -+ -+static void -+g_vfs_backend_afc_set_info_from_afcinfo (GVfsBackendAfc *self, -+ GFileInfo *info, -+ char **afcinfo, -+ const char *basename, -+ GFileAttributeMatcher *matcher, -+ GFileQueryInfoFlags flags) -+{ -+ GFileType type = G_FILE_TYPE_REGULAR; -+ GIcon *icon = NULL; -+ gchar *content_type = NULL; -+ char *display_name; -+ char *linktarget = NULL; -+ char **afctargetinfo = NULL; -+ int i; -+ -+ /* get file attributes from info list */ -+ for (i = 0; afcinfo[i]; i += 2) -+ { -+ if (afcinfo[i] == NULL) -+ continue; -+ if (g_str_equal (afcinfo[i], "st_size")) -+ { -+ g_file_info_set_size (info, atoll(afcinfo[i+1])); -+ } else if (g_str_equal (afcinfo[i], "st_blocks")) -+ { -+ g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_UNIX_BLOCKS, atoi(afcinfo[i+1])); -+ } -+ else if (g_str_equal (afcinfo[i], "st_ifmt")) -+ { -+ if (g_str_equal (afcinfo[i+1], "S_IFREG")) -+ { -+ type = G_FILE_TYPE_REGULAR; -+ } -+ else if (g_str_equal (afcinfo[i+1], "S_IFDIR")) -+ { -+ type = G_FILE_TYPE_DIRECTORY; -+ } -+ else if (g_str_equal (afcinfo[i+1], "S_IFLNK")) -+ { -+ type = G_FILE_TYPE_SYMBOLIC_LINK; -+ content_type = g_strdup ("inode/symlink"); -+ } -+ else if (g_str_equal (afcinfo[i+1], "S_IFBLK")) -+ { -+ type = G_FILE_TYPE_SPECIAL; -+ content_type = g_strdup ("inode/blockdevice"); -+ } -+ else if (g_str_equal (afcinfo[i+1], "S_IFCHR")) -+ { -+ type = G_FILE_TYPE_SPECIAL; -+ content_type = g_strdup ("inode/chardevice"); -+ } -+ else if (g_str_equal (afcinfo[i+1], "S_IFIFO")) -+ { -+ type = G_FILE_TYPE_SPECIAL; -+ content_type = g_strdup ("inode/fifo"); -+ } -+ else if (g_str_equal (afcinfo[i+1], "S_IFSOCK")) -+ { -+ type = G_FILE_TYPE_SPECIAL; -+ content_type = g_strdup ("inode/socket"); -+ } -+ g_file_info_set_file_type (info, type); -+ } -+ else if (g_str_equal (afcinfo[i], "st_nlink")) -+ { -+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_NLINK, atoi(afcinfo[i+1])); -+ } -+ else if (g_str_equal (afcinfo[i], "LinkTarget")) -+ { -+ linktarget = g_strdup (afcinfo[i+1]); -+ g_file_info_set_symlink_target (info, linktarget); -+ g_file_info_set_is_symlink (info, TRUE); -+ } -+ } -+ -+ /* and set some additional info */ -+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_UID, getuid ()); -+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_GID, getgid ()); -+ -+ /* -+ * Maybe this icon stuff should be moved out into a generic function? It -+ * seems a little funny to put this in the backends. -+ */ -+ if (g_file_attribute_matcher_matches (matcher, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE) -+ || g_file_attribute_matcher_matches (matcher, G_FILE_ATTRIBUTE_STANDARD_ICON)) -+ { -+ if (type == G_FILE_TYPE_DIRECTORY) -+ { -+ content_type = g_strdup ("inode/directory"); -+ icon = g_themed_icon_new ("folder"); -+ } -+ else -+ { -+ if (content_type == NULL) -+ content_type = g_content_type_guess (basename, NULL, 0, NULL); -+ if (content_type) -+ { -+ icon = g_content_type_get_icon (content_type); -+ if (G_IS_THEMED_ICON(icon)) -+ g_themed_icon_append_name (G_THEMED_ICON(icon), "text-x-generic"); -+ } -+ } -+ -+ if (content_type) -+ g_file_info_set_content_type (info, content_type); -+ -+ if (icon == NULL) -+ icon = g_themed_icon_new ("text-x-generic"); -+ -+ g_file_info_set_icon (info, icon); -+ g_object_unref (icon); -+ } -+ -+ g_free (content_type); -+ -+ /* for symlinks to work we need to return GFileInfo for the linktarget */ -+ if ((flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS) == 0) -+ { -+ if (type == G_FILE_TYPE_SYMBOLIC_LINK) -+ { -+ /* query the linktarget instead and merge the file info of it */ -+ if (AFC_E_SUCCESS == afc_get_file_info (self->afc_cli, linktarget, &afctargetinfo)) -+ g_vfs_backend_afc_set_info_from_afcinfo (self, info, afctargetinfo, linktarget, matcher, flags); -+ if (afctargetinfo) -+ g_strfreev (afctargetinfo); -+ } -+ } -+ -+ g_free (linktarget); -+ -+ /* regardless of symlink recursion; still set the basename of the source */ -+ g_file_info_set_name(info, basename); -+ -+ /* handle root directory */ -+ if (g_str_equal (basename, "/")) -+ display_name = g_strdup (g_vfs_backend_get_display_name (G_VFS_BACKEND(self))); -+ else -+ display_name = g_filename_display_name (basename); -+ -+ if (g_file_attribute_matcher_matches (matcher, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME)) -+ g_file_info_set_display_name (info, display_name); -+ -+ if (g_file_attribute_matcher_matches (matcher, G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME)) -+ g_file_info_set_edit_name (info, display_name); -+ -+ g_free (display_name); -+} -+ -+/* Callback for iterating over a directory. */ -+static void -+g_vfs_backend_afc_enumerate (GVfsBackend *backend, -+ GVfsJobEnumerate *job, -+ const char *path, -+ GFileAttributeMatcher *matcher, -+ GFileQueryInfoFlags flags) -+{ -+ GFileInfo *info; -+ GVfsBackendAfc *self; -+ gboolean trailing_slash; -+ gchar *file_path; -+ char **ptr, **list = NULL; -+ char **afcinfo = NULL; -+ -+ self = G_VFS_BACKEND_AFC(backend); -+ g_return_if_fail (self->connected); -+ -+ if (G_UNLIKELY(g_vfs_backend_afc_check (afc_read_directory (self->afc_cli, path, &list), -+ G_VFS_JOB(job)))) -+ { -+ return; -+ } -+ -+ trailing_slash = g_str_has_suffix (path, "/"); -+ -+ for (ptr = list; *ptr; ptr++) -+ { -+ if (g_str_equal(*ptr, ".") || g_str_equal(*ptr, "..")) -+ continue; -+ -+ if (!trailing_slash) -+ file_path = g_strdup_printf ("%s/%s", path, *ptr); -+ else -+ file_path = g_strdup_printf ("%s%s", path, *ptr); -+ -+ /* -+ * This call might fail if the file in question is removed while we're -+ * iterating over the directory list. In that case, just don't include -+ * it in the list. -+ */ -+ if (G_LIKELY(afc_get_file_info(self->afc_cli, file_path, &afcinfo) == AFC_E_SUCCESS)) -+ { -+ info = g_file_info_new (); -+ g_vfs_backend_afc_set_info_from_afcinfo (self, info, afcinfo, *ptr, matcher, flags); -+ g_vfs_job_enumerate_add_info (job, info); -+ g_object_unref (G_OBJECT(info)); -+ g_strfreev (afcinfo); -+ } -+ -+ g_free (file_path); -+ } -+ -+ g_strfreev (list); -+ -+ g_vfs_job_enumerate_done (job); -+ g_vfs_job_succeeded (G_VFS_JOB(job)); -+} -+ -+static void -+g_vfs_backend_afc_query_info (GVfsBackend *backend, -+ GVfsJobQueryInfo *job, -+ const char *path, -+ GFileQueryInfoFlags flags, -+ GFileInfo *info, -+ GFileAttributeMatcher *matcher) -+{ -+ GVfsBackendAfc *self; -+ const char *basename, *ptr; -+ char **afcinfo = NULL; -+ -+ self = G_VFS_BACKEND_AFC(backend); -+ g_return_if_fail (self->connected); -+ -+ if (G_UNLIKELY(g_vfs_backend_afc_check (afc_get_file_info (self->afc_cli, path, &afcinfo), -+ G_VFS_JOB(job)))) -+ { -+ if (afcinfo) -+ g_strfreev(afcinfo); -+ return; -+ } -+ -+ ptr = strrchr (path, '/'); -+ if (ptr && ptr[1] != '\0') -+ basename = ptr + 1; -+ else -+ basename = path; -+ -+ g_vfs_backend_afc_set_info_from_afcinfo (self, info, afcinfo, basename, matcher, flags); -+ if (afcinfo) -+ g_strfreev (afcinfo); -+ -+ g_vfs_job_succeeded (G_VFS_JOB(job)); -+} -+ -+/* -+ * The following keys are currently known: -+ * Model: 'iPhone1,1' -+ * FSTotalBytes: storage capacity of drive -+ * FSFreeBytes: free space on drive -+ * FSBlockSize: block granularity -+ */ -+static void -+g_vfs_backend_afc_query_fs_info (GVfsBackend *backend, -+ GVfsJobQueryFsInfo *job, -+ const char *path, -+ GFileInfo *info, -+ GFileAttributeMatcher *matcher) -+{ -+ GVfsBackendAfc *self; -+ char **kvps, **ptr; -+ uint64_t totalspace = 0, freespace = 0; -+ int blocksize = 0; -+ -+ self = G_VFS_BACKEND_AFC(backend); -+ -+ g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE, "afc"); -+ -+ if (self->connected) -+ { -+ if (G_UNLIKELY(g_vfs_backend_afc_check (afc_get_device_info (self->afc_cli, &kvps), G_VFS_JOB(job)))) -+ return; -+ -+ for (ptr = kvps; *ptr; ptr++) -+ { -+ if (g_str_equal (*ptr, "FSTotalBytes")) -+ { -+ totalspace = g_ascii_strtoull (*(ptr+1), (char **) NULL, 10); -+ } -+ else if (g_str_equal (*ptr, "FSFreeBytes")) -+ { -+ freespace = g_ascii_strtoull (*(ptr+1), (char **) NULL, 10); -+ } -+ else if (g_str_equal (*ptr, "FSBlockSize")) -+ { -+ blocksize = atoi (*(ptr+1)); -+ } -+ } -+ -+ g_strfreev (kvps); -+ -+ g_file_info_set_attribute_uint32 (info, -+ G_FILE_ATTRIBUTE_UNIX_BLOCK_SIZE, -+ (guint32) blocksize); -+ g_file_info_set_attribute_uint64 (info, -+ G_FILE_ATTRIBUTE_FILESYSTEM_SIZE, -+ (guint64) totalspace); -+ g_file_info_set_attribute_uint64 (info, -+ G_FILE_ATTRIBUTE_FILESYSTEM_FREE, -+ (guint64) freespace); -+ g_file_info_set_attribute_boolean (info, -+ G_FILE_ATTRIBUTE_FILESYSTEM_READONLY, -+ FALSE); -+ g_file_info_set_attribute_uint32 (info, -+ G_FILE_ATTRIBUTE_FILESYSTEM_USE_PREVIEW, -+ G_FILESYSTEM_PREVIEW_TYPE_IF_LOCAL); -+ } -+ -+ g_vfs_job_succeeded (G_VFS_JOB(job)); -+} -+ -+static void -+g_vfs_backend_afc_set_display_name (GVfsBackend *backend, -+ GVfsJobSetDisplayName *job, -+ const char *filename, -+ const char *display_name) -+{ -+ GVfsBackendAfc *self; -+ -+ self = G_VFS_BACKEND_AFC(backend); -+ g_return_if_fail (self->connected); -+ -+ if (G_UNLIKELY(g_vfs_backend_afc_check (afc_rename_path (self->afc_cli, -+ filename, display_name), -+ G_VFS_JOB(job)))) -+ { -+ return; -+ } -+ -+ g_vfs_job_set_display_name_set_new_path (job, display_name); -+ -+ g_vfs_job_succeeded (G_VFS_JOB(job)); -+} -+ -+static void -+g_vfs_backend_afc_make_directory (GVfsBackend *backend, -+ GVfsJobMakeDirectory *job, -+ const char *path) -+{ -+ GVfsBackendAfc *self; -+ -+ self = G_VFS_BACKEND_AFC(backend); -+ g_return_if_fail(self->connected); -+ -+ if (G_UNLIKELY(g_vfs_backend_afc_check (afc_make_directory (self->afc_cli, -+ path), -+ G_VFS_JOB(job)))) -+ { -+ return; -+ } -+ -+ g_vfs_job_succeeded (G_VFS_JOB(job)); -+} -+ -+static void -+g_vfs_backend_afc_make_symlink (GVfsBackend *backend, -+ GVfsJobMakeSymlink *job, -+ const char *filename, -+ const char *symlink_value) -+{ -+ GVfsBackendAfc *self; -+ -+ self = G_VFS_BACKEND_AFC(backend); -+ g_return_if_fail (self->connected); -+ -+ if (G_UNLIKELY(g_vfs_backend_afc_check (afc_make_link (self->afc_cli, -+ AFC_SYMLINK, symlink_value, filename), -+ G_VFS_JOB(job)))) -+ { -+ return; -+ } -+ -+ g_vfs_job_succeeded (G_VFS_JOB(job)); -+} -+ -+static void -+g_vfs_backend_afc_move (GVfsBackend *backend, -+ GVfsJobMove *job, -+ const char *source, -+ const char *destination, -+ GFileCopyFlags flags, -+ GFileProgressCallback progress_callback, -+ gpointer progress_callback_data) -+{ -+ GVfsBackendAfc *self; -+ -+ self = G_VFS_BACKEND_AFC(backend); -+ g_return_if_fail(self->connected); -+ -+ if (flags & G_FILE_COPY_BACKUP) -+ { -+ /* FIXME: implement! */ -+ g_vfs_job_failed (G_VFS_JOB (job), -+ G_IO_ERROR, -+ G_IO_ERROR_CANT_CREATE_BACKUP, -+ _("Backups are not yet supported.")); -+ return; -+ } -+ -+ if (G_UNLIKELY(g_vfs_backend_afc_check (afc_rename_path (self->afc_cli, -+ source, destination), -+ G_VFS_JOB(job)))) -+ { -+ return; -+ } -+ -+ g_vfs_job_succeeded (G_VFS_JOB(job)); -+} -+ -+static void -+g_vfs_backend_afc_delete (GVfsBackend *backend, -+ GVfsJobDelete *job, -+ const char *filename) -+{ -+ GVfsBackendAfc *self; -+ -+ self = G_VFS_BACKEND_AFC(backend); -+ g_return_if_fail (self->connected); -+ -+ if (G_UNLIKELY(g_vfs_backend_afc_check (afc_remove_path (self->afc_cli, -+ filename), -+ G_VFS_JOB(job)))) -+ { -+ return; -+ } -+ -+ g_vfs_job_succeeded (G_VFS_JOB(job)); -+} -+ -+ -+static void -+g_vfs_backend_afc_finalize (GObject *obj) -+{ -+ GVfsBackendAfc *self; -+ -+ self = G_VFS_BACKEND_AFC(obj); -+ g_vfs_backend_afc_close_connection (self); -+ -+ if (G_OBJECT_CLASS(g_vfs_backend_afc_parent_class)->finalize) -+ (*G_OBJECT_CLASS(g_vfs_backend_afc_parent_class)->finalize) (obj); -+} -+ -+static void -+g_vfs_backend_afc_init (GVfsBackendAfc *self) -+{ -+ if (g_getenv ("GVFS_DEBUG") != NULL) -+ { -+ /* enable full debugging */ -+ iphone_set_debug_level (1); -+ iphone_set_debug_mask (DBGMASK_ALL); -+ } -+} -+ -+static void -+g_vfs_backend_afc_class_init (GVfsBackendAfcClass *klass) -+{ -+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass); -+ GVfsBackendClass *backend_class = G_VFS_BACKEND_CLASS(klass); -+ -+ gobject_class->finalize = g_vfs_backend_afc_finalize; -+ -+ backend_class->mount = g_vfs_backend_afc_mount; -+ backend_class->unmount = g_vfs_backend_afc_unmount; -+ backend_class->open_for_read = g_vfs_backend_afc_open_for_read; -+ backend_class->close_read = g_vfs_backend_afc_close_read; -+ backend_class->read = g_vfs_backend_afc_read; -+ backend_class->seek_on_read = g_vfs_backend_afc_seek_on_read; -+ backend_class->create = g_vfs_backend_afc_create; -+ backend_class->append_to = g_vfs_backend_afc_append_to; -+ backend_class->replace = g_vfs_backend_afc_replace; -+ backend_class->close_write = g_vfs_backend_afc_close_write; -+ backend_class->write = g_vfs_backend_afc_write; -+ backend_class->seek_on_write = g_vfs_backend_afc_seek_on_write; -+ backend_class->enumerate = g_vfs_backend_afc_enumerate; -+ backend_class->query_info = g_vfs_backend_afc_query_info; -+ backend_class->query_fs_info = g_vfs_backend_afc_query_fs_info; -+ backend_class->make_directory = g_vfs_backend_afc_make_directory; -+ backend_class->delete = g_vfs_backend_afc_delete; -+ backend_class->make_symlink = g_vfs_backend_afc_make_symlink; -+ backend_class->move = g_vfs_backend_afc_move; -+ backend_class->set_display_name = g_vfs_backend_afc_set_display_name; -+} -+ -+/* -+ * vim: sw=2 ts=8 cindent expandtab cinoptions=f0,>4,n2,{2,(0,^-2,t0 ai -+ */ -diff --git a/daemon/gvfsbackendafc.h b/daemon/gvfsbackendafc.h -new file mode 100644 -index 0000000..6291180 ---- /dev/null -+++ b/daemon/gvfsbackendafc.h -@@ -0,0 +1,37 @@ -+/* -+ * gvfs/daemon/gvfsbackendafc.h -+ * -+ * Copyright (c) 2008 Patrick Walton -+ */ -+ -+#ifndef GVFSBACKENDAFC_H -+#define GVFSBACKENDAFC_H -+ -+#include -+#include -+ -+G_BEGIN_DECLS -+ -+#define G_VFS_TYPE_BACKEND_AFC (g_vfs_backend_afc_get_type()) -+#define G_VFS_BACKEND_AFC(o) (G_TYPE_CHECK_INSTANCE_CAST((o), G_VFS_TYPE_BACKEND_AFC, GVfsBackendAfc)) -+#define G_VFS_BACKEND_AFC_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_VFS_TYPE_BACKEND_AFC, GVfsBackendAfcClass)) -+#define G_VFS_IS_BACKEND_AFC(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), G_VFS_TYPE_BACKEND_AFC)) -+#define G_VFS_IS_BACKEND_AFC_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), G_VFS_TYPE_BACKEND_AFC)) -+#define G_VFS_BACKEND_AFC_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), G_VFS_TYPE_BACKEND_AFC, GVfsBackendAfcClass)) -+ -+typedef struct _GVfsBackendAfc GVfsBackendAfc; -+typedef struct _GVfsBackendAfcClass GVfsBackendAfcClass; -+ -+struct _GVfsBackendAfcClass { -+ GVfsBackendClass parent_class; -+}; -+ -+GType g_vfs_backend_afc_get_type (void) G_GNUC_CONST; -+ -+G_END_DECLS -+ -+#endif /* GVFSBACKENDAFC_H */ -+ -+/* -+ * vim: sw=2 ts=8 cindent expandtab cinoptions=f0,>4,n2,{2,(0,^-2,t0 ai -+ */ -diff --git a/monitor/Makefile.am b/monitor/Makefile.am -index f68423e..1dc984f 100644 ---- a/monitor/Makefile.am -+++ b/monitor/Makefile.am -@@ -1,4 +1,4 @@ -- -+DIST_SUBDIRS = proxy hal gdu gphoto2 afc - SUBDIRS = proxy - - if USE_HAL -@@ -12,3 +12,7 @@ endif - if USE_GPHOTO2 - SUBDIRS += gphoto2 - endif -+ -+if USE_AFC -+SUBDIRS += afc -+endif -diff --git a/monitor/afc/Makefile.am b/monitor/afc/Makefile.am -new file mode 100644 -index 0000000..9b3b17c ---- /dev/null -+++ b/monitor/afc/Makefile.am -@@ -0,0 +1,49 @@ -+NULL = -+ -+gvfs_src_dir = $(top_srcdir)/@with_gvfs_source@ -+ -+libexec_PROGRAMS = gvfs-afc-volume-monitor -+ -+gvfs_afc_volume_monitor_SOURCES = \ -+ afcvolume.c afcvolume.h \ -+ afcvolumemonitor.c afcvolumemonitor.h \ -+ afcvolumemonitordaemon.c \ -+ $(NULL) -+ -+gvfs_afc_volume_monitor_CFLAGS = \ -+ -DG_LOG_DOMAIN=\"GVFS-AFC\" \ -+ -I$(top_srcdir)/common \ -+ -I$(top_srcdir)/monitor/proxy \ -+ $(GLIB_CFLAGS) \ -+ $(AFC_CFLAGS) \ -+ $(WARN_CFLAGS) \ -+ -DGIO_MODULE_DIR=\"$(GIO_MODULE_DIR)\" \ -+ -DGVFS_LOCALEDIR=\"$(localedir)\" \ -+ -DG_DISABLE_DEPRECATED \ -+ $(NULL) -+ -+gvfs_afc_volume_monitor_LDADD = \ -+ $(GLIB_LIBS) \ -+ $(DBUS_LIBS) \ -+ $(AFC_LIBS) \ -+ $(top_srcdir)/common/libgvfscommon.la \ -+ $(top_srcdir)/monitor/proxy/libgvfsproxyvolumemonitordaemon-noin.la \ -+ $(NULL) -+ -+remote_volume_monitorsdir = $(datadir)/gvfs/remote-volume-monitors -+remote_volume_monitors_DATA = afc.monitor -+ -+servicedir = $(datadir)/dbus-1/services -+service_in_files = org.gtk.Private.AfcVolumeMonitor.service.in -+service_DATA = $(service_in_files:.service.in=.service) -+ -+$(service_DATA): $(service_in_files) Makefile -+ @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@ -+ -+clean-local: -+ rm -f *~ *.loT $(BUILT_SOURCES) $(service_DATA) -+ -+DISTCLEANFILES = $(service_DATA) -+ -+EXTRA_DIST = $(service_in_files) afc.monitor -+ -diff --git a/monitor/afc/afc.monitor b/monitor/afc/afc.monitor -new file mode 100644 -index 0000000..1663573 ---- /dev/null -+++ b/monitor/afc/afc.monitor -@@ -0,0 +1,5 @@ -+[RemoteVolumeMonitor] -+Name=GProxyVolumeMonitorAfc -+DBusName=org.gtk.Private.AfcVolumeMonitor -+IsNative=false -+ -diff --git a/monitor/afc/afcvolume.c b/monitor/afc/afcvolume.c -new file mode 100644 -index 0000000..688f75b ---- /dev/null -+++ b/monitor/afc/afcvolume.c -@@ -0,0 +1,353 @@ -+/* -+ * gvfs/monitor/afc/afc-volume.c -+ * -+ * Copyright (c) 2008 Patrick Walton -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "afcvolume.h" -+ -+#define DEFAULT_SERVICE "com.apple.afc" -+ -+struct _GVfsAfcVolume { -+ GObject parent; -+ -+ GVolumeMonitor *monitor; -+ -+ char *uuid; -+ -+ char *name; -+ char *icon; -+ char *icon_fallback; -+}; -+ -+static void g_vfs_afc_volume_iface_init (GVolumeIface *iface); -+ -+G_DEFINE_TYPE_EXTENDED(GVfsAfcVolume, g_vfs_afc_volume, G_TYPE_OBJECT, 0, -+ G_IMPLEMENT_INTERFACE(G_TYPE_VOLUME, g_vfs_afc_volume_iface_init)) -+ -+static void -+g_vfs_afc_volume_finalize (GObject *self_) -+{ -+ GVfsAfcVolume *self; -+ -+ self = G_VFS_AFC_VOLUME(self); -+ -+ g_free (self->uuid); -+ -+ g_free (self->name); -+ g_free (self->icon); -+ g_free (self->icon_fallback); -+ -+ if (G_OBJECT_CLASS(g_vfs_afc_volume_parent_class)->finalize) -+ (*G_OBJECT_CLASS(g_vfs_afc_volume_parent_class)->finalize) (G_OBJECT(self)); -+} -+ -+static void -+g_vfs_afc_volume_init (GVfsAfcVolume *self) -+{ -+ GVfsAfcVolume *afc_volume = G_VFS_AFC_VOLUME (self); -+ -+ afc_volume->name = g_strdup ("iPhone"); -+ afc_volume->icon = g_strdup ("phone-apple-iphone"); -+} -+ -+static void -+g_vfs_afc_volume_class_init (GVfsAfcVolumeClass *klass) -+{ -+ GObjectClass *gobject_class; -+ gobject_class = G_OBJECT_CLASS(klass); -+ gobject_class->finalize = g_vfs_afc_volume_finalize; -+} -+ -+static int -+_g_vfs_afc_volume_update_metadata (GVfsAfcVolume *self) -+{ -+ iphone_device_t dev; -+ afc_client_t afc_cli; -+ lockdownd_client_t lockdown_cli = NULL; -+ iphone_error_t err; -+ guint retries; -+ char *model, *display_name; -+ int port; -+ -+ retries = 0; -+ do { -+ err = iphone_get_device_by_uuid (&dev, self->uuid); -+ if (err == IPHONE_E_SUCCESS) -+ break; -+ g_usleep (G_USEC_PER_SEC); -+ } while (retries++ < 10); -+ -+ if (err != IPHONE_E_SUCCESS) -+ return 0; -+ -+ if (lockdownd_client_new (dev, &lockdown_cli) != LOCKDOWN_E_SUCCESS) -+ { -+ iphone_device_free (dev); -+ return 0; -+ } -+ -+ /* try to use pretty device name */ -+ if (lockdownd_get_device_name (lockdown_cli, &display_name) == LOCKDOWN_E_SUCCESS) -+ { -+ g_free (self->name); -+ self->name = display_name; -+ } -+ -+ if (lockdownd_start_service (lockdown_cli, DEFAULT_SERVICE, &port) != LOCKDOWN_E_SUCCESS) -+ { -+ lockdownd_client_free (lockdown_cli); -+ iphone_device_free (dev); -+ return 0; -+ } -+ -+ if (afc_client_new (dev, port, &afc_cli) == AFC_E_SUCCESS) -+ { -+ /* set correct fd icon spec name depending on device model */ -+ model = afc_get_device_info_field (afc_cli, "Model"); -+ if (model != NULL) -+ { -+ if(g_str_has_prefix(model, "iPod") != FALSE) -+ { -+ g_free (self->icon); -+ self->icon = g_strdup ("multimedia-player-apple-ipod-touch"); -+ } -+ g_free (model); -+ } -+ afc_client_free(afc_cli); -+ } -+ -+ lockdownd_client_free (lockdown_cli); -+ iphone_device_free (dev); -+ -+ return 1; -+} -+ -+GVfsAfcVolume * -+g_vfs_afc_volume_new (GVolumeMonitor *monitor, -+ const char *uuid) -+{ -+ GVfsAfcVolume *self; -+ -+ self = G_VFS_AFC_VOLUME(g_object_new (G_VFS_TYPE_AFC_VOLUME, NULL)); -+ self->monitor = monitor; -+ self->uuid = g_strdup (uuid); -+ -+ /* Get mount information here */ -+ if (!_g_vfs_afc_volume_update_metadata (self)) -+ return NULL; -+ -+ return self; -+} -+ -+static char * -+g_vfs_afc_volume_get_name (GVolume *volume) -+{ -+ GVfsAfcVolume *afc_volume = G_VFS_AFC_VOLUME (volume); -+ char *name; -+ -+ name = g_strdup (afc_volume->name); -+ -+ return name; -+} -+ -+static GIcon * -+g_vfs_afc_volume_get_icon (GVolume *volume) -+{ -+ GVfsAfcVolume *afc_volume = G_VFS_AFC_VOLUME (volume); -+ GIcon *icon; -+ -+ icon = g_themed_icon_new_with_default_fallbacks (afc_volume->icon); -+ -+ return icon; -+} -+ -+static char * -+g_vfs_afc_volume_get_uuid (GVolume *volume) -+{ -+ GVfsAfcVolume *afc_volume = G_VFS_AFC_VOLUME (volume); -+ -+ return g_strdup (afc_volume->uuid); -+} -+ -+static gboolean -+g_vfs_afc_volume_can_mount (GVolume *volume) -+{ -+ return TRUE; -+} -+ -+static gboolean -+g_vfs_afc_volume_should_automount (GVolume *volume) -+{ -+ return TRUE; -+} -+ -+static GDrive * -+g_vfs_afc_volume_get_drive (GVolume *volume) -+{ -+ return NULL; -+} -+ -+static GMount * -+g_vfs_afc_volume_get_mount (GVolume *volume) -+{ -+ return NULL; -+} -+ -+typedef struct -+{ -+ GVfsAfcVolume *enclosing_volume; -+ GAsyncReadyCallback callback; -+ GFile *root; -+ gpointer user_data; -+} ActivationMountOp; -+ -+static void -+mount_callback (GObject *source_object, -+ GAsyncResult *res, -+ gpointer user_data) -+{ -+ ActivationMountOp *data = user_data; -+ data->callback (G_OBJECT (data->enclosing_volume), res, data->user_data); -+ g_object_unref (data->root); -+ g_free (data); -+} -+ -+static void -+g_vfs_afc_volume_mount (GVolume *volume, -+ GMountMountFlags flags, -+ GMountOperation *mount_operation, -+ GCancellable *cancellable, -+ GAsyncReadyCallback callback, -+ gpointer user_data) -+{ -+ GVfsAfcVolume *afc_volume = G_VFS_AFC_VOLUME (volume); -+ ActivationMountOp *data; -+ GFile *root; -+ char *uri; -+ -+ g_print ("g_vfs_afc_volume_mount (can_mount=%d uuid=%s)\n", -+ g_vfs_afc_volume_can_mount (volume), -+ afc_volume->uuid); -+ -+ uri = g_strdup_printf ("afc://%s", afc_volume->uuid); -+ root = g_file_new_for_uri (uri); -+ g_free (uri); -+ -+ data = g_new0 (ActivationMountOp, 1); -+ data->enclosing_volume = afc_volume; -+ data->callback = callback; -+ data->user_data = user_data; -+ data->root = root; -+ -+ g_object_set_data_full (G_OBJECT(volume), "root", g_object_ref (root), g_object_unref); -+ -+ g_file_mount_enclosing_volume (root, -+ 0, -+ mount_operation, -+ cancellable, -+ mount_callback, -+ data); -+} -+ -+static gboolean -+g_vfs_afc_volume_mount_finish (GVolume *volume, -+ GAsyncResult *result, -+ GError **error) -+{ -+ GFile *root; -+ gboolean res; -+ -+ root = g_object_get_data (G_OBJECT (volume), "root"); -+ res = g_file_mount_enclosing_volume_finish (root, result, error); -+ -+ return res; -+} -+ -+static char * -+g_vfs_afc_volume_get_identifier (GVolume *volume, -+ const char *kind) -+{ -+ GVfsAfcVolume *afc_volume = G_VFS_AFC_VOLUME (volume); -+ char *id; -+ -+ id = NULL; -+ if (g_str_equal (kind, G_VOLUME_IDENTIFIER_KIND_UUID) != FALSE) -+ id = g_strdup (afc_volume->uuid); -+ -+ return id; -+} -+ -+static char ** -+g_vfs_afc_volume_enumerate_identifiers (GVolume *volume) -+{ -+ GVfsAfcVolume *afc_volume = G_VFS_AFC_VOLUME (volume); -+ GPtrArray *res; -+ -+ res = g_ptr_array_new (); -+ -+ g_ptr_array_add (res, -+ g_strdup (G_VOLUME_IDENTIFIER_KIND_HAL_UDI)); -+ -+ if (afc_volume->uuid && *afc_volume->uuid != 0) -+ { -+ g_ptr_array_add (res, -+ g_strdup (G_VOLUME_IDENTIFIER_KIND_UUID)); -+ } -+ -+ /* Null-terminate */ -+ g_ptr_array_add (res, NULL); -+ -+ return (char **)g_ptr_array_free (res, FALSE); -+} -+ -+static GFile * -+g_vfs_afc_volume_get_activation_root (GVolume *volume) -+{ -+ GFile *root; -+ -+ root = g_object_get_data (G_OBJECT (volume), "root"); -+ if (root == NULL) -+ return NULL; -+ -+ return g_object_ref (root); -+} -+ -+static void -+g_vfs_afc_volume_iface_init (GVolumeIface *iface) -+{ -+ iface->get_name = g_vfs_afc_volume_get_name; -+ iface->get_icon = g_vfs_afc_volume_get_icon; -+ iface->get_uuid = g_vfs_afc_volume_get_uuid; -+ iface->get_drive = g_vfs_afc_volume_get_drive; -+ iface->get_mount = g_vfs_afc_volume_get_mount; -+ iface->can_mount = g_vfs_afc_volume_can_mount; -+ iface->should_automount = g_vfs_afc_volume_should_automount; -+ iface->mount_fn = g_vfs_afc_volume_mount; -+ iface->mount_finish = g_vfs_afc_volume_mount_finish; -+ iface->eject = NULL; -+ iface->eject_finish = NULL; -+ iface->get_identifier = g_vfs_afc_volume_get_identifier; -+ iface->enumerate_identifiers = g_vfs_afc_volume_enumerate_identifiers; -+ iface->get_activation_root = g_vfs_afc_volume_get_activation_root; -+} -+ -+gboolean g_vfs_afc_volume_has_uuid(GVfsAfcVolume *volume, const char *uuid) -+{ -+ GVfsAfcVolume *afc_volume = G_VFS_AFC_VOLUME (volume); -+ g_return_val_if_fail (uuid != NULL, FALSE); -+ return (g_strcmp0 (afc_volume->uuid, uuid) == 0); -+} -+ -+/* -+ * vim: sw=2 ts=8 cindent expandtab cinoptions=f0,>4,n2,{2,(0,^-2,t0 ai -+ */ -diff --git a/monitor/afc/afcvolume.h b/monitor/afc/afcvolume.h -new file mode 100644 -index 0000000..de24cd5 ---- /dev/null -+++ b/monitor/afc/afcvolume.h -@@ -0,0 +1,44 @@ -+/* -+ * gvfs/monitor/afc/afc-volume.h -+ * -+ * Copyright (c) 2008 Patrick Walton -+ */ -+ -+#ifndef GVFS_MONITOR_AFC_AFC_VOLUME_H -+#define GVFS_MONITOR_AFC_AFC_VOLUME_H -+ -+#include -+#include -+ -+#include "afcvolumemonitor.h" -+ -+G_BEGIN_DECLS -+ -+#define G_VFS_TYPE_AFC_VOLUME (g_vfs_afc_volume_get_type()) -+#define G_VFS_AFC_VOLUME(o) (G_TYPE_CHECK_INSTANCE_CAST((o), G_VFS_TYPE_AFC_VOLUME, GVfsAfcVolume)) -+#define G_VFS_AFC_VOLUME_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_VFS_TYPE_AFC_VOLUME, GVfsAfcVolumeClass)) -+#define G_VFS_IS_AFC_VOLUME(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), G_VFS_TYPE_AFC_VOLUME)) -+#define G_VFS_IS_AFC_VOLUME_CLASS(k) ((G_TYPE_CHECK_CLASS_TYPE((k), G_VFS_TYPE_AFC_VOLUME)) -+#define G_VFS_AFC_VOLUME_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), G_VFS_TYPE_AFC_VOLUME, GVfsAfcVolumeClass)) -+ -+typedef struct _GVfsAfcVolume GVfsAfcVolume; -+typedef struct _GVfsAfcVolumeClass GVfsAfcVolumeClass; -+ -+struct _GVfsAfcVolumeClass { -+ GObjectClass parent_class; -+}; -+ -+GType g_vfs_afc_volume_get_type (void) G_GNUC_CONST; -+ -+GVfsAfcVolume *g_vfs_afc_volume_new (GVolumeMonitor *monitor, -+ const char *uuid); -+ -+gboolean g_vfs_afc_volume_has_uuid (GVfsAfcVolume *volume, const char *uuid); -+ -+G_END_DECLS -+ -+#endif /* GVFS_MONITOR_AFC_AFC_VOLUME_H */ -+ -+/* -+ * vim: sw=2 ts=8 cindent expandtab cinoptions=f0,>4,n2,{2,(0,^-2,t0 ai -+ */ -diff --git a/monitor/afc/afcvolumemonitor.c b/monitor/afc/afcvolumemonitor.c -new file mode 100644 -index 0000000..93926eb ---- /dev/null -+++ b/monitor/afc/afcvolumemonitor.c -@@ -0,0 +1,224 @@ -+/* -+ * gvfs/monitor/afc/afc-volume-monitor.c -+ * -+ * Copyright (c) 2008 Patrick Walton -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#define G_UDEV_API_IS_SUBJECT_TO_CHANGE -+#include -+#include "afcvolume.h" -+#include "afcvolumemonitor.h" -+ -+struct _GVfsAfcVolumeMonitor { -+ GNativeVolumeMonitor parent; -+ GUdevClient *client; -+ GList *volumes; -+}; -+ -+G_DEFINE_TYPE(GVfsAfcVolumeMonitor, g_vfs_afc_volume_monitor, G_TYPE_VOLUME_MONITOR) -+ -+static void -+g_vfs_afc_monitor_create_volume (GVfsAfcVolumeMonitor *self, -+ const char *uuid) -+{ -+ GVfsAfcVolume *volume = NULL; -+ -+ g_print ("creating volume for device uuid '%s'\n", uuid); -+ -+ volume = g_vfs_afc_volume_new (G_VOLUME_MONITOR (self), uuid); -+ if (volume != NULL) -+ { -+ self->volumes = g_list_prepend (self->volumes, volume); -+ g_signal_emit_by_name (self, "volume-added", volume); -+ } -+} -+ -+static GVfsAfcVolume * -+find_volume_by_uuid (GVfsAfcVolumeMonitor *self, -+ const char * uuid) -+{ -+ GList *l; -+ -+ for (l = self->volumes; l != NULL; l = l->next) -+ { -+ GVfsAfcVolume *volume = l->data; -+ if (volume && g_vfs_afc_volume_has_uuid (volume, uuid)) -+ return volume; -+ } -+ -+ return NULL; -+} -+ -+static void -+g_vfs_afc_monitor_remove_volume (GVfsAfcVolumeMonitor *self, -+ const char *uuid) -+{ -+ GVfsAfcVolume *volume = NULL; -+ -+ volume = find_volume_by_uuid (self, uuid); -+ if (volume != NULL) -+ { -+ g_print ("removing volume for device uuid '%s'\n", uuid); -+ self->volumes = g_list_remove (self->volumes, volume); -+ g_signal_emit_by_name (self, "volume-removed", volume); -+ } -+} -+ -+static void -+g_vfs_afc_monitor_uevent (GUdevClient *client, -+ const gchar *action, -+ GUdevDevice *device, -+ gpointer user_data) -+{ -+ GVfsAfcVolumeMonitor *self; -+ const char *vendor, *uuid; -+ -+ self = G_VFS_AFC_VOLUME_MONITOR(user_data); -+ -+ /* Vendor is Apple? */ -+ vendor = g_udev_device_get_property (device, "ID_VENDOR"); -+ if (vendor == NULL || -+ g_str_equal (vendor, "Apple_Inc.") == FALSE) { -+ return; -+ } -+ -+ /* Get us a UUID */ -+ uuid = g_udev_device_get_property (device, "ID_SERIAL_SHORT"); -+ if (uuid == NULL) -+ { -+ g_message ("No serial for device"); -+ return; -+ } -+ -+ if (g_str_equal (action, "add") != FALSE) -+ g_vfs_afc_monitor_create_volume (self, uuid); -+ else if (g_str_equal (action, "remove") != FALSE) -+ g_vfs_afc_monitor_remove_volume (self, uuid); -+} -+ -+static GObject * -+g_vfs_afc_volume_monitor_constructor (GType type, guint ncps, -+ GObjectConstructParam *cps) -+{ -+ GVfsAfcVolumeMonitor *self; -+ GList *devices, *l; -+ const gchar * const subsystems[] = { "usb", NULL }; -+ -+ /* Boilerplate code to chain from parent. */ -+ self = G_VFS_AFC_VOLUME_MONITOR((*G_OBJECT_CLASS(g_vfs_afc_volume_monitor_parent_class)->constructor)(type, ncps, cps)); -+ -+ self->client = g_udev_client_new (subsystems); -+ g_signal_connect (G_OBJECT (self->client), "uevent", -+ G_CALLBACK (g_vfs_afc_monitor_uevent), self); -+ -+ self->volumes = NULL; -+ -+ devices = g_udev_client_query_by_subsystem (self->client, subsystems[0]); -+ for (l = devices; l != NULL; l = l->next) -+ { -+ GUdevDevice *device = l->data; -+ g_vfs_afc_monitor_uevent (self->client, "add", device, self); -+ g_object_unref (device); -+ } -+ g_list_free (devices); -+ -+ g_print ("Volume monitor alive\n"); -+ -+ return G_OBJECT(self); -+} -+ -+static void -+list_free (GList *objects) -+{ -+ g_list_foreach (objects, (GFunc)g_object_unref, NULL); -+ g_list_free (objects); -+} -+ -+static void -+g_vfs_afc_volume_monitor_finalize (GObject *_self) -+{ -+ GVfsAfcVolumeMonitor *self; -+ -+ self = G_VFS_AFC_VOLUME_MONITOR(_self); -+ -+ if (self->volumes) -+ list_free (self->volumes); -+ -+ if (self->client) -+ { -+ g_object_unref (self->client); -+ self->client = NULL; -+ } -+ -+ if (G_OBJECT_CLASS(g_vfs_afc_volume_monitor_parent_class)->finalize) -+ (*G_OBJECT_CLASS(g_vfs_afc_volume_monitor_parent_class)->finalize)( G_OBJECT(self)); -+} -+ -+static GList * -+g_vfs_afc_volume_monitor_get_mounts (GVolumeMonitor *_self) -+{ -+ return NULL; -+} -+ -+static GList * -+g_vfs_afc_volume_monitor_get_volumes (GVolumeMonitor *_self) -+{ -+ GVfsAfcVolumeMonitor *self; -+ GList *l; -+ -+ self = G_VFS_AFC_VOLUME_MONITOR (_self); -+ -+ l = g_list_copy (self->volumes); -+ g_list_foreach (l, (GFunc)g_object_ref, NULL); -+ -+ return l; -+} -+ -+static GList * -+g_vfs_afc_volume_monitor_get_connected_drives (GVolumeMonitor *_self) -+{ -+ return NULL; -+} -+ -+static gboolean -+g_vfs_afc_volume_monitor_is_supported (void) -+{ -+ return TRUE; -+} -+ -+static void -+g_vfs_afc_volume_monitor_class_init (GVfsAfcVolumeMonitorClass * klass) -+{ -+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass); -+ GVolumeMonitorClass *monitor_class = G_VOLUME_MONITOR_CLASS(klass); -+ -+ gobject_class->constructor = g_vfs_afc_volume_monitor_constructor; -+ gobject_class->finalize = g_vfs_afc_volume_monitor_finalize; -+ -+ monitor_class->get_mounts = g_vfs_afc_volume_monitor_get_mounts; -+ monitor_class->get_volumes = g_vfs_afc_volume_monitor_get_volumes; -+ monitor_class->get_connected_drives = g_vfs_afc_volume_monitor_get_connected_drives; -+ monitor_class->is_supported = g_vfs_afc_volume_monitor_is_supported; -+} -+ -+static void -+g_vfs_afc_volume_monitor_init(GVfsAfcVolumeMonitor *self) -+{ -+} -+ -+GVolumeMonitor * -+g_vfs_afc_volume_monitor_new (void) -+{ -+ return G_VOLUME_MONITOR(g_object_new (G_VFS_TYPE_AFC_VOLUME_MONITOR, -+ NULL)); -+} -+ -+/* -+ * vim: sw=2 ts=8 cindent expandtab cinoptions=f0,>4,n2,{2,(0,^-2,t0 ai -+ */ -diff --git a/monitor/afc/afcvolumemonitor.h b/monitor/afc/afcvolumemonitor.h -new file mode 100644 -index 0000000..0bd5f32 ---- /dev/null -+++ b/monitor/afc/afcvolumemonitor.h -@@ -0,0 +1,39 @@ -+/* -+ * gvfs/monitor/afc/afc-volume-monitor.h -+ * -+ * Copyright (c) 2008 Patrick Walton -+ */ -+ -+#ifndef AFC_VOLUME_MONITOR_H -+#define AFC_VOLUME_MONITOR_H -+ -+#include -+#include -+ -+G_BEGIN_DECLS -+ -+#define G_VFS_TYPE_AFC_VOLUME_MONITOR (g_vfs_afc_volume_monitor_get_type()) -+#define G_VFS_AFC_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST((o), G_VFS_TYPE_AFC_VOLUME_MONITOR, GVfsAfcVolumeMonitor)) -+#define G_VFS_AFC_VOLUME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_VFS_TYPE_AFC_VOLUME_MONITOR, GVfsAfcVolumeMonitorClass)) -+#define G_VFS_IS_AFC_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), G_VFS_TYPE_AFC_VOLUME_MONITOR)) -+#define G_VFS_IS_AFC_VOLUME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), G_VFS_TYPE_AFC_VOLUME_MONITOR)) -+#define G_VFS_AFC_VOLUME_MONITOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), G_VFS_TYPE_AFC_VOLUME_MONITOR, GVfsAfcVolumeMonitorClass)) -+ -+typedef struct _GVfsAfcVolumeMonitor GVfsAfcVolumeMonitor; -+typedef struct _GVfsAfcVolumeMonitorClass GVfsAfcVolumeMonitorClass; -+ -+struct _GVfsAfcVolumeMonitorClass { -+ GVolumeMonitorClass parent_class; -+}; -+ -+GType g_vfs_afc_volume_monitor_get_type (void) G_GNUC_CONST; -+ -+GVolumeMonitor *g_vfs_afc_volume_monitor_new (void); -+ -+G_END_DECLS -+ -+#endif /* AFC_VOLUME_MONITOR_H */ -+ -+/* -+ * vim: sw=2 ts=8 cindent expandtab cinoptions=f0,>4,n2,{2,(0,^-2,t0 ai -+ */ -diff --git a/monitor/afc/afcvolumemonitordaemon.c b/monitor/afc/afcvolumemonitordaemon.c -new file mode 100644 -index 0000000..9c24a34 ---- /dev/null -+++ b/monitor/afc/afcvolumemonitordaemon.c -@@ -0,0 +1,31 @@ -+/* -+ * gvfs/monitor/afc/afc-volume-monitor-daemon.c -+ * -+ * Copyright (c) 2008-2009 Patrick Walton -+ * Copyright (c) 2009 Martin Szulecki -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "afcvolumemonitor.h" -+ -+int -+main (int argc, char *argv[]) -+{ -+ g_vfs_proxy_volume_monitor_daemon_init (); -+ return g_vfs_proxy_volume_monitor_daemon_main (argc, -+ argv, -+ "org.gtk.Private.AfcVolumeMonitor", -+ G_VFS_TYPE_AFC_VOLUME_MONITOR); -+} -+ -+/* -+ * vim: sw=2 ts=8 cindent expandtab cinoptions=f0,>4,n2,{2,(0,^-2,t0 ai -+ */ -diff --git a/monitor/afc/org.gtk.Private.AfcVolumeMonitor.service.in b/monitor/afc/org.gtk.Private.AfcVolumeMonitor.service.in -new file mode 100644 -index 0000000..4e6bd33 ---- /dev/null -+++ b/monitor/afc/org.gtk.Private.AfcVolumeMonitor.service.in -@@ -0,0 +1,4 @@ -+[D-BUS Service] -+Name=org.gtk.Private.AfcVolumeMonitor -+Exec=@libexecdir@/gvfs-afc-volume-monitor -+ --- -1.6.2.5 - diff --git a/gvfs-1.4.1-http-soup-header-parsing.patch b/gvfs-1.4.1-http-soup-header-parsing.patch deleted file mode 100644 index 4c5b68f..0000000 --- a/gvfs-1.4.1-http-soup-header-parsing.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 67069c464a2cb827a2afe2b7886e79707c7149e2 Mon Sep 17 00:00:00 2001 -From: Christian Kellner -Date: Fri, 16 Oct 2009 10:34:02 +0000 -Subject: [HTTP] Use soup's (2.26) header parsing function - -Libsoup has (since 2.26) specific functions for parsing various -well-known http headers, including Content-Type and Content-Length. -Bump the soup requirement accordingly. Based on a patch rom Robert -Ancell ---- -diff --git a/configure.ac b/configure.ac -index a2c9932..5069d73 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -121,7 +121,7 @@ HTTP_CFLAGS= - HTTP_LIBS= - - if test "x$enable_http" != "xno"; then -- PKG_CHECK_EXISTS(libsoup-gnome-2.4 >= 2.25.1, msg_http=yes) -+ PKG_CHECK_EXISTS(libsoup-gnome-2.4 >= 2.26.0, msg_http=yes) - - if test "x$msg_http" = "xyes"; then - PKG_CHECK_MODULES(HTTP, libsoup-gnome-2.4 libxml-2.0) -diff --git a/daemon/gvfsbackendhttp.c b/daemon/gvfsbackendhttp.c -index 23d1f97..ee531d1 100644 ---- a/daemon/gvfsbackendhttp.c -+++ b/daemon/gvfsbackendhttp.c -@@ -549,40 +549,24 @@ file_info_from_message (SoupMessage *msg, - if (basename != NULL && - g_file_attribute_matcher_matches (matcher, - G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME)) -- { -- ed_name = gvfs_file_info_populate_names_as_local (info, basename); -- } -+ ed_name = gvfs_file_info_populate_names_as_local (info, basename); - - if (ed_name != NULL && - g_file_attribute_matcher_matches (matcher, - G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME)) -- { -- g_file_info_set_edit_name (info, ed_name); -- } -+ g_file_info_set_edit_name (info, ed_name); - - g_free (basename); - g_free (ed_name); - -- text = soup_message_headers_get (msg->response_headers, -- "Content-Length"); -- if (text) -- { -- guint64 size = g_ascii_strtoull (text, NULL, 10); -- g_file_info_set_size (info, size); -- } -- -+ if (soup_message_headers_get_encoding(msg->response_headers) == SOUP_ENCODING_CONTENT_LENGTH) -+ g_file_info_set_size (info, soup_message_headers_get_content_length (msg->response_headers)); - -- text = soup_message_headers_get (msg->response_headers, -- "Content-Type"); -+ text = soup_message_headers_get_content_type (msg->response_headers, NULL); - if (text) - { -- char *p = strchr (text, ';'); -- char *tmp = NULL; - GIcon *icon; - -- if (p != NULL) -- text = tmp = g_strndup (text, p - text); -- - g_file_info_set_file_type (info, G_FILE_TYPE_REGULAR); - g_file_info_set_content_type (info, text); - g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE, text); -@@ -590,9 +574,6 @@ file_info_from_message (SoupMessage *msg, - icon = g_content_type_get_icon (text); - g_file_info_set_icon (info, icon); - g_object_unref (icon); -- -- g_free (tmp); -- - } - - --- -cgit v0.8.2 diff --git a/gvfs-1.4.1-http-suport-stream-query-info.patch b/gvfs-1.4.1-http-suport-stream-query-info.patch deleted file mode 100644 index 1391906..0000000 --- a/gvfs-1.4.1-http-suport-stream-query-info.patch +++ /dev/null @@ -1,157 +0,0 @@ -From 47a6cb95996df5538bab4b9b07cdd8f944c0b24b Mon Sep 17 00:00:00 2001 -From: Christian Kellner -Date: Fri, 16 Oct 2009 10:18:17 +0000 -Subject: [HTTP] Support g_file_input_stream_query_info() - -Fixes bug 598505. Based on a patch from Robert Ancell. ---- -diff --git a/daemon/gvfsbackendhttp.c b/daemon/gvfsbackendhttp.c -index 97c6ce7..23d1f97 100644 ---- a/daemon/gvfsbackendhttp.c -+++ b/daemon/gvfsbackendhttp.c -@@ -529,30 +529,15 @@ try_close_read (GVfsBackend *backend, - - /* *** query_info () *** */ - --static void --query_info_ready (SoupSession *session, -- SoupMessage *msg, -- gpointer user_data) -+static void -+file_info_from_message (SoupMessage *msg, -+ GFileInfo *info, -+ GFileAttributeMatcher *matcher) - { -- GFileAttributeMatcher *matcher; -- GVfsJobQueryInfo *job; -- const SoupURI *uri; -- const char *text; -- GFileInfo *info; -- char *basename; -- char *ed_name; -- -- job = G_VFS_JOB_QUERY_INFO (user_data); -- info = job->file_info; -- matcher = job->attribute_matcher; -- ed_name = NULL; -- -- if (! SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) -- { -- g_vfs_job_failed_from_http_status (G_VFS_JOB (job), msg->status_code, -- msg->reason_phrase); -- return; -- } -+ const SoupURI *uri; -+ const char *text; -+ char *basename; -+ char *ed_name = NULL; - - uri = soup_message_get_uri (msg); - basename = http_uri_get_basename (uri->path); -@@ -636,7 +621,29 @@ query_info_ready (SoupSession *session, - G_FILE_ATTRIBUTE_ETAG_VALUE, - text); - } -+} -+ -+static void -+query_info_ready (SoupSession *session, -+ SoupMessage *msg, -+ gpointer user_data) -+{ -+ GFileAttributeMatcher *matcher; -+ GVfsJobQueryInfo *job; -+ GFileInfo *info; -+ -+ job = G_VFS_JOB_QUERY_INFO (user_data); -+ info = job->file_info; -+ matcher = job->attribute_matcher; -+ -+ if (! SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) -+ { -+ g_vfs_job_failed_from_http_status (G_VFS_JOB (job), msg->status_code, -+ msg->reason_phrase); -+ return; -+ } - -+ file_info_from_message (msg, info, matcher); - - g_vfs_job_succeeded (G_VFS_JOB (job)); - } -@@ -663,6 +670,24 @@ try_query_info (GVfsBackend *backend, - } - - -+static gboolean -+try_query_info_on_read (GVfsBackend *backend, -+ GVfsJobQueryInfoRead *job, -+ GVfsBackendHandle handle, -+ GFileInfo *info, -+ GFileAttributeMatcher *attribute_matcher) -+{ -+ SoupMessage *msg = soup_input_stream_get_message (G_INPUT_STREAM (handle)); -+ -+ file_info_from_message (msg, info, attribute_matcher); -+ g_object_unref (msg); -+ -+ g_vfs_job_succeeded (G_VFS_JOB (job)); -+ -+ return TRUE; -+} -+ -+ - static void - g_vfs_backend_http_class_init (GVfsBackendHttpClass *klass) - { -@@ -673,11 +698,11 @@ g_vfs_backend_http_class_init (GVfsBackendHttpClass *klass) - - backend_class = G_VFS_BACKEND_CLASS (klass); - -- backend_class->try_mount = try_mount; -- backend_class->try_open_for_read = try_open_for_read; -- backend_class->try_read = try_read; -- backend_class->try_seek_on_read = try_seek_on_read; -- backend_class->try_close_read = try_close_read; -- backend_class->try_query_info = try_query_info; -- -+ backend_class->try_mount = try_mount; -+ backend_class->try_open_for_read = try_open_for_read; -+ backend_class->try_read = try_read; -+ backend_class->try_seek_on_read = try_seek_on_read; -+ backend_class->try_close_read = try_close_read; -+ backend_class->try_query_info = try_query_info; -+ backend_class->try_query_info_on_read = try_query_info_on_read; - } -diff --git a/daemon/soup-input-stream.c b/daemon/soup-input-stream.c -index facce17..e1928af 100644 ---- a/daemon/soup-input-stream.c -+++ b/daemon/soup-input-stream.c -@@ -912,6 +912,13 @@ soup_input_stream_truncate (GSeekable *seekable, - return FALSE; - } - -+SoupMessage * -+soup_input_stream_get_message (GInputStream *stream) -+{ -+ SoupInputStreamPrivate *priv = SOUP_INPUT_STREAM_GET_PRIVATE (stream); -+ return priv->msg ? g_object_ref (priv->msg) : NULL; -+} -+ - GQuark - soup_http_error_quark (void) - { -diff --git a/daemon/soup-input-stream.h b/daemon/soup-input-stream.h -index dd2c540..f425291 100644 ---- a/daemon/soup-input-stream.h -+++ b/daemon/soup-input-stream.h -@@ -70,6 +70,8 @@ gboolean soup_input_stream_send_finish (GInputStream *stream, - GAsyncResult *result, - GError **error); - -+SoupMessage *soup_input_stream_get_message (GInputStream *stream); -+ - #define SOUP_HTTP_ERROR soup_http_error_quark() - GQuark soup_http_error_quark (void); - --- -cgit v0.8.2 diff --git a/gvfs-1.4.2-handle-null-gdudevices.patch b/gvfs-1.4.2-handle-null-gdudevices.patch deleted file mode 100644 index 59b9de4..0000000 --- a/gvfs-1.4.2-handle-null-gdudevices.patch +++ /dev/null @@ -1,404 +0,0 @@ -From 48cf9c174f347f92c3fab7ff50b38effda0eb78a Mon Sep 17 00:00:00 2001 -From: Tomas Bzatek -Date: Fri, 30 Oct 2009 17:06:26 +0000 -Subject: Gently handle NULL GduDevice objects - -This patch adds bunch of tests for NULL GduDevice objects. According to -gdu docs, there's a possibility to have GduPresentable and no associated -GduDevice. It's not common but true for several special cases - -like GduLinuxMdDrive. - -Signed-off-by: David Zeuthen ---- -diff --git a/monitor/gdu/ggduvolume.c b/monitor/gdu/ggduvolume.c -index 865a7b7..28839fd 100644 ---- a/monitor/gdu/ggduvolume.c -+++ b/monitor/gdu/ggduvolume.c -@@ -172,7 +172,7 @@ static gboolean - update_volume (GGduVolume *volume) - { - GduDevice *device; -- GduPool *pool; -+ GduPool *pool = NULL; - time_t now; - gboolean changed; - gboolean old_can_mount; -@@ -217,10 +217,11 @@ update_volume (GGduVolume *volume) - - /* in with the new */ - device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->gdu_volume)); -- pool = gdu_device_get_pool (device); -+ if (device != NULL) -+ pool = gdu_device_get_pool (device); - - keep_cleartext_volume = FALSE; -- if (gdu_device_is_luks (device)) -+ if (device != NULL && gdu_device_is_luks (device)) - { - const gchar *holder_objpath; - -@@ -287,13 +288,17 @@ update_volume (GGduVolume *volume) - volume->name = gdu_presentable_get_name (GDU_PRESENTABLE (volume->cleartext_gdu_volume)); - - g_free (volume->device_file); -- volume->device_file = g_strdup (gdu_device_get_device_file (luks_cleartext_volume_device)); -+ if (luks_cleartext_volume_device != NULL) -+ volume->device_file = g_strdup (gdu_device_get_device_file (luks_cleartext_volume_device)); -+ else -+ volume->device_file = NULL; - - volume->can_mount = TRUE; - - volume->should_automount = FALSE; - -- g_object_unref (luks_cleartext_volume_device); -+ if (luks_cleartext_volume_device != NULL) -+ g_object_unref (luks_cleartext_volume_device); - } - else - { -@@ -321,7 +326,10 @@ update_volume (GGduVolume *volume) - } - - g_free (volume->device_file); -- volume->device_file = g_strdup (gdu_device_get_device_file (device)); -+ if (device != NULL) -+ volume->device_file = g_strdup (gdu_device_get_device_file (device)); -+ else -+ volume->device_file = NULL; - - volume->can_mount = TRUE; - -@@ -341,14 +349,16 @@ update_volume (GGduVolume *volume) - * nopolicy is only FALSE for "physical" devices - e.g. only "physical" devices will - * be set to be automounted. - */ -- if (gdu_device_get_presentation_nopolicy (device)) -+ if (device != NULL && gdu_device_get_presentation_nopolicy (device)) - volume->should_automount = FALSE; - - g_free (activation_uri); - } - -- g_object_unref (pool); -- g_object_unref (device); -+ if (pool != NULL) -+ g_object_unref (pool); -+ if (device != NULL) -+ g_object_unref (device); - - /* ---------------------------------------------------------------------------------------------------- */ - -@@ -1082,6 +1092,20 @@ g_gdu_volume_mount (GVolume *_volume, - } - - device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->gdu_volume)); -+ -+ if (device == NULL) -+ { -+ simple = g_simple_async_result_new_error (G_OBJECT (volume), -+ callback, -+ user_data, -+ G_IO_ERROR, -+ G_IO_ERROR_FAILED, -+ "Underlying device missing"); -+ g_simple_async_result_complete (simple); -+ g_object_unref (simple); -+ goto out; -+ } -+ - pool = gdu_device_get_pool (device); - - /* Makes no sense to mount -@@ -1129,11 +1153,14 @@ g_gdu_volume_mount (GVolume *_volume, - - luks_cleartext_volume_device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->cleartext_gdu_volume)); - -- object_path_of_cleartext_device = gdu_device_get_object_path (luks_cleartext_volume_device); -+ if (luks_cleartext_volume_device != NULL) -+ { -+ object_path_of_cleartext_device = gdu_device_get_object_path (luks_cleartext_volume_device); - -- mount_cleartext_device (data, object_path_of_cleartext_device); -+ mount_cleartext_device (data, object_path_of_cleartext_device); - -- g_object_unref (luks_cleartext_volume_device); -+ g_object_unref (luks_cleartext_volume_device); -+ } - goto out; - } - -@@ -1551,17 +1578,20 @@ g_gdu_volume_get_identifier (GVolume *_volume, - { - device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->gdu_volume)); - -- label = gdu_device_id_get_label (device); -- uuid = gdu_device_id_get_uuid (device); -+ if (device != NULL) -+ { -+ label = gdu_device_id_get_label (device); -+ uuid = gdu_device_id_get_uuid (device); - -- g_object_unref (device); -+ g_object_unref (device); - -- if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE) == 0) -- id = g_strdup (volume->device_file); -- else if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_LABEL) == 0) -- id = strlen (label) > 0 ? g_strdup (label) : NULL; -- else if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_UUID) == 0) -- id = strlen (uuid) > 0 ? g_strdup (uuid) : NULL; -+ if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE) == 0) -+ id = g_strdup (volume->device_file); -+ else if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_LABEL) == 0) -+ id = strlen (label) > 0 ? g_strdup (label) : NULL; -+ else if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_UUID) == 0) -+ id = strlen (uuid) > 0 ? g_strdup (uuid) : NULL; -+ } - } - - return id; -@@ -1577,19 +1607,24 @@ g_gdu_volume_enumerate_identifiers (GVolume *_volume) - const gchar *uuid; - - p = g_ptr_array_new (); -+ label = NULL; - - if (volume->gdu_volume != NULL) - { - device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->gdu_volume)); -- label = gdu_device_id_get_label (device); -- uuid = gdu_device_id_get_uuid (device); -- g_object_unref (device); -- -- g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE)); -- if (strlen (label) > 0) -- g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_LABEL)); -- if (strlen (uuid) > 0) -- g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_UUID)); -+ -+ if (device != NULL) -+ { -+ label = gdu_device_id_get_label (device); -+ uuid = gdu_device_id_get_uuid (device); -+ g_object_unref (device); -+ -+ g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE)); -+ if (strlen (label) > 0) -+ g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_LABEL)); -+ if (strlen (uuid) > 0) -+ g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_UUID)); -+ } - } - - g_ptr_array_add (p, NULL); -@@ -1638,8 +1673,11 @@ g_gdu_volume_has_device_file (GGduVolume *volume, - { - GduDevice *luks_cleartext_volume_device; - luks_cleartext_volume_device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->cleartext_gdu_volume)); -- _device_file = gdu_device_get_device_file (luks_cleartext_volume_device); -- g_object_unref (luks_cleartext_volume_device); -+ if (luks_cleartext_volume_device != NULL) -+ { -+ _device_file = gdu_device_get_device_file (luks_cleartext_volume_device); -+ g_object_unref (luks_cleartext_volume_device); -+ } - } - - return g_strcmp0 (_device_file, device_file) == 0; -@@ -1682,8 +1720,11 @@ g_gdu_volume_has_uuid (GGduVolume *volume, - { - GduDevice *luks_cleartext_volume_device; - luks_cleartext_volume_device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->cleartext_gdu_volume)); -- _uuid = gdu_device_id_get_uuid (luks_cleartext_volume_device); -- g_object_unref (luks_cleartext_volume_device); -+ if (luks_cleartext_volume_device != NULL) -+ { -+ _uuid = gdu_device_id_get_uuid (luks_cleartext_volume_device); -+ g_object_unref (luks_cleartext_volume_device); -+ } - } - - return g_strcmp0 (_uuid, uuid) == 0; -diff --git a/monitor/gdu/ggduvolumemonitor.c b/monitor/gdu/ggduvolumemonitor.c -index e81dce2..398fed4 100644 ---- a/monitor/gdu/ggduvolumemonitor.c -+++ b/monitor/gdu/ggduvolumemonitor.c -@@ -779,9 +779,10 @@ should_volume_be_ignored (GduPool *pool, GduVolume *volume, GList *fstab_mount_p - const gchar *type; - - ret = TRUE; -- device = NULL; - - device = gdu_presentable_get_device (GDU_PRESENTABLE (volume)); -+ if (device == NULL) -+ goto out; - - if (gdu_device_get_presentation_hide (device)) - goto out; -@@ -827,7 +828,8 @@ should_volume_be_ignored (GduPool *pool, GduVolume *volume, GList *fstab_mount_p - - out: - -- g_object_unref (device); -+ if (device != NULL) -+ g_object_unref (device); - return ret; - } - -@@ -1269,15 +1271,18 @@ update_volumes (GGduVolumeMonitor *monitor, - - d = gdu_presentable_get_device (p); - -- volume = find_volume_for_device_file (monitor, gdu_device_get_device_file (d)); -- if (volume != NULL) -+ if (d != NULL) - { -- /*g_debug ("removing volume %s", gdu_device_get_device_file (d));*/ -- g_gdu_volume_removed (volume); -- monitor->volumes = g_list_remove (monitor->volumes, volume); -- *removed_volumes = g_list_prepend (*removed_volumes, volume); -+ volume = find_volume_for_device_file (monitor, gdu_device_get_device_file (d)); -+ if (volume != NULL) -+ { -+ /*g_debug ("removing volume %s", gdu_device_get_device_file (d));*/ -+ g_gdu_volume_removed (volume); -+ monitor->volumes = g_list_remove (monitor->volumes, volume); -+ *removed_volumes = g_list_prepend (*removed_volumes, volume); -+ } -+ g_object_unref (d); - } -- g_object_unref (d); - } - - for (l = added; l != NULL; l = l->next) -@@ -1285,9 +1290,12 @@ update_volumes (GGduVolumeMonitor *monitor, - GduPresentable *p = GDU_PRESENTABLE (l->data); - GduDevice *d; - -+ volume = NULL; - d = gdu_presentable_get_device (p); - -- volume = find_volume_for_device_file (monitor, gdu_device_get_device_file (d)); -+ if (d != NULL) -+ volume = find_volume_for_device_file (monitor, gdu_device_get_device_file (d)); -+ - if (volume == NULL) - { - GduPresentable *toplevel_presentable; -@@ -1297,12 +1305,16 @@ update_volumes (GGduVolumeMonitor *monitor, - { - GduDevice *toplevel_device; - -+ drive = NULL; - toplevel_device = gdu_presentable_get_device (toplevel_presentable); -- drive = find_drive_by_device_file (monitor, gdu_device_get_device_file (toplevel_device)); -- /*g_debug ("adding volume %s (drive %s)", -- gdu_device_get_device_file (d), -- gdu_device_get_device_file (toplevel_device));*/ -- g_object_unref (toplevel_device); -+ if (toplevel_device != NULL) -+ { -+ drive = find_drive_by_device_file (monitor, gdu_device_get_device_file (toplevel_device)); -+ /*g_debug ("adding volume %s (drive %s)", -+ gdu_device_get_device_file (d), -+ gdu_device_get_device_file (toplevel_device));*/ -+ g_object_unref (toplevel_device); -+ } - g_object_unref (toplevel_presentable); - } - else -@@ -1320,9 +1332,10 @@ update_volumes (GGduVolumeMonitor *monitor, - monitor->volumes = g_list_prepend (monitor->volumes, volume); - *added_volumes = g_list_prepend (*added_volumes, g_object_ref (volume)); - } -- } -+ } - -- g_object_unref (d); -+ if (d != NULL) -+ g_object_unref (d); - } - - g_list_free (added); -@@ -1579,10 +1592,15 @@ update_discs (GGduVolumeMonitor *monitor, - GduPresentable *p = GDU_PRESENTABLE (l->data); - GduDevice *d; - -+ volume = NULL; -+ mount = NULL; - d = gdu_presentable_get_device (p); - -- volume = find_disc_volume_for_device_file (monitor, gdu_device_get_device_file (d)); -- mount = find_disc_mount_for_volume (monitor, volume); -+ if (d != NULL) -+ { -+ volume = find_disc_volume_for_device_file (monitor, gdu_device_get_device_file (d)); -+ mount = find_disc_mount_for_volume (monitor, volume); -+ } - - if (mount != NULL) - { -@@ -1600,7 +1618,8 @@ update_discs (GGduVolumeMonitor *monitor, - *removed_volumes = g_list_prepend (*removed_volumes, volume); - } - -- g_object_unref (d); -+ if (d != NULL) -+ g_object_unref (d); - } - - for (l = added; l != NULL; l = l->next) -@@ -1609,11 +1628,16 @@ update_discs (GGduVolumeMonitor *monitor, - GduDevice *d; - gboolean is_blank; - -+ volume = NULL; -+ is_blank = TRUE; - d = gdu_presentable_get_device (p); - -- is_blank = gdu_device_optical_disc_get_is_blank (d); -+ if (d != NULL) -+ { -+ is_blank = gdu_device_optical_disc_get_is_blank (d); -+ volume = find_disc_volume_for_device_file (monitor, gdu_device_get_device_file (d)); -+ } - -- volume = find_disc_volume_for_device_file (monitor, gdu_device_get_device_file (d)); - if (volume == NULL) - { - GduPresentable *toplevel_presentable; -@@ -1623,12 +1647,16 @@ update_discs (GGduVolumeMonitor *monitor, - { - GduDevice *toplevel_device; - -+ drive = NULL; - toplevel_device = gdu_presentable_get_device (toplevel_presentable); -- drive = find_drive_by_device_file (monitor, gdu_device_get_device_file (toplevel_device)); -- /*g_debug ("adding volume %s (drive %s)", -- gdu_device_get_device_file (d), -- gdu_device_get_device_file (toplevel_device));*/ -- g_object_unref (toplevel_device); -+ if (toplevel_device != NULL) -+ { -+ drive = find_drive_by_device_file (monitor, gdu_device_get_device_file (toplevel_device)); -+ /*g_debug ("adding volume %s (drive %s)", -+ gdu_device_get_device_file (d), -+ gdu_device_get_device_file (toplevel_device));*/ -+ g_object_unref (toplevel_device); -+ } - g_object_unref (toplevel_presentable); - } - else -@@ -1682,7 +1710,8 @@ update_discs (GGduVolumeMonitor *monitor, - } - } - -- g_object_unref (d); -+ if (d != NULL) -+ g_object_unref (d); - } - - g_list_free (added); --- -cgit v0.8.2 diff --git a/gvfs-1.4.2-remove-dead-code.patch b/gvfs-1.4.2-remove-dead-code.patch deleted file mode 100644 index 02105f9..0000000 --- a/gvfs-1.4.2-remove-dead-code.patch +++ /dev/null @@ -1,66 +0,0 @@ -From cd2afbd07bbcf4e7caee1dd0ca1c65d74974884d Mon Sep 17 00:00:00 2001 -From: Tomas Bzatek -Date: Fri, 30 Oct 2009 17:03:35 +0000 -Subject: Remove dead code - -Signed-off-by: David Zeuthen ---- -diff --git a/monitor/gdu/ggduvolumemonitor.c b/monitor/gdu/ggduvolumemonitor.c -index 83d8fc2..e81dce2 100644 ---- a/monitor/gdu/ggduvolumemonitor.c -+++ b/monitor/gdu/ggduvolumemonitor.c -@@ -842,7 +842,6 @@ should_drive_be_ignored (GduPool *pool, GduDrive *d, GList *fstab_mount_points) - GList *l; - - ignored = FALSE; -- device = NULL; - enclosed = NULL; - - device = gdu_presentable_get_device (GDU_PRESENTABLE (d)); -@@ -1074,7 +1073,7 @@ find_disc_volume_for_device_file (GGduVolumeMonitor *monitor, - - static GGduVolume * - find_volume_for_device_file (GGduVolumeMonitor *monitor, -- const gchar *device_file) -+ const gchar *device_file) - { - GList *l; - GGduVolume *ret; -@@ -1183,9 +1182,6 @@ update_drives (GGduVolumeMonitor *monitor, - for (l = removed; l != NULL; l = l->next) - { - GduPresentable *p = GDU_PRESENTABLE (l->data); -- GduDevice *d; -- -- d = gdu_presentable_get_device (p); - - drive = find_drive_by_presentable (monitor, p); - if (drive != NULL) -@@ -1195,16 +1191,11 @@ update_drives (GGduVolumeMonitor *monitor, - monitor->drives = g_list_remove (monitor->drives, drive); - *removed_drives = g_list_prepend (*removed_drives, drive); - } -- if (d != NULL) -- g_object_unref (d); - } - - for (l = added; l != NULL; l = l->next) - { - GduPresentable *p = GDU_PRESENTABLE (l->data); -- GduDevice *d; -- -- d = gdu_presentable_get_device (p); - - drive = find_drive_by_presentable (monitor, p); - if (drive == NULL) -@@ -1217,8 +1208,6 @@ update_drives (GGduVolumeMonitor *monitor, - *added_drives = g_list_prepend (*added_drives, g_object_ref (drive)); - } - } -- if (d != NULL) -- g_object_unref (d); - } - - g_list_free (added); --- -cgit v0.8.2 diff --git a/gvfs-1.4.2-smb-queryfs.patch b/gvfs-1.4.2-smb-queryfs.patch deleted file mode 100644 index 1ca7364..0000000 --- a/gvfs-1.4.2-smb-queryfs.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 62f7058bec6f96c2dcc8a12431a1114e24eac6e8 Mon Sep 17 00:00:00 2001 -From: Tomas Bzatek -Date: Tue, 10 Nov 2009 17:53:50 +0100 -Subject: [PATCH] [SMB] Support querying filesystem size and free space - -Requires libsmbclient >= 3.2.0 - -Fixes rfe bug 565337 ---- - daemon/gvfsbackendsmb.c | 30 +++++++++++++++++++++++++++++- - 1 files changed, 29 insertions(+), 1 deletions(-) - -diff --git a/daemon/gvfsbackendsmb.c b/daemon/gvfsbackendsmb.c -index bc8c415..2106a43 100644 ---- a/daemon/gvfsbackendsmb.c -+++ b/daemon/gvfsbackendsmb.c -@@ -1591,8 +1591,36 @@ do_query_fs_info (GVfsBackend *backend, - GFileInfo *info, - GFileAttributeMatcher *attribute_matcher) - { -+ GVfsBackendSmb *op_backend = G_VFS_BACKEND_SMB (backend); -+ smbc_statvfs_fn smbc_statvfs; -+ struct statvfs st = {0}; -+ char *uri; -+ int res; -+ - g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE, "cifs"); -- -+ -+#ifdef DEPRECATED_SMBC_INTERFACE -+ if (g_file_attribute_matcher_matches (attribute_matcher, -+ G_FILE_ATTRIBUTE_FILESYSTEM_SIZE) || -+ g_file_attribute_matcher_matches (attribute_matcher, -+ G_FILE_ATTRIBUTE_FILESYSTEM_FREE) || -+ g_file_attribute_matcher_matches (attribute_matcher, -+ G_FILE_ATTRIBUTE_FILESYSTEM_READONLY)) -+ { -+ uri = create_smb_uri (op_backend->server, op_backend->share, filename); -+ smbc_statvfs = smbc_getFunctionStatVFS (op_backend->smb_context); -+ res = smbc_statvfs (op_backend->smb_context, uri, &st); -+ g_free (uri); -+ -+ if (res == 0) -+ { -+ g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE, st.f_bsize * st.f_blocks); -+ g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE, st.f_bsize * st.f_bavail); -+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY, st.f_flag & SMBC_VFS_FEATURE_RDONLY); -+ } -+ } -+#endif -+ - g_vfs_job_succeeded (G_VFS_JOB (job)); - } - --- -1.6.5.2 - diff --git a/gvfs-1.5.1-afc-remove-unreleased.patch b/gvfs-1.5.1-afc-remove-unreleased.patch new file mode 100644 index 0000000..1085dc2 --- /dev/null +++ b/gvfs-1.5.1-afc-remove-unreleased.patch @@ -0,0 +1,59 @@ +diff --git a/daemon/gvfsbackendafc.c b/daemon/gvfsbackendafc.c +index 8722ca7..8b87141 100644 +--- a/daemon/gvfsbackendafc.c ++++ b/daemon/gvfsbackendafc.c +@@ -1150,46 +1150,6 @@ g_vfs_backend_afc_set_display_name (GVfsBackend *backend, + } + + static void +-g_vfs_backend_afc_set_attribute (GVfsBackend *backend, +- GVfsJobSetAttribute *job, +- const char *filename, +- const char *attribute, +- GFileAttributeType type, +- gpointer value_p, +- GFileQueryInfoFlags flags) +-{ +- GVfsBackendAfc *self; +- uint64_t mtime = 0; +- afc_error_t err; +- +- self = G_VFS_BACKEND_AFC(backend); +- g_return_if_fail(self->connected); +- +- if (g_str_equal (attribute, G_FILE_ATTRIBUTE_TIME_MODIFIED) == FALSE) +- { +- g_vfs_job_failed (G_VFS_JOB (job), +- G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, +- _("Operation unsupported")); +- return; +- } +- +- mtime = *(guint64*)(value_p) * (guint64)1000000000; +- +- err = afc_set_file_time (self->afc_cli, filename, mtime); +- if (err == AFC_E_UNKNOWN_PACKET_TYPE) +- { +- /* ignore error for pre-3.1 devices as the do not support setting file modification times */ +- return g_vfs_job_succeeded (G_VFS_JOB(job)); +- } +- if (G_UNLIKELY(g_vfs_backend_afc_check (err, G_VFS_JOB(job)))) +- { +- return; +- } +- +- g_vfs_job_succeeded (G_VFS_JOB(job)); +-} +- +-static void + g_vfs_backend_afc_make_directory (GVfsBackend *backend, + GVfsJobMakeDirectory *job, + const char *path) +@@ -1336,7 +1296,6 @@ g_vfs_backend_afc_class_init (GVfsBackendAfcClass *klass) + backend_class->make_symlink = g_vfs_backend_afc_make_symlink; + backend_class->move = g_vfs_backend_afc_move; + backend_class->set_display_name = g_vfs_backend_afc_set_display_name; +- backend_class->set_attribute = g_vfs_backend_afc_set_attribute; + } + + /* diff --git a/gvfs.spec b/gvfs.spec index 37ab0c7..5663e01 100644 --- a/gvfs.spec +++ b/gvfs.spec @@ -1,11 +1,11 @@ Summary: Backends for the gio framework in GLib Name: gvfs -Version: 1.4.1 -Release: 6%{?dist} +Version: 1.5.1 +Release: 1%{?dist} License: LGPLv2+ Group: System Environment/Libraries URL: http://www.gtk.org -Source: http://download.gnome.org/sources/gvfs/1.4/gvfs-%{version}.tar.bz2 +Source: http://download.gnome.org/sources/gvfs/1.5/gvfs-%{version}.tar.bz2 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: pkgconfig BuildRequires: glib2-devel >= 2.21.2 @@ -14,7 +14,7 @@ BuildRequires: /usr/bin/ssh BuildRequires: libcdio-devel >= 0.78.2 BuildRequires: hal-devel >= 0.5.10 BuildRequires: libgudev-devel -BuildRequires: libsoup-devel >= 2.25.2 +BuildRequires: libsoup-devel >= 2.26.0 BuildRequires: avahi-glib-devel >= 0.6 BuildRequires: gnome-keyring-devel BuildRequires: intltool @@ -22,9 +22,7 @@ BuildRequires: gettext-devel BuildRequires: GConf2-devel BuildRequires: gnome-disk-utility-devel >= 2.28.1-1 BuildRequires: PolicyKit-devel -# This is a hack until the xfce4-notifyd dependency issue is fixed -# https://fedorahosted.org/rel-eng/ticket/1788 -#BuildRequires: notification-daemon +BuildRequires: expat-devel Requires(post): desktop-file-utils @@ -35,17 +33,9 @@ BuildRequires: automake autoconf BuildRequires: libtool # http://bugzilla.gnome.org/show_bug.cgi?id=567235 Patch0: gvfs-archive-integration.patch -# http://bugzilla.gnome.org/show_bug.cgi?id=591005 -Patch1: 0001-Add-AFC-backend.patch -# from upstream -Patch2: http-icons.patch -# https://bugzilla.gnome.org/show_bug.cgi?id=565337 -Patch3: gvfs-1.4.2-smb-queryfs.patch -# from upstream -Patch12: gvfs-1.4.1-http-suport-stream-query-info.patch -Patch13: gvfs-1.4.1-http-soup-header-parsing.patch -Patch14: gvfs-1.4.2-remove-dead-code.patch -Patch15: gvfs-1.4.2-handle-null-gdudevices.patch +# some AFC code depends on unreleased libiphone additions +Patch1: gvfs-1.5.1-afc-remove-unreleased.patch + Obsoletes: gnome-mount <= 0.8 Obsoletes: gnome-mount-nautilus-properties <= 0.8 @@ -106,7 +96,6 @@ Group: System Environment/Libraries Requires: %{name} = %{version}-%{release} Requires: obex-data-server >= 0.3.4-6 BuildRequires: bluez-libs-devel >= 3.12 -BuildRequires: expat-devel Obsoletes: gnome-vfs2-obexftp <= 0.4 %description obexftp @@ -132,7 +121,7 @@ Summary: AFC support for gvfs Group: System Environment/Libraries Requires: %{name} = %{version}-%{release} Requires: usbmuxd -BuildRequires: libiphone-devel >= 0.9.2 +BuildRequires: libiphone-devel >= 0.9.4 %description afc This package provides support for reading files on Apple iPhones and @@ -142,13 +131,7 @@ and iPod Touches to applications using gvfs. %prep %setup -q %patch0 -p1 -b .archive-integration -%patch1 -p1 -b .afc -%patch2 -p1 -b .http-icons -%patch3 -p1 -b .smb-queryfs -%patch12 -p1 -b .http-query-info -%patch13 -p1 -b .http-headers -%patch14 -p1 -b .dead-code -%patch15 -p1 -b .gdu-null-devices +%patch1 -p1 -b .afc-unreleased %build @@ -314,6 +297,10 @@ killall -USR1 gvfsd >&/dev/null || : %{_datadir}/gvfs/remote-volume-monitors/afc.monitor %changelog +* Wed Nov 18 2009 Tomas Bzatek - 1.5.1-1 +- Update to 1.5.1 +- AFC: temporarily disable setting file modification times + * Thu Nov 12 2009 Matthias Clasen 1.4.1-6 - Add obsoletes for gnome-mount diff --git a/http-icons.patch b/http-icons.patch deleted file mode 100644 index 5c0fabc..0000000 --- a/http-icons.patch +++ /dev/null @@ -1,91 +0,0 @@ -diff --git a/daemon/gvfsbackendhttp.c b/daemon/gvfsbackendhttp.c -index 45ea54d..97c6ce7 100644 ---- a/daemon/gvfsbackendhttp.c -+++ b/daemon/gvfsbackendhttp.c -@@ -47,6 +47,7 @@ - #include "gvfsjobqueryattributes.h" - #include "gvfsjobenumerate.h" - #include "gvfsdaemonprotocol.h" -+#include "gvfsdaemonutils.h" - - #include "soup-input-stream.h" - -@@ -539,10 +540,12 @@ query_info_ready (SoupSession *session, - const char *text; - GFileInfo *info; - char *basename; -+ char *ed_name; - - job = G_VFS_JOB_QUERY_INFO (user_data); - info = job->file_info; - matcher = job->attribute_matcher; -+ ed_name = NULL; - - if (! SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) - { -@@ -562,30 +565,18 @@ query_info_ready (SoupSession *session, - g_file_attribute_matcher_matches (matcher, - G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME)) - { -- char *display_name = g_filename_display_name (basename); -- -- if (strstr (display_name, "\357\277\275") != NULL) -- { -- char *p = display_name; -- display_name = g_strconcat (display_name, _(" (invalid encoding)"), NULL); -- g_free (p); -- } -- -- g_file_info_set_display_name (info, display_name); -- g_free (display_name); -+ ed_name = gvfs_file_info_populate_names_as_local (info, basename); - } - -- if (basename != NULL && -+ if (ed_name != NULL && - g_file_attribute_matcher_matches (matcher, - G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME)) - { -- char *edit_name = g_filename_display_name (basename); -- g_file_info_set_edit_name (info, edit_name); -- g_free (edit_name); -- } -+ g_file_info_set_edit_name (info, ed_name); -+ } - - g_free (basename); -- -+ g_free (ed_name); - - text = soup_message_headers_get (msg->response_headers, - "Content-Length"); -@@ -601,15 +592,22 @@ query_info_ready (SoupSession *session, - if (text) - { - char *p = strchr (text, ';'); -+ char *tmp = NULL; -+ GIcon *icon; - - if (p != NULL) -- { -- char *tmp = g_strndup (text, p - text); -- g_file_info_set_content_type (info, tmp); -- g_free (tmp); -- } -- else -- g_file_info_set_content_type (info, text); -+ text = tmp = g_strndup (text, p - text); -+ -+ g_file_info_set_file_type (info, G_FILE_TYPE_REGULAR); -+ g_file_info_set_content_type (info, text); -+ g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE, text); -+ -+ icon = g_content_type_get_icon (text); -+ g_file_info_set_icon (info, icon); -+ g_object_unref (icon); -+ -+ g_free (tmp); -+ - } - - diff --git a/sources b/sources index 130549a..a10bbba 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -6eff809d50e618f289d5192724a049de gvfs-1.4.1.tar.bz2 +46a7efa529d2fb8a0beee213da650b4d gvfs-1.5.1.tar.bz2