Removed some leftover dependencies on message fields which no longer exist
[citadel.git] / citadel / modules / calendar / serv_calendar.c
index f51e427d26590b3061ca7ee04f770b8af2dfd4e8..c38ffd250b5c1103cff240adebe9f03be68f8929 100644 (file)
@@ -3,37 +3,28 @@
  * room on a Citadel server.  It handles iCalendar objects using the
  * iTIP protocol.  See RFCs 2445 and 2446.
  *
+ * Copyright (c) 1987-2020 by the citadel.org team
  *
- * Copyright (c) 1987-2011 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 open source software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  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.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 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.
  */
 
 #define PRODID "-//Citadel//NONSGML Citadel Calendar//EN"
 
 #include "ctdl_module.h"
-
 #include <libical/ical.h>
-
 #include "msgbase.h"
 #include "internet_addressing.h"
 #include "serv_calendar.h"
+#include "room_ops.h"
 #include "euidindex.h"
-#include "ical_dezonify.h"
-
-
+#include "default_timezone.h"
+#include "config.h"
 
 struct ical_respond_data {
        char desired_partnum[SIZ];
@@ -50,7 +41,7 @@ icalcomponent *icalcomponent_new_citadel_vcalendar(void) {
 
        encaps = icalcomponent_new_vcalendar();
        if (encaps == NULL) {
-               syslog(LOG_CRIT, "ERROR: could not allocate component!\n");
+               syslog(LOG_ERR, "calendar: could not allocate component");
                return NULL;
        }
 
@@ -89,8 +80,6 @@ icalcomponent *ical_encapsulate_subcomponent(icalcomponent *subcomp) {
 }
 
 
-
-
 /*
  * Write a calendar object into the specified user's calendar room.
  * If the supplied user is NULL, this function writes the calendar object
@@ -98,6 +87,7 @@ icalcomponent *ical_encapsulate_subcomponent(icalcomponent *subcomp) {
  */
 void ical_write_to_cal(struct ctdluser *u, icalcomponent *cal) {
        char *ser = NULL;
+       long serlen;
        icalcomponent *encaps = NULL;
        struct CtdlMessage *msg = NULL;
        icalcomponent *tmp=NULL;
@@ -119,13 +109,15 @@ void ical_write_to_cal(struct ctdluser *u, icalcomponent *cal) {
        ser = icalcomponent_as_ical_string_r(cal);
        if (ser == NULL) return;
 
+       serlen = strlen(ser);
+
        /* 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 */
-                       strlen(ser)+1,          /* length */
+                       serlen + 1,             /* length */
                        u,                      /* which user */
                        0,                      /* not binary */
                        0,                      /* don't delete others of this type */
@@ -135,22 +127,26 @@ void ical_write_to_cal(struct ctdluser *u, icalcomponent *cal) {
 
        /* If the caller did not supply a user, write to the currently selected room */
        if (!u) {
+               struct CitContext *CCC = CC;
+               StrBuf *MsgBody;
+
                msg = malloc(sizeof(struct CtdlMessage));
                memset(msg, 0, sizeof(struct CtdlMessage));
                msg->cm_magic = CTDLMESSAGE_MAGIC;
                msg->cm_anon_type = MES_NORMAL;
                msg->cm_format_type = 4;
-               msg->cm_fields['A'] = strdup(CC->user.fullname);
-               msg->cm_fields['O'] = strdup(CC->room.QRname);
-               msg->cm_fields['N'] = strdup(config.c_nodename);
-               msg->cm_fields['H'] = strdup(config.c_humannode);
-               msg->cm_fields['M'] = malloc(strlen(ser) + 40);
-               strcpy(msg->cm_fields['M'], "Content-type: text/calendar\r\n\r\n");
-               strcat(msg->cm_fields['M'], ser);
+               CM_SetField(msg, eAuthor, CCC->user.fullname, strlen(CCC->user.fullname));
+               CM_SetField(msg, eOriginalRoom, CCC->room.QRname, strlen(CCC->room.QRname));
+
+               MsgBody = NewStrBufPlain(NULL, serlen + 100);
+               StrBufAppendBufPlain(MsgBody, HKEY("Content-type: text/calendar\r\n\r\n"), 0);
+               StrBufAppendBufPlain(MsgBody, ser, serlen, 0);
+
+               CM_SetAsFieldSB(msg, eMesageText, &MsgBody);
        
                /* Now write the data */
                CtdlSubmitMsg(msg, NULL, "", QP_EADDR);
-               CtdlFreeMessage(msg);
+               CM_Free(msg);
        }
 
        /* In either case, now we can free the serialized calendar object */
@@ -175,25 +171,25 @@ void ical_send_a_reply(icalcomponent *request, char *action) {
        icalproperty *summary = NULL;
        char summary_string[SIZ];
        icalproperty *me_attend = NULL;
-       struct recptypes *recp = NULL;
+       recptypes *recp = NULL;
        icalparameter *partstat = NULL;
        char *serialized_reply = NULL;
        char *reply_message_text = NULL;
        const char *ch;
        struct CtdlMessage *msg = NULL;
-       struct recptypes *valid = NULL;
+       recptypes *valid = NULL;
 
-       strcpy(organizer_string, "");
+       *organizer_string = '\0';
        strcpy(summary_string, "Calendar item");
 
        if (request == NULL) {
-               syslog(LOG_ERR, "ERROR: trying to reply to NULL event?\n");
+               syslog(LOG_ERR, "calendar: trying to reply to NULL event");
                return;
        }
 
        the_reply = icalcomponent_new_clone(request);
        if (the_reply == NULL) {
-               syslog(LOG_ERR, "ERROR: cannot clone request\n");
+               syslog(LOG_ERR, "calendar: cannot clone request");
                return;
        }
 
@@ -231,7 +227,7 @@ void ical_send_a_reply(icalcomponent *request, char *action) {
                /* We found our own address in the attendee list. */
                if (me_attend) {
                        /* Change the partstat from NEEDS-ACTION to ACCEPT or DECLINE */
-                       icalproperty_remove_parameter(me_attend, ICAL_PARTSTAT_PARAMETER);
+                       icalproperty_remove_parameter_by_kind(me_attend, ICAL_PARTSTAT_PARAMETER);
 
                        if (!strcasecmp(action, "accept")) {
                                partstat = icalparameter_new_partstat(ICAL_PARTSTAT_ACCEPTED);
@@ -302,7 +298,7 @@ void ical_send_a_reply(icalcomponent *request, char *action) {
                if (msg != NULL) {
                        valid = validate_recipients(organizer_string, NULL, 0);
                        CtdlSubmitMsg(msg, valid, "", QP_EADDR);
-                       CtdlFreeMessage(msg);
+                       CM_Free(msg);
                        free_recipients(valid);
                }
        }
@@ -310,7 +306,6 @@ 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
@@ -365,7 +360,7 @@ void ical_respond(long msgnum, char *partnum, char *action) {
                return;
        }
 
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg == NULL) {
                cprintf("%d Message %ld not found.\n",
                        ERROR + ILLEGAL_VALUE,
@@ -376,18 +371,17 @@ void ical_respond(long msgnum, char *partnum, char *action) {
 
        memset(&ird, 0, sizeof ird);
        strcpy(ird.desired_partnum, partnum);
-       mime_parser(msg->cm_fields['M'],
-               NULL,
-               *ical_locate_part,              /* callback function */
-               NULL, NULL,
-               (void *) &ird,                  /* user data */
-               0
+       mime_parser(CM_RANGE(msg, eMesageText),
+                   *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.
         */
-       CtdlFreeMessage(msg);
+       CM_Free(msg);
 
        /*
         * Here is the real meat of this function.  Handle the event.
@@ -571,8 +565,6 @@ STARTOVER:
 }
 
 
-
-
 /*
  * Handle an incoming RSVP (object with method==ICAL_METHOD_REPLY) for a
  * calendar event.  The object has already been deserialized for us; all
@@ -596,13 +588,13 @@ int ical_update_my_calendar_with_reply(icalcomponent *cal) {
        /* Figure out just what event it is we're dealing with */
        strcpy(uid, "--==<< InVaLiD uId >>==--");
        ical_learn_uid_of_reply(uid, cal);
-       syslog(LOG_DEBUG, "UID of event being replied to is <%s>\n", uid);
+       syslog(LOG_DEBUG, "calendar: UID of event being replied to is <%s>", uid);
 
        strcpy(hold_rm, CC->room.QRname);       /* save current room */
 
        if (CtdlGetRoom(&CC->room, USERCALENDARROOM) != 0) {
                CtdlGetRoom(&CC->room, hold_rm);
-               syslog(LOG_CRIT, "cannot get user calendar room\n");
+               syslog(LOG_ERR, "calendar: cannot get user calendar room");
                return(2);
        }
 
@@ -616,7 +608,7 @@ int ical_update_my_calendar_with_reply(icalcomponent *cal) {
 
        CtdlGetRoom(&CC->room, hold_rm);        /* return to saved room */
 
-       syslog(LOG_DEBUG, "msgnum_being_replaced == %ld\n", msgnum_being_replaced);
+       syslog(LOG_DEBUG, "calendar: msgnum_being_replaced == %ld", msgnum_being_replaced);
        if (msgnum_being_replaced == 0) {
                return(1);                      /* no calendar event found */
        }
@@ -627,23 +619,22 @@ int ical_update_my_calendar_with_reply(icalcomponent *cal) {
         * us the ability to load the event into memory so we can diddle the
         * attendees.
         */
-       msg = CtdlFetchMessage(msgnum_being_replaced, 1);
+       msg = CtdlFetchMessage(msgnum_being_replaced, 1, 1);
        if (msg == NULL) {
                return(2);                      /* internal error */
        }
        oec.c = NULL;
-       mime_parser(msg->cm_fields['M'],
-               NULL,
-               *ical_locate_original_event,    /* callback function */
-               NULL, NULL,
-               &oec,                           /* user data */
-               0
+       mime_parser(CM_RANGE(msg, eMesageText),
+                   *ical_locate_original_event,        /* callback function */
+                   NULL, NULL,
+                   &oec,                               /* user data */
+                   0
        );
-       CtdlFreeMessage(msg);
+       CM_Free(msg);
 
        original_event = oec.c;
        if (original_event == NULL) {
-               syslog(LOG_ERR, "ERROR: Original_component is NULL.\n");
+               syslog(LOG_ERR, "calendar: original_component is NULL");
                return(2);
        }
 
@@ -679,7 +670,7 @@ int ical_update_my_calendar_with_reply(icalcomponent *cal) {
                if (msg != NULL) {
                        CIT_ICAL->avoid_sending_invitations = 1;
                        CtdlSubmitMsg(msg, NULL, roomname, QP_EADDR);
-                       CtdlFreeMessage(msg);
+                       CM_Free(msg);
                        CIT_ICAL->avoid_sending_invitations = 0;
                }
        }
@@ -708,7 +699,7 @@ void ical_handle_rsvp(long msgnum, char *partnum, char *action) {
                return;
        }
 
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg == NULL) {
                cprintf("%d Message %ld not found.\n",
                        ERROR + ILLEGAL_VALUE,
@@ -719,18 +710,17 @@ void ical_handle_rsvp(long msgnum, char *partnum, char *action) {
 
        memset(&ird, 0, sizeof ird);
        strcpy(ird.desired_partnum, partnum);
-       mime_parser(msg->cm_fields['M'],
-               NULL,
-               *ical_locate_part,              /* callback function */
-               NULL, NULL,
-               (void *) &ird,                  /* user data */
-               0
-       );
+       mime_parser(CM_RANGE(msg, eMesageText),
+                   *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.
         */
-       CtdlFreeMessage(msg);
+       CM_Free(msg);
 
        /*
         * Here is the real meat of this function.  Handle the event.
@@ -847,7 +837,7 @@ int ical_ctdl_is_overlap(
                return(1);
        }
 
-       /* syslog(LOG_DEBUG, "Comparing t1start %d:%d t1end %d:%d t2start %d:%d t2end %d:%d \n",
+       /* syslog(LOG_DEBUG, "Comparing t1start %d:%d t1end %d:%d t2start %d:%d t2end %d:%d",
                t1start.hour, t1start.minute, t1end.hour, t1end.minute,
                t2start.hour, t2start.minute, t2end.hour, t2end.minute);
        */
@@ -856,16 +846,17 @@ int ical_ctdl_is_overlap(
 
        /* If event 1 ends before event 2 starts, we're in the clear. */
        if (icaltime_compare(t1end, t2start) <= 0) return(0);
-       /* syslog(LOG_DEBUG, "first passed\n"); */
+       /* syslog(LOG_DEBUG, "calendar: first passed"); */
 
        /* If event 2 ends before event 1 starts, we're also ok. */
        if (icaltime_compare(t2end, t1start) <= 0) return(0);
-       /* syslog(LOG_DEBUG, "second passed\n"); */
+       /* syslog(LOG_DEBUG, "calendar: second passed"); */
 
        /* Otherwise, they overlap. */
        return(1);
 }
 
+
 /* 
  * Phase 6 of "hunt for conflicts"
  * called by ical_conflicts_phase5()
@@ -905,11 +896,11 @@ int ical_conflicts_phase6(struct icaltimetype t1start,
                        existing_msgnum,
                        conflict_event_uid,
                        conflict_event_summary,
-                       (       ((strlen(compare_uid)>0)
+                       (       (!IsEmptyStr(compare_uid)
                                &&(!strcasecmp(compare_uid,
                                conflict_event_uid))) ? 1 : 0
-                       )
-               );
+                               )
+                       );
                conflict_reported = 1;
        }
 
@@ -917,7 +908,6 @@ int ical_conflicts_phase6(struct icaltimetype t1start,
 }
 
 
-
 /*
  * Phase 5 of "hunt for conflicts"
  * Called by ical_conflicts_phase4()
@@ -986,6 +976,9 @@ void ical_conflicts_phase5(struct icaltimetype t1start,
                }
                dur = icaltime_subtract(t2end, t2start);
        }
+       else {
+               memset (&dur, 0, sizeof(struct icaldurationtype));
+       }
 
        rrule = ical_ctdl_get_subprop(existing_event, ICAL_RRULE_PROPERTY);
        if (rrule) {
@@ -1029,8 +1022,6 @@ void ical_conflicts_phase5(struct icaltimetype t1start,
 }
 
 
-
-
 /*
  * Phase 4 of "hunt for conflicts"
  * Called by ical_hunt_for_conflicts_backend()
@@ -1043,8 +1034,6 @@ void ical_conflicts_phase4(icalcomponent *proposed_event,
                long existing_msgnum)
 {
        struct icaltimetype t1start, t1end;
-       t1start = icaltime_null_time();
-       t1end = icaltime_null_time();
        icalproperty *p;
        char compare_uid[SIZ];
 
@@ -1056,13 +1045,17 @@ void ical_conflicts_phase4(icalcomponent *proposed_event,
        int num_recur = 0;
 
        /* initialization */
-       strcpy(compare_uid, "");
+       t1end = icaltime_null_time();
+       *compare_uid = '\0';
 
        /* proposed event stuff */
 
        p = ical_ctdl_get_subprop(proposed_event, ICAL_DTSTART_PROPERTY);
-       if (p == NULL) return;
-       if (p != NULL) t1start = icalproperty_get_dtstart(p);
+       if (p == NULL)
+               return;
+       else
+               t1start = icalproperty_get_dtstart(p);
+
        if (icaltime_is_utc(t1start)) {
                t1start.zone = icaltimezone_get_utc_timezone();
        }
@@ -1097,6 +1090,9 @@ void ical_conflicts_phase4(icalcomponent *proposed_event,
 
                dur = icaltime_subtract(t1end, t1start);
        }
+       else {
+               memset (&dur, 0, sizeof(struct icaldurationtype));
+       }
 
        rrule = ical_ctdl_get_subprop(proposed_event, ICAL_RRULE_PROPERTY);
        if (rrule) {
@@ -1127,7 +1123,6 @@ void ical_conflicts_phase4(icalcomponent *proposed_event,
 }
 
 
-
 /*
  * Phase 3 of "hunt for conflicts"
  * Called by ical_hunt_for_conflicts()
@@ -1139,18 +1134,17 @@ void ical_hunt_for_conflicts_backend(long msgnum, void *data) {
 
        proposed_event = (icalcomponent *)data;
 
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg == NULL) return;
        memset(&ird, 0, sizeof ird);
        strcpy(ird.desired_partnum, "_HUNT_");
-       mime_parser(msg->cm_fields['M'],
-               NULL,
-               *ical_locate_part,              /* callback function */
-               NULL, NULL,
-               (void *) &ird,                  /* user data */
-               0
+       mime_parser(CM_RANGE(msg, eMesageText),
+                   *ical_locate_part,          /* callback function */
+                   NULL, NULL,
+                   (void *) &ird,                      /* user data */
+                   0
        );
-       CtdlFreeMessage(msg);
+       CM_Free(msg);
 
        if (ird.cal == NULL) return;
 
@@ -1159,7 +1153,6 @@ void ical_hunt_for_conflicts_backend(long msgnum, void *data) {
 }
 
 
-
 /* 
  * Phase 2 of "hunt for conflicts" operation.
  * At this point we have a calendar object which represents the VEVENT that
@@ -1193,7 +1186,6 @@ void ical_hunt_for_conflicts(icalcomponent *cal) {
 }
 
 
-
 /*
  * Hunt for conflicts (Phase 1 -- retrieve the object and call Phase 2)
  */
@@ -1201,7 +1193,7 @@ void ical_conflicts(long msgnum, char *partnum) {
        struct CtdlMessage *msg = NULL;
        struct ical_respond_data ird;
 
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg == NULL) {
                cprintf("%d Message %ld not found\n",
                        ERROR + ILLEGAL_VALUE,
@@ -1212,15 +1204,14 @@ void ical_conflicts(long msgnum, char *partnum) {
 
        memset(&ird, 0, sizeof ird);
        strcpy(ird.desired_partnum, partnum);
-       mime_parser(msg->cm_fields['M'],
-               NULL,
-               *ical_locate_part,              /* callback function */
-               NULL, NULL,
-               (void *) &ird,                  /* user data */
-               0
-       );
+       mime_parser(CM_RANGE(msg, eMesageText),
+                   *ical_locate_part,          /* callback function */
+                   NULL, NULL,
+                   (void *) &ird,                      /* user data */
+                   0
+               );
 
-       CtdlFreeMessage(msg);
+       CM_Free(msg);
 
        if (ird.cal != NULL) {
                ical_hunt_for_conflicts(ird.cal);
@@ -1232,7 +1223,6 @@ void ical_conflicts(long msgnum, char *partnum) {
 }
 
 
-
 /*
  * Look for busy time in a VEVENT and add it to the supplied VFREEBUSY.
  *
@@ -1244,8 +1234,8 @@ void ical_add_to_freebusy(icalcomponent *fb, icalcomponent *top_level_cal) {
        icalproperty *p;
        icalvalue *v;
        struct icalperiodtype this_event_period = icalperiodtype_null_period();
-       icaltimetype dtstart = icaltime_null_time();
-       icaltimetype dtend = icaltime_null_time();
+       icaltimetype dtstart;
+       icaltimetype dtend;
 
        /* recur variables */
        icalproperty *rrule = NULL;
@@ -1298,6 +1288,9 @@ void ical_add_to_freebusy(icalcomponent *fb, icalcomponent *top_level_cal) {
        if (!icaltime_is_null_time(dtend)) {
                dur = icaltime_subtract(dtend, dtstart);
        }
+       else {
+               memset (&dur, 0, sizeof(struct icaldurationtype));
+       }
 
        /* Is a recurrence specified?  If so, get ready to process it... */
        rrule = ical_ctdl_get_subprop(cal, ICAL_RRULE_PROPERTY);
@@ -1360,7 +1353,6 @@ void ical_add_to_freebusy(icalcomponent *fb, icalcomponent *top_level_cal) {
                        if (!icaltime_is_null_time(dtend)) {
                                dtend = icaltime_add(dtstart, dur);
                                dtend.zone = dtstart.zone;
-                               dtend.is_utc = dtstart.is_utc;
                        }
                        ++num_recur;
                }
@@ -1370,7 +1362,6 @@ void ical_add_to_freebusy(icalcomponent *fb, icalcomponent *top_level_cal) {
 }
 
 
-
 /*
  * Backend for ical_freebusy()
  *
@@ -1386,18 +1377,17 @@ void ical_freebusy_backend(long msgnum, void *data) {
 
        fb = (icalcomponent *)data;             /* User-supplied data will be the VFREEBUSY component */
 
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg == NULL) return;
        memset(&ird, 0, sizeof ird);
        strcpy(ird.desired_partnum, "_HUNT_");
-       mime_parser(msg->cm_fields['M'],
-               NULL,
-               *ical_locate_part,              /* callback function */
-               NULL, NULL,
-               (void *) &ird,                  /* user data */
-               0
-       );
-       CtdlFreeMessage(msg);
+       mime_parser(CM_RANGE(msg, eMesageText),
+                   *ical_locate_part,          /* callback function */
+                   NULL, NULL,
+                   (void *) &ird,                      /* user data */
+                   0
+               );
+       CM_Free(msg);
 
        if (ird.cal) {
                ical_add_to_freebusy(fb, ird.cal);              /* Add VEVENT times to VFREEBUSY */
@@ -1406,7 +1396,6 @@ void ical_freebusy_backend(long msgnum, void *data) {
 }
 
 
-
 /*
  * Grab another user's free/busy times
  */
@@ -1418,7 +1407,7 @@ void ical_freebusy(char *who) {
        icalcomponent *encaps = NULL;
        icalcomponent *fb = NULL;
        int found_user = (-1);
-       struct recptypes *recp = NULL;
+       recptypes *recp = NULL;
        char buf[256];
        char host[256];
        char type[256];
@@ -1432,7 +1421,7 @@ void ical_freebusy(char *who) {
        if (found_user != 0) {
                strcpy(buf, who);
                recp = validate_recipients(buf, NULL, 0);
-               syslog(LOG_DEBUG, "Trying <%s>\n", buf);
+               syslog(LOG_DEBUG, "calendar: trying <%s>", buf);
                if (recp != NULL) {
                        if (recp->num_local == 1) {
                                found_user = CtdlGetUser(&usbuf, recp->recp_local);
@@ -1445,8 +1434,8 @@ void ical_freebusy(char *who) {
         * primary FQDN of this Citadel node.
         */
        if (found_user != 0) {
-               snprintf(buf, sizeof buf, "%s@%s", who, config.c_fqdn);
-               syslog(LOG_DEBUG, "Trying <%s>\n", buf);
+               snprintf(buf, sizeof buf, "%s@%s", who, CtdlGetConfigStr("c_fqdn"));
+               syslog(LOG_DEBUG, "calendar: trying <%s>", buf);
                recp = validate_recipients(buf, NULL, 0);
                if (recp != NULL) {
                        if (recp->num_local == 1) {
@@ -1469,7 +1458,7 @@ void ical_freebusy(char *who) {
                        if ( (!strcasecmp(type, "localhost"))
                           || (!strcasecmp(type, "directory")) ) {
                                snprintf(buf, sizeof buf, "%s@%s", who, host);
-                               syslog(LOG_DEBUG, "Trying <%s>\n", buf);
+                               syslog(LOG_DEBUG, "calendar: trying <%s>", buf);
                                recp = validate_recipients(buf, NULL, 0);
                                if (recp != NULL) {
                                        if (recp->num_local == 1) {
@@ -1498,11 +1487,10 @@ void ical_freebusy(char *who) {
        }
 
        /* Create a VFREEBUSY subcomponent */
-       syslog(LOG_DEBUG, "Creating VFREEBUSY component\n");
+       syslog(LOG_DEBUG, "calendar: creating VFREEBUSY component");
        fb = icalcomponent_new_vfreebusy();
        if (fb == NULL) {
-               cprintf("%d Internal error: cannot allocate memory.\n",
-                       ERROR + INTERNAL_ERROR);
+               cprintf("%d Internal error: cannot allocate memory.\n", ERROR + INTERNAL_ERROR);
                CtdlGetRoom(&CC->room, hold_rm);
                return;
        }
@@ -1511,13 +1499,13 @@ void ical_freebusy(char *who) {
        icalcomponent_set_method(fb, ICAL_METHOD_PUBLISH);
 
        /* Set the DTSTAMP to right now. */
-       icalcomponent_set_dtstamp(fb, icaltime_from_timet(time(NULL), 0));
+       icalcomponent_set_dtstamp(fb, icaltime_from_timet_with_zone(time(NULL), 0, icaltimezone_get_utc_timezone()));
 
        /* Add the user's email address as ORGANIZER */
        sprintf(buf, "MAILTO:%s", who);
        if (strchr(buf, '@') == NULL) {
                strcat(buf, "@");
-               strcat(buf, config.c_fqdn);
+               strcat(buf, CtdlGetConfigStr("c_fqdn"));
        }
        for (i=0; buf[i]; ++i) {
                if (buf[i]==' ') buf[i] = '_';
@@ -1525,21 +1513,21 @@ void ical_freebusy(char *who) {
        icalcomponent_add_property(fb, icalproperty_new_organizer(buf));
 
        /* Add busy time from events */
-       syslog(LOG_DEBUG, "Adding busy time from events\n");
+       syslog(LOG_DEBUG, "calendar: adding busy time from events");
        CtdlForEachMessage(MSGS_ALL, 0, NULL, NULL, NULL, ical_freebusy_backend, (void *)fb );
 
        /* If values for DTSTART and DTEND are still not present, set them
         * to yesterday and tomorrow as default values.
         */
        if (icalcomponent_get_first_property(fb, ICAL_DTSTART_PROPERTY) == NULL) {
-               icalcomponent_set_dtstart(fb, icaltime_from_timet(time(NULL)-86400L, 0));
+               icalcomponent_set_dtstart(fb, icaltime_from_timet_with_zone(time(NULL)-86400L, 0, icaltimezone_get_utc_timezone()));
        }
        if (icalcomponent_get_first_property(fb, ICAL_DTEND_PROPERTY) == NULL) {
-               icalcomponent_set_dtend(fb, icaltime_from_timet(time(NULL)+86400L, 0));
+               icalcomponent_set_dtend(fb, icaltime_from_timet_with_zone(time(NULL)+86400L, 0, icaltimezone_get_utc_timezone()));
        }
 
        /* Put the freebusy component into the calendar component */
-       syslog(LOG_DEBUG, "Encapsulating\n");
+       syslog(LOG_DEBUG, "calendar: encapsulating");
        encaps = ical_encapsulate_subcomponent(fb);
        if (encaps == NULL) {
                icalcomponent_free(fb);
@@ -1550,11 +1538,11 @@ void ical_freebusy(char *who) {
        }
 
        /* Set the method to PUBLISH */
-       syslog(LOG_DEBUG, "Setting method\n");
+       syslog(LOG_DEBUG, "calendar: setting method");
        icalcomponent_set_method(encaps, ICAL_METHOD_PUBLISH);
 
        /* Serialize it */
-       syslog(LOG_DEBUG, "Serializing\n");
+       syslog(LOG_DEBUG, "calendar: serializing");
        serialized_request = icalcomponent_as_ical_string_r(encaps);
        icalcomponent_free(encaps);     /* Don't need this anymore. */
 
@@ -1570,7 +1558,6 @@ void ical_freebusy(char *who) {
 }
 
 
-
 /*
  * Backend for ical_getics()
  * 
@@ -1587,18 +1574,17 @@ void ical_getics_backend(long msgnum, void *data) {
 
        /* Look for the calendar event... */
 
-       msg = CtdlFetchMessage(msgnum, 1);
+       msg = CtdlFetchMessage(msgnum, 1, 1);
        if (msg == NULL) return;
        memset(&ird, 0, sizeof ird);
        strcpy(ird.desired_partnum, "_HUNT_");
-       mime_parser(msg->cm_fields['M'],
-               NULL,
-               *ical_locate_part,              /* callback function */
-               NULL, NULL,
-               (void *) &ird,                  /* user data */
-               0
+       mime_parser(CM_RANGE(msg, eMesageText),
+                   *ical_locate_part,          /* callback function */
+                   NULL, NULL,
+                   (void *) &ird,                      /* user data */
+                   0
        );
-       CtdlFreeMessage(msg);
+       CM_Free(msg);
 
        if (ird.cal == NULL) return;
 
@@ -1645,7 +1631,6 @@ void ical_getics_backend(long msgnum, void *data) {
 }
 
 
-
 /*
  * Retrieve all of the calendar items in the current room, and output them
  * as a single icalendar object.
@@ -1663,7 +1648,7 @@ void ical_getics(void)
 
        encaps = icalcomponent_new_vcalendar();
        if (encaps == NULL) {
-               syslog(LOG_ALERT, "ERROR: could not allocate component!\n");
+               syslog(LOG_ERR, "calendar: could not allocate component!");
                cprintf("%d Could not allocate memory\n", ERROR+INTERNAL_ERROR);
                return;
        }
@@ -1741,7 +1726,7 @@ void ical_putics(void)
        }
 
        cprintf("%d Transmit data now\n", SEND_LISTING);
-       calstream = CtdlReadMessageBody(HKEY("000"), config.c_maxmsglen, NULL, 0, 0);
+       calstream = CtdlReadMessageBody(HKEY("000"), CtdlGetConfigLong("c_maxmsglen"), NULL, 0);
        if (calstream == NULL) {
                return;
        }
@@ -1789,7 +1774,7 @@ void ical_putics(void)
                                HashPos = GetNewHashPos(tzidlist, 0);
 
                                while (GetNextHashPos(tzidlist, HashPos, &len, &Key, &Value)) {
-                                       syslog(LOG_DEBUG, "Attaching timezone '%s'\n", (char*) Value);
+                                       syslog(LOG_DEBUG, "calendar: attaching timezone '%s'", (char*) Value);
                                        icaltimezone *t = NULL;
 
                                        /* First look for a timezone attached to the original calendar */
@@ -1854,10 +1839,8 @@ void cmd_ical(char *argbuf)
        }
 
        if (!strcasecmp(subcmd, "sgi")) {
-               CIT_ICAL->server_generated_invitations =
-                       (extract_int(argbuf, 1) ? 1 : 0) ;
-               cprintf("%d %d\n",
-                       CIT_OK, CIT_ICAL->server_generated_invitations);
+               CIT_ICAL->server_generated_invitations = (extract_int(argbuf, 1) ? 1 : 0) ;
+               cprintf("%d %d\n", CIT_OK, CIT_ICAL->server_generated_invitations);
                return;
        }
 
@@ -1900,7 +1883,6 @@ void cmd_ical(char *argbuf)
 }
 
 
-
 /*
  * We don't know if the calendar room exists so we just create it at login
  */
@@ -1914,7 +1896,7 @@ void ical_CtdlCreateRoom(void)
 
        /* Set expiration policy to manual; otherwise objects will be lost! */
        if (CtdlGetRoomLock(&qr, USERCALENDARROOM)) {
-               syslog(LOG_CRIT, "Couldn't get the user calendar room!\n");
+               syslog(LOG_ERR, "calendar: couldn't get the user calendar room");
                return;
        }
        qr.QRep.expire_mode = EXPIRE_MANUAL;
@@ -1931,7 +1913,7 @@ void ical_CtdlCreateRoom(void)
 
        /* Set expiration policy to manual; otherwise objects will be lost! */
        if (CtdlGetRoomLock(&qr, USERTASKSROOM)) {
-               syslog(LOG_CRIT, "Couldn't get the user calendar room!\n");
+               syslog(LOG_ERR, "calendar: couldn't get the user calendar room!");
                return;
        }
        qr.QRep.expire_mode = EXPIRE_MANUAL;
@@ -1948,7 +1930,7 @@ void ical_CtdlCreateRoom(void)
 
        /* Set expiration policy to manual; otherwise objects will be lost! */
        if (CtdlGetRoomLock(&qr, USERNOTESROOM)) {
-               syslog(LOG_CRIT, "Couldn't get the user calendar room!\n");
+               syslog(LOG_ERR, "calendar: couldn't get the user calendar room!");
                return;
        }
        qr.QRep.expire_mode = EXPIRE_MANUAL;
@@ -1978,7 +1960,7 @@ void ical_send_out_invitations(icalcomponent *top_level_cal, icalcomponent *cal)
        icalcomponent *encaps = NULL;
        char *request_message_text = NULL;
        struct CtdlMessage *msg = NULL;
-       struct recptypes *valid = NULL;
+       recptypes *valid = NULL;
        char attendees_string[SIZ];
        int num_attendees = 0;
        char this_attendee[256];
@@ -1997,11 +1979,10 @@ void ical_send_out_invitations(icalcomponent *top_level_cal, icalcomponent *cal)
        const char *tzidc = NULL;
 
        if (cal == NULL) {
-               syslog(LOG_ERR, "ERROR: trying to reply to NULL event?\n");
+               syslog(LOG_ERR, "calendar: trying to reply to NULL event?");
                return;
        }
 
-
        /* If this is a VCALENDAR component, look for a VEVENT subcomponent. */
        if (icalcomponent_isa(cal) == ICAL_VCALENDAR_COMPONENT) {
                ical_send_out_invitations(top_level_cal,
@@ -2015,7 +1996,7 @@ void ical_send_out_invitations(icalcomponent *top_level_cal, icalcomponent *cal)
        /* Clone the event */
        the_request = icalcomponent_new_clone(cal);
        if (the_request == NULL) {
-               syslog(LOG_ERR, "ERROR: cannot clone calendar object\n");
+               syslog(LOG_ERR, "calendar: cannot clone calendar object");
                return;
        }
 
@@ -2049,7 +2030,7 @@ void ical_send_out_invitations(icalcomponent *top_level_cal, icalcomponent *cal)
                }
        }
 
-       syslog(LOG_DEBUG, "<%d> attendees: <%s>\n", num_attendees, attendees_string);
+       syslog(LOG_DEBUG, "calendar: <%d> attendees: <%s>", num_attendees, attendees_string);
 
        /* If there are no attendees, there are no invitations to send, so...
         * don't bother putting one together!  Punch out, Maverick!
@@ -2062,7 +2043,7 @@ void ical_send_out_invitations(icalcomponent *top_level_cal, icalcomponent *cal)
        /* Encapsulate the VEVENT component into a complete VCALENDAR */
        encaps = icalcomponent_new_vcalendar();
        if (encaps == NULL) {
-               syslog(LOG_ALERT, "ERROR: could not allocate component!\n");
+               syslog(LOG_ERR, "calendar: could not allocate component!");
                icalcomponent_free(the_request);
                return;
        }
@@ -2139,8 +2120,7 @@ void ical_send_out_invitations(icalcomponent *top_level_cal, icalcomponent *cal)
                                        attached_zones[num_zones_attached++] = z;
                                }
 
-                               icalproperty_set_parameter(p,
-                                       icalparameter_new_tzid(icaltimezone_get_tzid(z))
+                               icalproperty_set_parameter(p, icalparameter_new_tzid(icaltimezone_get_tzid(z))
                                );
                        }
                }
@@ -2190,7 +2170,7 @@ void ical_send_out_invitations(icalcomponent *top_level_cal, icalcomponent *cal)
                if (msg != NULL) {
                        valid = validate_recipients(attendees_string, NULL, 0);
                        CtdlSubmitMsg(msg, valid, "", QP_EADDR);
-                       CtdlFreeMessage(msg);
+                       CM_Free(msg);
                        free_recipients(valid);
                }
        }
@@ -2214,7 +2194,7 @@ void ical_saving_vevent(icalcomponent *top_level_cal, icalcomponent *cal) {
        icalproperty *organizer = NULL;
        char organizer_string[SIZ];
 
-       syslog(LOG_DEBUG, "ical_saving_vevent() has been called!\n");
+       syslog(LOG_DEBUG, "calendar: ical_saving_vevent() has been called");
 
        /* Don't send out invitations unless the client wants us to. */
        if (CIT_ICAL->server_generated_invitations == 0) {
@@ -2263,7 +2243,6 @@ void ical_saving_vevent(icalcomponent *top_level_cal, icalcomponent *cal) {
 }
 
 
-
 /*
  * Back end for ical_obj_beforesave()
  * This hunts for the UID of the calendar event (becomes Citadel msg EUID),
@@ -2274,10 +2253,10 @@ void ical_obj_beforesave_backend(char *name, char *filename, char *partnum,
                char *disp, void *content, char *cbtype, char *cbcharset, size_t length,
                char *encoding, char *cbid, void *cbuserdata)
 {
+       const char* pch;
        icalcomponent *cal, *nested_event, *nested_todo, *whole_cal;
        icalproperty *p;
        char new_uid[256] = "";
-       char buf[1024] = "";
        struct CtdlMessage *msg = (struct CtdlMessage *) cbuserdata;
 
        if (!msg) return;
@@ -2323,13 +2302,10 @@ void ical_obj_beforesave_backend(char *name, char *filename, char *partnum,
                                p = ical_ctdl_get_subprop(cal, ICAL_UID_PROPERTY);
                        }
                        if (p != NULL) {
-                               safestrncpy(buf, icalproperty_get_comment(p), sizeof buf);
-                               if (!IsEmptyStr(buf)) {
-                                       if (msg->cm_fields['E'] != NULL) {
-                                               free(msg->cm_fields['E']);
-                                       }
-                                       msg->cm_fields['E'] = strdup(buf);
-                                       syslog(LOG_DEBUG, "Saving calendar UID <%s>\n", buf);
+                               pch = icalproperty_get_comment(p);
+                               if (!IsEmptyStr(pch)) {
+                                       CM_SetField(msg, eExclusiveID, pch, strlen(pch));
+                                       syslog(LOG_DEBUG, "calendar: saving calendar UID <%s>", pch);
                                }
                        }
 
@@ -2337,12 +2313,12 @@ void ical_obj_beforesave_backend(char *name, char *filename, char *partnum,
 
                        p = ical_ctdl_get_subprop(cal, ICAL_SUMMARY_PROPERTY);
                        if (p != NULL) {
-                               safestrncpy(buf, icalproperty_get_comment(p), sizeof buf);
-                               if (!IsEmptyStr(buf)) {
-                                       if (msg->cm_fields['U'] != NULL) {
-                                               free(msg->cm_fields['U']);
-                                       }
-                                       msg->cm_fields['U'] = rfc2047encode(buf, strlen(buf));
+                               pch = icalproperty_get_comment(p);
+                               if (!IsEmptyStr(pch)) {
+                                       char *subj;
+
+                                       subj = rfc2047encode(pch, strlen(pch));
+                                       CM_SetAsField(msg, eMsgSubject, &subj, strlen(subj));
                                }
                        }
 
@@ -2353,11 +2329,7 @@ void ical_obj_beforesave_backend(char *name, char *filename, char *partnum,
                                time_t idtstart;
                                idtstart = icaltime_as_timet(icalproperty_get_dtstart(p));
                                if (idtstart > 0) {
-                                       if (msg->cm_fields['T'] != NULL) {
-                                               free(msg->cm_fields['T']);
-                                       }
-                                       msg->cm_fields['T'] = strdup("000000000000000000");
-                                       sprintf(msg->cm_fields['T'], "%ld", idtstart);
+                                       CM_SetFieldLONG(msg, eTimestamp, idtstart);
                                }
                        }
 
@@ -2370,8 +2342,6 @@ void ical_obj_beforesave_backend(char *name, char *filename, char *partnum,
 }
 
 
-
-
 /*
  * See if we need to prevent the object from being saved (we don't allow
  * MIME types other than text/calendar in "calendar" or "tasks" rooms).
@@ -2379,7 +2349,7 @@ void ical_obj_beforesave_backend(char *name, char *filename, char *partnum,
  * If the message is being saved, we also set various message header fields
  * using data found in the iCalendar object.
  */
-int ical_obj_beforesave(struct CtdlMessage *msg)
+int ical_obj_beforesave(struct CtdlMessage *msg, recptypes *recp)
 {
        /* First determine if this is a calendar or tasks room */
        if (  (CC->room.QRdefaultview != VIEW_CALENDAR)
@@ -2390,22 +2360,21 @@ int ical_obj_beforesave(struct CtdlMessage *msg)
 
        /* It must be an RFC822 message! */
        if (msg->cm_format_type != 4) {
-               syslog(LOG_DEBUG, "Rejecting non-RFC822 message\n");
+               syslog(LOG_DEBUG, "calendar: rejecting non-RFC822 message");
                return(1);              /* You tried to save a non-RFC822 message! */
        }
 
-       if (msg->cm_fields['M'] == NULL) {
+       if (CM_IsEmpty(msg, eMesageText)) {
                return(1);              /* You tried to save a null message! */
        }
 
        /* Do all of our lovely back-end parsing */
-       mime_parser(msg->cm_fields['M'],
-               NULL,
-               *ical_obj_beforesave_backend,
-               NULL, NULL,
-               (void *)msg,
-               0
-       );
+       mime_parser(CM_RANGE(msg, eMesageText),
+                   *ical_obj_beforesave_backend,
+                   NULL, NULL,
+                   (void *)msg,
+                   0
+               );
 
        return(0);
 }
@@ -2447,7 +2416,7 @@ void ical_obj_aftersave_backend(char *name, char *filename, char *partnum,
  * (This will start back end tasks such as automatic generation of invitations,
  * if such actions are appropriate.)
  */
-int ical_obj_aftersave(struct CtdlMessage *msg)
+int ical_obj_aftersave(struct CtdlMessage *msg, recptypes *recp)
 {
        char roomname[ROOMNAMELEN];
 
@@ -2465,16 +2434,15 @@ int ical_obj_aftersave(struct CtdlMessage *msg)
        if (msg->cm_format_type != 4) return(1);
 
        /* Reject null messages */
-       if (msg->cm_fields['M'] == NULL) return(1);
+       if (CM_IsEmpty(msg, eMesageText)) return(1);
        
        /* Now recurse through it looking for our icalendar data */
-       mime_parser(msg->cm_fields['M'],
-               NULL,
-               *ical_obj_aftersave_backend,
-               NULL, NULL,
-               NULL,
-               0
-       );
+       mime_parser(CM_RANGE(msg, eMesageText),
+                   *ical_obj_aftersave_backend,
+                   NULL, NULL,
+                   NULL,
+                   0
+               );
 
        return(0);
 }
@@ -2485,6 +2453,7 @@ void ical_session_startup(void) {
        memset(CIT_ICAL, 0, sizeof(struct cit_ical));
 }
 
+
 void ical_session_shutdown(void) {
        free(CIT_ICAL);
 }
@@ -2493,9 +2462,7 @@ void ical_session_shutdown(void) {
 /*
  * Back end for ical_fixed_output()
  */
-void ical_fixed_output_backend(icalcomponent *cal,
-                       int recursion_level
-) {
+void ical_fixed_output_backend(icalcomponent *cal, int recursion_level) {
        icalcomponent *c;
        icalproperty *p;
        char buf[256];
@@ -2540,7 +2507,6 @@ void ical_fixed_output_backend(icalcomponent *cal,
 }
 
 
-
 /*
  * 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
@@ -2566,12 +2532,11 @@ void ical_fixed_output(char *ptr, int len) {
 }
 
 
-
-void serv_calendar_destroy(void)
-{
+void serv_calendar_destroy(void) {
        icaltimezone_free_builtin_timezones();
 }
 
+
 /*
  * Register this module with the Citadel server.
  */
@@ -2581,7 +2546,12 @@ CTDL_MODULE_INIT(calendar)
        {
 
                /* 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
+               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 */
                icaltimezone_set_tzid_prefix("/citadel.org/");
@@ -2589,15 +2559,15 @@ CTDL_MODULE_INIT(calendar)
                /* Initialize our hook functions */
                CtdlRegisterMessageHook(ical_obj_beforesave, EVT_BEFORESAVE);
                CtdlRegisterMessageHook(ical_obj_aftersave, EVT_AFTERSAVE);
-               CtdlRegisterSessionHook(ical_CtdlCreateRoom, EVT_LOGIN);
-               CtdlRegisterProtoHook(cmd_ical, "ICAL", "Citadel iCal commands");
-               CtdlRegisterSessionHook(ical_session_startup, EVT_START);
-               CtdlRegisterSessionHook(ical_session_shutdown, EVT_STOP);
+               CtdlRegisterSessionHook(ical_CtdlCreateRoom, EVT_LOGIN, PRIO_LOGIN + 1);
+               CtdlRegisterProtoHook(cmd_ical, "ICAL", "Citadel iCalendar commands");
+               CtdlRegisterSessionHook(ical_session_startup, EVT_START, PRIO_START + 1);
+               CtdlRegisterSessionHook(ical_session_shutdown, EVT_STOP, PRIO_STOP + 80);
                CtdlRegisterFixedOutputHook("text/calendar", ical_fixed_output);
                CtdlRegisterFixedOutputHook("application/ics", ical_fixed_output);
                CtdlRegisterCleanupHook(serv_calendar_destroy);
        }
-       
-       /* return our Subversion id for the Log */
+
+       /* return our module name for the log */
        return "calendar";
 }