Codebase list cyrus-imapd / debian/3.0.12-1 imap / mailbox.h
debian/3.0.12-1

Tree @debian/3.0.12-1 (Download .tar.gz)

mailbox.h @debian/3.0.12-1raw · history · blame

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
/* mailbox.h -- Mailbox format definitions
 *
 * Copyright (c) 1994-2008 Carnegie Mellon University.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The name "Carnegie Mellon University" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For permission or any legal
 *    details, please contact
 *      Carnegie Mellon University
 *      Center for Technology Transfer and Enterprise Creation
 *      4615 Forbes Avenue
 *      Suite 302
 *      Pittsburgh, PA  15213
 *      (412) 268-7393, fax: (412) 268-7395
 *      innovation@andrew.cmu.edu
 *
 * 4. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by Computing Services
 *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
 *
 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef INCLUDED_MAILBOX_H
#define INCLUDED_MAILBOX_H

#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#include <config.h>

#include "byteorder64.h"
#include "conversations.h"
#include "message_guid.h"
#include "message.h"
#include "ptrarray.h"
#include "quota.h"
#include "sequence.h"
#include "util.h"

#define MAX_MAILBOX_NAME 490
/* enough space for all possible rewrites and DELETED.* and stuff */
#define MAX_MAILBOX_BUFFER 1024
#define MAX_MAILBOX_PATH 4096

#define MAX_USER_FLAGS (16*8)

#define MAILBOX_HEADER_MAGIC ("\241\002\213\015Cyrus mailbox header\n" \
     "\"The best thing about this system was that it had lots of goals.\"\n" \
     "\t--Jim Morris on Andrew\n")


/* NOTE: the mailbox minor version must be changed whenever any on-disk
 * format changes are made to any mailbox files.  It is also important to
 * make sure all the mailbox upgrade and downgrade code in mailbox.c is
 * changed to be able to convert both backwards and forwards between the
 * new version and all supported previous versions */
#define MAILBOX_MINOR_VERSION   13
#define MAILBOX_CACHE_MINOR_VERSION 6

#define FNAME_HEADER "/cyrus.header"
#define FNAME_INDEX "/cyrus.index"
#define FNAME_CACHE "/cyrus.cache"
#define FNAME_SQUAT "/cyrus.squat"
#define FNAME_EXPUNGE "/cyrus.expunge"
#ifdef WITH_DAV
#define FNAME_DAV "/cyrus.dav"
#endif
#define FNAME_ANNOTATIONS "/cyrus.annotations"

enum meta_filename {
  META_HEADER = 1,
  META_INDEX,
  META_CACHE,
  META_SQUAT,
  META_EXPUNGE,
  META_ANNOTATIONS,
#ifdef WITH_DAV
  META_DAV,
#endif
  META_ARCHIVECACHE
};

#define MAILBOX_FNAME_LEN 256

#define LOCK_NONE 0
#define LOCK_SHARED 1
#define LOCK_EXCLUSIVE 2
#define LOCK_NONBLOCK   4   /* flag to OR in */
#define LOCK_NONBLOCKING (LOCK_NONBLOCK|LOCK_EXCLUSIVE)

#define NUM_CACHE_FIELDS 10

struct cacheitem {
    unsigned offset;
    unsigned len;
};

struct cacherecord {
    const struct buf *buf;
    unsigned offset;
    unsigned len;
    struct cacheitem item[NUM_CACHE_FIELDS];
};

struct statusdata {
    const char *userid;
    unsigned statusitems;

    uint32_t messages;
    uint32_t recent;
    uint32_t uidnext;
    uint32_t uidvalidity;
    uint32_t unseen;
    modseq_t highestmodseq;
    conv_status_t xconv;
};

#define STATUSDATA_INIT { NULL, 0, 0, 0, 0, 0, 0, 0, CONV_STATUS_INIT }

struct index_record {
    uint32_t uid;
    time_t internaldate;
    time_t sentdate;
    uint32_t size;
    uint32_t header_size;
    time_t gmtime;
    uint32_t cache_offset;
    time_t last_updated;
    uint32_t system_flags;
    uint32_t user_flags[MAX_USER_FLAGS/32];
    uint32_t content_lines;
    uint32_t cache_version;
    struct message_guid guid;
    modseq_t modseq;
    bit64 cid;
    bit32 cache_crc;

