* Renamed "dynloader" to "serv_extensions" globally. We don't want people
[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
20 #if TIME_WITH_SYS_TIME
21 # include <sys/time.h>
22 # include <time.h>
23 #else
24 # if HAVE_SYS_TIME_H
25 #  include <sys/time.h>
26 # else
27 #  include <time.h>
28 # endif
29 #endif
30
31 #include <sys/wait.h>
32 #include <ctype.h>
33 #include <string.h>
34 #include <limits.h>
35 #include "citadel.h"
36 #include "server.h"
37 #include "sysdep_decls.h"
38 #include "citserver.h"
39 #include "support.h"
40 #include "config.h"
41 #include "serv_extensions.h"
42 #include "room_ops.h"
43 #include "user_ops.h"
44 #include "policy.h"
45 #include "database.h"
46 #include "msgbase.h"
47 #include "tools.h"
48 #include "internet_addressing.h"
49 #include "serv_imap.h"
50 #include "imap_tools.h"
51 #include "imap_fetch.h"
52 #include "imap_search.h"
53 #include "genstamp.h"
54
55
56
57
58
59
60 /*
61  * imap_do_search() calls imap_do_search_msg() to output the deta of an
62  * individual message, once it has been successfully loaded from disk.
63  */
64 void imap_do_search_msg(int seq, struct CtdlMessage *msg,
65                         int num_items, char **itemlist, int is_uid) {
66
67         int is_valid = 0;
68
69         /*** FIXME ***
70          * We haven't written the search command logic yet.  Instead we
71          * simply return every message as valid.  This will probably surprise
72          * some users.  Could someone out there please be the hero of the
73          * century and write this function?
74          */
75         is_valid = 1;
76
77         /*
78          * If the message meets the specified search criteria, output its
79          * sequence number *or* UID, depending on what the client wants.
80          */
81         if (is_valid) {
82                 if (is_uid)     cprintf("%ld ", IMAP->msgids[seq-1]);
83                 else            cprintf("%d ", seq);
84         }
85
86 }
87
88
89
90 /*
91  * imap_search() calls imap_do_search() to do its actual work, once it's
92  * validated and boiled down the request a bit.
93  */
94 void imap_do_search(int num_items, char **itemlist, int is_uid) {
95         int i;
96         struct CtdlMessage *msg;
97
98         cprintf("* SEARCH ");
99         if (IMAP->num_msgs > 0)
100          for (i = 0; i < IMAP->num_msgs; ++i)
101           if (IMAP->flags[i] && IMAP_SELECTED) {
102                 msg = CtdlFetchMessage(IMAP->msgids[i]);
103                 if (msg != NULL) {
104                         imap_do_search_msg(i+1, msg, num_items,
105                                         itemlist, is_uid);
106                         CtdlFreeMessage(msg);
107                 }
108                 else {
109                         lprintf(1, "SEARCH internal error\n");
110                 }
111         }
112         cprintf("\r\n");
113 }
114
115
116 /*
117  * This function is called by the main command loop.
118  */
119 void imap_search(int num_parms, char *parms[]) {
120         char items[1024];
121         char *itemlist[256];
122         int num_items;
123         int i;
124
125         if (num_parms < 3) {
126                 cprintf("%s BAD invalid parameters\r\n", parms[0]);
127                 return;
128         }
129
130         for (i=1; i<num_parms; ++i) {
131                 if (imap_is_message_set(parms[i])) {
132                         imap_pick_range(parms[i], 0);
133                 }
134         }
135
136         strcpy(items, "");
137         for (i=2; i<num_parms; ++i) {
138                 strcat(items, parms[i]);
139                 if (i < (num_parms-1)) strcat(items, " ");
140         }
141
142         num_items = imap_extract_data_items(itemlist, items);
143         if (num_items < 1) {
144                 cprintf("%s BAD invalid data item list\r\n", parms[0]);
145                 return;
146         }
147
148         imap_do_search(num_items, itemlist, 0);
149         cprintf("%s OK SEARCH completed\r\n", parms[0]);
150 }
151
152 /*
153  * This function is called by the main command loop.
154  */
155 void imap_uidsearch(int num_parms, char *parms[]) {
156         char items[1024];
157         char *itemlist[256];
158         int num_items;
159         int i;
160
161         if (num_parms < 4) {
162                 cprintf("%s BAD invalid parameters\r\n", parms[0]);
163                 return;
164         }
165
166         for (i=1; i<num_parms; ++i) {
167                 if (imap_is_message_set(parms[i])) {
168                         imap_pick_range(parms[i], 1);
169                 }
170         }
171
172         strcpy(items, "");
173         for (i=4; i<num_parms; ++i) {
174                 strcat(items, parms[i]);
175                 if (i < (num_parms-1)) strcat(items, " ");
176         }
177
178         num_items = imap_extract_data_items(itemlist, items);
179         if (num_items < 1) {
180                 cprintf("%s BAD invalid data item list\r\n", parms[0]);
181                 return;
182         }
183
184         imap_do_search(num_items, itemlist, 1);
185         cprintf("%s OK UID SEARCH completed\r\n", parms[0]);
186 }
187
188