From: Art Cancro Date: Thu, 4 Jan 2024 16:32:31 +0000 (-0500) Subject: End support for libical <2.0 X-Git-Tag: v997~35 X-Git-Url: https://code.citadel.org/?p=citadel.git;a=commitdiff_plain;h=6b42de0e239e26e4f1a9a7b8a5f6bf7aacb24239 End support for libical <2.0 --- diff --git a/citadel/server/modules/calendar/serv_calendar.c b/citadel/server/modules/calendar/serv_calendar.c index 1bd2a45f7..35bc404ea 100644 --- a/citadel/server/modules/calendar/serv_calendar.c +++ b/citadel/server/modules/calendar/serv_calendar.c @@ -1,18 +1,11 @@ -/* - * This module implements iCalendar object processing and the Calendar> - * room on a Citadel server. It handles iCalendar objects using the - * iTIP protocol. See RFCs 2445 and 2446. - * - * Copyright (c) 1987-2023 by the citadel.org team - * - * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ +// This module implements iCalendar object processing and the Calendar> +// room on a Citadel server. It handles iCalendar objects using the +// iTIP protocol. See RFCs 2445 and 2446. +// +// Copyright (c) 1987-2024 by the citadel.org team +// +// This program is open source software. Use, duplication, or disclosure +// are subject to the terms of the GNU General Public License version 3. #define PRODID "-//Citadel//NONSGML Citadel Calendar//EN" @@ -32,10 +25,8 @@ struct ical_respond_data { }; -/* - * Utility function to create a new VCALENDAR component with some of the - * required fields already set the way we like them. - */ +// Utility function to create a new VCALENDAR component with some of the +// required fields already set the way we like them. icalcomponent *icalcomponent_new_citadel_vcalendar(void) { icalcomponent *encaps; @@ -45,46 +36,40 @@ icalcomponent *icalcomponent_new_citadel_vcalendar(void) { return NULL; } - /* Set the Product ID */ + // Set the Product ID icalcomponent_add_property(encaps, icalproperty_new_prodid(PRODID)); - /* Set the Version Number */ + // Set the Version Number icalcomponent_add_property(encaps, icalproperty_new_version("2.0")); return(encaps); } -/* - * Utility function to encapsulate a subcomponent into a full VCALENDAR - */ +// Utility function to encapsulate a subcomponent into a full VCALENDAR icalcomponent *ical_encapsulate_subcomponent(icalcomponent *subcomp) { icalcomponent *encaps; - /* If we're already looking at a full VCALENDAR component, - * don't bother ... just return itself. - */ + // If we're already looking at a full VCALENDAR component, don't bother ... just return itself. if (icalcomponent_isa(subcomp) == ICAL_VCALENDAR_COMPONENT) { return subcomp; } - /* Encapsulate the VEVENT component into a complete VCALENDAR */ + // Encapsulate the VEVENT component into a complete VCALENDAR encaps = icalcomponent_new_citadel_vcalendar(); if (encaps == NULL) return NULL; - /* Encapsulate the subcomponent inside */ + // Encapsulate the subcomponent inside icalcomponent_add_component(encaps, subcomp); - /* Return the object we just created. */ + // Return the object we just created. return(encaps); } -/* - * Write a calendar object into the specified user's calendar room. - * If the supplied user is NULL, this function writes the calendar object - * to the currently selected room. - */ +// Write a calendar object into the specified user's calendar room. +// If the supplied user is NULL, this function writes the calendar object +// to the currently selected room. void ical_write_to_cal(struct ctdluser *u, icalcomponent *cal) { char *ser = NULL; long serlen; @@ -94,9 +79,8 @@ void ical_write_to_cal(struct ctdluser *u, icalcomponent *cal) { if (cal == NULL) return; - /* If the supplied object is a subcomponent, encapsulate it in - * a full VCALENDAR component, and save that instead. - */ + // If the supplied object is a subcomponent, encapsulate it in + // a full VCALENDAR component, and save that instead. if (icalcomponent_isa(cal) != ICAL_VCALENDAR_COMPONENT) { tmp = icalcomponent_new_clone(cal); encaps = ical_encapsulate_subcomponent(tmp); @@ -111,20 +95,20 @@ void ical_write_to_cal(struct ctdluser *u, icalcomponent *cal) { serlen = strlen(ser); - /* If the caller supplied a user, write to that user's default calendar room */ + // If the caller supplied a user, write to that user's default calendar room if (u) { - /* This handy API function does all the work for us. */ - CtdlWriteObject(USERCALENDARROOM, /* which room */ - "text/calendar", /* MIME type */ - ser, /* data */ - serlen + 1, /* length */ - u, /* which user */ - 0, /* not binary */ - 0 /* no flags */ + CtdlWriteObject( // This handy API function does all the work for us. + USERCALENDARROOM, // which room + "text/calendar", // MIME type + ser, // data + serlen + 1, // length + u, // which user + 0, // not binary + 0 // no flags ); } - /* If the caller did not supply a user, write to the currently selected room */ + // If the caller did not supply a user, write to the currently selected room if (!u) { struct CitContext *CCC = CC; StrBuf *MsgBody; @@ -143,23 +127,20 @@ void ical_write_to_cal(struct ctdluser *u, icalcomponent *cal) { CM_SetAsFieldSB(msg, eMesageText, &MsgBody); - /* Now write the data */ + // Now write the data CtdlSubmitMsg(msg, NULL, ""); CM_Free(msg); } - /* In either case, now we can free the serialized calendar object */ + // In either case, now we can free the serialized calendar object free(ser); } -/* - * Send a reply to a meeting invitation. - * - * 'request' is the invitation to reply to. - * 'action' is the string "accept" or "decline" or "tentative". - * - */ +// Send a reply to a meeting invitation. +// +// 'request' is the invitation to reply to. +// 'action' is the string "accept" or "decline" or "tentative". void ical_send_a_reply(icalcomponent *request, char *action) { icalcomponent *the_reply = NULL; icalcomponent *vevent = NULL; @@ -192,15 +173,14 @@ void ical_send_a_reply(icalcomponent *request, char *action) { return; } - /* Change the method from REQUEST to REPLY */ + // Change the method from REQUEST to REPLY icalcomponent_set_method(the_reply, ICAL_METHOD_REPLY); vevent = icalcomponent_get_first_component(the_reply, ICAL_VEVENT_COMPONENT); if (vevent != NULL) { - /* Hunt for attendees, removing ones that aren't us. - * (Actually, remove them all, cloning our own one so we can - * re-insert it later) - */ + // Hunt for attendees, removing ones that aren't us. + // (Actually, remove them all, cloning our own one so we can + // re-insert it later) while (attendee = icalcomponent_get_first_property(vevent, ICAL_ATTENDEE_PROPERTY), (attendee != NULL) ) { @@ -218,14 +198,14 @@ void ical_send_a_reply(icalcomponent *request, char *action) { } } - /* Remove it... */ + // Remove it... icalcomponent_remove_property(vevent, attendee); icalproperty_free(attendee); } - /* We found our own address in the attendee list. */ + // We found our own address in the attendee list. if (me_attend) { - /* Change the partstat from NEEDS-ACTION to ACCEPT or DECLINE */ + // Change the partstat from NEEDS-ACTION to ACCEPT or DECLINE icalproperty_remove_parameter_by_kind(me_attend, ICAL_PARTSTAT_PARAMETER); if (!strcasecmp(action, "accept")) { @@ -240,11 +220,11 @@ void ical_send_a_reply(icalcomponent *request, char *action) { if (partstat) icalproperty_add_parameter(me_attend, partstat); - /* Now insert it back into the vevent. */ + // Now insert it back into the vevent. icalcomponent_add_property(vevent, me_attend); } - /* Figure out who to send this thing to */ + // Figure out who to send this thing to organizer = icalcomponent_get_first_property(vevent, ICAL_ORGANIZER_PROPERTY); if (organizer != NULL) { if (icalproperty_get_organizer(organizer)) { @@ -255,13 +235,12 @@ void ical_send_a_reply(icalcomponent *request, char *action) { if (!strncasecmp(organizer_string, "MAILTO:", 7)) { strcpy(organizer_string, &organizer_string[7]); string_trim(organizer_string); - } else { + } + else { strcpy(organizer_string, ""); } - /* Extract the summary string -- we'll use it as the - * message subject for the reply - */ + // Extract the summary string -- we'll use it as the message subject for the reply summary = icalcomponent_get_first_property(vevent, ICAL_SUMMARY_PROPERTY); if (summary != NULL) { if (icalproperty_get_summary(summary)) { @@ -271,9 +250,9 @@ void ical_send_a_reply(icalcomponent *request, char *action) { } } - /* Now generate the reply message and send it out. */ + // Now generate the reply message and send it out. serialized_reply = icalcomponent_as_ical_string_r(the_reply); - icalcomponent_free(the_reply); /* don't need this anymore */ + icalcomponent_free(the_reply); // don't need this anymore if (serialized_reply == NULL) return; reply_message_text = malloc(strlen(serialized_reply) + SIZ); @@ -284,15 +263,18 @@ void ical_send_a_reply(icalcomponent *request, char *action) { ); msg = CtdlMakeMessage(&CC->user, - organizer_string, /* to */ - "", /* cc */ - CC->room.QRname, 0, FMT_RFC822, + organizer_string, // to + "", // cc + CC->room.QRname, + 0, + FMT_RFC822, "", "", - summary_string, /* Use summary for subject */ + summary_string, // Use the event SUMMARY as the message subject NULL, reply_message_text, - NULL); + NULL + ); if (msg != NULL) { valid = validate_recipients(organizer_string, NULL, 0); @@ -305,11 +287,9 @@ void ical_send_a_reply(icalcomponent *request, char *action) { } -/* - * Callback function for mime parser that hunts for calendar content types - * and turns them into calendar objects. If something is found, it is placed - * in ird->cal, and the caller now owns that memory and is responsible for freeing it. - */ +// Callback function for mime parser that hunts for calendar content types +// and turns them into calendar objects. If something is found, it is placed +// in ird->cal, and the caller now owns that memory and is responsible for freeing it. void ical_locate_part(char *name, char *filename, char *partnum, char *disp, void *content, char *cbtype, char *cbcharset, size_t length, char *encoding, char *cbid, void *cbuserdata) { @@ -318,10 +298,9 @@ void ical_locate_part(char *name, char *filename, char *partnum, char *disp, ird = (struct ical_respond_data *) cbuserdata; - /* desired_partnum can be set to "_HUNT_" to have it just look for - * the first part with a content type of text/calendar. Otherwise - * we have to only process the right one. - */ + // desired_partnum can be set to "_HUNT_" to have it just look for + // the first part with a content type of text/calendar. Otherwise + // we have to only process the right one. if (strcasecmp(ird->desired_partnum, "_HUNT_")) { if (strcasecmp(partnum, ird->desired_partnum)) { return; @@ -342,9 +321,7 @@ void ical_locate_part(char *name, char *filename, char *partnum, char *disp, } -/* - * Respond to a meeting request. - */ +// Respond to a meeting request. void ical_respond(long msgnum, char *partnum, char *action) { struct CtdlMessage *msg = NULL; struct ical_respond_data ird; @@ -353,55 +330,46 @@ void ical_respond(long msgnum, char *partnum, char *action) { (strcasecmp(action, "accept")) && (strcasecmp(action, "decline")) ) { - cprintf("%d Action must be 'accept' or 'decline'\n", - ERROR + ILLEGAL_VALUE - ); + cprintf("%d Action must be 'accept' or 'decline'\n", ERROR + ILLEGAL_VALUE); return; } msg = CtdlFetchMessage(msgnum, 1); if (msg == NULL) { - cprintf("%d Message %ld not found.\n", - ERROR + ILLEGAL_VALUE, - (long)msgnum - ); + cprintf("%d Message %ld not found.\n", ERROR + ILLEGAL_VALUE, (long)msgnum); return; } memset(&ird, 0, sizeof ird); strcpy(ird.desired_partnum, partnum); mime_parser(CM_RANGE(msg, eMesageText), - *ical_locate_part, /* callback function */ - NULL, NULL, - (void *) &ird, /* user data */ - 0 + *ical_locate_part, // callback function + NULL, + NULL, + (void *) &ird, // user data + 0 ); - /* We're done with the incoming message, because we now have a - * calendar object in memory. - */ + // We're done with the incoming message, because we now have a * calendar object in memory. CM_Free(msg); - /* - * Here is the real meat of this function. Handle the event. - */ + // Here is the real meat of this function. Handle the event. if (ird.cal != NULL) { - /* Save this in the user's calendar if necessary */ + // Save this in the user's calendar if necessary if (!strcasecmp(action, "accept")) { ical_write_to_cal(&CC->user, ird.cal); } - /* Send a reply if necessary */ + // Send a reply if necessary if (icalcomponent_get_method(ird.cal) == ICAL_METHOD_REQUEST) { ical_send_a_reply(ird.cal, action); } - /* We used to delete the invitation after handling it. - * We don't do that anymore, but here is the code that handled it: - * CtdlDeleteMessages(CC->room.QRname, &msgnum, 1, ""); - */ + // We used to delete the invitation after handling it. + // We don't do that anymore, but here is the code that handled it: + // CtdlDeleteMessages(CC->room.QRname, &msgnum, 1, ""); - /* Free the memory we allocated and return a response. */ + // Free the memory we allocated and return a response. icalcomponent_free(ird.cal); ird.cal = NULL; cprintf("%d ok\n", CIT_OK); @@ -412,7 +380,7 @@ void ical_respond(long msgnum, char *partnum, char *action) { return; } - /* should never get here */ + // should never get here } @@ -2429,13 +2397,13 @@ int ical_obj_aftersave(struct CtdlMessage *msg, struct recptypes *recp) return(0); /* Not the Calendar room -- don't do anything. */ } - /* It must be an RFC822 message! */ + // It must be an RFC822 message! if (msg->cm_format_type != 4) return(1); - /* Reject null messages */ + // Reject null messages if (CM_IsEmpty(msg, eMesageText)) return(1); - /* Now recurse through it looking for our icalendar data */ + // Now recurse through it looking for our icalendar data mime_parser(CM_RANGE(msg, eMesageText), *ical_obj_aftersave_backend, NULL, NULL, @@ -2458,9 +2426,7 @@ void ical_session_shutdown(void) { } -/* - * Back end for ical_fixed_output() - */ +// Back end for ical_fixed_output() void ical_fixed_output_backend(icalcomponent *cal, int recursion_level) { icalcomponent *c; icalproperty *p; @@ -2482,13 +2448,13 @@ void ical_fixed_output_backend(icalcomponent *cal, int recursion_level) { cprintf("%s\n", (const char *)icalproperty_get_comment(p)); } - /* If the component has attendees, iterate through them. */ + // If the component has attendees, iterate through them. for (p = icalcomponent_get_first_property(cal, ICAL_ATTENDEE_PROPERTY); (p != NULL); p = icalcomponent_get_next_property(cal, ICAL_ATTENDEE_PROPERTY)) { ch = icalproperty_get_attendee(p); if ((ch != NULL) && !strncasecmp(ch, "MAILTO:", 7)) { - /* screen name or email address */ + // screen name or email address safestrncpy(buf, ch + 7, sizeof(buf)); string_trim(buf); cprintf("%s ", buf); @@ -2496,21 +2462,19 @@ void ical_fixed_output_backend(icalcomponent *cal, int recursion_level) { cprintf("\n"); } - /* If the component has subcomponents, recurse through them. */ + // If the component has subcomponents, recurse through them. for (c = icalcomponent_get_first_component(cal, ICAL_ANY_COMPONENT); (c != 0); c = icalcomponent_get_next_component(cal, ICAL_ANY_COMPONENT)) { - /* Recursively process subcomponent */ + // Recursively process subcomponent ical_fixed_output_backend(c, recursion_level+1); } } -/* - * Function to output iCalendar data as plain text. Nobody uses MSG0 - * anymore, so really this is just so we expose the vCard data to the full - * text indexer. - */ +// Function to output iCalendar data as plain text. Nobody uses MSG0 +// anymore, so really this is just so we expose the vCard data to the full +// text indexer. void ical_fixed_output(char *ptr, int len) { icalcomponent *cal; char *stringy_cal; @@ -2526,7 +2490,7 @@ void ical_fixed_output(char *ptr, int len) { ical_fixed_output_backend(cal, 0); - /* Free the memory we obtained from libical's constructor */ + // Free the memory we obtained from libical's constructor icalcomponent_free(cal); } @@ -2535,18 +2499,14 @@ void ical_fixed_output(char *ptr, int len) { char *ctdl_module_init_calendar(void) { if (!threading) { - /* Tell libical to return errors instead of aborting if it gets bad data */ - -#ifdef LIBICAL_ICAL_EXPORT // cheap and sleazy way to detect libical >=2.0 + // Tell libical to return errors instead of aborting if it gets bad data. + // If this library call is not found, you need to upgrade libical. icalerror_set_errors_are_fatal(0); -#else - icalerror_errors_are_fatal = 0; -#endif - /* Use our own application prefix in tzid's generated from system tzdata */ + // Use our own application prefix in tzid's generated from system tzdata icaltimezone_set_tzid_prefix("/citadel.org/"); - /* Initialize our hook functions */ + // Initialize our hook functions CtdlRegisterMessageHook(ical_obj_beforesave, EVT_BEFORESAVE); CtdlRegisterMessageHook(ical_obj_aftersave, EVT_AFTERSAVE); CtdlRegisterSessionHook(ical_CtdlCreateRoom, EVT_LOGIN, PRIO_LOGIN + 1); @@ -2557,6 +2517,6 @@ char *ctdl_module_init_calendar(void) { CtdlRegisterFixedOutputHook("application/ics", ical_fixed_output); } - /* return our module name for the log */ + // return our module name for the log return "calendar"; }