    /* metadata */
    uint32_t recno;
    int silent;
    struct cacherecord crec;
};

struct synccrcs {
    uint32_t basic;
    uint32_t annot;
};

struct index_header {
    /* track if it's been changed */
    int dirty;

    /* header fields */
    bit32 generation_no;
    int format;
    int minor_version;
    uint32_t start_offset;
    uint32_t record_size;
    uint32_t num_records;
    time_t last_appenddate;
    uint32_t last_uid;
    quota_t quota_mailbox_used;
    time_t pop3_last_login;
    uint32_t uidvalidity;

    uint32_t deleted;
    uint32_t answered;
    uint32_t flagged;

    uint32_t options;
    uint32_t leaked_cache_records;
    modseq_t highestmodseq;
    modseq_t deletedmodseq;
    uint32_t exists;
    time_t first_expunged;
    time_t last_repack_time;

    bit32 header_file_crc;
    struct synccrcs synccrcs;

    uint32_t recentuid;
    time_t recenttime;

    time_t pop3_show_after;
    quota_t quota_annot_used;
};

#define CHANGE_ISAPPEND (1<<0)
#define CHANGE_WASEXPUNGED (1<<1)
#define CHANGE_WASUNLINKED (1<<2)

struct index_change {
    struct index_record record;
    uint32_t mapnext;
    uint32_t flags;
};

#define INDEX_MAP_SIZE 65536

struct mailbox {
    int index_fd;
    int header_fd;

    ptrarray_t caches;
    const char *index_base;
    size_t index_len;   /* mapped size */

    int index_locktype; /* 0 = none, 1 = shared, 2 = exclusive */
    int is_readonly; /* true = open index and cache files readonly */

    ino_t header_file_ino;
    bit32 header_file_crc;

    time_t index_mtime;
    ino_t index_ino;
    size_t index_size;

    /* Information in mailbox list */
    char *name;
    uint32_t mbtype;
    char *part;
    char *acl;

    struct index_header i;

    /* Information in header */
    char *uniqueid;
    char *quotaroot;
    char *flagname[MAX_USER_FLAGS];

    struct timeval starttime;

    /* annotations */
    struct annotate_state *annot_state;

    /* conversations */
    struct conversations_state *local_cstate;

#ifdef WITH_DAV
    struct caldav_db *local_caldav;
    struct carddav_db *local_carddav;
    struct webdav_db *local_webdav;
#endif

    /* change management */
    int silentchanges;
    int modseq_dirty;
    int header_dirty;
    int quota_dirty;
    int has_changed;
    time_t last_updated; /* for appends*/
    quota_t quota_previously_used[QUOTA_NUMRESOURCES]; /* for quota change */

    /* index change map */
    uint32_t index_change_map[INDEX_MAP_SIZE];
    struct index_change *index_changes;
    uint32_t index_change_alloc;
    uint32_t index_change_count;
};

#define ITER_SKIP_UNLINKED (1<<0)
#define ITER_SKIP_EXPUNGED (1<<1)
#define ITER_SKIP_DELETED (1<<2)

/* pre-declare message_t to avoid circular dependency problems */
typedef struct message message_t;

struct mailbox_iter {
    struct mailbox *mailbox;
    message_t *msg;
    modseq_t changedsince;
    uint32_t recno;
    uint32_t num_records;
    unsigned skipflags;
};

/* Offsets of index/expunge header fields
 *
 * NOTE: Since we might be using a 64-bit MODSEQ in the index record,
 *       the size of the index header MUST be a multiple of 8 bytes.
 */
