fix all the <time.h> vs. <sys/time.h> issues, hopefully
[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 "dynloader.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         is_valid = 1;  /* FIXME ... replace with a real test */
70
71         /*
72          * If the message meets the specified search criteria, output its
73          * sequence number *or* UID, depending on what the client wants.
74          */
75         if (is_valid) {
76                 if (is_uid)     cprintf("%ld ", IMAP->msgids[seq-1]);
77                 else            cprintf("%d ", seq);
78         }
79
80 }
81
82
83
84 /*
85  * imap_search() calls imap_do_search() to do its actual work, once it's
86  * validated and boiled down the request a bit.
87  */
88 void imap_do_search(int num_items, char **itemlist, int is_uid) {
89         int i;
90         struct CtdlMessage *msg;
91
92         cprintf("* SEARCH ");
93         if (IMAP->num_msgs > 0)
94          for (i = 0; i < IMAP->num_msgs; ++i)
95           if (IMAP->flags[i] && IMAP_SELECTED) {
96                 msg = CtdlFetchMessage(IMAP->msgids[i]);
97                 if (msg != NULL) {
98                         imap_do_search_msg(i+1, msg, num_items,
99                                         itemlist, is_uid);
100                         CtdlFreeMessage(msg);
101                 }
102                 else {
103                         lprintf(1, "SEARCH internal error\n");
104                 }
105         }
106         cprintf("\r\n");
107 }
108
109
110 /*
111  * This function is called by the main command loop.
112  */
113 void imap_search(int num_parms, char *parms[]) {
114         char items[1024];
115         char *itemlist[256];
116         int num_items;
117         int i;
118
119         if (num_parms < 3) {
120                 cprintf("%s BAD invalid parameters\r\n", parms[0]);
121                 return;
122         }
123
124         for (i=1; i<num_parms; ++i) {
125                 if (imap_is_message_set(parms[i])) {
126                         imap_pick_range(parms[i], 0);
127                 }
128         }
129
130         strcpy(items, "");
131         for (i=2; i<num_parms; ++i) {
132                 strcat(items, parms[i]);
133                 if (i < (num_parms-1)) strcat(items, " ");
134         }
135
136         num_items = imap_extract_data_items(itemlist, items);
137         if (num_items < 1) {
138                 cprintf("%s BAD invalid data item list\r\n", parms[0]);
139                 return;
140         }
141
142         imap_do_search(num_items, itemlist, 0);
143         cprintf("%s OK SEARCH completed\r\n", parms[0]);
144 }
145
146 /*
147  * This function is called by the main command loop.
148  */
149 void imap_uidsearch(int num_parms, char *parms[]) {
150         char items[1024];
151         char *itemlist[256];
152         int num_items;
153         int i;
154
155         if (num_parms < 4) {
156                 cprintf("%s BAD invalid parameters\r\n", parms[0]);
157                 return;
158         }
159
160         for (i=1; i<num_parms; ++i) {
161                 if (imap_is_message_set(parms[i])) {
162                         imap_pick_range(parms[i], 1);
163                 }
164         }
165
166         strcpy(items, "");
167         for (i=4; i<num_parms; ++i) {
168                 strcat(items, parms[i]);
169                 if (i < (num_parms-1)) strcat(items, " ");
170         }
171
172         num_items = imap_extract_data_items(itemlist, items);
173         if (num_items < 1) {
174                 cprintf("%s BAD invalid data item list\r\n", parms[0]);
175                 return;
176         }
177
178         imap_do_search(num_items, itemlist, 1);
179         cprintf("%s OK UID SEARCH completed\r\n", parms[0]);
180 }
181
182