fc40923abb200a753887c7bbc426a5ec28a6add2
[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 "serv_imap.h"
40 #include "imap_tools.h"
41 #include "imap_fetch.h"
42 #include "imap_search.h"
43 #include "genstamp.h"
44
45
46
47
48
49
50 /*
51  * imap_do_search() calls imap_do_search_msg() to output the deta of an
52  * individual message, once it has been successfully loaded from disk.
53  */
54 void imap_do_search_msg(int seq, struct CtdlMessage *msg,
55                         int num_items, char **itemlist, int is_uid) {
56
57         int is_valid = 0;
58
59         is_valid = 1;  /* FIXME ... replace with a real test */
60
61         /*
62          * If the message meets the specified search criteria, output its
63          * sequence number *or* UID, depending on what the client wants.
64          */
65         if (is_valid) {
66                 if (is_uid)     cprintf("%ld ", IMAP->msgids[seq-1]);
67                 else            cprintf("%d ", seq);
68         }
69
70 }
71
72
73
74 /*
75  * imap_search() calls imap_do_search() to do its actual work, once it's
76  * validated and boiled down the request a bit.
77  */
78 void imap_do_search(int num_items, char **itemlist, int is_uid) {
79         int i;
80         struct CtdlMessage *msg;
81
82         cprintf("* SEARCH ");
83         if (IMAP->num_msgs > 0)
84          for (i = 0; i < IMAP->num_msgs; ++i)
85           if (IMAP->flags[i] && IMAP_SELECTED) {
86                 msg = CtdlFetchMessage(IMAP->msgids[i]);
87                 if (msg != NULL) {
88                         imap_do_search_msg(i+1, msg, num_items,
89                                         itemlist, is_uid);
90                         CtdlFreeMessage(msg);
91                 }
92                 else {
93                         lprintf(1, "SEARCH internal error\n");
94                 }
95         }
96         cprintf("\r\n");
97 }
98
99
100 /*
101  * This function is called by the main command loop.
102  */
103 void imap_search(int num_parms, char *parms[]) {
104         char items[1024];
105         char *itemlist[256];
106         int num_items;
107         int i;
108
109         if (num_parms < 3) {
110                 cprintf("%s BAD invalid parameters\r\n", parms[0]);
111                 return;
112         }
113
114         for (i=1; i<num_parms; ++i) {
115                 if (imap_is_message_set(parms[i])) {
116                         imap_pick_range(parms[i], 0);
117                 }
118         }
119
120         strcpy(items, "");
121         for (i=2; i<num_parms; ++i) {
122                 strcat(items, parms[i]);
123                 if (i < (num_parms-1)) strcat(items, " ");
124         }
125
126         num_items = imap_extract_data_items(itemlist, items);
127         if (num_items < 1) {
128                 cprintf("%s BAD invalid data item list\r\n", parms[0]);
129                 return;
130         }
131
132         imap_do_search(num_items, itemlist, 0);
133         cprintf("%s OK SEARCH completed\r\n", parms[0]);
134 }
135
136 /*
137  * This function is called by the main command loop.
138  */
139 void imap_uidsearch(int num_parms, char *parms[]) {
140         char items[1024];
141         char *itemlist[256];
142         int num_items;
143         int i;
144
145         if (num_parms < 4) {
146                 cprintf("%s BAD invalid parameters\r\n", parms[0]);
147                 return;
148         }
149
150         for (i=1; i<num_parms; ++i) {
151                 if (imap_is_message_set(parms[i])) {
152                         imap_pick_range(parms[i], 1);
153                 }
154         }
155
156         strcpy(items, "");
157         for (i=4; i<num_parms; ++i) {
158                 strcat(items, parms[i]);
159                 if (i < (num_parms-1)) strcat(items, " ");
160         }
161
162         num_items = imap_extract_data_items(itemlist, items);
163         if (num_items < 1) {
164                 cprintf("%s BAD invalid data item list\r\n", parms[0]);
165                 return;
166         }
167
168         imap_do_search(num_items, itemlist, 1);
169         cprintf("%s OK UID SEARCH completed\r\n", parms[0]);
170 }
171
172