]> code.citadel.org Git - citadel.git/blobdiff - citadel/serv_calendar.c
* Finished removing all the "dynamic session data" stuff in order to
[citadel.git] / citadel / serv_calendar.c
index fb259f7d1783d6bdb99bf839b1b6e902b5bea263..7d28b940377618b40cc75e5a7fa3b8fe741b3222 100644 (file)
@@ -2,7 +2,7 @@
  * $Id$ 
  *
  * This module implements iCalendar object processing and the Calendar>
- * room on a Citadel/UX server.  It handles iCalendar objects using the
+ * room on a Citadel server.  It handles iCalendar objects using the
  * iTIP protocol.  See RFCs 2445 and 2446.
  *
  */
@@ -387,7 +387,7 @@ void ical_respond(long msgnum, char *partnum, char *action) {
                return;
        }
 
-       msg = CtdlFetchMessage(msgnum);
+       msg = CtdlFetchMessage(msgnum, 1);
        if (msg == NULL) {
                cprintf("%d Message %ld not found.\n",
                        ERROR + ILLEGAL_VALUE,
@@ -567,15 +567,10 @@ STARTOVER:
                                 * reply's copy will have the same address, but an updated
                                 * status.)
                                 */
-                               TRACE;
                                icalcomponent_remove_property(event, e_attendee);
-                               TRACE;
                                icalproperty_free(e_attendee);
-                               TRACE;
                                icalcomponent_remove_property(reply, r_attendee);
-                               TRACE;
                                icalcomponent_add_property(event, r_attendee);
-                               TRACE;
 
                                /* Since we diddled both sets of attendees, we have to start
                                 * the iteration over again.  This will not create an infinite
@@ -656,7 +651,7 @@ 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);
+       msg = CtdlFetchMessage(msgnum_being_replaced, 1);
        if (msg == NULL) {
                return(2);                      /* internal error */
        }
@@ -733,7 +728,7 @@ void ical_handle_rsvp(long msgnum, char *partnum, char *action) {
                return;
        }
 
