4 * Functions which handle calendar objects and their processing/display.
14 #include <sys/types.h>
16 #include <sys/socket.h>
18 #include <netinet/in.h>
27 #include "webserver.h"
37 * Handler stubs for builds with no calendar library available
39 void cal_process_attachment(char *part_source) {
41 wprintf("<I>This message contains calendaring/scheduling information,"
42 " but support for calendars is not available on this "
43 "particular system. Please ask your system administrator to "
44 "install a new version of the Citadel web service with "
45 "calendaring enabled.</I><BR>\n"
50 void display_calendar(long msgnum) {
51 wprintf("<i>Cannot display calendar item</i><br>\n");
54 void display_task(long msgnum) {
55 wprintf("<i>Cannot display item from task list</i><br>\n");
58 #else /* HAVE_ICAL_H */
63 * Process a single calendar component.
64 * It won't be a compound component at this point because those have
65 * already been broken down by cal_process_object().
67 void cal_process_subcomponent(icalcomponent *cal) {
68 wprintf("cal_process_subcomponent() called<BR>\n");
69 wprintf("cal_process_subcomponent() exiting<BR>\n");
77 * Process a calendar object
78 * ...at this point it's already been deserialized by cal_process_attachment()
80 void cal_process_object(icalcomponent *cal) {
82 int num_subcomponents = 0;
84 wprintf("cal_process_object() called<BR>\n");
86 /* Iterate through all subcomponents */
87 wprintf("Iterating through all sub-components<BR>\n");
88 for (c = icalcomponent_get_first_component(cal, ICAL_ANY_COMPONENT);
90 c = icalcomponent_get_next_component(cal, ICAL_ANY_COMPONENT)) {
91 cal_process_subcomponent(c);
95 /* Iterate through all subcomponents */
96 wprintf("Iterating through VEVENTs<BR>\n");
97 for (c = icalcomponent_get_first_component(cal, ICAL_VEVENT_COMPONENT);
99 c = icalcomponent_get_next_component(cal, ICAL_VEVENT_COMPONENT)) {
100 cal_process_subcomponent(c);
104 /* Iterate through all subcomponents */
105 wprintf("Iterating through VTODOs<BR>\n");
106 for (c = icalcomponent_get_first_component(cal, ICAL_VTODO_COMPONENT);
108 c = icalcomponent_get_next_component(cal, ICAL_VTODO_COMPONENT)) {
109 cal_process_subcomponent(c);
113 /* Iterate through all subcomponents */
114 wprintf("Iterating through VJOURNALs<BR>\n");
115 for (c = icalcomponent_get_first_component(cal, ICAL_VJOURNAL_COMPONENT);
117 c = icalcomponent_get_next_component(cal, ICAL_VJOURNAL_COMPONENT)) {
118 cal_process_subcomponent(c);
122 /* Iterate through all subcomponents */
123 wprintf("Iterating through VCALENDARs<BR>\n");
124 for (c = icalcomponent_get_first_component(cal, ICAL_VCALENDAR_COMPONENT);
126 c = icalcomponent_get_next_component(cal, ICAL_VCALENDAR_COMPONENT)) {
127 cal_process_subcomponent(c);
131 /* Iterate through all subcomponents */
132 wprintf("Iterating through VFREEBUSYs<BR>\n");
133 for (c = icalcomponent_get_first_component(cal, ICAL_VFREEBUSY_COMPONENT);
135 c = icalcomponent_get_next_component(cal, ICAL_VFREEBUSY_COMPONENT)) {
136 cal_process_subcomponent(c);
140 /* Iterate through all subcomponents */
141 wprintf("Iterating through VALARMs<BR>\n");
142 for (c = icalcomponent_get_first_component(cal, ICAL_VALARM_COMPONENT);
144 c = icalcomponent_get_next_component(cal, ICAL_VALARM_COMPONENT)) {
145 cal_process_subcomponent(c);
149 /* Iterate through all subcomponents */
150 wprintf("Iterating through VTIMEZONEs<BR>\n");
151 for (c = icalcomponent_get_first_component(cal, ICAL_VTIMEZONE_COMPONENT);
153 c = icalcomponent_get_next_component(cal, ICAL_VTIMEZONE_COMPONENT)) {
154 cal_process_subcomponent(c);
158 /* Iterate through all subcomponents */
159 wprintf("Iterating through VSCHEDULEs<BR>\n");
160 for (c = icalcomponent_get_first_component(cal, ICAL_VSCHEDULE_COMPONENT);
162 c = icalcomponent_get_next_component(cal, ICAL_VSCHEDULE_COMPONENT)) {
163 cal_process_subcomponent(c);
167 /* Iterate through all subcomponents */
168 wprintf("Iterating through VQUERYs<BR>\n");
169 for (c = icalcomponent_get_first_component(cal, ICAL_VQUERY_COMPONENT);
171 c = icalcomponent_get_next_component(cal, ICAL_VQUERY_COMPONENT)) {
172 cal_process_subcomponent(c);
176 /* Iterate through all subcomponents */
177 wprintf("Iterating through VCARs<BR>\n");
178 for (c = icalcomponent_get_first_component(cal, ICAL_VCAR_COMPONENT);
180 c = icalcomponent_get_next_component(cal, ICAL_VCAR_COMPONENT)) {
181 cal_process_subcomponent(c);
185 /* Iterate through all subcomponents */
186 wprintf("Iterating through VCOMMANDs<BR>\n");
187 for (c = icalcomponent_get_first_component(cal, ICAL_VCOMMAND_COMPONENT);
189 c = icalcomponent_get_next_component(cal, ICAL_VCOMMAND_COMPONENT)) {
190 cal_process_subcomponent(c);
194 if (num_subcomponents != 0) {
195 wprintf("Warning: %d subcomponents unhandled<BR>\n",
199 wprintf("cal_process_object() exiting<BR>\n");
204 * Deserialize a calendar object in a message so it can be processed.
205 * (This is the main entry point for these things)
207 void cal_process_attachment(char *part_source) {
210 wprintf("Processing calendar attachment<BR>\n");
211 cal = icalcomponent_new_from_string(part_source);
214 wprintf("Error parsing calendar object: %s<BR>\n",
215 icalerror_strerror(icalerrno));
219 cal_process_object(cal);
221 /* Free the memory we obtained from libical's constructor */
222 icalcomponent_free(cal);
225 /*****************************************************************************/
232 * Display handlers for message reading
234 void display_individual_cal(icalcomponent *cal, long msgnum) {
235 wprintf("display_individual_cal() called<BR>\n");
241 * Display a task in the task list
243 void display_individual_task(icalcomponent *vtodo, long msgnum) {
246 p = icalcomponent_get_first_property(vtodo, ICAL_SUMMARY_PROPERTY);
247 wprintf("<LI><A HREF=\"/display_edit_task?msgnum=%ld\">", msgnum);
248 if (p != NULL) escputs(icalproperty_get_comment(p));
250 icalproperty_free(p);
255 * Display/edit a task by itself FIXME
257 void display_edit_individual_task(icalcomponent *vtodo, long msgnum) {
261 wprintf("<TABLE WIDTH=100%% BORDER=0 BGCOLOR=007700><TR><TD>"
262 "<FONT SIZE=+1 COLOR=\"FFFFFF\""
264 "</FONT></TD></TR></TABLE><BR>\n"
267 wprintf("<FORM METHOD=\"POST\" ACTION=\"/edit_task\">\n");
268 wprintf("<INPUT TYPE=\"hidden\" NAME=\"msgnum\" VALUE=\"%ld\">\n",
272 "<INPUT TYPE=\"text\" NAME=\"summary\" "
273 "MAXLENGTH=\"64\" SIZE=\"64\" VALUE=\"");
274 p = icalcomponent_get_first_property(vtodo, ICAL_SUMMARY_PROPERTY);
275 if (p != NULL) escputs(icalproperty_get_comment(p));
276 icalproperty_free(p);
279 wprintf("</FORM>\n");
282 "<A HREF=\"/readfwd\">"
283 "Back to task list</A>\n"
289 * Code common to all display handlers. Given a message number and a MIME
290 * type, we load the message and hunt for that MIME type. If found, we load
291 * the relevant part, deserialize it into a libical component, filter it for
292 * the requested object type, and feed it to the specified handler.
294 void display_using_handler(long msgnum,
296 icalcomponent_kind which_kind,
297 void (*callback)(icalcomponent *, long)
300 char mime_partnum[SIZ];
301 char mime_filename[SIZ];
302 char mime_content_type[SIZ];
303 char mime_disposition[SIZ];
305 char relevant_partnum[SIZ];
306 char *relevant_source = NULL;
307 icalcomponent *cal, *c;
309 sprintf(buf, "MSG0 %ld|1", msgnum); /* ask for headers only */
312 if (buf[0] != '1') return;
314 while (serv_gets(buf), strcmp(buf, "000")) {
315 if (!strncasecmp(buf, "part=", 5)) {
316 extract(mime_filename, &buf[5], 1);
317 extract(mime_partnum, &buf[5], 2);
318 extract(mime_disposition, &buf[5], 3);
319 extract(mime_content_type, &buf[5], 4);
320 mime_length = extract_int(&buf[5], 5);
322 if (!strcasecmp(mime_content_type, "text/calendar")) {
323 strcpy(relevant_partnum, mime_partnum);
329 if (strlen(relevant_partnum) > 0) {
330 relevant_source = load_mimepart(msgnum, relevant_partnum);
331 if (relevant_source != NULL) {
333 /* Display the task */
334 cal = icalcomponent_new_from_string(relevant_source);
336 for (c = icalcomponent_get_first_component(cal,
339 c = icalcomponent_get_next_component(cal,
343 icalcomponent_free(cal);
345 free(relevant_source);
351 void display_calendar(long msgnum) {
352 display_using_handler(msgnum, "text/calendar",
354 display_individual_cal);
357 void display_task(long msgnum) {
358 display_using_handler(msgnum, "text/calendar",
359 ICAL_VTODO_COMPONENT,
360 display_individual_task);
363 void display_edit_task(void) {
366 msgnum = atol(bstr("msgnum"));
367 display_using_handler(msgnum, "text/calendar",
368 ICAL_VTODO_COMPONENT,
369 display_edit_individual_task);
372 #endif /* HAVE_ICAL_H */