From b0d8fc4334c742a42253488be5a8f00fc2184d3f Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 21 Jul 2010 14:56:03 +0100 Subject: [PATCH] Convert response handling to SoupSoapResonse, fix memory leaks --- ews_syncfolder.c | 167 +++++++++++++++++++++++------------------------ 1 file changed, 83 insertions(+), 84 deletions(-) diff --git a/ews_syncfolder.c b/ews_syncfolder.c index 446f41f..ac3ff24 100644 --- a/ews_syncfolder.c +++ b/ews_syncfolder.c @@ -38,16 +38,24 @@ static void souptest_authenticate(SoupSession *sess, SoupMessage *msg, soup_auth_authenticate (auth, authdata->username, authdata->password); } +static gchar *get_child_string(xmlNode *node, const gchar *name) +{ + node = soup_soap_parameter_get_first_child_by_name(node, name); + if (!node) + return NULL; + return soup_soap_parameter_get_string_value(node); +} + int main(int argc, char **argv) { SoupSession *sess; SoupSoapMessage *msg; - xmlDoc *doc; + SoupSoapResponse *resp; xmlNode *node; guint status; struct ews_auth auth; char *url; - char *responseclass; + char *str; struct item_change *changes = NULL; gchar *syncstate = NULL; gboolean last_in_range = TRUE; @@ -114,10 +122,13 @@ int main(int argc, char **argv) soup_soap_message_end_element(msg); /* SyncFolderId */ - if (syncstate && syncstate[0]) { - soup_soap_message_start_element(msg, "SyncState", NULL, NULL); - soup_soap_message_write_string(msg, syncstate); - soup_soap_message_end_element(msg); + if (syncstate) { + if (syncstate[0]) { + soup_soap_message_start_element(msg, "SyncState", NULL, NULL); + soup_soap_message_write_string(msg, syncstate); + soup_soap_message_end_element(msg); + } + g_free(syncstate); } soup_soap_message_start_element(msg, "MaxChangesReturned", NULL, NULL); soup_soap_message_write_int(msg, 50); @@ -131,101 +142,87 @@ int main(int argc, char **argv) status = soup_session_send_message(sess, SOUP_MESSAGE(msg)); - if (status != 200) { - fprintf(stderr, "Unexpected response from server: %d\n", status); + if (!SOUP_STATUS_IS_SUCCESSFUL(status)) { + const gchar *error = soup_status_get_phrase(status); + if (!error) + error = "Unknown error"; + + fprintf(stderr, "SyncFolderChanges message failed: %s\n", error); exit(1); } - doc = xmlReadMemory (SOUP_MESSAGE(msg)->response_body->data, SOUP_MESSAGE(msg)->response_body->length, - "syncresponse.xml", NULL, 0); - if (!doc) { - fprintf(stderr, "Failed to parse SyncFolderItems response XML\n"); + resp = soup_soap_message_parse_response(msg); + if (!resp) { + fprintf(stderr, "Failed to parse SyncFolderChanges response\n"); exit(1); } - node = xmlDocGetRootElement(doc); - if (strcmp((char *)node->name, "Envelope")) { - fprintf(stderr, "Failed to find SOAP element\n"); - exit (1); - } - for (node = node->children; node; node = node->next) { - if (node->type == XML_ELEMENT_NODE && - !strcmp((char *)node->name, "Body")) - break; - } + node = soup_soap_response_get_first_parameter_by_name(resp, "ResponseMessages"); if (!node) { - fprintf(stderr, "Failed to find SOAP element\n"); - exit (1); - } - for (node = node->children; node; node = node->next) { - if (node->type == XML_ELEMENT_NODE && - !strcmp((char *)node->name, "SyncFolderItemsResponse")) - break; + 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, "Failed to find element\n"); - exit (1); + fprintf(stderr, "No element in SyncFolderChanges reply\n"); + exit(1); } - for (node = node->children; node; node = node->next) { - if (node->type == XML_ELEMENT_NODE && - !strcmp((char *)node->name, "ResponseMessages")) - break; + 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); + exit(1); } - if (!node) { - fprintf(stderr, "Failed to find element\n"); + g_free(str); + str = get_child_string(node, "IncludesLastItemInRange"); + if (!str) { + fprintf(stderr, "No LastItemInRange element in SyncFolderItems response\n"); exit (1); } - for (node = node->children; node; node = node->next) { - if (node->type == XML_ELEMENT_NODE && - !strcmp((char *)node->name, "SyncFolderItemsResponseMessage")) - break; + 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); + exit(1); } - if (!node) { - fprintf(stderr, "Failed to find element\n"); + g_free(str); + + syncstate = (gchar *)get_child_string(node, "SyncState"); + if (!syncstate) { + fprintf(stderr, "No SyncState element in SyncFolderItems response\n"); exit (1); } - responseclass = (char *)xmlGetProp(node, (xmlChar *)"ResponseClass"); - if (!strcmp(responseclass, "Error")) { - for (node = node->children; node; node = node->next) { - if (node->type != XML_ELEMENT_NODE) - continue; - if (!strcmp((char *)node->name, "MessageText")) { - fprintf(stderr, "Server returned error: %s\n", - xmlNodeGetContent(node)); - } else if (!strcmp((char *)node->name, "ResponseCode")) { - fprintf(stderr, "Response code: %s\n", - xmlNodeGetContent(node)); - } - } + node = soup_soap_parameter_get_first_child_by_name(node, "Changes"); + if (node && process_changes(node, &changes)) exit(1); - } else if (strcmp(responseclass, "Success")) { - fprintf(stderr, "Unknown response class '%s' from server\n", - responseclass); - exit(1); - } - for (node = node->children; node; node = node->next) { - if (node->type != XML_ELEMENT_NODE) - continue; - if (!strcmp((char *)node->name, "LastItemInRange")) { - const char *truth = (const char *)xmlNodeGetContent(node); - if (!strcmp(truth, "true")) - last_in_range = TRUE; - else if (!strcmp(truth, "false")) - last_in_range = FALSE; - else { - fprintf(stderr, "Invalid value for : %s\n", - truth); - exit(1); - } - } else if (!strcmp((char *)node->name, "SyncState")) { - syncstate = (char *)xmlNodeGetContent(node); - } else if (!strcmp((char *)node->name, "Changes")) { - if (process_changes(node, &changes)) - exit(1); - } - } - xmlFreeDoc(doc); - + g_object_unref(resp); + while (changes) { struct item_change *this = changes; char *xml_filename = g_strdup_printf("%s/ews-sync/%s.xml", @@ -244,6 +241,8 @@ int main(int argc, char **argv) free(this); } g_file_set_contents(statefilename, syncstate, strlen(syncstate), NULL); + g_free(syncstate); + g_free(statefilename); return 0; } -- 2.49.0