]> code.citadel.org Git - citadel.git/blob - citadel/imap_search.c
* Added a skeleton IMAP "SEARCH" command (based on the FETCH logic)
[citadel.git] / citadel / imap_search.c
1 /*
2  * $Id$
3  *
4  * Implements the SEARCH command in IMAP.
5  * This command is way too convoluted.  Marc Crispin is a fscking idiot.
6  *
7  */
8
9
10 #include "sysdep.h"
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <stdio.h>
14 #include <fcntl.h>
15 #include <signal.h>
16 #include <pwd.h>
17 #include <errno.h>
18 #include <sys/types.h>
19 #include <sys/time.h>
20 #include <sys/wait.h>
21 #include <ctype.h>
22 #include <string.h>
23 #include <limits.h>
24 #include "citadel.h"
25 #include "server.h"
26 #include <time.h>
27 #include "sysdep_decls.h"
28 #include "citserver.h"
29 #include "support.h"
30 #include "config.h"
31 #include "dynloader.h"
32 #include "room_ops.h"
33 #include "user_ops.h"
34 #include "policy.h"
35 #include "database.h"
36 #include "msgbase.h"
37 #include "tools.h"
38 #include "internet_addressing.h"
39 #include "mime_parser.h"
40 #include "serv_imap.h"
41 #include "imap_tools.h"
42 #include "imap_fetch.h"
43 #include "imap_search.h"
44 #include "genstamp.h"
45
46
47
48
49
50
51 /*
52  * imap_do_search() calls imap_do_search_msg() to output the deta of an
53  * individual message, once it has been successfully loaded from disk.
54  */
55 void imap_do_search_msg(int seq, struct CtdlMessage *msg,
56                         int num_items, char **itemlist, int is_uid) {
57
58         int is_valid = 0;
59
60         is_valid = 1;  /* FIXME ... replace with a real test */
61
62         /*
63          * If the message meets the specified search criteria, output its
64          * sequence number *or* UID, depending on what the client wants.
65          */
66         if (is_valid) {
67                 if (is_uid)     cprintf("%ld ", IMAP->msgids[seq-1]);
68                 else            cprintf("%d ", seq);
69         }
70
71 }
72
73
74
75 /*
76  * imap_search() calls imap_do_search() to do its actual work, once it's
77  * validated and boiled down the request a bit.
78  */
79 void imap_do_search(int num_items, char **itemlist, int is_uid) {
80         int i;
81         struct CtdlMessage *msg;
82
83         cprintf("* SEARCH ");
84         if (IMAP->num_msgs > 0)
85          for (i = 0; i < IMAP->num_msgs; ++i)
86           if (IMAP->flags[i] && IMAP_FETCHED) {
87                 msg = CtdlFetchMessage(IMAP->msgids[i]);
88                 if (msg != NULL) {
89                         imap_do_search_msg(i+1, msg, num_items,
90                                         itemlist, is_uid);
91                         CtdlFreeMessage(msg);
92                 }
93                 else {
94                         lprintf(1, "SEARCH internal error\n");
95                 }
96         }
97         cprintf("\r\n");
98 }
99
100
101 /*
102  * This function is called by the main command loop.
103  */
104 void imap_search(int num_parms, char *parms[]) {
105         char items[1024];
106         char *itemlist[256];
107         int num_items;
108         int i;
109
110         if (num_parms < 4) {
111                 cprintf("%s BAD invalid parameters\r\n", parms[0]);
112                 return;
113         }
114
115         imap_pick_range(parms[2], 0);
116
117         strcpy(items, "");
118         for (i=3; i<num_parms; ++i) {
119                 strcat(items, parms[i]);
120                 if (i < (num_parms-1)) strcat(items, " ");
121         }
122
123         num_items = imap_extract_data_items(itemlist, items);
124         if (num_items < 1) {
125                 cprintf("%s BAD invalid data item list\r\n", parms[0]);
126                 return;
127         }
128
129         imap_do_search(num_items, itemlist, 0);
130         cprintf("%s OK SEARCH completed\r\n", parms[0]);
131 }
132
133 /*
134  * This function is called by the main command loop.
135  */
136 void imap_uidsearch(int num_parms, char *parms[]) {
137         char items[1024];
138         char *itemlist[256];
139         int num_items;
140         int i;
141
142         if (num_parms < 5) {
143                 cprintf("%s BAD invalid parameters\r\n", parms[0]);
144                 return;
145         }
146
147         imap_pick_range(parms[3], 1);
148
149         strcpy(items, "");
150         for (i=4; i<num_parms; ++i) {
151                 strcat(items, parms[i]);
152                 if (i < (num_parms-1)) strcat(items, " ");
153         }
154
155         num_items = imap_extract_data_items(itemlist, items);
156         if (num_items < 1) {
157                 cprintf("%s BAD invalid data item list\r\n", parms[0]);
158                 return;
159         }
160
161         imap_do_search(num_items, itemlist, 1);
162         cprintf("%s OK UID SEARCH completed\r\n", parms[0]);
163 }
164
165