#define OFFSET_GENERATION_NO 0
#define OFFSET_FORMAT 4
#define OFFSET_MINOR_VERSION 8
#define OFFSET_START_OFFSET 12
#define OFFSET_RECORD_SIZE 16
#define OFFSET_NUM_RECORDS 20
#define OFFSET_LAST_APPENDDATE 24
#define OFFSET_LAST_UID 28
#define OFFSET_QUOTA_MAILBOX_USED 32  /* offset for 64bit quotas */
#define OFFSET_POP3_LAST_LOGIN 40
#define OFFSET_UIDVALIDITY 44
#define OFFSET_DELETED 48      /* added for ACAP */
#define OFFSET_ANSWERED 52
#define OFFSET_FLAGGED 56
#define OFFSET_MAILBOX_OPTIONS 60
#define OFFSET_LEAKED_CACHE 64     /* Number of leaked records in cache file */
#define OFFSET_HIGHESTMODSEQ 68    /* CONDSTORE (64-bit modseq) */
#define OFFSET_DELETEDMODSEQ 76    /* CONDSTORE (64-bit modseq) */
#define OFFSET_EXISTS 84           /* Non-expunged records */
#define OFFSET_FIRST_EXPUNGED 88   /* last_updated of oldest expunged message */
#define OFFSET_LAST_REPACK_TIME 92 /* time of last expunged cleanup  */
#define OFFSET_HEADER_FILE_CRC 96  /* CRC32 of the index header file */
#define OFFSET_SYNCCRCS_BASIC 100  /* XOR of SYNC CRCs of unexpunged records */
#define OFFSET_RECENTUID 104       /* last UID the owner was told about */
#define OFFSET_RECENTTIME 108      /* last timestamp for seen data */
#define OFFSET_POP3_SHOW_AFTER 112 /* time after which to show messages
                                    * to POP3 */
#define OFFSET_QUOTA_ANNOT_USED 116 /* bytes of per-mailbox and per-message
                                     * annotations for this mailbox */
                          /* Spares - only use these if the index */
                          /*  record size remains the same */
#define OFFSET_SYNCCRCS_ANNOT 120 /* SYNC_CRC of the annotations */
#define OFFSET_HEADER_CRC 124 /* includes all zero for the spares! */
/* NEXT UPDATE - add Bug #3562 "TOTAL_MAILBOX_USED" field, 64 bit
 * value which counts the total size of all files included expunged
 * files.  This will need a header size change, hence putting it off */

/* Offsets of index_record fields in index/expunge file
 *
 * NOTE: Since we might be using a 64-bit MODSEQ in the index record,
 *       OFFSET_MODSEQ_64 and the size of the index record MUST be
 *       multiples of 8 bytes.
 */
#define OFFSET_UID 0
#define OFFSET_INTERNALDATE 4
#define OFFSET_SENTDATE 8
#define OFFSET_SIZE 12
#define OFFSET_HEADER_SIZE 16
#define OFFSET_GMTIME 20
#define OFFSET_CACHE_OFFSET 24
#define OFFSET_LAST_UPDATED 28
#define OFFSET_SYSTEM_FLAGS 32
#define OFFSET_USER_FLAGS 36
#define OFFSET_CONTENT_LINES 52 /* added for nntpd */
#define OFFSET_CACHE_VERSION 56
#define OFFSET_MESSAGE_GUID 60
#define OFFSET_MODSEQ 80 /* CONDSTORE (64-bit modseq) */
#define OFFSET_THRID 88       /* conversation id, added in v13 */
#define OFFSET_CACHE_CRC 96 /* CRC32 of cache record */
#define OFFSET_RECORD_CRC 100

#define INDEX_HEADER_SIZE (OFFSET_HEADER_CRC+4)
#define INDEX_RECORD_SIZE (OFFSET_RECORD_CRC+4)

#define FLAG_ANSWERED (1<<0)
#define FLAG_FLAGGED (1<<1)
#define FLAG_DELETED (1<<2)
#define FLAG_DRAFT (1<<3)
#define FLAG_SEEN (1<<4)
#define FLAG_NEEDS_CLEANUP (1<<28)
#define FLAG_ARCHIVED (1<<29)
#define FLAG_UNLINKED (1<<30)
#define FLAG_EXPUNGED (1U<<31)

#define FLAGS_SYSTEM   (FLAG_ANSWERED|FLAG_FLAGGED|FLAG_DELETED|FLAG_DRAFT|FLAG_SEEN)
#define FLAGS_INTERNAL (FLAG_NEEDS_CLEANUP|FLAG_ARCHIVED|FLAG_UNLINKED|FLAG_EXPUNGED)
/* for replication */
#define FLAGS_LOCAL    (FLAG_NEEDS_CLEANUP|FLAG_ARCHIVED|FLAG_UNLINKED)
#define FLAGS_GLOBAL   (FLAGS_SYSTEM|FLAG_EXPUNGED)

#define OPT_POP3_NEW_UIDL (1<<0)        /* added for Outlook stupidity */
/* NOTE: not used anymore - but don't reuse it */
#define OPT_IMAP_CONDSTORE (1<<1)       /* added for CONDSTORE extension */

/* these two are annotations, if you add more, update annotate.c
 * struct annotate_mailbox_flags */