-       msg = CtdlFetchMessage(msgnum);
+       msg = CtdlFetchMessage(msgnum, 1);
        if (msg == NULL) {
                cprintf("%d Message %ld not found.\n",
                        ERROR + ILLEGAL_VALUE,
@@ -896,7 +891,7 @@ void ical_hunt_for_conflicts_backend(long msgnum, void *data) {
        strcpy(conflict_event_uid, "");
        strcpy(conflict_event_summary, "");
 
-       msg = CtdlFetchMessage(msgnum);
+       msg = CtdlFetchMessage(msgnum, 1);
        if (msg == NULL) return;
        memset(&ird, 0, sizeof ird);
        strcpy(ird.desired_partnum, "_HUNT_");
@@ -1003,7 +998,7 @@ void ical_conflicts(long msgnum, char *partnum) {
        struct CtdlMessage *msg;
        struct ical_respond_data ird;
 
-       msg = CtdlFetchMessage(msgnum);
+       msg = CtdlFetchMessage(msgnum, 1);
        if (msg == NULL) {
                cprintf("%d Message %ld not found.\n",
                        ERROR + ILLEGAL_VALUE,
@@ -1145,7 +1140,7 @@ void ical_freebusy_backend(long msgnum, void *data) {
 
        cal = (icalcomponent *)data;
 
-       msg = CtdlFetchMessage(msgnum);
+       msg = CtdlFetchMessage(msgnum, 1);
        if (msg == NULL) return;
        memset(&ird, 0, sizeof ird);
        strcpy(ird.desired_partnum, "_HUNT_");
@@ -1409,7 +1404,7 @@ void ical_create_room(void)
        struct visit vbuf;
 
        /* Create the calendar room if it doesn't already exist */
-       create_room(USERCALENDARROOM, 4, "", 0, 1, 0);
+       create_room(USERCALENDARROOM, 4, "", 0, 1, 0, VIEW_CALENDAR);
 
        /* Set expiration policy to manual; otherwise objects will be lost! */
        if (lgetroom(&qr, USERCALENDARROOM)) {
@@ -1417,16 +1412,16 @@ void ical_create_room(void)
                return;
        }
        qr.QRep.expire_mode = EXPIRE_MANUAL;
-       qr.QRdefaultview = 3;   /* 3 = calendar view */
+       qr.QRdefaultview = VIEW_CALENDAR;       /* 3 = calendar view */
        lputroom(&qr);
 
        /* Set the view to a calendar view */
        CtdlGetRelationship(&vbuf, &CC->user, &qr);
-       vbuf.v_view = 3;        /* 3 = calendar */
+       vbuf.v_view = VIEW_CALENDAR;
        CtdlSetRelationship(&vbuf, &CC->user, &qr);
 
        /* Create the tasks list room if it doesn't already exist */
-       create_room(USERTASKSROOM, 4, "", 0, 1, 0);
+       create_room(USERTASKSROOM, 4, "", 0, 1, 0, VIEW_TASKS);
 
        /* Set expiration policy to manual; otherwise objects will be lost! */
        if (lgetroom(&qr, USERTASKSROOM)) {
@@ -1434,12 +1429,29 @@ void ical_create_room(void)
                return;
        }
        qr.QRep.expire_mode = EXPIRE_MANUAL;
-       qr.QRdefaultview = 4;   /* 4 = tasks view */
+       qr.QRdefaultview = VIEW_TASKS;
        lputroom(&qr);
 
        /* Set the view to a task list view */
        CtdlGetRelationship(&vbuf, &CC->user, &qr);
-       vbuf.v_view = 4;        /* 4 = tasks */
+       vbuf.v_view = VIEW_TASKS;
+       CtdlSetRelationship(&vbuf, &CC->user, &qr);
+
+       /* Create the notes room if it doesn't already exist */
+       create_room(USERNOTESROOM, 4, "", 0, 1, 0, VIEW_NOTES);
+
+       /* Set expiration policy to manual; otherwise objects will be lost! */
+       if (lgetroom(&qr, USERNOTESROOM)) {
+               lprintf(CTDL_CRIT, "Couldn't get the user calendar room!\n");
+               return;
+       }
+       qr.QRep.expire_mode = EXPIRE_MANUAL;
+       qr.QRdefaultview = VIEW_NOTES;
+       lputroom(&qr);
+
+       /* Set the view to a notes view */
+       CtdlGetRelationship(&vbuf, &CC->user, &qr);
+       vbuf.v_view = VIEW_NOTES;
        CtdlSetRelationship(&vbuf, &CC->user, &qr);
 
        return;
@@ -1651,38 +1663,57 @@ void ical_saving_vevent(icalcomponent *cal) {
  * the summary of the event (becomes message subject),
  * and the start time (becomes message date/time).
  */
-void ical_ctdl_set_extended_msgid(char *name, char *filename, char *partnum,
+void ical_ctdl_set_exclusive_msgid(char *name, char *filename, char *partnum,
                char *disp, void *content, char *cbtype, size_t length,
                char *encoding, void *cbuserdata)
 {
-       icalcomponent *cal;
+       icalcomponent *cal, *nested_event, *nested_todo;
        icalproperty *p;
        struct icalmessagemod *imm;
+       char new_uid[SIZ];
 
        imm = (struct icalmessagemod *)cbuserdata;
 
        /* If this is a text/calendar object, hunt for the UID and drop it in
         * the "user data" pointer for the MIME parser.  When
-        * ical_obj_beforesave() sees it there, it'll set the Extended msgid
+        * ical_obj_beforesave() sees it there, it'll set the Exclusive msgid
         * to that string.
         */
        if (!strcasecmp(cbtype, "text/calendar")) {
                cal = icalcomponent_new_from_string(content);
                if (cal != NULL) {
                        if (icalcomponent_isa(cal) == ICAL_VCALENDAR_COMPONENT) {
-                               cal = icalcomponent_get_first_component(
+                               nested_event = icalcomponent_get_first_component(
                                        cal, ICAL_VEVENT_COMPONENT
                                );
+                               nested_todo = icalcomponent_get_first_component(
+                                       cal, ICAL_VTODO_COMPONENT
+                               );
+                               if (nested_event != NULL) {
+                                       cal = nested_event;
+                               }
+                               else if (nested_todo != NULL) {
+                                       cal = nested_todo;
+                               }
                        }
                }
                if (cal != NULL) {
                        p = ical_ctdl_get_subprop(cal, ICAL_UID_PROPERTY);
+                       if (p == NULL) {
+                               /* If there's no uid we must generate one */
+                               generate_uuid(new_uid);
+                               icalcomponent_add_property(cal, icalproperty_new_uid(new_uid));
+                               p = ical_ctdl_get_subprop(cal, ICAL_UID_PROPERTY);
+                       }
                        if (p != NULL) {
                                strcpy(imm->uid, icalproperty_get_comment(p));
+                               strcpy(imm->subject,
+                                               icalproperty_get_comment(p));
                        }
                        p = ical_ctdl_get_subprop(cal, ICAL_SUMMARY_PROPERTY);
                        if (p != NULL) {
-                               strcpy(imm->subject,
+                               strcat(imm->subject, " ");
+                               strcat(imm->subject,
                                                icalproperty_get_comment(p));
                        }
                        p = ical_ctdl_get_subprop(cal, ICAL_DTSTART_PROPERTY);
@@ -1700,9 +1731,9 @@ void ical_ctdl_set_extended_msgid(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 the Calendar> room).  Also, when
- * saving an event to the calendar, set the message's Citadel extended message
- * ID to the UID of the object.  This causes our replication checker to
+ * MIME types other than text/calendar in "calendar" or "tasks"  rooms).  Also,
+ * when saving an event to the calendar, set the message's Citadel exclusive
+ * message ID to the UID of the object.  This causes our replication checker to
  * automatically delete any existing instances of the same object.  (Isn't
  * that cool?)
  *
@@ -1711,30 +1742,20 @@ void ical_ctdl_set_extended_msgid(char *name, char *filename, char *partnum,
  */
 int ical_obj_beforesave(struct CtdlMessage *msg)
 {
-       char roomname[ROOMNAMELEN];
        char *p;
        int a;
        struct icalmessagemod imm;
 
-       /*
-        * Only messages with content-type text/calendar
-        * may be saved to Calendar>.  If the message is bound for
-        * Calendar> but doesn't have this content-type, throw an error
-        * so that the message may not be posted.
-        */
-
-       /* First determine if this is our room */
-       MailboxName(roomname, sizeof roomname, &CC->user, USERCALENDARROOM);
-       if (strcasecmp(roomname, CC->room.QRname)) {
-               return 0;       /* It's not the Calendar room. */
+       /* First determine if this is a calendar or tasks room */
+       if ( (CC->curr_view != VIEW_CALENDAR)
+          &&(CC->curr_view != VIEW_TASKS) ) {
+               return(0);              /* Not a vCalendar-centric room */
        }
 
-       /* Then determine content-type of the message */
-       
        /* It must be an RFC822 message! */
-       /* FIXME: Not handling MIME multipart messages; implement with IMIP */
-       if (msg->cm_format_type != 4)
+       if (msg->cm_format_type != 4) {
                return 1;       /* You tried to save a non-RFC822 message! */
+       }
        
        /* Find the Content-Type: header */
        p = msg->cm_fields['M'];
@@ -1745,7 +1766,7 @@ int ical_obj_beforesave(struct CtdlMessage *msg)
                                memset(&imm, 0, sizeof(struct icalmessagemod));
                                mime_parser(msg->cm_fields['M'],
                                        NULL,
-                                       *ical_ctdl_set_extended_msgid,
+                                       *ical_ctdl_set_exclusive_msgid,
                                        NULL, NULL,
                                        (void *)&imm,
                                        0
@@ -1795,7 +1816,7 @@ void ical_obj_aftersave_backend(char *name, char *filename, char *partnum,
 
        /* If this is a text/calendar object, hunt for the UID and drop it in
         * the "user data" pointer for the MIME parser.  When
-        * ical_obj_beforesave() sees it there, it'll set the Extended msgid
+        * ical_obj_beforesave() sees it there, it'll set the Exclusive msgid
         * to that string.
         */
        if (!strcasecmp(cbtype, "text/calendar")) {
@@ -1862,10 +1883,14 @@ int ical_obj_aftersave(struct CtdlMessage *msg)
 
 
 void ical_session_startup(void) {
-       CtdlAllocUserData(SYM_CIT_ICAL, sizeof(struct cit_ical));
+       CIT_ICAL = malloc(sizeof(struct cit_ical));
        memset(CIT_ICAL, 0, sizeof(struct cit_ical));
 }
 
+void ical_session_shutdown(void) {
+       free(CIT_ICAL);
+}
+
 
 #endif /* CITADEL_WITH_CALENDAR_SERVICE */
 
@@ -1880,6 +1905,7 @@ char *serv_calendar_init(void)
        CtdlRegisterSessionHook(ical_create_room, EVT_LOGIN);
        CtdlRegisterProtoHook(cmd_ical, "ICAL", "Citadel iCal commands");
        CtdlRegisterSessionHook(ical_session_startup, EVT_START);
+       CtdlRegisterSessionHook(ical_session_shutdown, EVT_STOP);
 #endif
        return "$Id$";
 }