From: David Woodhouse Date: Fri, 23 Jul 2010 16:59:51 +0000 (+0100) Subject: Update process_changes() to process the whole SoupSoapResponse X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=e312c63355dd469c1425c44aa760cc57540adfc5;p=users%2Fdwmw2%2Fews-sync.git Update process_changes() to process the whole SoupSoapResponse --- diff --git a/ews_syncfolder.c b/ews_syncfolder.c index d47506b..7513391 100644 --- a/ews_syncfolder.c +++ b/ews_syncfolder.c @@ -24,7 +24,9 @@ struct item_change { void combine_ical_files(void); -int process_changes(xmlNode *node, struct item_change **changes); +gboolean process_changes(SoupSoapResponse *resp, struct item_change **changes, + gboolean *last, gchar **syncstate, GError **error); + icalcomponent *fetch_xml_item(SoupSession *sess, char *url, const char *itemid, const char *xml_filename, const char *parent_id, icaltimezone *parent_zone, GError **error); @@ -68,14 +70,13 @@ soup_ews_message_new(const gchar *url, const gchar *request) int main(int argc, char **argv) { + GError *error = NULL; SoupSession *sess; SoupSoapMessage *msg; SoupSoapResponse *resp; - xmlNode *node; guint status; struct ews_auth auth; char *url; - char *str; struct item_change *changes = NULL; gchar *syncstate = NULL; gboolean last_in_range = TRUE; @@ -116,7 +117,6 @@ int main(int argc, char **argv) again: msg = soup_ews_message_new(url, "SyncFolderItems"); - soup_soap_message_start_element(msg, "ItemShape", NULL, NULL); soup_soap_message_start_element(msg, "BaseShape", "types", NULL); @@ -158,79 +158,19 @@ int main(int argc, char **argv) if (!error) error = "Unknown error"; - fprintf(stderr, "SyncFolderChanges message failed: %s\n", error); + fprintf(stderr, "SyncFolderItems message failed: %s\n", error); exit(1); } resp = soup_soap_message_parse_response(msg); if (!resp) { - fprintf(stderr, "Failed to parse SyncFolderChanges response\n"); - exit(1); - } - node = soup_soap_response_get_first_parameter_by_name(resp, "ResponseMessages"); - if (!node) { - fprintf(stderr, "No element in SyncFolderChanges reply\n"); - exit(1); - } - node = soup_soap_parameter_get_first_child_by_name(node, "SyncFolderItemsResponseMessage"); - if (!node) { - fprintf(stderr, "No element in SyncFolderChanges reply\n"); - exit(1); - } - str = soup_soap_parameter_get_property(node, "ResponseClass"); - if (!strcmp(str, "Error")) { - gchar *msgtext = NULL; - gchar *respcode = NULL; - - xmlNode *n2 = soup_soap_parameter_get_first_child_by_name(node, "MessageText"); - if (n2) { - msgtext = soup_soap_parameter_get_string_value(n2); - fprintf(stderr, "Server returned error: %s\n", - msgtext); - } else - fprintf(stderr, "Server returned erorr without MessageText\n"); - - n2 = soup_soap_parameter_get_first_child_by_name(node, "ResponseCode"); - if (n2) { - respcode = soup_soap_parameter_get_string_value(n2); - fprintf(stderr, "Response Code: %s\n", respcode); - } - g_free(msgtext); - g_free(respcode); - g_free(str); - exit(1); - } else if (strcmp(str, "Success")) { - fprintf(stderr, "Unknown response class '%s' from server\n", - str); - g_free(str); + fprintf(stderr, "Failed to parse SyncFolderItems response\n"); exit(1); } - g_free(str); - str = get_child_string(node, "IncludesLastItemInRange"); - if (!str) { - fprintf(stderr, "No LastItemInRange element in SyncFolderItems response\n"); - exit (1); - } - if (!strcmp(str, "true")) - last_in_range = TRUE; - else if (!strcmp(str, "false")) - last_in_range = FALSE; - else { - fprintf(stderr, "Invalid value for : %s\n", - str); - g_free(str); + if (!process_changes(resp, &changes, &last_in_range, &syncstate, &error)) { + fprintf(stderr, "Process changes failed: %s\n", error->message); exit(1); } - g_free(str); - - syncstate = (gchar *)get_child_string(node, "SyncState"); - if (!syncstate) { - fprintf(stderr, "No SyncState element in SyncFolderItems response\n"); - exit (1); - } - node = soup_soap_parameter_get_first_child_by_name(node, "Changes"); - if (node && process_changes(node, &changes)) - exit(1); g_object_unref(resp); @@ -266,7 +206,7 @@ int main(int argc, char **argv) changes = this->next; free(this); } - + g_file_set_contents(statefilename, syncstate, strlen(syncstate), NULL); if (!last_in_range) { printf("Not last in range; restarting\n"); @@ -340,7 +280,7 @@ icalcomponent *fetch_xml_item(SoupSession *sess, char *url, const char *itemid, errtxt = "Unknown error"; g_set_error(error, EWS_ERROR, EWS_ERROR_SOAP, - "GetItem message failed: %s\n", errtxt); + "GetItem message failed: %s", errtxt); return NULL; } @@ -390,11 +330,15 @@ icalcomponent *fetch_xml_item(SoupSession *sess, char *url, const char *itemid, g_set_error(error, EWS_ERROR, EWS_ERROR_SERVER, "Server returned error: %s (ResponseCode %s)", msgtext, respcode); + g_free(responseclass); + g_free(msgtext); + g_free(respcode); goto out; } else if (strcmp(responseclass, "Success")) { g_set_error(error, EWS_ERROR, EWS_ERROR_PARSE, "Unknown response class '%s' from server", responseclass); + g_free(responseclass); goto out; } @@ -419,66 +363,142 @@ icalcomponent *fetch_xml_item(SoupSession *sess, char *url, const char *itemid, return calcomp; } -int process_changes(xmlNode *node, struct item_change **changes) +gboolean process_changes(SoupSoapResponse *resp, struct item_change **changes, + gboolean *last, gchar **syncstate, GError **error) { - xmlNode *node2; + xmlNode *node, *node2; + char *str; - for (node = node->children; node; node = node->next) { - int type; - char *itemid; + node = soup_soap_response_get_first_parameter_by_name(resp, "ResponseMessages"); + if (!node) { + g_set_error(error, EWS_ERROR, EWS_ERROR_PARSE, + "No element in SyncFolderItems reply"); + return FALSE; + } + node = soup_soap_parameter_get_first_child_by_name(node, "SyncFolderItemsResponseMessage"); + if (!node) { + g_set_error(error, EWS_ERROR, EWS_ERROR_PARSE, + "No element in SyncFolderItems reply"); + return FALSE; + } + str = soup_soap_parameter_get_property(node, "ResponseClass"); + if (!str) { + g_set_error(error, EWS_ERROR, EWS_ERROR_PARSE, + "No ResponseClass parameter in SyncFolderItems reply"); + return FALSE; + } + if (!strcmp(str, "Error")) { + gchar *msgtext = NULL; + gchar *respcode = NULL; + xmlNode *n2; + + n2 = soup_soap_parameter_get_first_child_by_name(node, "MessageText"); + if (n2) + msgtext = soup_soap_parameter_get_string_value(n2); + + n2 = soup_soap_parameter_get_first_child_by_name(node, "ResponseCode"); + if (n2) + respcode = soup_soap_parameter_get_string_value(n2); + + g_set_error(error, EWS_ERROR, EWS_ERROR_SERVER, + "Server returned error: %s (ResponseCode %s)", + msgtext, respcode); + g_free(msgtext); + g_free(respcode); + g_free(str); + return FALSE; + } else if (strcmp(str, "Success")) { + g_set_error(error, EWS_ERROR, EWS_ERROR_PARSE, + "Unknown response class '%s' from server", + str); + g_free(str); + return FALSE; + } + g_free(str); + str = get_child_string(node, "IncludesLastItemInRange"); + if (!str) { + g_set_error(error, EWS_ERROR, EWS_ERROR_PARSE, + "No LastItemInRange element in SyncFolderItems response"); + return FALSE; + } + if (!strcmp(str, "true")) + *last = TRUE; + else if (!strcmp(str, "false")) + *last = FALSE; + else { + g_set_error(error, EWS_ERROR, EWS_ERROR_PARSE, + "Invalid value for : %s", + str); + g_free(str); + return FALSE; + } + g_free(str); + + *syncstate = (gchar *)get_child_string(node, "SyncState"); + if (!*syncstate) { + g_set_error(error, EWS_ERROR, EWS_ERROR_PARSE, + "No SyncState element in SyncFolderItems response"); + return FALSE; + } + node = soup_soap_parameter_get_first_child_by_name(node, "Changes"); + if (!node) + return TRUE; + + for (node = soup_soap_parameter_get_first_child(node); + node; node = soup_soap_parameter_get_next_child(node)) { struct item_change *new_change; + char *itemid; + int type; - if (node->type != XML_ELEMENT_NODE) - continue; - if (!strcmp((char *)node->name, "Create")) + if (!strcmp((char *)node->name, "Create")) { type = ITEM_CREATE; - else if (!strcmp((char *)node->name, "Delete")) { + } else if (!strcmp((char *)node->name, "Update")) { + type = ITEM_UPDATE; + } else if (!strcmp((char *)node->name, "Delete")) { type = ITEM_DELETE; node2 = node; goto itemid; - } else if (!strcmp((char *)node->name, "Update")) - type = ITEM_UPDATE; - else { - fprintf(stderr, "Unknown change type '%s'\n", - node->name); - return -1; - } - for (node2 = node->children; node2; node2 = node2->next) { - if (node2->type != XML_ELEMENT_NODE) - continue; - if (!strcmp((char *)node2->name, "CalendarItem")) - break; + } else { + g_set_error(error, EWS_ERROR, EWS_ERROR_PARSE, + "Unknown change type '%s'", + node->name); + err_changes: + while (*changes) { + new_change = *changes; + *changes = new_change->next; + g_free(new_change); + } + return FALSE; } + node2 = soup_soap_parameter_get_first_child_by_name(node, "CalendarItem"); if (!node2) { - fprintf(stderr, "<%s> node has no child\n", - node->name); - return -1; + g_set_error(error, EWS_ERROR, EWS_ERROR_PARSE, + "<%s> node has no child", + node->name); + goto err_changes; } itemid: - for (node2 = node2->children; node2; node2 = node2->next) { - if (node2->type != XML_ELEMENT_NODE) - continue; - if (!strcmp((char *)node2->name, "ItemId")) - break; - } + node2 = soup_soap_parameter_get_first_child_by_name(node2, "ItemId"); if (!node2) { - fprintf(stderr, "<%s> node has no child\n", - node->name); - return -1; + g_set_error(error, EWS_ERROR, EWS_ERROR_PARSE, + "<%s> node has no child", + node->name); + goto err_changes; } itemid = (char *)xmlGetProp(node2, (xmlChar *)"Id"); new_change = malloc(sizeof(*new_change) + strlen(itemid) + 1); if (!new_change) { - fprintf(stderr, "Out of memory\n"); - return -1; + g_set_error(error, EWS_ERROR, EWS_ERROR_PARSE, + "Out of memory"); + goto err_changes; } new_change->next = *changes; new_change->type = type; strcpy(new_change->itemid, itemid); *changes = new_change; } - return 0; + return TRUE; } void combine_ical_files(void)