[gvfs/mtp-backend: 63/64] MTP: Make recursive push work.
- From: Philip Langdale <philipl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs/mtp-backend: 63/64] MTP: Make recursive push work.
- Date: Sat, 12 Jan 2013 04:39:26 +0000 (UTC)
commit 31bf79d68f8d29f299ae0110cc05058043da0186
Author: Philip Langdale <philipl overt org>
Date: Mon Jan 7 07:41:43 2013 -0800
MTP: Make recursive push work.
This introduces a path normalization helper that turns filenames
into entity IDs where needed to allow the push of a directory
to the device to work.
daemon/gvfsbackendmtp.c | 140 +++++++++++++++++++++++++++++++++++++----------
1 files changed, 111 insertions(+), 29 deletions(-)
---
diff --git a/daemon/gvfsbackendmtp.c b/daemon/gvfsbackendmtp.c
index 2c59fd7..1ee6dd7 100644
--- a/daemon/gvfsbackendmtp.c
+++ b/daemon/gvfsbackendmtp.c
@@ -868,6 +868,97 @@ do_enumerate (GVfsBackend *backend,
}
+/**
+ * get_file_for_filename:
+ *
+ * Get the entity ID for an element given its filename and
+ * the IDs of its parents.
+ *
+ * Called with backend mutex lock held.
+ */
+static LIBMTP_file_t *
+get_file_for_filename (LIBMTP_mtpdevice_t *device,
+ gchar **elements,
+ unsigned int i)
+{
+ LIBMTP_file_t *file = NULL;
+
+ DEBUG ("(III) get_file_for_filename (element %d '%s') ", i, elements[i]);
+ long parent_id = -1;
+ if (i > 2) {
+ parent_id = strtol (elements[i - 1], NULL, 10);
+ }
+ LIBMTP_file_t *f = LIBMTP_Get_Files_And_Folders (device, strtol (elements[1], NULL, 10),
+ parent_id);
+ while (f != NULL) {
+ DEBUG_ENUMERATE ("(III) query (entity = %s, name = %s) ", f->filename, elements[i]);
+ if (strcmp (f->filename, elements[i]) == 0) {
+ file = f;
+ f = f->next;
+ break;
+ } else {
+ LIBMTP_file_t *tmp = f;
+ f = f->next;
+ LIBMTP_destroy_file_t (tmp);
+ }
+ }
+ while (f != NULL) {
+ LIBMTP_file_t *tmp = f;
+ f = f->next;
+ LIBMTP_destroy_file_t (tmp);
+ }
+ DEBUG ("(III) get_file_for_filename done");
+ return file;
+}
+
+
+/**
+ * normalize_elements:
+ *
+ * Take a set of path elements and turn any file/directory names into
+ * MTP entity IDs.
+ *
+ * Called with backend mutex lock held.
+ */
+static void
+normalize_elements (LIBMTP_mtpdevice_t *device,
+ gchar **elements,
+ unsigned int ne)
+{
+ DEBUG ("(II) normalize_elements (ne = %d)", ne);
+ if (ne < 3) {
+ /* In these cases, elements are always normal. */
+ return;
+ }
+
+ unsigned int i;
+ for (i = 2; i < ne; i++) {
+ LIBMTP_file_t *file = NULL;
+ char *endptr;
+ long file_id = strtol (elements[i], &endptr, 10);
+
+ if (file_id == 0 || *endptr != '\0') {
+ file = get_file_for_filename(device, elements, i);
+ if (file == NULL) {
+ /* Missing entity. Cannot normalize. */
+ DEBUG ("(II) Cannot normalize missing entity '%s'", elements[i]);
+ continue;
+ } else {
+ char *item_id = g_strdup_printf ("%d", file->item_id);
+ DEBUG ("(II) %s = %s", elements[i], item_id);
+ g_free (elements[i]);
+ elements[i] = item_id;
+ LIBMTP_destroy_file_t (file);
+ }
+ } else {
+ /* Already normal. */
+ DEBUG ("(II) normal entity '%s'", elements[i]);
+ continue;
+ }
+ }
+ DEBUG ("(II) normalize_elements done");
+}
+
static void
do_query_info (GVfsBackend *backend,
GVfsJobQueryInfo *job,
@@ -900,49 +991,28 @@ do_query_info (GVfsBackend *backend,
}
for (storage = device->storage; storage != 0; storage = storage->next) {
if (storage->id == strtol (elements[ne-1], NULL, 10)) {
- DEBUG ("(III) found storage %u", storage->id);
+ DEBUG ("(I) found storage %u", storage->id);
get_storage_info (storage, info);
}
}
} else {
LIBMTP_file_t *file = NULL;
char *endptr;
- if (strtol (elements[ne-1], &endptr, 10) == 0 ||
- *endptr != '\0') {
- DEBUG ("(II) try get files and folders");
- int parent_id = -1;
- if (ne > 3) {
- parent_id = strtol (elements[ne-2], NULL, 10);
- }
- LIBMTP_file_t *i = LIBMTP_Get_Files_And_Folders (device, strtol (elements[1], NULL, 10),
- parent_id);
- while (i != NULL) {
- DEBUG ("(II) backup query (entity = %s, name = %s) ", i->filename, elements[ne-1]);
- if (strcmp (i->filename, elements[ne-1]) == 0) {
- file = i;
- i = i->next;
- break;
- } else {
- LIBMTP_file_t *tmp = i;
- i = i->next;
- LIBMTP_destroy_file_t (tmp);
- }
- }
- while (i != NULL) {
- LIBMTP_file_t *tmp = i;
- i = i->next;
- LIBMTP_destroy_file_t (tmp);
- }
+ long file_id = strtol (elements[ne - 1], &endptr, 10);
+
+ if (file_id == 0 || *endptr != '\0') {
+ file = get_file_for_filename (device, elements, ne - 1);
if (file == NULL) {
/* The backup query might have found nothing. */
- DEBUG ("(II) backup query could not find file");
+ DEBUG ("(I) get_file_for_filename could not find '%s'",
+ elements[ne - 1]);
g_vfs_job_failed_literal (G_VFS_JOB (job),
G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
_("File not found"));
goto exit;
}
} else {
- file = LIBMTP_Get_Filemetadata (device, strtol (elements[ne-1], NULL, 10));
+ file = LIBMTP_Get_Filemetadata (device, file_id);
}
if (file != NULL) {
@@ -1053,6 +1123,12 @@ do_make_directory (GVfsBackend *backend,
LIBMTP_mtpdevice_t *device;
device = G_VFS_BACKEND_MTP (backend)->device;
+ /*
+ * Might be called as part of a batch copy of a nested directory hierarchy.
+ * New directories would then be referred to by name and not id.
+ */
+ normalize_elements(device, elements, ne - 1);
+
int parent_id = 0;
if (ne > 3) {
parent_id = strtol (elements[ne-2], NULL, 10);
@@ -1173,6 +1249,12 @@ do_push (GVfsBackend *backend,
LIBMTP_mtpdevice_t *device;
device = G_VFS_BACKEND_MTP (backend)->device;
+ /*
+ * Might be called as part of a batch copy of a nested directory hierarchy.
+ * New files would then be referred to by name and not id.
+ */
+ normalize_elements(device, elements, ne - 1);
+
int parent_id = 0;
if (ne > 3) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]