4 * Implements the LIST and LSUB commands.
6 * Copyright (C) 2000-2007 by Art Cancro and others.
7 * This code is released under the terms of the GNU General Public License.
19 #include <sys/types.h>
21 #if TIME_WITH_SYS_TIME
22 # include <sys/time.h>
26 # include <sys/time.h>
38 #include "sysdep_decls.h"
39 #include "citserver.h"
42 #include "serv_extensions.h"
49 #include "internet_addressing.h"
50 #include "serv_imap.h"
51 #include "imap_tools.h"
52 #include "imap_fetch.h"
53 #include "imap_search.h"
54 #include "imap_store.h"
56 #include "imap_misc.h"
59 #include "serv_crypto.h"
63 * Used by LIST and LSUB to show the floors in the listing
65 void imap_list_floors(char *verb, char *pattern)
70 for (i = 0; i < MAXFLOORS; ++i) {
72 if (fl->f_flags & F_INUSE) {
73 if (imap_mailbox_matches_pattern
74 (pattern, fl->f_name)) {
75 cprintf("* %s (\\NoSelect) \"/\" ", verb);
76 imap_strout(fl->f_name);
85 * Back end for imap_list()
87 * Implementation note: IMAP "subscribed folder" is equivalent to Citadel "known room"
89 * The "user data" field is actually an array of pointers; see below for the breakdown
92 void imap_list_listroom(struct ctdlroom *qrbuf, void *data)
96 int yes_output_this_room;
98 char **data_for_callback;
101 int subscribed_rooms_only;
103 /* Here's how we break down the array of pointers passed to us */
104 data_for_callback = data;
105 pattern = data_for_callback[0];
106 verb = data_for_callback[1];
107 subscribed_rooms_only = (int) data_for_callback[2];
109 /* Only list rooms to which the user has access!! */
110 yes_output_this_room = 0;
111 CtdlRoomAccess(qrbuf, &CC->user, &ra, NULL);
113 if (subscribed_rooms_only) {
115 yes_output_this_room = 1;
119 if ((ra & UA_KNOWN) || ((ra & UA_GOTOALLOWED) && (ra & UA_ZAPPED))) {
120 yes_output_this_room = 1;
124 if (yes_output_this_room) {
125 imap_mailboxname(buf, sizeof buf, qrbuf);
126 if (imap_mailbox_matches_pattern(pattern, buf)) {
127 cprintf("* %s () \"/\" ", verb);
136 * Implements the LIST and LSUB commands
138 void imap_list(int num_parms, char *parms[])
141 int subscribed_rooms_only = 0;
144 char *data_for_callback[3];
147 cprintf("%s BAD arguments invalid\r\n", parms[0]);
151 /* parms[1] is the IMAP verb being used (e.g. LIST or LSUB)
152 * This tells us how to behave, and what verb to return back to the caller
154 safestrncpy(verb, parms[1], sizeof verb);
156 for (i=0; i<j; ++i) {
157 verb[i] = toupper(verb[i]);
160 if (!strcasecmp(verb, "LSUB")) {
161 subscribed_rooms_only = 1;
165 * In order to implement draft-ietf-imapext-list-extensions-18
166 * ("LIST Command Extensions") we need to:
167 * 1. Extract "selection options"
168 * 2. Extract "return options"
169 * 3. Determine whether there is more than one match pattern
172 /* Citadel does not yet implement the abovementioned extension, and
173 * therefore the root and pattern will always be in these positions.
175 snprintf(pattern, sizeof pattern, "%s%s", parms[2], parms[3]);
177 data_for_callback[0] = pattern;
178 data_for_callback[1] = verb;
179 data_for_callback[2] = (char *) subscribed_rooms_only;
181 if (strlen(parms[3]) == 0) {
182 cprintf("* %s (\\Noselect) \"/\" \"\"\r\n", verb);
186 imap_list_floors(verb, pattern);
187 ForEachRoom(imap_list_listroom, data_for_callback);
190 cprintf("%s OK %s completed\r\n", parms[0], verb);