From e33c318584893816ada03e508891d10fbef682e1 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 16 Jul 2010 19:07:34 +0100 Subject: [PATCH] Add basic xml to ical converter --- Makefile | 20 +++++ ews2ical.c | 212 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 232 insertions(+) create mode 100644 Makefile create mode 100644 ews2ical.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fff23de --- /dev/null +++ b/Makefile @@ -0,0 +1,20 @@ + +ifdef RPM_OPT_FLAGS +OPT_FLAGS := $(RPM_OPT_FLAGS) +else +OPT_FLAGS := -O2 -g -Wall +endif + +XML2_CFLAGS += $(shell xml2-config --cflags) +XML2_LDFLAGS += $(shell xml2-config --libs) +ifeq ($(XML2_LDFLAGS),) +$(error "No libxml2 support. Cannot continue"); +endif + +CFLAGS := $(OPT_FLAGS) $(XML2_CFLAGS) + +%.o: %.c + $(CC) -c -o $@ $(CFLAGS) $(CFLAGS_$@) $< -MD -MF .$@.dep + +ews2ical: ews2ical.o + $(CC) -o $@ $< $(LDFLAGS) $(XML2_LDFLAGS) diff --git a/ews2ical.c b/ews2ical.c new file mode 100644 index 0000000..e928d6a --- /dev/null +++ b/ews2ical.c @@ -0,0 +1,212 @@ +#include +#include + +#include +#include +#include +#include +#include +#include + +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; +} -- 2.50.1