4 * IMAP METADATA extension
6 * This is a partial implementation of draft-daboo-imap-annotatemore-11
7 * intended to help a specific connector product work with Citadel.
20 #include <sys/types.h>
22 #if TIME_WITH_SYS_TIME
23 # include <sys/time.h>
27 # include <sys/time.h>
39 #include "sysdep_decls.h"
40 #include "citserver.h"
49 #include "internet_addressing.h"
50 #include "serv_imap.h"
51 #include "imap_tools.h"
52 #include "imap_fetch.h"
53 #include "imap_misc.h"
59 * Implements the SETMETADATA command.
61 * Again, the only thing we're interested in setting here is the folder type.
63 * Attempting to set anything else calls a stub which fools the client into
64 * thinking that there is no remaining space available to store annotations.
66 void imap_setmetadata(int num_parms, char *parms[]) {
67 char roomname[ROOMNAMELEN];
68 char savedroom[ROOMNAMELEN];
71 int setting_user_value = 0;
75 cprintf("%s BAD usage error\r\n", parms[0]);
80 * Don't allow other types of metadata to be set
82 if (strcasecmp(parms[3], "/vendor/kolab/folder-type")) {
83 cprintf("%s NO [METADATA TOOMANY] SETMETADATA failed\r\n", parms[0]);
87 if (!strcasecmp(parms[4], "(value.shared")) {
88 setting_user_value = 0; /* global view */
90 else if (!strcasecmp(parms[4], "(value.priv")) {
91 setting_user_value = 1; /* per-user view */
94 cprintf("%s NO [METADATA TOOMANY] SETMETADATA failed\r\n", parms[0]);
99 * Extract the folder type without any parentheses.
101 extract_token(set_value, parms[5], 0, ')', sizeof set_value);
103 ret = imap_grabroom(roomname, parms[2], 0);
105 cprintf("%s NO Invalid mailbox name or access denied\r\n",
111 * usergoto() formally takes us to the desired room. (If another
112 * folder is selected, save its name so we can return there!!!!!)
114 if (IMAP->selected) {
115 strcpy(savedroom, CC->room.QRname);
117 usergoto(roomname, 0, 0, &msgs, &new);
120 * FIXME ... NOW DO SOMETHING
124 * on success: cprintf("%s OK SETANNOTATION complete\r\n", parms[0]);
127 cprintf("%s NO [METADATA TOOMANY] SETMETADATA failed\r\n", parms[0]);
130 * If a different folder was previously selected, return there now.
132 if ( (IMAP->selected) && (strcasecmp(roomname, savedroom)) ) {
133 usergoto(savedroom, 0, 0, &msgs, &new);
140 * Implements the GETMETADATA command.
142 * Regardless of what the client asked for, we are going to supply them with
143 * the folder type. It's the only metadata we have anyway.
145 void imap_getmetadata(int num_parms, char *parms[]) {
146 char roomname[ROOMNAMELEN];
147 char savedroom[ROOMNAMELEN];
152 cprintf("%s BAD usage error\r\n", parms[0]);
156 ret = imap_grabroom(roomname, parms[2], 0);
158 cprintf("%s NO Invalid mailbox name or access denied\r\n",
164 * usergoto() formally takes us to the desired room. (If another
165 * folder is selected, save its name so we can return there!!!!!)
167 if (IMAP->selected) {
168 strcpy(savedroom, CC->room.QRname);
170 usergoto(roomname, 0, 0, &msgs, &new);
172 cprintf("* METADATA ");
173 imap_strout(parms[2]);
174 cprintf(" \"/vendor/kolab/folder-type\" (\"value.shared\" \"");
176 /* If it's one of our hard-coded default rooms, we know what to do... */
178 if (!strcasecmp(&CC->room.QRname[11], MAILROOM)) {
179 cprintf("mail.inbox");
181 else if (!strcasecmp(&CC->room.QRname[11], SENTITEMS)) {
182 cprintf("mail.sentitems");
184 else if (!strcasecmp(&CC->room.QRname[11], USERCALENDARROOM)) {
185 cprintf("event.default");
187 else if (!strcasecmp(&CC->room.QRname[11], USERCONTACTSROOM)) {
188 cprintf("contact.default");
190 else if (!strcasecmp(&CC->room.QRname[11], USERNOTESROOM)) {
191 cprintf("note.default");
193 else if (!strcasecmp(&CC->room.QRname[11], USERTASKSROOM)) {
194 cprintf("task.default");
197 /* Otherwise, use the view for this room to determine the type of data.
198 * We are going with the default view rather than the user's view, because
199 * the default view almost always defines the actual contents, while the
200 * user's view might only make changes to presentation. It also saves us
201 * an extra database access because we don't need to load the visit record.
204 else if (CC->room.QRdefaultview == VIEW_CALENDAR) {
207 else if (CC->room.QRdefaultview == VIEW_ADDRESSBOOK) {
210 else if (CC->room.QRdefaultview == VIEW_TASKS) {
213 else if (CC->room.QRdefaultview == VIEW_NOTES) {
216 else if (CC->room.QRdefaultview == VIEW_JOURNAL) {
220 /* If none of the above conditions were met, consider it an ordinary mailbox. */
225 /* "mail.outbox" and "junkemail" are not implemented. */
230 * If a different folder was previously selected, return there now.
232 if ( (IMAP->selected) && (strcasecmp(roomname, savedroom)) ) {
233 usergoto(savedroom, 0, 0, &msgs, &new);
236 cprintf("%s OK GETMETADATA complete\r\n", parms[0]);