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