+#define _GNU_SOURCE /* for asprintf */
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libical/icaltimezone.h>
FILE *calfile;
-
-int process_organizer(xmlNode *xml_node);
-int process_required_attendees(xmlNode *xml_node);
-int process_start(xmlNode *xml_node, icaltimezone *zone);
-int process_end(xmlNode *xml_node, icaltimezone *zone);
-int process_location(xmlNode *xml_node);
-int process_body(xmlNode *xml_node);
-int process_subject(xmlNode *xml_node);
-int process_recurrence(xmlNode *xml_node);
-int process_itemid(xmlNode *xmlnode);
+int process_relativeyearlyrecurrence(xmlNode *xml_node, struct icalrecurrencetype *ical_recur);
+int process_absoluteyearlyrecurrence(xmlNode *xml_node, struct icalrecurrencetype *ical_recur);
+int process_relativemonthlyrecurrence(xmlNode *xml_node, struct icalrecurrencetype *ical_recur);
+int process_absolutemonthlyrecurrence(xmlNode *xml_node, struct icalrecurrencetype *ical_recur);
+int process_weeklyrecurrence(xmlNode *xml_node, struct icalrecurrencetype *ical_recur);
+int process_dailyrecurrence(xmlNode *xml_node, struct icalrecurrencetype *ical_recur);
+
+int process_organizer(icalcomponent *comp, xmlNode *xml_node);
+int process_required_attendees(icalcomponent *comp, xmlNode *xml_node);
+int process_start(icalcomponent *comp, xmlNode *xml_node, icaltimezone *zone);
+int process_end(icalcomponent *comp, xmlNode *xml_node, icaltimezone *zone);
+int process_location(icalcomponent *comp, xmlNode *xml_node);
+int process_body(icalcomponent *comp, xmlNode *xml_node);
+int process_subject(icalcomponent *comp, xmlNode *xml_node);
+int process_recurrence(icalcomponent *comp, xmlNode *xml_node);
+int process_itemid(icalcomponent *comp, xmlNode *xmlnode);
icaltimezone *get_timezone(xmlNode *xmlnode);
icaltimezone *get_meeting_timezone(xmlNode *xml_node);
xmlDocPtr xml_doc;
xmlNode *xml_node;
icaltimezone *icaltz;
+ icalcomponent *comp;
int xmlfd = 0; /* stdin */
char buf[1];
fprintf(calfile, "%s", vtz);
free(vtz);
}
- fprintf(calfile, "BEGIN:VEVENT\n");
+ comp = icalcomponent_new(ICAL_VEVENT_COMPONENT);
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);
+ process_organizer(comp, xml_node);
else if (!strcmp((char *)xml_node->name, "RequiredAttendees"))
- process_required_attendees(xml_node);
+ process_required_attendees(comp, xml_node);
else if (!strcmp((char *)xml_node->name, "Start"))
- process_start(xml_node, icaltz);
+ process_start(comp, xml_node, icaltz);
else if (!strcmp((char *)xml_node->name, "End"))
- process_end(xml_node, icaltz);
+ process_end(comp, xml_node, icaltz);
else if (!strcmp((char *)xml_node->name, "Body"))
- process_body(xml_node);
+ process_body(comp, xml_node);
else if (!strcmp((char *)xml_node->name, "Location"))
- process_location(xml_node);
+ process_location(comp, xml_node);
else if (!strcmp((char *)xml_node->name, "Subject"))
- process_subject(xml_node);
+ process_subject(comp, xml_node);
else if (!strcmp((char *)xml_node->name, "Recurrence"))
- process_recurrence(xml_node);
+ process_recurrence(comp, xml_node);
else if (!strcmp((char *)xml_node->name, "ItemId"))
- process_itemid(xml_node);
+ process_itemid(comp, xml_node);
#if 0
else
fprintf(stderr, "Unhandled node type '%s'\n", xml_node->name);
#endif
}
- fprintf(calfile, "END:VEVENT\n");
+ if (1) {
+ char *vtz = icalcomponent_as_ical_string_r(comp);
+ fprintf(calfile, "%s", vtz);
+ free(vtz);
+ }
fprintf(calfile, "END:VCALENDAR\n");
+
return 0;
}
return 0;
}
-int process_organizer(xmlNode *xml_node)
+int process_organizer(icalcomponent *comp, xmlNode *xml_node)
{
+ icalproperty *prop;
+ icalparameter *param;
+
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;
+ char *mailtoname;
if (process_mailbox(xml_node, &name, &email))
return -1;
- fprintf(calfile, "ORGANIZER;CN=\"%s\":MAILTO:%s\n",
- name, email);
+
+ asprintf(&mailtoname, "mailto:%s", email);
+
+ prop = icalproperty_new_organizer(mailtoname);
+ free(mailtoname);
+ param = icalparameter_new_cn(name);
+ icalproperty_add_parameter(prop, param);
+ icalcomponent_add_property(comp, prop);
}
}
return 0;
}
-int process_required_attendee(xmlNode *xml_node)
+int process_required_attendee(icalcomponent *comp, xmlNode *xml_node)
{
+ icalproperty *prop;
+ icalparameter *param;
+
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;
+ char *mailtoname;
if (process_mailbox(xml_node, &name, &email))
return -1;
- fprintf(calfile, "ATTENDEE;ROLE=REQ-PARTICIPANT;CN=\"%s\":MAILTO:%s\n",
- name, email);
+
+ asprintf(&mailtoname, "mailto:%s", email);
+
+ prop = icalproperty_new_organizer(mailtoname);
+ free(mailtoname);
+ param = icalparameter_new_cn(name);
+ icalproperty_add_parameter(prop, param);
+ param = icalparameter_new_role(ICAL_ROLE_REQPARTICIPANT);
+ icalproperty_add_parameter(prop, param);
+ icalcomponent_add_property(comp, prop);
}
}
return 0;
}
-int process_required_attendees(xmlNode *xml_node)
+int process_required_attendees(icalcomponent *comp, 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, "Attendee")) {
- if (process_required_attendee(xml_node))
+ if (process_required_attendee(comp, xml_node))
{ }
}
}
return 0;
}
-int process_time(xmlNode *xml_node, const char *name, icaltimezone *zone)
+int process_time(icalcomponent *comp, xmlNode *xml_node, int dtend, icaltimezone *zone)
{
char *ews_time = (char *)xmlNodeGetContent(xml_node);
struct icaltimetype ical_time;
if (zone)
ical_time = icaltime_convert_to_zone(ical_time, zone);
- fprintf(calfile, "%s", name);
-
- if (zone)
- fprintf(calfile, ";TZID=\"%s\"", icaltimezone_get_tzid(zone));
- fprintf(calfile, ":%04d%02d%02dT%02d%02d%02d%s\n",
- ical_time.year, ical_time.month, ical_time.day,
- ical_time.hour, ical_time.minute, ical_time.second,
- zone?"":"Z");
+ if (dtend)
+ icalcomponent_set_dtend(comp, ical_time);
+ else
+ icalcomponent_set_dtstart(comp, ical_time);
return 0;
}
-int process_start(xmlNode *xml_node, icaltimezone *zone)
+int process_start(icalcomponent *comp, xmlNode *xml_node, icaltimezone *zone)
{
- return process_time(xml_node, "DTSTART", zone);
+ return process_time(comp, xml_node, 0, zone);
}
-int process_end(xmlNode *xml_node, icaltimezone *zone)
+int process_end(icalcomponent *comp, xmlNode *xml_node, icaltimezone *zone)
{
- return process_time(xml_node, "DTEND", zone);
+ return process_time(comp, xml_node, 1, zone);
}
-int process_location (xmlNode *xml_node)
+int process_location (icalcomponent *comp, xmlNode *xml_node)
{
- const char *dur = (char *)xmlNodeGetContent(xml_node);
- if (!dur)
+ const char *loc = (char *)xmlNodeGetContent(xml_node);
+
+ if (!loc)
return -1;
- fprintf(calfile, "LOCATION: %s\n", dur);
+ icalcomponent_set_location(comp, loc);
return 0;
}
-int process_body(xmlNode *xml_node)
+int process_body(icalcomponent *comp, xmlNode *xml_node)
{
const char *body = (char *)xmlNodeGetContent(xml_node);
- int col;
if (!body)
return -1;
- col = fprintf(calfile, "DESCRIPTION:");
+ if (!strncasecmp(body, "<html", 5)) {
+#if 0 /* XX: libical doesn't seem to escape this properly */
+ icalproperty *prop;
+ icalparameter *param;
- while (*body) {
- switch (*body) {
- case '\n':
- col += fprintf(calfile, "\\n");
- break;
- case ',':
- case '"':
- col++; fputc('\\', calfile);
- default:
- col++; fputc(*body, calfile);
- break;
- }
- body++;
- if (col >= 76) {
- fprintf(calfile, "\n ");
- col = 1;
- }
+ prop = icalproperty_new_x(body);
+ icalproperty_set_x_name(prop, "X-ALT-DESC");
+
+ param = icalparameter_new_fmttype("text/html");
+ icalproperty_add_parameter(prop, param);
+ icalcomponent_add_property(comp, prop);
+#endif
+ /* FIXME: html2text */
+ icalcomponent_set_description(comp, body);
+ } else {
+ icalcomponent_set_description(comp, body);
}
- fputc('\n', calfile);
+
+
return 0;
}
-int process_subject(xmlNode *xml_node)
+int process_subject(icalcomponent *comp, xmlNode *xml_node)
{
const char *subject = (char *)xmlNodeGetContent(xml_node);
+
if (!subject)
return -1;
- fprintf(calfile, "SUMMARY:\"%s\"\n", subject);
+ icalcomponent_set_summary(comp, subject);
return 0;
}
{
static char *days[] = {
"Sunday", "Monday", "Tuesday", "Wednesday",
- "Thursday", "Friday", "Saturday"
+ "Thursday", "Friday", "Saturday",
+ /* "Day", "Weekday", "WeekendDay" */
+
};
int daynr;
for (daynr = 0; daynr < 7; daynr++) {
return 0;
}
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
-static const char *weekday_to_ical(const char *weekday)
-{
- static struct {
- const char *exch;
- const char *ical;
- } table[] = {
- { "Sunday", "SU" },
- { "Monday", "MO" },
- { "Tuesday", "TU" },
- { "Wednesday", "WE" },
- { "Thursday", "TH" },
- { "Friday", "FR" },
- { "Saturday", "SA" },
- { "Day", "SU,MO,TU,WE,TH,FR,SA" },
- { "Weekday", "MO,TU,WE,TH,FR" },
- { "WeekendDay", "SA,SU" },
- };
- int i;
-
- for (i=0 ; i < ARRAY_SIZE(table); i++) {
- if (!strcmp(weekday, table[i].exch))
- return table[i].ical;
- }
- fprintf(stderr, "Unrecognised DaysOfWeek '%s'\n", weekday);
- return NULL;
-}
static int weekindex_to_ical(const char *week)
{
return 0;
}
-int process_recurrence(xmlNode *xml_node)
+int process_recurrence(icalcomponent *comp, xmlNode *xml_node)
{
+ struct icalrecurrencetype ical_recur;
+ char *end_date = NULL, *nr_occurrences = NULL;
+ icalproperty *prop;
xmlNode *xml_node2;
- const char *weekly_interval = NULL;
- const char *weekday = NULL;
- const char *daily_interval = NULL;
- const char *monthly_interval = NULL;
- const char *day_of_month = NULL;
- const char *month = NULL;
- const char *week_index = NULL;
- const char *end_date = NULL;
- const char *nr_recurrences = NULL;
+
+ ical_recur.freq = ICAL_NO_RECURRENCE;
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, "WeeklyRecurrence")) {
- for (xml_node2 = xml_node->children; xml_node2;
- xml_node2 = xml_node2->next) {
- if (xml_node2->type != XML_ELEMENT_NODE)
- continue;
- if (!strcmp((char *)xml_node2->name, "Interval"))
- weekly_interval = (char *)xmlNodeGetContent(xml_node2);
- else if (!strcmp((char *)xml_node2->name, "DaysOfWeek"))
- weekday = (char *)xmlNodeGetContent(xml_node2);
- }
+ if (process_weeklyrecurrence(xml_node, &ical_recur))
+ return -1;
} else if (!strcmp((char *)xml_node->name, "DailyRecurrence")) {
- for (xml_node2 = xml_node->children; xml_node2;
- xml_node2 = xml_node2->next) {
- if (xml_node2->type != XML_ELEMENT_NODE)
- continue;
- if (!strcmp((char *)xml_node2->name, "Interval"))
- daily_interval = (char *)xmlNodeGetContent(xml_node2);
- }
+ if (process_dailyrecurrence(xml_node, &ical_recur))
+ return -1;
} else if (!strcmp((char *)xml_node->name, "AbsoluteYearlyRecurrence")) {
- for (xml_node2 = xml_node->children; xml_node2;
- xml_node2 = xml_node2->next) {
- if (xml_node2->type != XML_ELEMENT_NODE)
- continue;
- if (!strcmp((char *)xml_node2->name, "DayOfMonth"))
- day_of_month = (char *)xmlNodeGetContent(xml_node2);
- else if (!strcmp((char *)xml_node2->name, "Month"))
- month = (char *)xmlNodeGetContent(xml_node2);
- }
+ if (process_absoluteyearlyrecurrence(xml_node, &ical_recur))
+ return -1;
} else if (!strcmp((char *)xml_node->name, "RelativeYearlyRecurrence")) {
- for (xml_node2 = xml_node->children; xml_node2;
- xml_node2 = xml_node2->next) {
- if (xml_node2->type != XML_ELEMENT_NODE)
- continue;
- if (!strcmp((char *)xml_node2->name, "DaysOfWeek"))
- weekday = (char *)xmlNodeGetContent(xml_node2);
- else if (!strcmp((char *)xml_node2->name, "Month"))
- month = (char *)xmlNodeGetContent(xml_node2);
- else if (!strcmp((char *)xml_node2->name, "DayOfWeekIndex"))
- week_index = (char *)xmlNodeGetContent(xml_node2);
- }
+ if (process_relativeyearlyrecurrence(xml_node, &ical_recur))
+ return -1;
} else if (!strcmp((char *)xml_node->name, "AbsoluteMonthlyRecurrence")) {
- for (xml_node2 = xml_node->children; xml_node2;
- xml_node2 = xml_node2->next) {
- if (xml_node2->type != XML_ELEMENT_NODE)
- continue;
- if (!strcmp((char *)xml_node2->name, "DayOfMonth"))
- day_of_month = (char *)xmlNodeGetContent(xml_node2);
- else if (!strcmp((char *)xml_node2->name, "Interval"))
- monthly_interval = (char *)xmlNodeGetContent(xml_node2);
- }
+ if (process_absolutemonthlyrecurrence(xml_node, &ical_recur))
+ return -1;
} else if (!strcmp((char *)xml_node->name, "RelativeMonthlyRecurrence")) {
- for (xml_node2 = xml_node->children; xml_node2;
- xml_node2 = xml_node2->next) {
- if (xml_node2->type != XML_ELEMENT_NODE)
- continue;
- if (!strcmp((char *)xml_node2->name, "DaysOfWeek"))
- weekday = (char *)xmlNodeGetContent(xml_node2);
- else if (!strcmp((char *)xml_node2->name, "Interval"))
- monthly_interval = (char *)xmlNodeGetContent(xml_node2);
- else if (!strcmp((char *)xml_node2->name, "DayOfWeekIndex"))
- week_index = (char *)xmlNodeGetContent(xml_node2);
- }
+ if (process_relativemonthlyrecurrence(xml_node, &ical_recur))
+ return -1;
} else if (!strcmp((char *)xml_node->name, "EndDateRecurrence")) {
for (xml_node2 = xml_node->children; xml_node2;
xml_node2 = xml_node2->next) {
if (xml_node2->type != XML_ELEMENT_NODE)
continue;
if (!strcmp((char *)xml_node2->name, "NumberOfOccurrences"))
- nr_recurrences = (char *)xmlNodeGetContent(xml_node2);
+ nr_occurrences = (char *)xmlNodeGetContent(xml_node2);
}
}
}
- if (daily_interval) {
- fprintf(calfile, "RRULE:FREQ=DAILY;INTERVAL=%s", daily_interval);
- } else if (weekday && month && week_index) {
- int monthnr = month_to_number(month);
- int week = weekindex_to_ical(week_index);
- const char *weekday_ical = weekday_to_ical(weekday);
- if (!monthnr || !week || !weekday_ical)
- return -1;
-
- fprintf(calfile, "RRULE:FREQ=YEARLY;MONTH=%d;BYDAY=%d%s",
- monthnr, week, weekday_ical);
- /* Relative Yearly */
- } else if (monthly_interval && weekday && week_index) {
- int week = weekindex_to_ical(week_index);
- const char *weekday_ical = weekday_to_ical(weekday);
- if (!week || !weekday_ical)
- return -1;
- fprintf(calfile, "RRULE:FREQ=MONTHLY;INTERVAL=%s;BYDAY=%d%s",
- monthly_interval, week, weekday_ical);
- } else if (day_of_month && month) {
- int monthnr = month_to_number(month);
- if (!monthnr)
- return -1;
- fprintf(calfile, "RRULE:FREQ=YEARLY;BYMONTH=%d;BYMONTHDAY=%s",
- monthnr, day_of_month);
- } else if (monthly_interval && day_of_month) {
- fprintf(calfile, "RRULE:FREQ=MONTHLY;INTERVAL=%s;BYMONTHDAY=%s",
- monthly_interval, day_of_month);
- } else if (weekly_interval && weekday) {
- char day[3];
- day[0] = toupper(weekday[0]);
- day[1] = toupper(weekday[1]);
- day[2] = 0;
-
- fprintf(calfile, "RRULE:FREQ=WEEKLY;INTERVAL=%s;BYDAY=%s;WKST=SU",
- weekly_interval, day);
- } else {
- fprintf(stderr, "Unknown Recurrence type\n");
+ if (ical_recur.freq == ICAL_NO_RECURRENCE) {
+ fprintf(stderr, "No recognised Recurrence type\n");
return -1;
}
if (end_date) {
- fprintf(calfile, ";UNTIL=%.4s%.2s%.2sT235959Z",
- end_date, end_date + 5, end_date + 8);
- } else if (nr_recurrences) {
- fprintf(calfile, ";COUNT=%s", nr_recurrences);
+ if (strlen(end_date) != 11 || end_date[4] != '-' ||
+ end_date[7] != '-' || end_date[10] != 'Z') {
+ fprintf(stderr, "Failed to parse Recurrence EndDate '%s'\n",
+ end_date);
+ return -1;
+ }
+ end_date = strdup(end_date);
+ end_date[10] = 0;
+ ical_recur.until = icaltime_from_string(end_date);
+ printf("parsed as %04d-%02d-%02d\n",
+ ical_recur.until.year, ical_recur.until.month, ical_recur.until.day);
+ } else if (nr_occurrences) {
+ ical_recur.count = strtol(nr_occurrences, NULL, 10);
}
-
- fputc('\n', calfile);
+ prop = icalproperty_new_rrule(ical_recur);
+ icalcomponent_add_property(comp, prop);
return 0;
}
-int process_itemid(xmlNode *xml_node)
+int process_itemid(icalcomponent *comp, xmlNode *xml_node)
{
const char *id = (char *)xmlGetProp(xml_node, (unsigned char *)"Id");
if (!id)
return -1;
- fprintf(calfile, "UID:%s\n", id);
+ icalcomponent_set_uid(comp, id);
return 0;
}
}
}
if (!week || !month || !weekday) {
- fprintf(stderr, "RelativeWeeklyRecurrence missing essential fields (%s,%s,%s)\n",
+ fprintf(stderr, "RelativeYearlyRecurrence missing essential fields (%s,%s,%s)\n",
week, month, weekday);
return -1;
}
return 0;
}
+int process_absoluteyearlyrecurrence(xmlNode *xml_node, struct icalrecurrencetype *ical_recur)
+{
+ const char *day_of_month = NULL;
+ const char *month = NULL;
+ int daynr, monthnr;
+
+ 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, "DayOfMonth"))
+ day_of_month = (char *)xmlNodeGetContent(xml_node);
+ else if (!strcmp((char *)xml_node->name, "Month"))
+ month = (char *)xmlNodeGetContent(xml_node);
+ }
+ if (!day_of_month || !month) {
+ fprintf(stderr, "AbsoluteYearlyRecurrence missing essential fields (%s,%s)\n",
+ day_of_month, month);
+ return -1;
+ }
+ daynr = strtol(day_of_month, NULL, 10);
+ if (!daynr) {
+ fprintf(stderr, "Failed to parse DayOfMonth '%s'\n", day_of_month);
+ return -1;
+ }
+ monthnr = month_to_number(month);
+ if (!month)
+ return -1;
+
+ icalrecurrencetype_clear(ical_recur);
+ ical_recur->freq = ICAL_YEARLY_RECURRENCE;
+ ical_recur->by_month[0] = monthnr;
+ ical_recur->by_month_day[0] = daynr;
+ return 0;
+}
+
+int process_relativemonthlyrecurrence(xmlNode *xml_node, struct icalrecurrencetype *ical_recur)
+{
+ const char *week = NULL, *interval = NULL, *weekday = NULL;
+ int weeknr, intervalnr, daynr;
+
+ 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, "DaysOfWeek")) {
+ weekday = (char *)xmlNodeGetContent(xml_node);
+ } else if (!strcmp((char *)xml_node->name, "Interval")) {
+ interval = (char *)xmlNodeGetContent(xml_node);
+ } else if (!strcmp((char *)xml_node->name, "DayOfWeekIndex")) {
+ week = (char *)xmlNodeGetContent(xml_node);
+ }
+ }
+ if (!week || !interval || !weekday) {
+ fprintf(stderr, "RelativeMonthlyRecurrence missing essential fields (%s,%s,%s)\n",
+ week, interval, weekday);
+ return -1;
+ }
+ intervalnr = strtol(interval, NULL, 10);
+ if (!intervalnr) {
+ fprintf(stderr, "Failed to parse Interval '%s'\n", interval);
+ return -1;
+ }
+ weeknr = weekindex_to_ical(week);
+ if (!weeknr)
+ return -1;
+
+ daynr = weekday_to_number(weekday);
+ if (!daynr)
+ return -1;
+
+ icalrecurrencetype_clear(ical_recur);
+ ical_recur->freq = ICAL_MONTHLY_RECURRENCE;
+ ical_recur->interval = intervalnr;
+ if (weeknr > 0)
+ ical_recur->by_day[0] = daynr + (weeknr * 8);
+ else
+ ical_recur->by_day[0] = -8 - daynr;
+
+ return 0;
+}
+int process_absolutemonthlyrecurrence(xmlNode *xml_node, struct icalrecurrencetype *ical_recur)
+{
+ const char *interval = NULL, *monthday = NULL;
+ int intervalnr, monthdaynr;
+
+ 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, "DayOfMonth")) {
+ monthday = (char *)xmlNodeGetContent(xml_node);
+ } else if (!strcmp((char *)xml_node->name, "Interval")) {
+ interval = (char *)xmlNodeGetContent(xml_node);
+ }
+ }
+ if (!interval || !monthday) {
+ fprintf(stderr, "AbsoluteMonthlyRecurrence missing essential fields (%s,%s)\n",
+ interval, monthday);
+ return -1;
+ }
+ intervalnr = strtol(interval, NULL, 10);
+ if (!intervalnr) {
+ fprintf(stderr, "Failed to parse Interval '%s'\n", interval);
+ return -1;
+ }
+ monthdaynr = strtol(monthday, NULL, 10);
+ if (!monthday) {
+ fprintf(stderr, "Failed to parse DayOfMonth '%s'\n", monthday);
+ return -1;
+ }
+
+ icalrecurrencetype_clear(ical_recur);
+ ical_recur->freq = ICAL_MONTHLY_RECURRENCE;
+ ical_recur->interval = intervalnr;
+ ical_recur->by_month_day[0] = monthdaynr;
+ return 0;
+}
+
+int process_weeklyrecurrence(xmlNode *xml_node, struct icalrecurrencetype *ical_recur)
+{
+ const char *interval = NULL, *weekday = NULL, *firstday = NULL;
+ int intervalnr, daynr, firstdaynr;
+
+ 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, "DaysOfWeek")) {
+ weekday = (char *)xmlNodeGetContent(xml_node);
+ } else if (!strcmp((char *)xml_node->name, "Interval")) {
+ interval = (char *)xmlNodeGetContent(xml_node);
+ } else if (!strcmp((char *)xml_node->name, "FirstDayOfWeek")) {
+ firstday = (char *)xmlNodeGetContent(xml_node);
+ }
+ }
+ if (!interval || !weekday) {
+ fprintf(stderr, "WeeklyRecurrence missing essential fields (%s,%s)\n",
+ interval, weekday);
+ return -1;
+ }
+ intervalnr = strtol(interval, NULL, 10);
+ if (!intervalnr) {
+ fprintf(stderr, "Failed to parse Interval '%s'\n", interval);
+ return -1;
+ }
+ daynr = weekday_to_number(weekday);
+ if (!daynr)
+ return -1;
+
+ if (firstday)
+ firstdaynr = weekday_to_number(firstday);
+ else
+ firstdaynr = 0;
+
+ icalrecurrencetype_clear(ical_recur);
+ ical_recur->freq = ICAL_WEEKLY_RECURRENCE;
+ ical_recur->interval = intervalnr;
+ ical_recur->by_day[0] = daynr;
+ ical_recur->week_start = firstdaynr;
+ return 0;
+}
+int process_dailyrecurrence(xmlNode *xml_node, struct icalrecurrencetype *ical_recur)
+{
+ const char *interval = NULL;
+ int intervalnr;
+ 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, "Interval")) {
+ interval = (char *)xmlNodeGetContent(xml_node);
+ }
+ }
+ if (!interval) {
+ fprintf(stderr, "DailyRecurrence missing essential fields (%s)\n",
+ interval);
+ return -1;
+ }
+ intervalnr = strtol(interval, NULL, 10);
+ if (!intervalnr) {
+ fprintf(stderr, "Failed to parse Interval '%s'\n", interval);
+ return -1;
+ }
+
+ icalrecurrencetype_clear(ical_recur);
+ ical_recur->freq = ICAL_DAILY_RECURRENCE;
+ ical_recur->interval = intervalnr;
+
+ return 0;
+}
icalcomponent *process_timezone_rule(xmlNode *xml_node,
icalcomponent_kind kind, int *offset)
{