4 * Function to go through an ical component set and convert all non-UTC
5 * date/time properties to UTC. It also strips out any VTIMEZONE
6 * subcomponents afterwards, because they're irrelevant.
14 #include <sys/types.h>
21 #include "citserver.h"
22 #include "sysdep_decls.h"
26 #ifdef CITADEL_WITH_CALENDAR_SERVICE
28 #include "ical_dezonify.h"
32 * Back end function for ical_dezonify()
34 * We supply this with the master component, the relevant component,
35 * and the property (which will be a DTSTART, DTEND, etc.)
36 * which we want to convert to UTC.
38 void ical_dezonify_backend(icalcomponent *cal,
42 icaltimezone *t = NULL;
45 struct icaltimetype TheTime;
47 /* Give me nothing and I will give you nothing in return. */
48 if (cal == NULL) return;
50 /* Hunt for a TZID parameter in this property. */
51 param = icalproperty_get_first_parameter(prop, ICAL_TZID_PARAMETER);
53 /* Get the stringish name of this TZID. */
55 tzid = icalparameter_get_tzid(param);
57 /* Convert it to an icaltimezone type. */
59 t = icalcomponent_get_timezone(cal, tzid);
64 /* Now we know the timezone. Convert to UTC. */
66 if (icalproperty_isa(prop) == ICAL_DTSTART_PROPERTY) {
67 TheTime = icalproperty_get_dtstart(prop);
69 else if (icalproperty_isa(prop) == ICAL_DTEND_PROPERTY) {
70 TheTime = icalproperty_get_dtend(prop);
72 else if (icalproperty_isa(prop) == ICAL_DUE_PROPERTY) {
73 TheTime = icalproperty_get_due(prop);
75 else if (icalproperty_isa(prop) == ICAL_EXDATE_PROPERTY) {
76 TheTime = icalproperty_get_exdate(prop);
83 lprintf(CTDL_DEBUG, " * This property is ALREADY UTC.\n");
86 /* Do the conversion. */
88 lprintf(CTDL_DEBUG, " * Timezone prop found. Converting to UTC.\n");
89 icaltimezone_convert_time(&TheTime,
91 icaltimezone_get_utc_timezone()
96 lprintf(CTDL_DEBUG, " * Not UTC but no tzid found; WTF??\n");
99 icalproperty_remove_parameter_by_kind(prop, ICAL_TZID_PARAMETER);
101 /* Now add the converted property back in. */
102 if (icalproperty_isa(prop) == ICAL_DTSTART_PROPERTY) {
103 icalproperty_set_dtstart(prop, TheTime);
105 else if (icalproperty_isa(prop) == ICAL_DTEND_PROPERTY) {
106 icalproperty_set_dtend(prop, TheTime);
108 else if (icalproperty_isa(prop) == ICAL_DUE_PROPERTY) {
109 icalproperty_set_due(prop, TheTime);
111 else if (icalproperty_isa(prop) == ICAL_EXDATE_PROPERTY) {
112 icalproperty_set_exdate(prop, TheTime);
118 * Recursive portion of ical_dezonify()
120 void ical_dezonify_recur(icalcomponent *cal, icalcomponent *rcal) {
125 * Recurse through all subcomponents *except* VTIMEZONE ones.
127 for (c=icalcomponent_get_first_component(
128 rcal, ICAL_ANY_COMPONENT);
130 c = icalcomponent_get_next_component(
131 rcal, ICAL_ANY_COMPONENT)
133 if (icalcomponent_isa(c) != ICAL_VTIMEZONE_COMPONENT) {
134 ical_dezonify_recur(cal, c);
139 * Now look for DTSTART and DTEND properties
141 for (p=icalcomponent_get_first_property(
142 rcal, ICAL_ANY_PROPERTY);
144 p = icalcomponent_get_next_property(
145 rcal, ICAL_ANY_PROPERTY)
148 (icalproperty_isa(p) == ICAL_DTSTART_PROPERTY)
149 || (icalproperty_isa(p) == ICAL_DTEND_PROPERTY)
150 || (icalproperty_isa(p) == ICAL_DUE_PROPERTY)
151 || (icalproperty_isa(p) == ICAL_EXDATE_PROPERTY)
153 ical_dezonify_backend(cal, rcal, p);
160 * Convert all DTSTART and DTEND properties in all subcomponents to UTC.
161 * This function will search any VTIMEZONE subcomponents to learn the
162 * relevant timezone information.
164 void ical_dezonify(icalcomponent *cal) {
165 icalcomponent *vt = NULL;
167 lprintf(CTDL_DEBUG, "ical_dezonify() started\n");
169 /* Convert all times to UTC */
170 ical_dezonify_recur(cal, cal);
172 /* Strip out VTIMEZONE subcomponents -- we don't need them anymore */
173 while (vt = icalcomponent_get_first_component(
174 cal, ICAL_VTIMEZONE_COMPONENT), vt != NULL) {
175 icalcomponent_remove_component(cal, vt);
176 icalcomponent_free(vt);
179 lprintf(CTDL_DEBUG, "ical_dezonify() completed\n");
183 #endif /* CITADEL_WITH_CALENDAR_SERVICE */