gvfs r1279 - in trunk: . daemon
- From: gicmo svn gnome org
- To: svn-commits-list gnome org
- Subject: gvfs r1279 - in trunk: . daemon
- Date: Fri, 15 Feb 2008 19:00:51 +0000 (GMT)
Author: gicmo
Date: Fri Feb 15 19:00:51 2008
New Revision: 1279
URL: http://svn.gnome.org/viewvc/gvfs?rev=1279&view=rev
Log:
2008-02-15 Christian Kellner <gicmo gnome org>
* daemon/gvfsbackenddav.c:
Completly redo Multistatus parsing.
Modified:
trunk/ChangeLog
trunk/daemon/gvfsbackenddav.c
Modified: trunk/daemon/gvfsbackenddav.c
==============================================================================
--- trunk/daemon/gvfsbackenddav.c (original)
+++ trunk/daemon/gvfsbackenddav.c Fri Feb 15 19:00:51 2008
@@ -130,7 +130,7 @@
}
/* ************************************************************************* */
-/* */
+/* generic xml parsing functions */
static inline gboolean
node_has_name (xmlNodePtr node, const char *name)
@@ -140,6 +140,104 @@
return ! strcmp ((char *) node->name, name);
}
+static inline gboolean
+node_has_name_ns (xmlNodePtr node, const char *name, const char *ns_href)
+{
+ gboolean has_name;
+ gboolean has_ns;
+
+ g_return_val_if_fail (node != NULL, FALSE);
+
+ has_name = has_ns = TRUE;
+
+ if (name)
+ has_name = node->name && ! strcmp ((char *) node->name, name);
+
+ if (ns_href)
+ has_ns = node->ns && node->ns->href &&
+ ! g_ascii_strcasecmp ((char *) node->ns->href, ns_href);
+
+ return has_name && has_ns;
+}
+
+static inline gboolean
+node_is_element (xmlNodePtr node)
+{
+ return node->type == XML_ELEMENT_NODE && node->name != NULL;
+}
+
+
+static inline gboolean
+node_is_element_with_name (xmlNodePtr node, const char *name)
+{
+ return node->type == XML_ELEMENT_NODE &&
+ node->name != NULL &&
+ ! strcmp ((char *) node->name, name);
+}
+
+static const char *
+node_get_content (xmlNodePtr node)
+{
+ if (node == NULL)
+ return NULL;
+
+ switch (node->type)
+ {
+ case XML_ELEMENT_NODE:
+ return node_get_content (node->children);
+ break;
+ case XML_TEXT_NODE:
+ return (const char *) node->content;
+ break;
+ default:
+ return NULL;
+ }
+ return NULL;
+}
+
+typedef struct _xmlNodeIter {
+
+ xmlNodePtr cur_node;
+ xmlNodePtr next_node;
+
+ const char *name;
+ const char *ns_href;
+
+ void *user_data;
+
+} xmlNodeIter;
+
+static xmlNodePtr
+xml_node_iter_next (xmlNodeIter *iter)
+{
+ xmlNodePtr node;
+
+ while ((node = iter->next_node))
+ {
+ iter->next_node = node->next;
+
+ if (node->type == XML_ELEMENT_NODE) {
+ if (node_has_name_ns (node, iter->name, iter->ns_href))
+ break;
+ }
+ }
+
+ iter->cur_node = node;
+ return node;
+}
+
+static void *
+xml_node_iter_get_user_data (xmlNodeIter *iter)
+{
+ return iter->user_data;
+}
+
+static xmlNodePtr
+xml_node_iter_get_current (xmlNodeIter *iter)
+{
+ return iter->cur_node;
+}
+
static xmlDocPtr
parse_xml (SoupMessage *msg,
xmlNodePtr *root,
@@ -160,7 +258,11 @@
msg->response_body->length,
"response.xml",
NULL,
- 0);
+ XML_PARSE_NOWARNING |
+ XML_PARSE_NOBLANKS |
+ XML_PARSE_NSCLEAN |
+ XML_PARSE_NOCDATA |
+ XML_PARSE_COMPACT);
if (doc == NULL)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
@@ -170,7 +272,7 @@
*root = xmlDocGetRootElement (doc);
- if (doc == NULL)
+ if (*root == NULL || (*root)->children == NULL)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"%s", _("Empty response"));
@@ -187,253 +289,422 @@
return doc;
}
+/* ************************************************************************* */
+/* Multistatus parsing code */
-static xmlDocPtr
-multistatus_parse_xml (SoupMessage *msg, xmlNodePtr *root, GError **error)
-{
- return parse_xml (msg, root, "multistatus", error);
-}
+typedef struct _Multistatus Multistatus;
+typedef struct _MsResponse MsResponse;
+typedef struct _MsPropstat MsPropstat;
+struct _Multistatus {
-static GFileType
-parse_resourcetype (xmlNodePtr rt)
+ xmlDocPtr doc;
+ xmlNodePtr root;
+
+ const SoupURI *target;
+
+};
+
+struct _MsResponse {
+
+ Multistatus *multistatus;
+
+ xmlNodePtr href;
+ xmlNodePtr first_propstat;
+};
+
+struct _MsPropstat {
+
+ Multistatus *multistatus;
+
+ xmlNodePtr prop_node;
+ guint status_code;
+
+};
+
+
+static gboolean
+multistatus_parse (SoupMessage *msg, Multistatus *multistatus, GError **error)
{
- xmlNodePtr node;
- GFileType type;
+ xmlDocPtr doc;
+ xmlNodePtr root;
- for (node = rt->children; node; node = node->next)
- {
- if (node->type == XML_ELEMENT_NODE &&
- node->name != NULL)
- break;
- }
+ doc = parse_xml (msg, &root, "multistatus", error);
- if (node == NULL)
- return G_FILE_TYPE_REGULAR;
+ if (doc == NULL)
+ return FALSE;
- if (! strcmp ((char *) node->name, "collection"))
- type = G_FILE_TYPE_DIRECTORY;
- else if (! strcmp ((char *) node->name, "redirectref"))
- type = G_FILE_TYPE_SYMBOLIC_LINK;
- else
- type = G_FILE_TYPE_UNKNOWN;
+ multistatus->doc = doc;
+ multistatus->root = root;
+ multistatus->target = soup_message_get_uri (msg);
- return type;
+ return TRUE;
}
-static const char *
-node_get_content (xmlNodePtr node)
+static void
+multistatus_free (Multistatus *multistatus)
{
- if (node == NULL)
- return NULL;
+ xmlFreeDoc (multistatus->doc);
+}
- switch (node->type)
- {
- case XML_ELEMENT_NODE:
- return node_get_content (node->children);
- break;
- case XML_TEXT_NODE:
- return (const char *) node->content;
- break;
- default:
- return NULL;
- }
- return NULL;
+static void
+multistatus_get_response_iter (Multistatus *multistatus, xmlNodeIter *iter)
+{
+ iter->cur_node = multistatus->root->children;
+ iter->next_node = multistatus->root->children;
+ iter->name = "response";
+ iter->ns_href = "DAV:";
+ iter->user_data = multistatus;
}
-static GFileInfo *
-mulitstatus_parse_prop_node (xmlDocPtr doc, xmlNodePtr prop)
+static gboolean
+multistatus_get_response (xmlNodeIter *resp_iter, MsResponse *response)
{
- GFileInfo *info;
- xmlNodePtr node;
- const char *text;
- GTimeVal tv;
+ Multistatus *multistatus;
+ xmlNodePtr resp_node;
+ xmlNodePtr iter;
+ xmlNodePtr href;
+ xmlNodePtr propstat;
- info = g_file_info_new ();
+ multistatus = xml_node_iter_get_user_data (resp_iter);
+ resp_node = xml_node_iter_get_current (resp_iter);
+ if (resp_node == NULL)
+ return FALSE;
- for (node = prop->children; node; node = node->next)
+ propstat = NULL;
+ href = NULL;
+
+ for (iter = resp_node->children; iter; iter = iter->next)
{
- if (node->type != XML_ELEMENT_NODE ||
- node->name == NULL)
+ if (! node_is_element (iter))
{
continue;
}
-
- text = node_get_content (node);
-
- if (node_has_name (node, "resourcetype"))
- {
- GFileType type = parse_resourcetype (node);
- g_file_info_set_file_type (info, type);
- }
- else if (node_has_name (node, "displayname"))
+ else if (node_has_name_ns (iter, "href", "DAV:"))
{
- g_file_info_set_display_name (info, text);
+ href = iter;
}
- else if (node_has_name (node, "getetag"))
+ else if (node_has_name_ns (iter, "propstat", "DAV:"))
{
- g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_ETAG_VALUE,
- text);
+ if (propstat == NULL)
+ propstat = iter;
}
- else if (node_has_name (node, "creationdate"))
+
+ if (href && propstat)
+ break;
+ }
+
+ if (href == NULL)
+ return FALSE;
+
+ response->href = href;
+ response->multistatus = multistatus;
+ response->first_propstat = propstat;
+
+ return resp_node != NULL;
+}
+
+static char *
+ms_response_get_basename (MsResponse *response)
+{
+ const char *text;
+ text = node_get_content (response->href);
+
+ return uri_get_basename (text);
+
+}
+
+static gboolean
+ms_response_is_target (MsResponse *response)
+{
+ const char *text;
+ const char *path;
+ const SoupURI *target;
+ SoupURI *uri;
+ gboolean res;
+
+ res = FALSE;
+ uri = NULL;
+ path = NULL;
+ target = response->multistatus->target;
+ text = node_get_content (response->href);
+
+ if (text == NULL)
+ return FALSE;
+
+ if (*text == '/')
+ {
+ path = text;
+ }
+ else if (!g_ascii_strncasecmp (text, "http", 4))
+ {
+ uri = soup_uri_new (text);
+ path = uri->path;
+ }
+
+ if (path)
+ res = g_str_equal (path, target->path);
+
+ if (uri)
+ soup_uri_free (uri);
+
+ return res;
+}
+
+static void
+ms_response_get_propstat_iter (MsResponse *response, xmlNodeIter *iter)
+{
+ iter->cur_node = response->first_propstat;
+ iter->next_node = response->first_propstat;
+ iter->name = "propstat";
+ iter->ns_href = "DAV:";
+ iter->user_data = response;
+}
+
+static guint
+ms_response_get_propstat (xmlNodeIter *cur_node, MsPropstat *propstat)
+{
+ MsResponse *response;
+ xmlNodePtr pstat_node;
+ xmlNodePtr iter;
+ xmlNodePtr prop;
+ xmlNodePtr status;
+ const char *status_text;
+ gboolean res;
+ guint code;
+
+ response = xml_node_iter_get_user_data (cur_node);
+ pstat_node = xml_node_iter_get_current (cur_node);
+
+ if (pstat_node == NULL)
+ return 0;
+
+ status = NULL;
+ prop = NULL;
+
+ for (iter = pstat_node->children; iter; iter = iter->next)
+ {
+ if (!node_is_element (iter))
{
-
+ continue;
}
- else if (node_has_name (node, "getcontenttype"))
+ else if (node_has_name_ns (iter, "status", "DAV:"))
{
- g_file_info_set_content_type (info, text);
+ status = iter;
}
- else if (node_has_name (node, "getcontentlength"))
+ else if (node_has_name_ns (iter, "prop", "DAV:"))
{
- gint64 size;
- size = g_ascii_strtoll (text, NULL, 10);
- g_file_info_set_size (info, size);
+ prop = iter;
}
- else if (node_has_name (node, "getlastmodified"))
- {
- if (g_time_val_from_iso8601 (text, &tv))
- g_file_info_set_modification_time (info, &tv);
- }
+
+ if (status && prop)
+ break;
}
- return info;
+
+ status_text = node_get_content (status);
+
+ if (status_text == NULL || prop == NULL)
+ return 0;
+
+ res = soup_headers_parse_status_line ((char *) status_text,
+ NULL,
+ &code,
+ NULL);
+
+ if (res == FALSE)
+ return 0;
+
+ propstat->prop_node = prop;
+ propstat->status_code = code;
+ propstat->multistatus = response->multistatus;
+
+ return code;
}
-static GFileInfo *
-multistatus_parse_response (xmlDocPtr doc,
- xmlNodePtr resp,
- SoupURI *base)
+static GFileType
+parse_resourcetype (xmlNodePtr rt)
+{
+ xmlNodePtr node;
+ GFileType type;
+
+ for (node = rt->children; node; node = node->next)
+ {
+ if (node_is_element (node))
+ break;
+ }
+
+ if (node == NULL)
+ return G_FILE_TYPE_REGULAR;
+
+ if (! strcmp ((char *) node->name, "collection"))
+ type = G_FILE_TYPE_DIRECTORY;
+ else if (! strcmp ((char *) node->name, "redirectref"))
+ type = G_FILE_TYPE_SYMBOLIC_LINK;
+ else
+ type = G_FILE_TYPE_UNKNOWN;
+
+ return type;
+}
+
+static void
+ms_response_to_file_info (MsResponse *response,
+ GFileInfo *info)
{
- GFileInfo *info;
+ xmlNodeIter iter;
+ MsPropstat propstat;
xmlNodePtr node;
- char *name;
- gboolean res;
-
- info = NULL;
- name = NULL;
+ guint status;
+ char *basename;
- for (node = resp->children; node; node = node->next)
+ basename = ms_response_get_basename (response);
+ g_file_info_set_name (info, basename);
+ g_file_info_set_edit_name (info, basename);
+ g_free (basename);
+
+ ms_response_get_propstat_iter (response, &iter);
+
+ while (xml_node_iter_next (&iter))
{
- if (node->type != XML_ELEMENT_NODE ||
- node->name == NULL)
- {
- continue;
- }
- else if (node_has_name (node, "href"))
+ status = ms_response_get_propstat (&iter, &propstat);
+
+ if (! SOUP_STATUS_IS_SUCCESSFUL (status))
+ continue;
+
+ for (node = propstat.prop_node->children; node; node = node->next)
{
const char *text;
+ GTimeVal tv;
- text = node_get_content (node);
- name = uri_get_basename (text);
- }
+ if (! node_is_element (node))
+ continue; /* FIXME: check namespace, parse user data nodes*/
- else if (node_has_name (node, "propstat"))
- {
- xmlNodePtr iter;
- xmlNodePtr prop;
- xmlChar *status_text;
- guint code;
-
- status_text = NULL;
- prop = NULL;
-
- for (iter = node->children; iter; iter = iter->next)
- {
- if (node->type != XML_ELEMENT_NODE ||
- node->name == NULL)
- continue;
- else if (node_has_name (iter, "status"))
- {
- status_text = xmlNodeGetContent (iter);
- }
- else if (node_has_name (iter, "prop"))
- {
- prop = iter;
- }
+ text = node_get_content (node);
- if (status_text && prop)
- break;
+ if (node_has_name (node, "resourcetype"))
+ {
+ GFileType type = parse_resourcetype (node);
+ g_file_info_set_file_type (info, type);
}
-
- if (status_text == NULL || prop == NULL)
+ else if (node_has_name (node, "displayname"))
{
- if (status_text)
- xmlFree (status_text);
- continue;
- }
-
- res = soup_headers_parse_status_line ((char *) status_text,
- NULL,
- &code,
- NULL);
- xmlFree (status_text);
-
- if (res == FALSE || !SOUP_STATUS_IS_SUCCESSFUL (code))
- continue;
+ g_file_info_set_display_name (info, text);
+ }
+ else if (node_has_name (node, "getetag"))
+ {
+ g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_ETAG_VALUE,
+ text);
+ }
+ else if (node_has_name (node, "creationdate"))
+ {
+ if (! g_time_val_from_iso8601 (text, &tv))
+ continue;
- info = mulitstatus_parse_prop_node (doc, prop);
+ g_file_info_set_attribute_uint64 (info,
+ G_FILE_ATTRIBUTE_TIME_CREATED,
+ tv.tv_sec);
+
+ g_file_info_set_attribute_uint64 (info,
+ G_FILE_ATTRIBUTE_TIME_CREATED_USEC,
+ tv.tv_usec);
+ }
+ else if (node_has_name (node, "getcontenttype"))
+ {
+ g_file_info_set_content_type (info, text);
+ }
+ else if (node_has_name (node, "getcontentlength"))
+ {
+ gint64 size;
+ size = g_ascii_strtoll (text, NULL, 10);
+ g_file_info_set_size (info, size);
+ }
+ else if (node_has_name (node, "getlastmodified"))
+ {
+ if (g_time_val_from_iso8601 (text, &tv))
+ g_file_info_set_modification_time (info, &tv);
+ }
}
}
+}
- /* after this loop we should have a non-null info object
- * and the right name */
-
- if (info && name)
- {
- /* FIXME: that is *not* the name, since its not relative */
- g_file_info_set_name (info, name);
- g_file_info_set_edit_name (info, name);
- }
- else
+static GFileType
+ms_response_to_file_type (MsResponse *response)
+{
+ xmlNodeIter prop_iter;
+ MsPropstat propstat;
+ GFileType file_type;
+ guint status;
+
+ file_type = G_FILE_TYPE_UNKNOWN;
+
+ ms_response_get_propstat_iter (response, &prop_iter);
+ while (xml_node_iter_next (&prop_iter))
{
- if (info)
- g_object_unref (info);
-
- g_free (name);
- info = NULL;
+ xmlNodePtr iter;
+
+ status = ms_response_get_propstat (&prop_iter, &propstat);
+
+ if (! SOUP_STATUS_IS_SUCCESSFUL (status))
+ continue;
+
+ for (iter = propstat.prop_node->children; iter; iter = iter->next)
+ {
+ if (node_is_element (iter) &&
+ node_has_name_ns (iter, "resourcetype", "DAV:"))
+ break;
+ }
+
+ if (iter)
+ {
+ file_type = parse_resourcetype (iter);
+ break;
+ }
}
- return info;
+ return file_type;
}
static char *
create_propfind_request (GFileAttributeMatcher *matcher, gulong *size)
{
- xmlOutputBufferPtr buf;
- xmlNodePtr node;
- xmlNodePtr root;
- xmlDocPtr doc;
- xmlNsPtr nsdav;
- char *res;
-
- doc = xmlNewDoc ((xmlChar *) "1.0");
- root = xmlNewNode (NULL, (xmlChar *) "propfind");
- nsdav = xmlNewNs (root, (xmlChar *) "DAV:", (xmlChar *) "D");
- xmlSetNs (root, nsdav);
-
- node = xmlNewTextChild (root, nsdav, (xmlChar *) "prop", NULL);
-
- /* FIXME: we should just ask for properties that
- * the matcher tells us to ask for
- * nota bene: <D:reftarget/> */
- xmlNewTextChild (node, nsdav, (xmlChar *) "resourcetype", NULL);
- xmlNewTextChild (node, nsdav, (xmlChar *) "displayname", NULL);
- xmlNewTextChild (node, nsdav, (xmlChar *) "getetag", NULL);
- xmlNewTextChild (node, nsdav, (xmlChar *) "getlastmodified", NULL);
- xmlNewTextChild (node, nsdav, (xmlChar *) "creationdate", NULL);
- xmlNewTextChild (node, nsdav, (xmlChar *) "getcontenttype", NULL);
- xmlNewTextChild (node, nsdav, (xmlChar *) "getcontentlength", NULL);
-
- buf = xmlAllocOutputBuffer (NULL);
- xmlNodeDumpOutput (buf, doc, root, 0, 1, NULL);
- xmlOutputBufferFlush (buf);
-
- res = g_strndup ((char *) buf->buffer->content, buf->buffer->use);
- *size = buf->buffer->use;
-
- xmlOutputBufferClose (buf);
- xmlFreeDoc (doc);
- return res;
+ xmlOutputBufferPtr buf;
+ xmlNodePtr node;
+ xmlNodePtr root;
+ xmlDocPtr doc;
+ xmlNsPtr nsdav;
+ char *res;
+
+ doc = xmlNewDoc ((xmlChar *) "1.0");
+ root = xmlNewNode (NULL, (xmlChar *) "propfind");
+ nsdav = xmlNewNs (root, (xmlChar *) "DAV:", (xmlChar *) "D");
+ xmlSetNs (root, nsdav);
+
+ node = xmlNewTextChild (root, nsdav, (xmlChar *) "prop", NULL);
+
+
+
+
+ /* FIXME: we should just ask for properties that
+ * the matcher tells us to ask for
+ * nota bene: <D:reftarget/> */
+ xmlNewTextChild (node, nsdav, (xmlChar *) "resourcetype", NULL);
+ xmlNewTextChild (node, nsdav, (xmlChar *) "displayname", NULL);
+ xmlNewTextChild (node, nsdav, (xmlChar *) "getetag", NULL);
+ xmlNewTextChild (node, nsdav, (xmlChar *) "getlastmodified", NULL);
+ xmlNewTextChild (node, nsdav, (xmlChar *) "creationdate", NULL);
+ xmlNewTextChild (node, nsdav, (xmlChar *) "getcontenttype", NULL);
+ xmlNewTextChild (node, nsdav, (xmlChar *) "getcontentlength", NULL);
+
+ buf = xmlAllocOutputBuffer (NULL);
+ xmlNodeDumpOutput (buf, doc, root, 0, 1, NULL);
+ xmlOutputBufferFlush (buf);
+
+ res = g_strndup ((char *) buf->buffer->content, buf->buffer->use);
+ *size = buf->buffer->use;
+
+ xmlOutputBufferClose (buf);
+ xmlFreeDoc (doc);
+ return res;
}
@@ -540,6 +811,8 @@
const char *password;
char *prompt;
+ g_print ("+ soup_authenticate \n");
+
data = (MountOpData *) user_data;
if (soup_auth_is_for_proxy (auth))
@@ -588,6 +861,7 @@
G_ASK_PASSWORD_NEED_USERNAME,
ask_password_ready,
data);
+ g_print ("- soup_authenticate \n");
g_free (prompt);
}
@@ -753,51 +1027,51 @@
{
GVfsBackendDav *backend;
GVfsJobQueryInfo *job;
+ Multistatus ms;
+ xmlNodeIter iter;
SoupURI *base;
- GFileInfo *info;
+ gboolean res;
GError *error;
- xmlDocPtr doc;
- xmlNodePtr root;
- xmlNodePtr node;
job = G_VFS_JOB_QUERY_INFO (user_data);
backend = G_VFS_BACKEND_DAV (job->backend);
base = G_VFS_BACKEND_HTTP (backend)->mount_base;
error = NULL;
- info = NULL;
- doc = multistatus_parse_xml (msg, &root, &error);
+ res = multistatus_parse (msg, &ms, &error);
- if (doc == NULL)
+ if (res == FALSE)
{
g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
g_error_free (error);
return;
}
- for (node = root->children; node; node = node->next)
+ res = FALSE;
+ multistatus_get_response_iter (&ms, &iter);
+
+ while (xml_node_iter_next (&iter))
{
- if (node->type != XML_ELEMENT_NODE ||
- node->name == NULL ||
- strcmp ((char *) node->name, "response"))
+ MsResponse response;
+
+ if (! multistatus_get_response (&iter, &response))
continue;
- info = multistatus_parse_response (doc, node, base);
+ if (ms_response_is_target (&response))
+ {
+ ms_response_to_file_info (&response, job->file_info);
+ res = TRUE;
+ }
}
- if (info)
- {
- g_file_info_copy_into (info, job->file_info);
+ if (res)
g_vfs_job_succeeded (G_VFS_JOB (job));
- }
else
- {
g_vfs_job_failed (G_VFS_JOB (job),
G_IO_ERROR,G_IO_ERROR_FAILED,
_("Response invalid"));
- }
- xmlFreeDoc (doc);
+ multistatus_free (&ms);
}
/* *** query_info () *** */
@@ -864,57 +1138,51 @@
{
GVfsBackendDav *backend;
GVfsJobEnumerate *job;
+ Multistatus ms;
+ xmlNodeIter iter;
+ gboolean res;
SoupURI *base;
- GFileInfo *info;
GError *error;
- xmlDocPtr doc;
- xmlNodePtr root;
- xmlNodePtr node;
+
job = G_VFS_JOB_ENUMERATE (user_data);
backend = G_VFS_BACKEND_DAV (job->backend);
base = G_VFS_BACKEND_HTTP (backend)->mount_base;
error = NULL;
- info = NULL;
-
- doc = multistatus_parse_xml (msg, &root, &error);
+
+ res = multistatus_parse (msg, &ms, &error);
- if (doc == NULL)
+ if (res == FALSE)
{
g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
g_error_free (error);
return;
}
- for (node = root->children; node; node = node->next)
+ multistatus_get_response_iter (&ms, &iter);
+
+ while (xml_node_iter_next (&iter))
{
- GFileInfo *info;
- const char *fn;
+ MsResponse response;
+ const char *basename;
+ GFileInfo *info;
- if (node->type != XML_ELEMENT_NODE ||
- node->name == NULL ||
- strcmp ((char *) node->name, "response"))
+ if (! multistatus_get_response (&iter, &response))
continue;
- info = multistatus_parse_response (doc, node, base);
+ basename = ms_response_get_basename (&response);
- if (info == NULL)
+ if (ms_response_is_target (&response))
continue;
-
- fn = g_file_info_get_name (info);
-
- if (fn == NULL || g_str_equal (job->filename, fn))
- {
- g_object_unref (info);
- continue;
- }
- g_vfs_job_enumerate_add_info (job, info);
+ info = g_file_info_new ();
+ ms_response_to_file_info (&response, info);
+ g_vfs_job_enumerate_add_info (job, info);
}
g_vfs_job_succeeded (G_VFS_JOB (job)); /* should that be called earlier? */
g_vfs_job_enumerate_done (G_VFS_JOB_ENUMERATE (job));
- xmlFreeDoc (doc);
+ multistatus_free (&ms);
}
static gboolean
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]