1 /* index.h -- Routines for dealing with the index file in the imapd
2  *
3  * Copyright (c) 1994-2008 Carnegie Mellon University.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in
14  *    the documentation and/or other materials provided with the
15  *    distribution.
16  *
17  * 3. The name "Carnegie Mellon University" must not be used to
18  *    endorse or promote products derived from this software without
19  *    prior written permission. For permission or any legal
20  *    details, please contact
21  *      Carnegie Mellon University
22  *      Center for Technology Transfer and Enterprise Creation
23  *      4615 Forbes Avenue
24  *      Suite 302
25  *      Pittsburgh, PA  15213
26  *      (412) 268-7393, fax: (412) 268-7395
27  *      innovation@andrew.cmu.edu
28  *
29  * 4. Redistributions of any form whatsoever must retain the following
30  *    acknowledgment:
31  *    "This product includes software developed by Computing Services
32  *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
33  *
34  * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
35  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
36  * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
37  * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
38  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
39  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
40  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
41  */
42 
43 /* Header for internal usage of index.c + programs that make raw access
44  * to index files */
45 
46 #ifndef INDEX_H
47 #define INDEX_H
48 
49 #include <config.h>
50 
51 #include <stdio.h>
52 #include <string.h>
53 #include <sys/types.h>
54 #include <sys/stat.h>
55 #include <fcntl.h>
56 #include <netinet/in.h>
57 
58 #include "annotate.h" /* for strlist functionality */
59 #include "search_engines.h"
60 #include "message_guid.h"
61 #include "sequence.h"
62 #include "strarray.h"
63 
64 /* Special "sort criteria" to load message-id and references/in-reply-to
65  * into msgdata array for threaders that need them.
66  */
67 #define LOAD_IDS        256
68 
69 /* client capabilities by ENABLE command */
70 extern unsigned client_capa;
71 
72 struct message;
73 
74 struct vanished_params {
75     unsigned long uidvalidity;
76     modseq_t modseq;
77     const char *match_seq;
78     const char *match_uid;
79     const char *sequence;
80     int uidvalidity_is_max;
81 };
82 
83 struct index_init {
84     const char *userid;
85     struct auth_state *authstate;
86     struct protstream *out;
87     int examine_mode;
88     int select;
89     int want_dav;
90     uint32_t want_mbtype;
91     int want_expunged;
92     struct vanished_params vanished;
93     struct seqset *vanishedlist;
94 };
95 
96 struct index_map {
97     modseq_t modseq;
98     modseq_t told_modseq;
99     uint32_t uid;
100     uint32_t recno;
101     uint32_t system_flags;
102     uint32_t cache_offset;
103     uint32_t user_flags[MAX_USER_FLAGS/32];
104     unsigned int isseen:1;
105     unsigned int isrecent:1;
106 };
107 
108 struct index_state {
109     struct mailbox *mailbox;
110     unsigned num_records;
111     unsigned oldexists;
112     unsigned exists;
113     unsigned long last_uid;
114     uint32_t generation; /* to notice repacks */
115     uint32_t uidvalidity; /* to notice delete/recreate */
116     modseq_t oldhighestmodseq;
117     modseq_t highestmodseq;
118     modseq_t delayed_modseq;
119     struct index_map *map;
120     unsigned mapsize;
121     int internalseen;
122     int skipped_expunge;
123     int seen_dirty;
124     int examining;
125     int myrights;
126     unsigned numrecent;
127     unsigned numunseen;
128     unsigned firstnotseen;
129     char *flagname[MAX_USER_FLAGS];
130     char *userid;
131     char *mboxname;
132     struct protstream *out;
133     struct auth_state *authstate;
134     int want_dav;
135     uint32_t want_mbtype;
136     int want_expunged;
137     unsigned num_expunged;
138 };
139 
140 struct copyargs {
141     struct index_record *records;
142     int nummsg;
143     int msgalloc;
144 };
145 
146 typedef struct msgdata {
147     struct search_folder *folder; /* search folder (can be NULL) */
148 
149     /* items from the index_record */
150     bit32 uid;                  /* UID for output purposes */
151     uint32_t msgno;             /* message number */
152     conversation_id_t cid;      /* conversation id */
153     strarray_t ref;             /* array of references */
154     time_t sentdate;            /* sent date & time of message
155                                    from Date: header (adjusted by time zone) */
156     time_t internaldate;        /* internaldate */
157     size_t size;                /* message size */
158     modseq_t modseq;            /* modseq of record*/
159     bit32 hasflag;              /* hasflag values (up to 32 of them) */
160     struct message_guid guid;   /* message guid */
161     uint32_t system_flags;      /* system flags */
162 
163     /* items from the conversations database */
164     modseq_t convmodseq;        /* modseq of conversation */
165     uint32_t convexists;        /* exists count of conversation */
166     uint32_t convsize;          /* total size of messages in conversation */
167     bit32 hasconvflag;          /* hasconvflag values (up to 32 of them) */
168 
169     uint32_t spamscore;         /* x-spam-score header */
170 
171     /* items from the cache record */
172     char *msgid;                /* message ID */
173     char *listid;               /* List-Id and Mailing-List fields */
174     char *contenttype;          /* all MIME Content-Types except multipart */
175     char *cc;                   /* local-part of first "cc" address */
176     char *from;                 /* local-part of first "from" address */
177     char *to;                   /* local-part of first "to" address */
178     char *displayfrom;          /* display-name of first "from" address */
179     char *displayto;            /* display-name of first "to" address */
180     char *xsubj;                /* extracted subject text */
181     unsigned xsubj_hash;        /* hash of extracted subject text */
182     int is_refwd;               /* is message a reply or forward? */
183     strarray_t annot;           /* array of annotation attribute values
184                                    (stored in order of sortcrit) */
185 } MsgData;
186 
187 typedef struct thread {
188     MsgData *msgdata;           /* message data */
189     struct thread *parent;      /* parent message */
190     struct thread *child;       /* first child message */
191     struct thread *next;        /* next sibling message */
192 } Thread;
193 
194 struct rootset {
195     Thread *root;
196     unsigned nroot;
197 };
198 
199 struct thread_algorithm {
200     const char *alg_name;
201     void (*threader)(struct index_state *state, unsigned *msgno_list,
202                      unsigned int nmsg, int usinguid);
203 };
204 
205 struct nntp_overview {
206     unsigned long uid;
207     char *subj;
208     char *from;
209     char *date;
210     char *msgid;
211     char *ref;
212     unsigned long bytes;
213     unsigned long lines;
214 };
215 
216 enum index_warmup_flags
217 {
218     WARMUP_INDEX            = (1<<0),
219     WARMUP_CONVERSATIONS    = (1<<1),
220     WARMUP_ANNOTATIONS      = (1<<2),
221     WARMUP_FOLDERSTATUS     = (1<<3),
222     WARMUP_SEARCH           = (1<<4),
223     WARMUP_ALL              = (~WARMUP_SEARCH)
224 };
225 
226 /* non-locking, non-updating - just do a fetch on the state
227  * we already have */
228 void index_fetchresponses(struct index_state *state,
229                                  struct seqset *seq,
230                                  int usinguid,
231                                  const struct fetchargs *fetchargs,
232                                  int *fetchedsomething);
233 extern int index_fetch(struct index_state *state,
234                        const char* sequence,
235                        int usinguid,
236                        const struct fetchargs* fetchargs,
237                        int* fetchedsomething);
238 extern int index_store(struct index_state *state,
239                        char *sequence,
240                        struct storeargs *storeargs);
241 extern int index_run_annotator(struct index_state *state,
242                                const char *sequence, int usinguid,
243                                struct namespace *namespace, int isadmin);
244 extern int index_warmup(struct mboxlist_entry *, unsigned int warmup_flags,
245                         struct seqset *uids);
246 extern int index_sort(struct index_state *state, const struct sortcrit *sortcrit,
247                       struct searchargs *searchargs, int usinguid);
248 extern int index_convsort(struct index_state *state, struct sortcrit *sortcrit,
249                       struct searchargs *searchargs,
250                       const struct windowargs * windowargs);
251 extern int index_convmultisort(struct index_state *state,
252                                struct sortcrit *sortcrit,
253                                struct searchargs *searchargs,
254                                const struct windowargs * windowargs);
255 extern int index_snippets(struct index_state *state,
256                           const struct snippetargs *snippetargs,
257                           struct searchargs *searchargs);
258 extern int index_convupdates(struct index_state *state, struct sortcrit *sortcrit,
259                       struct searchargs *searchargs,
260                       const struct windowargs * windowargs);
261 extern int index_thread(struct index_state *state, int algorithm,
262                         struct searchargs *searchargs, int usinguid);
263 extern int index_search(struct index_state *state,
264                         struct searchargs *searchargs,
265                         int usinguid);
266 extern int index_scan(struct index_state *state,
267                       const char *contents);
268 extern int index_copy(struct index_state *state,
269                       char *sequence,
270                       int usinguid,
271                       char *name,
272                       char **copyuidp,
273                       int nolink,
274                       struct namespace *namespace,
275                       int isadmin,
276                       int ismove,
277                       int ignorequota);
278 extern int find_thread_algorithm(char *arg);
279 
280 extern int index_open(const char *name, struct index_init *init,
281                       struct index_state **stateptr);
282 extern int index_open_mailbox(struct mailbox *mailbox, struct index_init *init,
283                               struct index_state **stateptr);
284 extern int index_refresh(struct index_state *state);
285 extern void index_checkflags(struct index_state *state, int print, int dirty);
286 extern void index_select(struct index_state *state, struct index_init *init);
287 extern int index_status(struct index_state *state, struct statusdata *sdata);
288 extern void index_release(struct index_state *state);
289 extern void index_close(struct index_state **stateptr);
290 extern uint32_t index_finduid(struct index_state *state, uint32_t uid);
291 extern uint32_t index_getuid(struct index_state *state, uint32_t msgno);
292 extern void index_tellchanges(struct index_state *state, int canexpunge,
293                               int printuid, int printmodseq);
294 extern modseq_t index_highestmodseq(struct index_state *state);
295 extern int index_check(struct index_state *state, int usinguid, int printuid);
296 extern struct seqset *index_vanished(struct index_state *state,
297                                     struct vanished_params *params);
298 extern int index_urlfetch(struct index_state *state, uint32_t msgno,
299                           unsigned params, const char *section,
300                           unsigned long start_octet, unsigned long octet_count,
301                           struct protstream *pout, unsigned long *size);
302 extern char *index_get_msgid(struct index_state *state, uint32_t msgno);
303 extern struct message *index_get_message(struct index_state *state, uint32_t msgno);
304 extern struct nntp_overview *index_overview(struct index_state *state,
305                                             uint32_t msgno);
306 extern char *index_getheader(struct index_state *state, uint32_t msgno,
307                              char *hdr);
308 extern unsigned long index_getsize(struct index_state *state, uint32_t msgno);
309 extern unsigned long index_getlines(struct index_state *state, uint32_t msgno);
310 extern int index_copy_remote(struct index_state *state, char *sequence,
311                              int usinguid, struct protstream *pout);
312 
313 struct searchargs *new_searchargs(const char *tag, int state,
314                                   struct namespace *namespace,
315                                   const char *userid,
316                                   struct auth_state *authstate,
317                                   int isadmin);
318 
319 void freesequencelist(struct seqset *l);
320 void freesearchargs(struct searchargs *s);
321 char *sortcrit_as_string(const struct sortcrit *sortcrit);
322 void freesortcrit(struct sortcrit *s);
323 void index_msgdata_sort(MsgData **msgdata, int n, const struct sortcrit *sortcrit);
324 void index_msgdata_free(MsgData **, unsigned int);
325 MsgData **index_msgdata_load(struct index_state *state, unsigned *msgno_list, int n,
326                              const struct sortcrit *sortcrit,
327                              unsigned int anchor, int *found_anchor);
328 extern int index_search_evaluate(struct index_state *state, const search_expr_t *e, uint32_t msgno);
329 
330 extern int index_expunge(struct index_state *state, char *uidsequence,
331                          int need_deleted);
332 
333 extern int index_getsearchtext(struct message *msg,
334                                struct search_text_receiver *receiver,
335                                int snippet);
336 
337 extern int index_getuidsequence(struct index_state *state,
338                                 struct searchargs *searchargs,
339                                 unsigned **uid_list);
340 
341 extern const char *index_mboxname(const struct index_state *state);
342 extern int index_hasrights(const struct index_state *state, int rights);
343 
344 extern int index_reload_record(struct index_state *state,
345                                uint32_t msgno,
346                                struct index_record *record);
347 
348 
349 #endif /* INDEX_H */
350