#define OPT_IMAP_SHAREDSEEN (1<<2)      /* added for shared \Seen flag */
#define OPT_IMAP_DUPDELIVER (1<<3)      /* added to allow duplicate delivery */
#define OPT_MAILBOX_NEEDS_UNLINK (1<<29)        /* files to be unlinked */
#define OPT_MAILBOX_NEEDS_REPACK (1<<30)        /* repacking to do */
#define OPT_MAILBOX_DELETED (1U<<31)    /* mailbox is deleted an awaiting cleanup */

#define MAILBOX_OPTIONS_MASK (OPT_POP3_NEW_UIDL | \
                              OPT_IMAP_SHAREDSEEN | \
                              OPT_IMAP_DUPDELIVER)
#define MAILBOX_CLEANUP_MASK (OPT_MAILBOX_NEEDS_UNLINK | \
                              OPT_MAILBOX_NEEDS_REPACK | \
                              OPT_MAILBOX_DELETED)
#define MAILBOX_OPT_VALID (MAILBOX_OPTIONS_MASK | \
                           MAILBOX_CLEANUP_MASK)

/* reconstruct flags */
#define RECONSTRUCT_QUIET           (1<<1)
#define RECONSTRUCT_MAKE_CHANGES    (1<<2)
#define RECONSTRUCT_DO_STAT         (1<<3)
#define RECONSTRUCT_ALWAYS_PARSE    (1<<4)
#define RECONSTRUCT_GUID_REWRITE    (1<<5)
#define RECONSTRUCT_GUID_UNLINK     (1<<6)
#define RECONSTRUCT_REMOVE_ODDFILES (1<<7)
#define RECONSTRUCT_IGNORE_ODDFILES (1<<8)
#define RECONSTRUCT_PREFER_MBOXLIST (1<<9)

struct mailbox_header_cache {
    const char *name; /* Name of header */
    bit32 min_cache_version; /* Cache version it appeared in */
};

#define MAX_CACHED_HEADER_SIZE 32 /* Max size of a cached header name */
extern const struct mailbox_header_cache mailbox_cache_headers[];
extern const int MAILBOX_NUM_CACHE_HEADERS;

/* Aligned buffer for manipulating index header/record fields */
typedef union {
    unsigned char buf[INDEX_HEADER_SIZE > INDEX_RECORD_SIZE ?
                      INDEX_HEADER_SIZE : INDEX_RECORD_SIZE];
    bit64 align8; /* align on 8-byte boundary */
} indexbuffer_t;

/* Access assistance macros for memory-mapped cache file data */
/* CACHE_ITEM_BIT32: Convert to host byte order */
/* CACHE_ITEM_LEN: Get the length out */
/* CACHE_ITEM_NEXT: Return a pointer to the next entry.  Sizes are
 * 4-byte aligned, so round up to the next 4 byte boundry */
#define CACHE_ITEM_BIT32(ptr) (ntohl(*((bit32 *)(ptr))))
#define CACHE_ITEM_LEN(ptr) CACHE_ITEM_BIT32(ptr)
#define CACHE_ITEM_NEXT(ptr) ((ptr)+4+((3+CACHE_ITEM_LEN(ptr))&~3))

/* Size of a bit32 to skip when jumping over cache item sizes */
#define CACHE_ITEM_SIZE_SKIP sizeof(bit32)

/* Cache item positions */
enum {
    CACHE_ENVELOPE = 0,
    CACHE_BODYSTRUCTURE,
    CACHE_BODY,
    CACHE_SECTION,
    CACHE_HEADERS,
    CACHE_FROM,
    CACHE_TO,
    CACHE_CC,
    CACHE_BCC,
    CACHE_SUBJECT
};

/* Cached envelope token positions */
enum {
    ENV_DATE = 0,
    ENV_SUBJECT,
    ENV_FROM,
    ENV_SENDER,
    ENV_REPLYTO,
    ENV_TO,
    ENV_CC,
    ENV_BCC,
    ENV_INREPLYTO,
    ENV_MSGID
};
#define NUMENVTOKENS (10)

unsigned mailbox_cached_header(const char *s);
unsigned mailbox_cached_header_inline(const char *text);

typedef unsigned mailbox_decideproc_t(struct mailbox *mailbox,
                                      const struct index_record *index,
                                      void *rock);

typedef void mailbox_notifyproc_t(const char *mboxname);

