]> code.citadel.org Git - citadel.git/blob - citadel/imap_store.c
* More of IMAP STORE. Works for \Deleted now, but we don't have EXPUNGE yet
[citadel.git] / citadel / imap_store.c
1 /*
2  * $Id$
3  *
4  * Implements the STORE command in IMAP.
5  *
6  */
7
8
9 #include "sysdep.h"
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <stdio.h>
13 #include <fcntl.h>
14 #include <signal.h>
15 #include <pwd.h>
16 #include <errno.h>
17 #include <sys/types.h>
18 #include <sys/time.h>
19 #include <sys/wait.h>
20 #include <ctype.h>
21 #include <string.h>
22 #include <limits.h>
23 #include "citadel.h"
24 #include "server.h"
25 #include <time.h>
26 #include "sysdep_decls.h"
27 #include "citserver.h"
28 #include "support.h"
29 #include "config.h"
30 #include "dynloader.h"
31 #include "room_ops.h"
32 #include "user_ops.h"
33 #include "policy.h"
34 #include "database.h"
35 #include "msgbase.h"
36 #include "tools.h"
37 #include "internet_addressing.h"
38 #include "serv_imap.h"
39 #include "imap_tools.h"
40 #include "imap_fetch.h"
41 #include "imap_store.h"
42 #include "genstamp.h"
43
44
45 /*
46  * imap_do_store() calls imap_do_store_msg() to output the deta of an
47  * individual message, once it has been successfully loaded from disk.
48  */
49 void imap_do_store_msg(int num, int num_items, char **itemlist) {
50         int i;
51         int flagbucket = 0;
52
53         /* at this point it should be down to "item (flags)" */
54         if (num_items < 2) return;
55
56         /* put together the flag bucket */
57         for (i=0; i<strlen(itemlist[1]); ++i) {
58                 if (!strncasecmp(&itemlist[1][i], "\\Deleted", 8))
59                         flagbucket |= IMAP_DELETED;
60         }
61
62         /*
63          * Figure out what to do and do it.  Brazenly IGnore the ".SILENT"
64          * option, since it is not illegal to output the data anyway.
65          */
66         if (!strncasecmp(itemlist[0], "FLAGS", 5)) {
67                 IMAP->flags[num] &= IMAP_INTERNAL_MASK;
68                 IMAP->flags[num] |= flagbucket;
69         }
70
71         if (!strncasecmp(itemlist[0], "+FLAGS", 6)) {
72                 IMAP->flags[num] |= flagbucket;
73         }
74
75         if (!strncasecmp(itemlist[0], "-FLAGS", 6)) {
76                 IMAP->flags[num] &= ~flagbucket;
77         }
78
79         /*
80          * Tell the client what happen (someone set up us the bomb!)
81          */
82         cprintf("* %d FETCH (", num+1); /* output sequence number */
83         imap_output_flags(num);
84         cprintf(")\r\n");
85 }
86
87
88
89 /*
90  * imap_store() calls imap_do_store() to do its actual work, once it's
91  * validated and boiled down the request a bit.
92  */
93 void imap_do_store(int num_items, char **itemlist, int is_uid) {
94         int i;
95
96         if (IMAP->num_msgs > 0) {
97                 for (i = 0; i < IMAP->num_msgs; ++i) {
98                         if (IMAP->flags[i] && IMAP_SELECTED) {
99                                 imap_do_store_msg(i, num_items, itemlist);
100                         }
101                 }
102         }
103 }
104
105
106 /*
107  * This function is called by the main command loop.
108  */
109 void imap_store(int num_parms, char *parms[]) {
110         char items[1024];
111         char *itemlist[256];
112         int num_items;
113         int i;
114
115         if (num_parms < 4) {
116                 cprintf("%s BAD invalid parameters\r\n", parms[0]);
117                 return;
118         }
119
120         if (imap_is_message_set(parms[2])) {
121                 imap_pick_range(parms[2], 0);
122         }
123         else {
124                 cprintf("%s BAD No message set specified to STORE\r\n",
125                         parms[0]);
126                 return;
127         }
128
129         strcpy(items, "");
130         for (i=3; i<num_parms; ++i) {
131                 strcat(items, parms[i]);
132                 if (i < (num_parms-1)) strcat(items, " ");
133         }
134
135         num_items = imap_extract_data_items(itemlist, items);
136         if (num_items < 1) {
137                 cprintf("%s BAD invalid data item list\r\n", parms[0]);
138                 return;
139         }
140
141         imap_do_store(num_items, itemlist, 0);
142         cprintf("%s OK STORE completed\r\n", parms[0]);
143 }
144
145 /*
146  * This function is called by the main command loop.
147  */
148 void imap_uidstore(int num_parms, char *parms[]) {
149         char items[1024];
150         char *itemlist[256];
151         int num_items;
152         int i;
153
154         if (num_parms < 5) {
155                 cprintf("%s BAD invalid parameters\r\n", parms[0]);
156                 return;
157         }
158
159         if (imap_is_message_set(parms[3])) {
160                 imap_pick_range(parms[3], 1);
161         }
162         else {
163                 cprintf("%s BAD No message set specified to STORE\r\n",
164                         parms[0]);
165                 return;
166         }
167
168         strcpy(items, "");
169         for (i=4; i<num_parms; ++i) {
170                 strcat(items, parms[i]);
171                 if (i < (num_parms-1)) strcat(items, " ");
172         }
173
174         num_items = imap_extract_data_items(itemlist, items);
175         if (num_items < 1) {
176                 cprintf("%s BAD invalid data item list\r\n", parms[0]);
177                 return;
178         }
179
180         imap_do_store(num_items, itemlist, 1);
181         cprintf("%s OK UID STORE completed\r\n", parms[0]);
182 }
183
184