--- /dev/null
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+FILE *calfile;
+
+
+int process_organizer(xmlNode *xml_node);
+int process_required_attendees(xmlNode *xml_node);
+int process_start(xmlNode *xml_node);
+int process_end(xmlNode *xml_node);
+int process_body(xmlNode *xml_node);
+int process_subject(xmlNode *xml_node);
+
+
+int main(int argc, char **argv)
+{
+ xmlDocPtr xml_doc;
+ xmlNode *xml_node;
+ int xmlfd = 0; /* stdin */
+ char buf[1];
+
+ if (argc >= 2) {
+ xmlfd = open(argv[1], O_RDONLY);
+ if (xmlfd < 0) {
+ perror("open xml file");
+ return -1;
+ }
+ }
+ if (argc >= 3) {
+ calfile = fopen(argv[2], "w");
+ if (!calfile < 0) {
+ perror("open cal file");
+ return -1;
+ }
+ } else
+ calfile = fdopen(1, "w");
+
+
+ if (argc >= 4) {
+ fprintf(stderr, "Too many args. Want only xml file and ical file\n");
+ return -1;
+ }
+ // read(xmlfd, buf, 1);
+ xml_doc = xmlReadFd(xmlfd, "noname.xml", "utf-8", 0);
+ if (!xml_doc) {
+ fprintf(stderr, "Failed to parse XML\n");
+ return -1;
+ }
+ xml_node = xmlDocGetRootElement(xml_doc);
+ if (xml_node->type != XML_ELEMENT_NODE ||
+ strcmp((char *)xml_node->name, "Envelope")) {
+ fprintf(stderr, "Root node not as expected: %s\n", xml_node->name);
+ return -1;
+ }
+ for (xml_node = xml_node->children; xml_node; xml_node = xml_node->next) {
+ if (xml_node->type == XML_ELEMENT_NODE &&
+ !strcmp((char *)xml_node->name, "Body"))
+ break;
+ }
+ if (!xml_node) {
+ fprintf(stderr, "SOAP Body node not found\n");
+ return -1;
+ }
+
+ for (xml_node = xml_node->children; xml_node; xml_node = xml_node->next) {
+ if (xml_node->type == XML_ELEMENT_NODE &&
+ !strcmp((char *)xml_node->name, "GetItemResponse"))
+ break;
+ }
+ if (!xml_node) {
+ fprintf(stderr, "GetItemResponse node not found\n");
+ return -1;
+ }
+
+ for (xml_node = xml_node->children; xml_node; xml_node = xml_node->next) {
+ if (xml_node->type == XML_ELEMENT_NODE &&
+ !strcmp((char *)xml_node->name, "ResponseMessages"))
+ break;
+ }
+ if (!xml_node) {
+ fprintf(stderr, "ResponseMessages node not found\n");
+ return -1;
+ }
+
+ for (xml_node = xml_node->children; xml_node; xml_node = xml_node->next) {
+ if (xml_node->type == XML_ELEMENT_NODE &&
+ !strcmp((char *)xml_node->name, "GetItemResponseMessage"))
+ break;
+ }
+ if (!xml_node) {
+ fprintf(stderr, "GetItemResponseMessage node not found\n");
+ return -1;
+ }
+
+ for (xml_node = xml_node->children; xml_node; xml_node = xml_node->next) {
+ if (xml_node->type == XML_ELEMENT_NODE &&
+ !strcmp((char *)xml_node->name, "Items"))
+ break;
+ }
+ if (!xml_node) {
+ fprintf(stderr, "Items node not found\n");
+ return -1;
+ }
+
+ for (xml_node = xml_node->children; xml_node; xml_node = xml_node->next) {
+ if (xml_node->type == XML_ELEMENT_NODE &&
+ !strcmp((char *)xml_node->name, "CalendarItem"))
+ break;
+ }
+ if (!xml_node) {
+ fprintf(stderr, "CalendarItem node not found\n");
+ return -1;
+ }
+ fprintf(calfile, "BEGIN:VCALENDAR\n");
+ fprintf(calfile, "METHOD:PUBLISH\n");
+ fprintf(calfile, "VERSION:2.0\n");
+ fprintf(calfile, "BEGIN:VEVENT\n");
+ for (xml_node = xml_node->children; xml_node; xml_node = xml_node->next) {
+ if (xml_node->type != XML_ELEMENT_NODE)
+ continue;
+ if (!strcmp((char *)xml_node->name, "Organizer"))
+ process_organizer(xml_node);
+ else if (!strcmp((char *)xml_node->name, "RequiredAttendees"))
+ process_required_attendees(xml_node);
+ else if (!strcmp((char *)xml_node->name, "Start"))
+ process_start(xml_node);
+ else if (!strcmp((char *)xml_node->name, "End"))
+ process_end(xml_node);
+ else if (!strcmp((char *)xml_node->name, "Body"))
+ process_body(xml_node);
+ else if (!strcmp((char *)xml_node->name, "Subject"))
+ process_subject(xml_node);
+ else
+ fprintf(stderr, "Unhandled node type '%s'\n", xml_node->name);
+ }
+ fprintf(calfile, "END:VEVENT\n");
+ fprintf(calfile, "END:VCALENDAR\n");
+ return 0;
+}
+
+int process_mailbox(xmlNode *xml_node, const char **r_name, const char **r_email)
+{
+ const char *type, *name = NULL, *email = NULL;
+
+ for (xml_node = xml_node->children; xml_node; xml_node = xml_node->next) {
+ if (xml_node->type != XML_ELEMENT_NODE)
+ continue;
+ if (!strcmp((char *)xml_node->name, "Name"))
+ name = (char *)xmlNodeGetContent(xml_node);
+ if (!strcmp((char *)xml_node->name, "EmailAddress"))
+ email = (char *)xmlNodeGetContent(xml_node);
+ if (!strcmp((char *)xml_node->name, "RoutingType")) {
+ type = (char *)xmlNodeGetContent(xml_node);
+ if (strcmp(type, "SMTP")) {
+ printf("Unknown RoutingType '%s'\n", type);
+ return -1;
+ }
+ }
+ }
+
+ *r_name = name;
+ *r_email = email;
+ return 0;
+}
+
+int process_organizer(xmlNode *xml_node)
+{
+ for (xml_node = xml_node->children; xml_node; xml_node = xml_node->next) {
+ if (xml_node->type != XML_ELEMENT_NODE)
+ continue;
+ if (!strcmp((char *)xml_node->name, "Mailbox")) {
+ const char *name = NULL, *email = NULL;
+ if (process_mailbox(xml_node, &name, &email))
+ return -1;
+ fprintf(calfile, "ORGANIZER;CN=\"%s\":MAILTO:%s\n",
+ name, email);
+ }
+ }
+ return 0;
+}
+
+int process_required_attendees(xmlNode *xml_node)
+{
+ return 0;
+}
+
+int process_start(xmlNode *xml_node)
+{
+ return 0;
+}
+
+int process_end(xmlNode *xml_node)
+{
+ return 0;
+}
+
+int process_body(xmlNode *xml_node)
+{
+ return 0;
+}
+
+int process_subject(xmlNode *xml_node)
+{
+ return 0;
+}