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