]> code.citadel.org Git - citadel.git/blobdiff - citadel/modules/calendar/serv_calendar.c
oops, this also checks room access rights.
[citadel.git] / citadel / modules / calendar / serv_calendar.c
index 84fb9683caf202961be26064d6b959d5f5ec632b..1acd28251aa688ad4b5fcb6e44fc1580e3ff000b 100644 (file)
@@ -30,6 +30,7 @@
 #include "msgbase.h"
 #include "internet_addressing.h"
 #include "serv_calendar.h"
+#include "room_ops.h"
 #include "euidindex.h"
 #include "ical_dezonify.h"
 
@@ -98,6 +99,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 +121,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 +139,28 @@ 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));
+               CM_SetField(msg, eNodeName, config.c_nodename, strlen(config.c_nodename));
+               CM_SetField(msg, eHumanNode, config.c_humannode, strlen(config.c_humannode));
+
+               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 */
@@ -183,7 +193,7 @@ void ical_send_a_reply(icalcomponent *request, char *action) {
        struct CtdlMessage *msg = NULL;
        struct recptypes *valid = NULL;
 
-       strcpy(organizer_string, "");
+       *organizer_string = '\0';
        strcpy(summary_string, "Calendar item");
 
        if (request == NULL) {
@@ -302,7 +312,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);
                }
        }
@@ -376,7 +386,7 @@ 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'],
+       mime_parser(msg->cm_fields[eMesageText],
                NULL,
                *ical_locate_part,              /* callback function */
                NULL, NULL,
@@ -387,7 +397,7 @@ void ical_respond(long msgnum, char *partnum, char *action) {
        /* 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.
@@ -632,14 +642,14 @@ int ical_update_my_calendar_with_reply(icalcomponent *cal) {
                return(2);                      /* internal error */
        }
        oec.c = NULL;
-       mime_parser(msg->cm_fields['M'],
+       mime_parser(msg->cm_fields[eMesageText],
                NULL,
                *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) {
@@ -679,7 +689,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;
                }
        }
@@ -719,7 +729,7 @@ 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'],
+       mime_parser(msg->cm_fields[eMesageText],
                NULL,
                *ical_locate_part,              /* callback function */
                NULL, NULL,
@@ -730,7 +740,7 @@ void ical_handle_rsvp(long msgnum, char *partnum, char *action) {
        /* 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.
@@ -986,6 +996,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) {
@@ -1043,8 +1056,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 +1067,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 +1112,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) {
@@ -1143,14 +1161,14 @@ void ical_hunt_for_conflicts_backend(long msgnum, void *data) {
        if (msg == NULL) return;
        memset(&ird, 0, sizeof ird);
        strcpy(ird.desired_partnum, "_HUNT_");
-       mime_parser(msg->cm_fields['M'],
+       mime_parser(msg->cm_fields[eMesageText],
                NULL,
                *ical_locate_part,              /* callback function */
                NULL, NULL,
                (void *) &ird,                  /* user data */
                0
        );
-       CtdlFreeMessage(msg);
+       CM_Free(msg);
 
        if (ird.cal == NULL) return;
 
@@ -1212,7 +1230,7 @@ void ical_conflicts(long msgnum, char *partnum) {
 
        memset(&ird, 0, sizeof ird);
        strcpy(ird.desired_partnum, partnum);
-       mime_parser(msg->cm_fields['M'],
+       mime_parser(msg->cm_fields[eMesageText],
                NULL,
                *ical_locate_part,              /* callback function */
                NULL, NULL,
@@ -1220,7 +1238,7 @@ void ical_conflicts(long msgnum, char *partnum) {
                0
        );
 
-       CtdlFreeMessage(msg);
+       CM_Free(msg);
 
        if (ird.cal != NULL) {
                ical_hunt_for_conflicts(ird.cal);
@@ -1244,8 +1262,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 +1316,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);
@@ -1390,14 +1411,14 @@ void ical_freebusy_backend(long msgnum, void *data) {
        if (msg == NULL) return;
        memset(&ird, 0, sizeof ird);
        strcpy(ird.desired_partnum, "_HUNT_");
-       mime_parser(msg->cm_fields['M'],
+       mime_parser(msg->cm_fields[eMesageText],
                NULL,
                *ical_locate_part,              /* callback function */
                NULL, NULL,
                (void *) &ird,                  /* user data */
                0
        );
-       CtdlFreeMessage(msg);
+       CM_Free(msg);
 
        if (ird.cal) {
                ical_add_to_freebusy(fb, ird.cal);              /* Add VEVENT times to VFREEBUSY */
@@ -1591,14 +1612,14 @@ void ical_getics_backend(long msgnum, void *data) {
        if (msg == NULL) return;
        memset(&ird, 0, sizeof ird);
        strcpy(ird.desired_partnum, "_HUNT_");
-       mime_parser(msg->cm_fields['M'],
+       mime_parser(msg->cm_fields[eMesageText],
                NULL,
                *ical_locate_part,              /* callback function */
                NULL, NULL,
                (void *) &ird,                  /* user data */
                0
        );
-       CtdlFreeMessage(msg);
+       CM_Free(msg);
 
        if (ird.cal == NULL) return;
 
@@ -2190,7 +2211,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);
                }
        }
@@ -2274,10 +2295,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 +2344,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, "Saving calendar UID <%s>\n", pch);
                                }
                        }
 
@@ -2337,12 +2355,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 +2371,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);
                                }
                        }
 
@@ -2394,12 +2408,12 @@ int ical_obj_beforesave(struct CtdlMessage *msg)
                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'],
+       mime_parser(msg->cm_fields[eMesageText],
                NULL,
                *ical_obj_beforesave_backend,
                NULL, NULL,
@@ -2465,10 +2479,10 @@ 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'],
+       mime_parser(msg->cm_fields[eMesageText],
                NULL,
                *ical_obj_aftersave_backend,
                NULL, NULL,
@@ -2589,10 +2603,10 @@ 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);
+               CtdlRegisterSessionHook(ical_CtdlCreateRoom, EVT_LOGIN, PRIO_LOGIN + 1);
                CtdlRegisterProtoHook(cmd_ical, "ICAL", "Citadel iCal commands");
-               CtdlRegisterSessionHook(ical_session_startup, EVT_START);
-               CtdlRegisterSessionHook(ical_session_shutdown, EVT_STOP);
+               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);