]> www.infradead.org Git - users/dwmw2/ews-sync.git/commitdiff
Convert response handling to SoupSoapResonse, fix memory leaks
authorDavid Woodhouse <dwmw2@infradead.org>
Wed, 21 Jul 2010 13:56:03 +0000 (14:56 +0100)
committerDavid Woodhouse <dwmw2@infradead.org>
Wed, 21 Jul 2010 13:56:43 +0000 (14:56 +0100)
ews_syncfolder.c

index 446f41f815d458e590b5b7f76b463f84012d4326..ac3ff2401b9fb16d2ce63b8906b8b1523c3464a9 100644 (file)
@@ -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 <Envelope> 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 <Body> 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 <ResponseMessages> 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 <SyncFolderItemsResponse> element\n");
-               exit (1);
+               fprintf(stderr, "No <SyncFolderItemsResponseMessage> 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 <ResponseMessages> 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 <IncludesLastItemInRange>: %s\n",
+                       str);
+               g_free(str);
+               exit(1);
        }
-       if (!node) {
-               fprintf(stderr, "Failed to find <SyncFolderItemsResponseMessage> 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 <LastItemInRange>: %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;
 }