--- /dev/null
+#include <libsoup/soup.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+struct ews_auth {
+ const char *username;
+ const char *password;
+};
+
+static void souptest_authenticate(SoupSession *sess, SoupMessage *msg,
+ SoupAuth *auth, gboolean retrying, gpointer data)
+{
+ struct ews_auth *authdata = data;
+ soup_auth_authenticate (auth, authdata->username, authdata->password);
+}
+
+int main(int argc, char **argv)
+{
+ SoupSession *sess;
+ SoupMessage *msg;
+ xmlDoc *doc;
+ xmlNode *node, *child;
+ xmlNs *soap_ns, *types_ns, *messages_ns;
+ guint status;
+ xmlOutputBuffer *buf;
+ struct ews_auth auth;
+ char *url;
+ char *responseclass;
+
+ if (argc != 4) {
+ usage:
+ fprintf(stderr, "Usage: ews_syncfolder <ews_url> <DOMAIN\\username> <password>\n");
+ fprintf(stderr, "Sorry, no Kerberos auth support yet (https://bugzilla.gnome.org/587145)\n");
+ exit (1);
+ }
+ auth.username = argv[2];
+ auth.password = argv[3];
+
+ if (!strchr(argv[2], '\\')) {
+ fprintf(stderr, "No domain in username (https://bugzilla.gnome.org/624613)\n");
+ goto usage;
+ }
+
+ g_thread_init (NULL);
+ g_type_init ();
+
+ url = argv[1];
+
+ sess = soup_session_sync_new_with_options(SOUP_SESSION_USE_NTLM, TRUE, NULL);
+ g_signal_connect (sess, "authenticate",
+ G_CALLBACK(souptest_authenticate), &auth);
+
+ if (getenv("EWS_DEBUG")) {
+ SoupLogger *logger;
+ logger = soup_logger_new(SOUP_LOGGER_LOG_BODY, -1);
+ soup_session_add_feature(sess, SOUP_SESSION_FEATURE(logger));
+ }
+
+ msg = soup_message_new("POST", url);
+
+ soup_message_headers_append (msg->request_headers,
+ "User-Agent", "libews/0.1");
+
+ doc = xmlNewDoc((xmlChar *) "1.0");
+ node = xmlNewDocNode(doc, NULL, (xmlChar *)"Envelope", NULL);
+ xmlDocSetRootElement(doc, node);
+
+ soap_ns = xmlNewNs (node, (xmlChar *)"http://schemas.xmlsoap.org/soap/envelope/",
+ (xmlChar *)"soap");
+ xmlSetNs(node, soap_ns);
+ types_ns = xmlNewNs (node, (xmlChar *)"http://schemas.microsoft.com/exchange/services/2006/types",
+ (xmlChar *)"types");
+ node = xmlNewChild(node, soap_ns, (xmlChar *)"Body", NULL);
+ node = xmlNewChild(node, NULL, (xmlChar *)"SyncFolderItems", NULL);
+
+ messages_ns = xmlNewNs (node, (xmlChar *)"http://schemas.microsoft.com/exchange/services/2006/messages", NULL);
+ xmlSetNs(node, messages_ns);
+ child = xmlNewChild (node, messages_ns, (xmlChar *)"ItemShape", NULL);
+ xmlNewTextChild(child, types_ns, (xmlChar *)"BaseShape", (xmlChar *)"IdOnly");
+ child = xmlNewChild (node, messages_ns, (xmlChar *)"SyncFolderId", NULL);
+ xmlNewProp(xmlNewChild(child, types_ns, (xmlChar *)"DistinguishedFolderId", NULL),
+ (xmlChar *)"Id", (xmlChar *)"calendar");
+ child = xmlNewTextChild (node, messages_ns, (xmlChar *)"MaxChangesReturned",
+ (xmlChar *)"5");
+
+ buf = xmlAllocOutputBuffer(NULL);
+ xmlNodeDumpOutput(buf, doc, xmlDocGetRootElement(doc), 0, 1, NULL);
+ xmlOutputBufferFlush(buf);
+
+ soup_message_set_request(msg, "text/xml", SOUP_MEMORY_COPY,
+ (gchar *)buf->buffer->content,
+ buf->buffer->use);
+
+ status = soup_session_send_message(sess, msg);
+
+ xmlOutputBufferClose (buf);
+ xmlFreeDoc (doc);
+
+ if (status != 200) {
+ fprintf(stderr, "Unexpected response from server: %d\n", status);
+ exit(1);
+ }
+
+ doc = xmlReadMemory (msg->response_body->data, msg->response_body->length,
+ "syncresponse.xml", NULL, 0);
+ if (!doc) {
+ fprintf(stderr, "Failed to parse autodiscover response XML\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;
+ }
+ 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;
+ }
+ if (!node) {
+ fprintf(stderr, "Failed to find <SyncFolderItemsResponse> element\n");
+ exit (1);
+ }
+ for (node = node->children; node; node = node->next) {
+ if (node->type == XML_ELEMENT_NODE &&
+ !strcmp((char *)node->name, "ResponseMessages"))
+ break;
+ }
+ if (!node) {
+ fprintf(stderr, "Failed to find <ResponseMessages> element\n");
+ exit (1);
+ }
+ for (node = node->children; node; node = node->next) {
+ if (node->type == XML_ELEMENT_NODE &&
+ !strcmp((char *)node->name, "SyncFolderItemsResponseMessage"))
+ break;
+ }
+ if (!node) {
+ fprintf(stderr, "Failed to find <SyncFolderItemsResponseMessage> element\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));
+ }
+ }
+ exit(1);
+ } else if (strcmp(responseclass, "Success")) {
+ fprintf(stderr, "Unknown response class '%s' from server\n",
+ responseclass);
+ exit(1);
+ }
+ fprintf(stderr, "WRITE ME\n");
+
+ return 0;
+}