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