]> code.citadel.org Git - citadel.git/blob - citadel/imap_metadata.c
* Added new view type VIEW_JOURNAL - not yet used by
[citadel.git] / citadel / imap_metadata.c
1 /*
2  * $Id:  $
3  *
4  * IMAP METADATA extension
5  *
6  * This is a partial implementation of draft-daboo-imap-annotatemore-11
7  * intended to help a specific connector product work with Citadel.
8  *
9  */
10
11
12 #include "sysdep.h"
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include <stdio.h>
16 #include <fcntl.h>
17 #include <signal.h>
18 #include <pwd.h>
19 #include <errno.h>
20 #include <sys/types.h>
21
22 #if TIME_WITH_SYS_TIME
23 # include <sys/time.h>
24 # include <time.h>
25 #else
26 # if HAVE_SYS_TIME_H
27 #  include <sys/time.h>
28 # else
29 #  include <time.h>
30 # endif
31 #endif
32
33 #include <sys/wait.h>
34 #include <ctype.h>
35 #include <string.h>
36 #include <limits.h>
37 #include "citadel.h"
38 #include "server.h"
39 #include "sysdep_decls.h"
40 #include "citserver.h"
41 #include "support.h"
42 #include "config.h"
43 #include "serv_extensions.h"
44 #include "room_ops.h"
45 #include "user_ops.h"
46 #include "policy.h"
47 #include "database.h"
48 #include "msgbase.h"
49 #include "tools.h"
50 #include "internet_addressing.h"
51 #include "serv_imap.h"
52 #include "imap_tools.h"
53 #include "imap_fetch.h"
54 #include "imap_misc.h"
55 #include "genstamp.h"
56
57
58
59 /*
60  * Implements the SETMETADATA command.
61  *
62  * This is currently a stub which fools the client into thinking that there
63  * is no remaining space available to store annotations.
64  */
65 void imap_setmetadata(int num_parms, char *parms[]) {
66
67         cprintf("%s NO [METADATA TOOMANY] SETMETADATA failed\r\n", parms[0]);
68         return;
69 }
70
71
72 /*
73  * Implements the GETMETADATA command.
74  *
75  * This is currently a stub which returns no data, because we are not yet
76  * using any server annotations.
77  */
78 void imap_getmetadata(int num_parms, char *parms[]) {
79         char roomname[ROOMNAMELEN];
80         char savedroom[ROOMNAMELEN];
81         int msgs, new;
82         int ret;
83
84         if (num_parms > 5) {
85                 cprintf("%s BAD usage error\r\n", parms[0]);
86                 return;
87         }
88
89         ret = imap_grabroom(roomname, parms[2], 0);
90         if (ret != 0) {
91                 cprintf("%s NO Invalid mailbox name or access denied\r\n",
92                         parms[0]);
93                 return;
94         }
95
96         /*
97          * usergoto() formally takes us to the desired room.  (If another
98          * folder is selected, save its name so we can return there!!!!!)
99          */
100         if (IMAP->selected) {
101                 strcpy(savedroom, CC->room.QRname);
102         }
103         usergoto(roomname, 0, 0, &msgs, &new);
104
105         /*
106          * Ignore the client's request for a specific metadata.  Send them
107          * what we know: the Kolab-esque folder type.
108          */
109         cprintf("* METADATA ");
110         imap_strout(parms[2]);
111         cprintf(" \"/vendor/kolab/folder-type\" (\"value.shared\" \"");
112
113         /* If it's one of our hard-coded default rooms, we know what to do... */
114
115         if (!strcasecmp(&CC->room.QRname[11], MAILROOM)) {
116                 cprintf("mail.inbox");
117         }
118         else if (!strcasecmp(&CC->room.QRname[11], SENTITEMS)) {
119                 cprintf("mail.sentitems");
120         }
121         else if (!strcasecmp(&CC->room.QRname[11], USERCALENDARROOM)) {
122                 cprintf("event.default");
123         }
124         else if (!strcasecmp(&CC->room.QRname[11], USERCONTACTSROOM)) {
125                 cprintf("contact.default");
126         }
127         else if (!strcasecmp(&CC->room.QRname[11], USERNOTESROOM)) {
128                 cprintf("note.default");
129         }
130         else if (!strcasecmp(&CC->room.QRname[11], USERTASKSROOM)) {
131                 cprintf("task.default");
132         }
133
134         /* Otherwise, use the view for this room to determine the type of data.
135          * We are going with the default view rather than the user's view, because
136          * the default view almost always defines the actual contents, while the
137          * user's view might only make changes to presentation.  It also saves us
138          * an extra database access because we don't need to load the visit record.
139          */
140
141         else if (CC->room.QRdefaultview == VIEW_CALENDAR) {
142                 cprintf("event");
143         }
144         else if (CC->room.QRdefaultview == VIEW_ADDRESSBOOK) {
145                 cprintf("contact");
146         }
147         else if (CC->room.QRdefaultview == VIEW_TASKS) {
148                 cprintf("task");
149         }
150         else if (CC->room.QRdefaultview == VIEW_NOTES) {
151                 cprintf("note");
152         }
153         else if (CC->room.QRdefaultview == VIEW_JOURNAL) {
154                 cprintf("journal");
155         }
156
157         /* If none of the above conditions were met, consider it an ordinary mailbox. */
158         else {
159                 cprintf("mail");
160         }
161
162         /* "mail.outbox" and "junkemail" are not implemented. */
163
164         cprintf("\")\r\n");
165
166         /*
167          * If a different folder was previously selected, return there now.
168          */
169         if ( (IMAP->selected) && (strcasecmp(roomname, savedroom)) ) {
170                 usergoto(savedroom, 0, 0, &msgs, &new);
171         }
172
173         cprintf("%s OK GETMETADATA complete\r\n", parms[0]);
174         return;
175 }
176