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;
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);
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",
free(this);
}
g_file_set_contents(statefilename, syncstate, strlen(syncstate), NULL);
+ g_free(syncstate);
+ g_free(statefilename);
return 0;
}