From 2ad253defef8426e330d6f54aedc80c2ae506324 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Wed, 25 Dec 2002 21:39:38 +0000 Subject: [PATCH] * ical_dezonify.c: added. * calendar.c: convert incoming ical messages to UTC (the usual routines will then convert them to local time for display) --- webcit/ChangeLog | 6 ++ webcit/Makefile.in | 4 +- webcit/calendar.c | 3 + webcit/ical_dezonify.c | 144 +++++++++++++++++++++++++++++++++++++++++ webcit/webcit.h | 1 + 5 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 webcit/ical_dezonify.c diff --git a/webcit/ChangeLog b/webcit/ChangeLog index e3414fb6f..a7a07c3a4 100644 --- a/webcit/ChangeLog +++ b/webcit/ChangeLog @@ -1,4 +1,9 @@ $Log$ +Revision 400.69 2002/12/25 21:39:38 ajc +* ical_dezonify.c: added. +* calendar.c: convert incoming ical messages to UTC + (the usual routines will then convert them to local time for display) + Revision 400.68 2002/12/25 07:06:00 ajc * Tweaked the code to work with libical 0.24 @@ -1189,3 +1194,4 @@ Sun Dec 6 19:50:55 EST 1998 Art Cancro 1998-12-03 Nathan Bryant * webserver.c: warning fix + diff --git a/webcit/Makefile.in b/webcit/Makefile.in index 4fab90494..8912801c4 100644 --- a/webcit/Makefile.in +++ b/webcit/Makefile.in @@ -22,7 +22,7 @@ distclean: clean rm -f Makefile config.cache config.log config.status -webserver: webserver.o context_loop.o tools.o \ +webserver: webserver.o context_loop.o tools.o ical_dezonify.o \ cookie_conversion.o locate_host.o floors.o summary.o \ webcit.o auth.o tcp_sockets.o mainmenu.o serv_func.o who.o \ roomops.o messages.o userlist.o paging.o sysmsgs.o useredit.o \ @@ -35,7 +35,7 @@ webserver: webserver.o context_loop.o tools.o \ locate_host.o siteconfig.o subst.o vcard.o vcard_edit.o floors.o \ mime_parser.o graphics.o netconf.o preferences.o html2html.o \ summary.o calendar.o calendar_tools.o calendar_view.o event.o \ - $(LIBOBJS) $(LIBS) -o webserver + ical_dezonify.o $(LIBOBJS) $(LIBS) -o webserver .c.o: $(CC) $(CFLAGS) $(DEFS) -c $(PTHREAD_DEFS) -DWEBCITDIR=\"`pwd`\" $< diff --git a/webcit/calendar.c b/webcit/calendar.c index ad5b34b5e..dffbe339e 100644 --- a/webcit/calendar.c +++ b/webcit/calendar.c @@ -327,6 +327,7 @@ void cal_process_attachment(char *part_source, long msgnum, char *cal_partnum) { return; } + ical_dezonify(cal); cal_process_object(cal, 0, msgnum, cal_partnum); /* Free the memory we obtained from libical's constructor */ @@ -723,6 +724,8 @@ void display_using_handler(long msgnum, cal = icalcomponent_new_from_string(relevant_source); if (cal != NULL) { + ical_dezonify(cal); + /* Simple components of desired type */ if (icalcomponent_isa(cal) == which_kind) { callback(cal, msgnum); diff --git a/webcit/ical_dezonify.c b/webcit/ical_dezonify.c new file mode 100644 index 000000000..642da726e --- /dev/null +++ b/webcit/ical_dezonify.c @@ -0,0 +1,144 @@ +/* + * $Id$ + * + * Function to go through an ical component set and convert all non-UTC + * DTSTART and DTEND properties to UTC. It also strips out any VTIMEZONE + * subcomponents afterwards, because they're irrelevant. + * + */ + +#ifdef HAVE_ICAL_H + +#include +#include +#include +#include +#include +#include +#include + +/* + * Back end function for ical_dezonify() + * + * We supply this with the master component and the property (which will + * be a DTSTART or DTEND) which we want to convert to UTC. + */ +void ical_dezonify_backend(icalcomponent *cal, icalproperty *prop) { + icaltimezone *t; + icalparameter *param; + const char *tzid; + struct icaltimetype TheTime; + + /* Give me nothing and I will give you nothing in return. */ + if (cal == NULL) return; + + /* Hunt for a TZID parameter in this property. */ + param = icalproperty_get_first_parameter(prop, ICAL_TZID_PARAMETER); + if (param == NULL) { + printf("No tzid parameter found - " + "perhaps this component is already UTC?\n"); + return; + } + + /* Get the stringish name of this TZID. */ + tzid = icalparameter_get_tzid(param); + if (tzid == NULL) { + printf("icalparameter_get_tzid() returned NULL\n"); + return; + } + + /* Convert it to an icaltimezone type. */ + t = icalcomponent_get_timezone(cal, tzid); + if (t == NULL) { + printf("icalcomponent_get_timezone(%s) returned NULL\n", tzid); + } + + /* Now we know the timezone. Convert to UTC. */ + + if (icalproperty_isa(prop) == ICAL_DTSTART_PROPERTY) { + TheTime = icalproperty_get_dtstart(prop); + } + else if (icalproperty_isa(prop) == ICAL_DTEND_PROPERTY) { + TheTime = icalproperty_get_dtend(prop); + } + + /* Do the conversion. + */ + icaltimezone_convert_time(&TheTime, + t, + icaltimezone_get_utc_timezone() + ); + + /* Now strip the TZID parameter, because it's incorrect now. */ + icalproperty_remove_parameter(prop, ICAL_TZID_PARAMETER); + + if (icalproperty_isa(prop) == ICAL_DTSTART_PROPERTY) { + icalproperty_set_dtstart(prop, TheTime); + } + else if (icalproperty_isa(prop) == ICAL_DTEND_PROPERTY) { + icalproperty_set_dtend(prop, TheTime); + } + +} + + +/* + * Recursive portion of ical_dezonify() + */ +void ical_dezonify_recur(icalcomponent *cal, icalcomponent *rcal) { + icalcomponent *c; + icalproperty *p; + + /* + * Recurse through all subcomponents *except* VTIMEZONE ones. + */ + for (c=icalcomponent_get_first_component( + rcal, ICAL_ANY_COMPONENT); + c != NULL; + c = icalcomponent_get_next_component( + rcal, ICAL_ANY_COMPONENT) + ) { + if (icalcomponent_isa(c) != ICAL_VTIMEZONE_COMPONENT) { + ical_dezonify_recur(cal, c); + } + } + + /* + * Now look for DTSTART and DTEND properties + */ + for (p=icalcomponent_get_first_property( + rcal, ICAL_ANY_PROPERTY); + p != NULL; + p = icalcomponent_get_next_property( + rcal, ICAL_ANY_PROPERTY) + ) { + if ( + (icalproperty_isa(p) == ICAL_DTSTART_PROPERTY) + || (icalproperty_isa(p) == ICAL_DTEND_PROPERTY) + ) { + ical_dezonify_backend(cal, p); + } + } +} + + +/* + * Convert all DTSTART and DTEND properties in all subcomponents to UTC. + * This function will search any VTIMEZONE subcomponents to learn the + * relevant timezone information. + */ +void ical_dezonify(icalcomponent *cal) { + icalcomponent *vt = NULL; + + /* Convert all times to UTC */ + ical_dezonify_recur(cal, cal); + + /* Strip out VTIMEZONE subcomponents -- we don't need them anymore */ + while (vt = icalcomponent_get_first_component( + cal, ICAL_VTIMEZONE_COMPONENT), vt != NULL) { + icalcomponent_remove_component(cal, vt); + icalcomponent_free(vt); + } +} + +#endif /* HAVE_ICAL_H */ diff --git a/webcit/webcit.h b/webcit/webcit.h index da4f078f7..7e34e34c6 100644 --- a/webcit/webcit.h +++ b/webcit/webcit.h @@ -366,6 +366,7 @@ void save_individual_event(icalcomponent *supplied_vtodo, long msgnum); void generate_new_uid(char *); void respond_to_request(void); void handle_rsvp(void); +void ical_dezonify(icalcomponent *cal); #endif extern char *months[]; -- 2.39.2