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"
43 #include "serv_extensions.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"
60 * Implements the SETMETADATA command.
62 * This is currently a stub which fools the client into thinking that there
63 * is no remaining space available to store annotations.
65 void imap_setmetadata(int num_parms, char *parms[]) {
67 cprintf("%s NO [METADATA TOOMANY] SETMETADATA failed\r\n", parms[0]);
73 * Implements the GETMETADATA command.
75 * This is currently a stub which returns no data, because we are not yet
76 * using any server annotations.
78 void imap_getmetadata(int num_parms, char *parms[]) {
79 char roomname[ROOMNAMELEN];
80 char savedroom[ROOMNAMELEN];
85 cprintf("%s BAD usage error\r\n", parms[0]);
89 ret = imap_grabroom(roomname, parms[2], 0);
91 cprintf("%s NO Invalid mailbox name or access denied\r\n",
97 * usergoto() formally takes us to the desired room. (If another
98 * folder is selected, save its name so we can return there!!!!!)
100 if (IMAP->selected) {
101 strcpy(savedroom, CC->room.QRname);
103 usergoto(roomname, 0, 0, &msgs, &new);
106 * Ignore the client's request for a specific metadata. Send them
107 * what we know: the Kolab-esque folder type.
109 cprintf("* METADATA ");
110 imap_strout(parms[2]);
111 cprintf(" \"/vendor/kolab/folder-type\" (\"value.shared\" \"");
113 /* If it's one of our hard-coded default rooms, we know what to do... */
115 if (!strcasecmp(&CC->room.QRname[11], MAILROOM)) {
116 cprintf("mail.inbox");
118 else if (!strcasecmp(&CC->room.QRname[11], SENTITEMS)) {
119 cprintf("mail.sentitems");
121 else if (!strcasecmp(&CC->room.QRname[11], USERCALENDARROOM)) {
122 cprintf("event.default");
124 else if (!strcasecmp(&CC->room.QRname[11], USERCONTACTSROOM)) {
125 cprintf("contact.default");
127 else if (!strcasecmp(&CC->room.QRname[11], USERNOTESROOM)) {
128 cprintf("note.default");
130 else if (!strcasecmp(&CC->room.QRname[11], USERTASKSROOM)) {
131 cprintf("task.default");
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.
141 else if (CC->room.QRdefaultview == VIEW_CALENDAR) {
144 else if (CC->room.QRdefaultview == VIEW_ADDRESSBOOK) {
147 else if (CC->room.QRdefaultview == VIEW_TASKS) {
150 else if (CC->room.QRdefaultview == VIEW_NOTES) {
153 else if (CC->room.QRdefaultview == VIEW_JOURNAL) {
157 /* If none of the above conditions were met, consider it an ordinary mailbox. */
162 /* "mail.outbox" and "junkemail" are not implemented. */
167 * If a different folder was previously selected, return there now.
169 if ( (IMAP->selected) && (strcasecmp(roomname, savedroom)) ) {
170 usergoto(savedroom, 0, 0, &msgs, &new);
173 cprintf("%s OK GETMETADATA complete\r\n", parms[0]);