extern void mailbox_set_updatenotifier(mailbox_notifyproc_t *notifyproc);
extern mailbox_notifyproc_t *mailbox_get_updatenotifier(void);

/* file names on disk */
#define META_FNAME_NEW 1
extern const char *mailbox_meta_fname(struct mailbox *mailbox, int metafile);
extern const char *mailbox_meta_newfname(struct mailbox *mailbox, int metafile);
extern int mailbox_meta_rename(struct mailbox *mailbox, int metafile);

extern const char *mailbox_record_fname(struct mailbox *mailbox,
                                        const struct index_record *record);
extern const char *mailbox_datapath(struct mailbox *mailbox, uint32_t uid);
extern unsigned mailbox_should_archive(struct mailbox *mailbox,
                                       const struct index_record *record,
                                       void *rock);

/* map individual messages in */
extern int mailbox_map_record(struct mailbox *mailbox, const struct index_record *record, struct buf *buf);

/* cache record API */
int mailbox_cacherecord(struct mailbox *mailbox,
                        const struct index_record *record);
char *mailbox_cache_get_env(struct mailbox *mailbox,
                            const struct index_record *record,
                            int field);

/* field-based lookup functions */
const char *cacheitem_base(const struct index_record *record, int field);
unsigned cacheitem_size(const struct index_record *record, int field);
struct buf *cacheitem_buf(const struct index_record *record, int field);

/* opening and closing */
extern int mailbox_open_iwl(const char *name,
                            struct mailbox **mailboxptr);
extern int mailbox_open_irlnb(const char *name, struct mailbox **);
extern int mailbox_open_irl(const char *name,
                            struct mailbox **mailboxptr);
extern int mailbox_open_exclusive(const char *name,
                                  struct mailbox **mailboxptr);
extern void mailbox_close(struct mailbox **mailboxptr);
extern int mailbox_delete(struct mailbox **mailboxptr);

struct caldav_db *mailbox_open_caldav(struct mailbox *mailbox);
struct carddav_db *mailbox_open_carddav(struct mailbox *mailbox);
struct webdav_db *mailbox_open_webdav(struct mailbox *mailbox);

/* reading bits and pieces */
extern int mailbox_refresh_index_header(struct mailbox *mailbox);
extern int mailbox_write_header(struct mailbox *mailbox, int force);
extern void mailbox_index_dirty(struct mailbox *mailbox);
extern modseq_t mailbox_modseq_dirty(struct mailbox *mailbox);
extern int mailbox_reload_index_record(struct mailbox *mailbox,
                                     struct index_record *record);
extern int mailbox_rewrite_index_record(struct mailbox *mailbox,
                                        struct index_record *record);
extern int mailbox_append_index_record(struct mailbox *mailbox,
                                       struct index_record *record);
extern int mailbox_find_index_record(struct mailbox *mailbox, uint32_t uid,
                                     struct index_record *record);

extern int mailbox_set_acl(struct mailbox *mailbox, const char *acl,
                           int dirty_modseq);
extern int mailbox_set_quotaroot(struct mailbox *mailbox, const char *quotaroot);
extern int mailbox_user_flag(struct mailbox *mailbox, const char *flag,
                             int *flagnum, int create);
extern int mailbox_remove_user_flag(struct mailbox *mailbox, int flagnum);
extern int mailbox_record_hasflag(struct mailbox *mailbox,
                                  const struct index_record *record,
                                  const char *flag);
extern strarray_t *mailbox_extract_flags(const struct mailbox *mailbox,
                                         const struct index_record *record,
                                         const char *userid);
extern struct entryattlist *mailbox_extract_annots(const struct mailbox *mailbox,
                                                   const struct index_record *record);
extern int mailbox_commit(struct mailbox *mailbox);
extern int mailbox_abort(struct mailbox *mailbox);

/* seen state check */
extern int mailbox_internal_seen(const struct mailbox *mailbox, const char *userid);

extern unsigned mailbox_count_unseen(struct mailbox *mailbox);

/* index locking operations */
extern int mailbox_lock_index(struct mailbox *mailbox, int locktype);
extern int mailbox_index_islocked(struct mailbox *mailbox, int write);

extern int mailbox_expunge_cleanup(struct mailbox *mailbox, time_t expunge_mark,
                                   unsigned *ndeleted);
