* Be more strategic about when to call ical_dezonify()
[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  * DTSTART and DTEND properties to UTC.  It also strips out any VTIMEZONE
6  * subcomponents afterwards, because they're irrelevant.
7  *
8  */
9
10 #ifdef HAVE_ICAL_H
11
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include <string.h>
15 #include <ctype.h>
16 #include <fcntl.h>
17 #include <sys/types.h>
18 #include <ical.h>
19
20 /*
21  * Back end function for ical_dezonify()
22  *
23  * We supply this with the master component and the property (which will
24  * be a DTSTART or DTEND) which we want to convert to UTC.
25  */
26 void ical_dezonify_backend(icalcomponent *cal, icalproperty *prop) {
27         icaltimezone *t;
28         icalparameter *param;
29         const char *tzid;
30         struct icaltimetype TheTime;
31
32         /* Give me nothing and I will give you nothing in return. */
33         if (cal == NULL) return;
34
35         /* Hunt for a TZID parameter in this property. */
36         param = icalproperty_get_first_parameter(prop, ICAL_TZID_PARAMETER);
37         if (param == NULL) return;
38
39         /* Get the stringish name of this TZID. */
40         tzid = icalparameter_get_tzid(param);
41         if (tzid == NULL) return;
42
43         /* Convert it to an icaltimezone type. */
44         t = icalcomponent_get_timezone(cal, tzid);
45         if (t == NULL) return;
46
47         /* Now we know the timezone.  Convert to UTC. */
48
49         if (icalproperty_isa(prop) == ICAL_DTSTART_PROPERTY) {
50                 TheTime = icalproperty_get_dtstart(prop);
51         }
52         else if (icalproperty_isa(prop) == ICAL_DTEND_PROPERTY) {
53                 TheTime = icalproperty_get_dtend(prop);
54         }
55
56         /* Do the conversion.
57          */
58         icaltimezone_convert_time(&TheTime,
59                                 t,
60                                 icaltimezone_get_utc_timezone()
61         );
62
63         /* Now strip the TZID parameter, because it's incorrect now. */
64         icalproperty_remove_parameter(prop, ICAL_TZID_PARAMETER);
65
66         if (icalproperty_isa(prop) == ICAL_DTSTART_PROPERTY) {
67                 icalproperty_set_dtstart(prop, TheTime);
68         }
69         else if (icalproperty_isa(prop) == ICAL_DTEND_PROPERTY) {
70                 icalproperty_set_dtend(prop, TheTime);
71         }
72
73 }
74
75
76 /*
77  * Recursive portion of ical_dezonify()
78  */
79 void ical_dezonify_recur(icalcomponent *cal, icalcomponent *rcal) {
80         icalcomponent *c;
81         icalproperty *p;
82
83         /*
84          * Recurse through all subcomponents *except* VTIMEZONE ones.
85          */
86         for (c=icalcomponent_get_first_component(
87                                         rcal, ICAL_ANY_COMPONENT);
88                 c != NULL;
89                 c = icalcomponent_get_next_component(
90                                         rcal, ICAL_ANY_COMPONENT)
91         ) {
92                 if (icalcomponent_isa(c) != ICAL_VTIMEZONE_COMPONENT) {
93                         ical_dezonify_recur(cal, c);
94                 }
95         }
96
97         /*
98          * Now look for DTSTART and DTEND properties
99          */
100         for (p=icalcomponent_get_first_property(
101                                 rcal, ICAL_ANY_PROPERTY);
102                 p != NULL;
103                 p = icalcomponent_get_next_property(
104                                 rcal, ICAL_ANY_PROPERTY)
105         ) {
106                 if (
107                         (icalproperty_isa(p) == ICAL_DTSTART_PROPERTY)
108                         || (icalproperty_isa(p) == ICAL_DTEND_PROPERTY)
109                    ) {
110                         ical_dezonify_backend(cal, p);
111                 }
112         }
113 }
114
115
116 /*
117  * Convert all DTSTART and DTEND properties in all subcomponents to UTC.
118  * This function will search any VTIMEZONE subcomponents to learn the
119  * relevant timezone information.
120  */
121 void ical_dezonify(icalcomponent *cal) {
122         icalcomponent *vt = NULL;
123
124         /* Convert all times to UTC */
125         ical_dezonify_recur(cal, cal);
126
127         /* Strip out VTIMEZONE subcomponents -- we don't need them anymore */
128         while (vt = icalcomponent_get_first_component(
129                         cal, ICAL_VTIMEZONE_COMPONENT), vt != NULL) {
130                 icalcomponent_remove_component(cal, vt);
131                 icalcomponent_free(vt);
132         }
133 }
134
135 #endif /* HAVE_ICAL_H */