* Various changes to the calendar service to handle messages containing
[citadel.git] / webcit / ical_dezonify.c
1 /* 
2  * $Id$ 
3  *
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.
7  *
8  * Everything here will work on both a fully encapsulated VCALENDAR component
9  * or any type of subcomponent.
10  *
11  */
12
13
14 #include <unistd.h>
15 #include <sys/types.h>
16 #include <limits.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <strings.h>
20 #include "webcit.h"
21
22 #ifdef WEBCIT_WITH_CALENDAR_SERVICE
23
24
25 /*
26  * Back end function for ical_dezonify()
27  *
28  * We supply this with the master component, the relevant component,
29  * and the property (which will be a DTSTART, DTEND, etc.)
30  * which we want to convert to UTC.
31  */
32 void ical_dezonify_backend(icalcomponent *cal,
33                         icalcomponent *rcal,
34                         icalproperty *prop) {
35
36         icaltimezone *t = NULL;
37         icalparameter *param;
38         const char *tzid;
39         struct icaltimetype TheTime;
40
41         /* Give me nothing and I will give you nothing in return. */
42         if (cal == NULL) return;
43
44         /* Hunt for a TZID parameter in this property. */
45         param = icalproperty_get_first_parameter(prop, ICAL_TZID_PARAMETER);
46
47         /* Get the stringish name of this TZID. */
48         if (param != NULL) {
49                 tzid = icalparameter_get_tzid(param);
50
51                 /* Convert it to an icaltimezone type. */
52                 if (tzid != NULL) {
53                         t = icalcomponent_get_timezone(cal, tzid);
54                 }
55
56         }
57
58         /* Now we know the timezone.  Convert to UTC. */
59
60         if (icalproperty_isa(prop) == ICAL_DTSTART_PROPERTY) {
61                 TheTime = icalproperty_get_dtstart(prop);
62         }
63         else if (icalproperty_isa(prop) == ICAL_DTEND_PROPERTY) {
64                 TheTime = icalproperty_get_dtend(prop);
65         }
66         else if (icalproperty_isa(prop) == ICAL_DUE_PROPERTY) {
67                 TheTime = icalproperty_get_due(prop);
68         }
69         else if (icalproperty_isa(prop) == ICAL_EXDATE_PROPERTY) {
70                 TheTime = icalproperty_get_exdate(prop);
71         }
72         else {
73                 return;
74         }
75
76         /* Do the conversion. */
77         if (t != NULL) {
78                 icaltimezone_convert_time(&TheTime,
79                                         t,
80                                         icaltimezone_get_utc_timezone()
81                 );
82         }
83         TheTime.is_utc = 1;
84         icalproperty_remove_parameter_by_kind(prop, ICAL_TZID_PARAMETER);
85
86         /* Now add the converted property back in. */
87         if (icalproperty_isa(prop) == ICAL_DTSTART_PROPERTY) {
88                 icalproperty_set_dtstart(prop, TheTime);
89         }
90         else if (icalproperty_isa(prop) == ICAL_DTEND_PROPERTY) {
91                 icalproperty_set_dtend(prop, TheTime);
92         }
93         else if (icalproperty_isa(prop) == ICAL_DUE_PROPERTY) {
94                 icalproperty_set_due(prop, TheTime);
95         }
96         else if (icalproperty_isa(prop) == ICAL_EXDATE_PROPERTY) {
97                 icalproperty_set_exdate(prop, TheTime);
98         }
99 }
100
101
102 /*
103  * Recursive portion of ical_dezonify()
104  */
105 void ical_dezonify_recur(icalcomponent *cal, icalcomponent *rcal) {
106         icalcomponent *c;
107         icalproperty *p;
108
109         /*
110          * Recurse through all subcomponents *except* VTIMEZONE ones.
111          */
112         for (c=icalcomponent_get_first_component(
113                                         rcal, ICAL_ANY_COMPONENT);
114                 c != NULL;
115                 c = icalcomponent_get_next_component(
116                                         rcal, ICAL_ANY_COMPONENT)
117         ) {
118                 if (icalcomponent_isa(c) != ICAL_VTIMEZONE_COMPONENT) {
119                         ical_dezonify_recur(cal, c);
120                 }
121         }
122
123         /*
124          * Now look for DTSTART and DTEND properties
125          */
126         for (p=icalcomponent_get_first_property(
127                                 rcal, ICAL_ANY_PROPERTY);
128                 p != NULL;
129                 p = icalcomponent_get_next_property(
130                                 rcal, ICAL_ANY_PROPERTY)
131         ) {
132                 if (
133                         (icalproperty_isa(p) == ICAL_DTSTART_PROPERTY)
134                         || (icalproperty_isa(p) == ICAL_DTEND_PROPERTY)
135                         || (icalproperty_isa(p) == ICAL_DUE_PROPERTY)
136                         || (icalproperty_isa(p) == ICAL_EXDATE_PROPERTY)
137                    ) {
138                         ical_dezonify_backend(cal, rcal, p);
139                 }
140         }
141 }
142
143
144 /*
145  * Convert all DTSTART and DTEND properties in all subcomponents to UTC.
146  * This function will search any VTIMEZONE subcomponents to learn the
147  * relevant timezone information.
148  */
149 void ical_dezonify(icalcomponent *cal) {
150         icalcomponent *vt = NULL;
151
152         /* Convert all times to UTC */
153         ical_dezonify_recur(cal, cal);
154
155         /* Strip out VTIMEZONE subcomponents -- we don't need them anymore */
156         while (vt = icalcomponent_get_first_component(
157                         cal, ICAL_VTIMEZONE_COMPONENT), vt != NULL) {
158                 icalcomponent_remove_component(cal, vt);
159                 icalcomponent_free(vt);
160         }
161
162 }
163
164
165 #endif /* WEBCIT_WITH_CALENDAR_SERVICE */