* ical_dezonify.c: added.
[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) {
38                 printf("No tzid parameter found - "
39                         "perhaps this component is already UTC?\n");
40                 return;
41         }
42
43         /* Get the stringish name of this TZID. */
44         tzid = icalparameter_get_tzid(param);
45         if (tzid == NULL) {
46                 printf("icalparameter_get_tzid() returned NULL\n");
47                 return;
48         }
49
50         /* Convert it to an icaltimezone type. */
51         t = icalcomponent_get_timezone(cal, tzid);
52         if (t == NULL) {
53                 printf("icalcomponent_get_timezone(%s) returned NULL\n", tzid);
54         }
55
56         /* Now we know the timezone.  Convert to UTC. */
57
58         if (icalproperty_isa(prop) == ICAL_DTSTART_PROPERTY) {
59                 TheTime = icalproperty_get_dtstart(prop);
60         }
61         else if (icalproperty_isa(prop) == ICAL_DTEND_PROPERTY) {
62                 TheTime = icalproperty_get_dtend(prop);
63         }
64
65         /* Do the conversion.
66          */
67         icaltimezone_convert_time(&TheTime,
68                                 t,
69                                 icaltimezone_get_utc_timezone()
70         );
71
72         /* Now strip the TZID parameter, because it's incorrect now. */
73         icalproperty_remove_parameter(prop, ICAL_TZID_PARAMETER);
74
75         if (icalproperty_isa(prop) == ICAL_DTSTART_PROPERTY) {
76                 icalproperty_set_dtstart(prop, TheTime);
77         }
78         else if (icalproperty_isa(prop) == ICAL_DTEND_PROPERTY) {
79                 icalproperty_set_dtend(prop, TheTime);
80         }
81
82 }
83
84
85 /*
86  * Recursive portion of ical_dezonify()
87  */
88 void ical_dezonify_recur(icalcomponent *cal, icalcomponent *rcal) {
89         icalcomponent *c;
90         icalproperty *p;
91
92         /*
93          * Recurse through all subcomponents *except* VTIMEZONE ones.
94          */
95         for (c=icalcomponent_get_first_component(
96                                         rcal, ICAL_ANY_COMPONENT);
97                 c != NULL;
98                 c = icalcomponent_get_next_component(
99                                         rcal, ICAL_ANY_COMPONENT)
100         ) {
101                 if (icalcomponent_isa(c) != ICAL_VTIMEZONE_COMPONENT) {
102                         ical_dezonify_recur(cal, c);
103                 }
104         }
105
106         /*
107          * Now look for DTSTART and DTEND properties
108          */
109         for (p=icalcomponent_get_first_property(
110                                 rcal, ICAL_ANY_PROPERTY);
111                 p != NULL;
112                 p = icalcomponent_get_next_property(
113                                 rcal, ICAL_ANY_PROPERTY)
114         ) {
115                 if (
116                         (icalproperty_isa(p) == ICAL_DTSTART_PROPERTY)
117                         || (icalproperty_isa(p) == ICAL_DTEND_PROPERTY)
118                    ) {
119                         ical_dezonify_backend(cal, p);
120                 }
121         }
122 }
123
124
125 /*
126  * Convert all DTSTART and DTEND properties in all subcomponents to UTC.
127  * This function will search any VTIMEZONE subcomponents to learn the
128  * relevant timezone information.
129  */
130 void ical_dezonify(icalcomponent *cal) {
131         icalcomponent *vt = NULL;
132
133         /* Convert all times to UTC */
134         ical_dezonify_recur(cal, cal);
135
136         /* Strip out VTIMEZONE subcomponents -- we don't need them anymore */
137         while (vt = icalcomponent_get_first_component(
138                         cal, ICAL_VTIMEZONE_COMPONENT), vt != NULL) {
139                 icalcomponent_remove_component(cal, vt);
140                 icalcomponent_free(vt);
141         }
142 }
143
144 #endif /* HAVE_ICAL_H */