extern int mailbox_expunge(struct mailbox *mailbox,
                           mailbox_decideproc_t *decideproc, void *deciderock,
                           unsigned *nexpunged, int event_type);
extern void mailbox_archive(struct mailbox *mailbox,
                            mailbox_decideproc_t *decideproc, void *deciderock, unsigned flags);
extern void mailbox_remove_files_from_object_storage(struct mailbox *mailbox, unsigned flags);
extern int mailbox_cleanup(struct mailbox *mailbox, int iscurrentdir,
                           mailbox_decideproc_t *decideproc, void *deciderock);
extern void mailbox_unlock_index(struct mailbox *mailbox, struct statusdata *sd);
/* unlock and immediately lock again with the same type */
extern int mailbox_yield_index(struct mailbox *mailbox);

extern int mailbox_create(const char *name, uint32_t mbtype, const char *part, const char *acl,
                          const char *uniqueid, int options, unsigned uidvalidity,
                          modseq_t highestmodseq,
                          struct mailbox **mailboxptr);

extern int mailbox_copy_files(struct mailbox *mailbox, const char *newpart,
                              const char *newname, const char *newuniqueid);
extern int mailbox_delete_cleanup(struct mailbox *mailbox, const char *part, const char *name, const char *uniqueid);

extern int mailbox_rename_copy(struct mailbox *oldmailbox,
                               const char *newname, const char *newpart,
                               unsigned uidvalidity,
                               const char *userid, int ignorequota,
                               struct mailbox **newmailboxptr);
extern int mailbox_rename_cleanup(struct mailbox **mailboxptr, int isinbox);


extern int mailbox_copyfile(const char *from, const char *to, int nolink);

extern int mailbox_reconstruct(const char *name, int flags);
extern void mailbox_make_uniqueid(struct mailbox *mailbox);

extern int mailbox_setversion(struct mailbox *mailbox, int version);

extern int mailbox_index_recalc(struct mailbox *mailbox);

#define mailbox_quota_check(mailbox, delta) \
        (mailbox->quotaroot ? quota_check_useds((mailbox)->quotaroot, delta) : 0)
void mailbox_get_usage(struct mailbox *mailbox,
                        quota_t usage[QUOTA_NUMRESOURCES]);
void mailbox_annot_changed(struct mailbox *mailbox,
                           unsigned int uid,
                           const char *entry,
                           const char *userid,
                           const struct buf *oldval,
                           const struct buf *newval);

extern int mailbox_get_annotate_state(struct mailbox *mailbox,
                                      unsigned int uid,
                                      struct annotate_state **statep);

extern int mailbox_annotation_write(struct mailbox *mailbox, uint32_t uid,
                                    const char *entry, const char *userid,
                                    const struct buf *value);

extern int mailbox_annotation_writemask(struct mailbox *mailbox, uint32_t uid,
                                        const char *entry, const char *userid,
                                        const struct buf *value);

extern int mailbox_annotation_lookup(struct mailbox *mailbox, uint32_t uid,
                                     const char *entry, const char *userid,
                                     struct buf *value);


extern int mailbox_annotation_lookupmask(struct mailbox *mailbox, uint32_t uid,
                                         const char *entry, const char *userid,
                                         struct buf *value);

extern struct mailbox_iter *mailbox_iter_init(struct mailbox *mailbox,
                                              modseq_t changedsince,
                                              unsigned flags);
extern void mailbox_iter_startuid(struct mailbox_iter *iter, uint32_t uid);
extern const message_t *mailbox_iter_step(struct mailbox_iter *iter);
extern void mailbox_iter_done(struct mailbox_iter **iterp);

struct synccrcs mailbox_synccrcs(struct mailbox *mailbox, int recalc);

extern int mailbox_add_dav(struct mailbox *mailbox);

/* Rename a CID.  Note - this is just one mailbox! */
extern int mailbox_cid_rename(struct mailbox *mailbox,
                              conversation_id_t from_cid,
                              conversation_id_t to_cid);
extern int mailbox_add_conversations(struct mailbox *mailbox);
extern int mailbox_get_xconvmodseq(struct mailbox *mailbox, modseq_t *);
extern int mailbox_update_xconvmodseq(struct mailbox *mailbox, modseq_t, int force);
extern int mailbox_has_conversations(struct mailbox *mailbox);

extern struct conversations_state *mailbox_get_cstate(struct mailbox *mailbox);


#endif /* INCLUDED_MAILBOX_H */