]> code.citadel.org Git - citadel.git/blob - citadel/serv_ical.c
8d4d5d58fbf1180011272cfed73fd209e546f1fc
[citadel.git] / citadel / serv_ical.c
1 /* 
2  * $Id$ 
3  *
4  * This module implements iCalendar object processing and the My Calendar>
5  * room on a Citadel/UX server.  It handles iCalendar objects using the
6  * iTIP protocol.  See RFCs 2445 and 2446.
7  *
8  */
9
10 #include "sysdep.h"
11 #include <unistd.h>
12 #include <sys/types.h>
13 #include <limits.h>
14 #include <stdio.h>
15 #include <string.h>
16 #ifdef HAVE_STRINGS_H
17 #include <strings.h>
18 #endif
19 #include "serv_ical.h"
20 #include "citadel.h"
21 #include "server.h"
22 #include "citserver.h"
23 #include "sysdep_decls.h"
24 #include "support.h"
25 #include "config.h"
26 #include "dynloader.h"
27 #include "user_ops.h"
28 #include "room_ops.h"
29
30
31 /* Tell clients what level of support to expect */
32 void cmd_ical(char *argbuf)
33 {
34         /* argbuf is not used */
35         if (!(CC->logged_in)) {
36                 cprintf("%d Not logged in.\n", ERROR+NOT_LOGGED_IN);
37                 return;
38         }
39
40         cprintf("%d I support|ICAL\n", OK);
41         return;
42 }
43
44
45 /* We don't know if the calendar room exists so we just create it at login */
46 void ical_create_room(void)
47 {
48         char roomname[ROOMNAMELEN];
49         struct quickroom qr;
50
51         /* Create the room if it doesn't already exist */
52         MailboxName(roomname, &CC->usersupp, USERCALENDARROOM);
53         create_room(roomname, 4, "", 0);
54         /* Set expiration policy to manual; otherwise objects will be lost! */
55         if (lgetroom(&qr, roomname)) {
56                 lprintf(3, "Couldn't get the user calendar room!\n");
57                 return;
58         }
59         qr.QRep.expire_mode = EXPIRE_MANUAL;
60         lputroom(&qr);
61         return;
62 }
63
64
65 /* User is reading a message */
66 int ical_obj_beforeread(struct CtdlMessage *msg)
67 {
68         return 0;
69 }
70
71
72 /* See if we need to prevent the object from being saved */
73 int ical_obj_beforesave(struct CtdlMessage *msg)
74 {
75         char roomname[ROOMNAMELEN];
76         char *p;
77         int a;
78         
79         /*
80          * Only messages with content-type text/calendar or text/x-calendar
81          * may be saved to My Calendar>.  If the message is bound for
82          * My Calendar> but doesn't have this content-type, throw an error
83          * so that the message may not be posted.
84          */
85
86         /* First determine if this is our room */
87         MailboxName(roomname, &CC->usersupp, USERCALENDARROOM);
88         if (strncmp(roomname, msg->cm_fields['O'], ROOMNAMELEN))
89                 return 0;       /* It's not us... */
90
91         /* Then determine content-type of the message */
92         
93         /* It must be an RFC822 message! */
94         /* FIXME: Not handling MIME multipart messages; implement with IMIP */
95         if (msg->cm_format_type != 4)
96                 return 1;       /* You tried to save a non-RFC822 message! */
97         
98         /* Find the Content-Type: header */
99         p = msg->cm_fields['M'];
100         a = strlen(p);
101         while (--a > 0) {
102                 if (!strncasecmp(p, "Content-Type: ", 14)) {    /* Found it */
103                         if (!strncasecmp(p + 14, "text/x-calendar", 15) ||
104                             !strncasecmp(p + 14, "text/calendar", 13))
105                                 return 0;
106                         else
107                                 return 1;
108                 }
109                 p++;
110         }
111         
112         /* Oops!  No Content-Type in this message!  How'd that happen? */
113         lprintf(7, "RFC822 message with no Content-Type header!\n");
114         return 1;
115 }
116
117
118 /* aftersave processing */
119 int ical_obj_aftersave(struct CtdlMessage *msg)
120 {
121         return 0;
122 }
123
124
125 /* Register this module with the Citadel server. */
126 char *Dynamic_Module_Init(void)
127 {
128         CtdlRegisterSessionHook(ical_create_room, EVT_LOGIN);
129         CtdlRegisterMessageHook(ical_obj_beforeread, EVT_BEFOREREAD);
130         CtdlRegisterMessageHook(ical_obj_beforesave, EVT_BEFORESAVE);
131         CtdlRegisterMessageHook(ical_obj_aftersave, EVT_AFTERSAVE);
132         CtdlRegisterProtoHook(cmd_ical, "ICAL", "Register iCalendar support");
133         return "$Id$";
134 }