1 #ifndef MAILDIR_UIDLIST_H 2 #define MAILDIR_UIDLIST_H 3 4 #include "mail-storage.h" 5 6 #define MAILDIR_UIDLIST_NAME "dovecot-uidlist" 7 /* how many seconds to wait before overriding uidlist.lock */ 8 #define MAILDIR_UIDLIST_LOCK_STALE_TIMEOUT (60*2) 9 10 struct maildir_mailbox; 11 struct maildir_uidlist; 12 struct maildir_uidlist_sync_ctx; 13 struct maildir_uidlist_rec; 14 15 enum maildir_uidlist_sync_flags { 16 MAILDIR_UIDLIST_SYNC_PARTIAL = 0x01, 17 MAILDIR_UIDLIST_SYNC_KEEP_STATE = 0x02, 18 MAILDIR_UIDLIST_SYNC_FORCE = 0x04, 19 MAILDIR_UIDLIST_SYNC_TRYLOCK = 0x08, 20 MAILDIR_UIDLIST_SYNC_NOREFRESH = 0x10, 21 MAILDIR_UIDLIST_SYNC_NOLOCK = 0x20 22 }; 23 24 enum maildir_uidlist_rec_flag { 25 MAILDIR_UIDLIST_REC_FLAG_NEW_DIR = 0x01, 26 MAILDIR_UIDLIST_REC_FLAG_MOVED = 0x02, 27 MAILDIR_UIDLIST_REC_FLAG_RECENT = 0x04, 28 MAILDIR_UIDLIST_REC_FLAG_NONSYNCED = 0x08, 29 MAILDIR_UIDLIST_REC_FLAG_RACING = 0x10 30 }; 31 32 enum maildir_uidlist_hdr_ext_key { 33 MAILDIR_UIDLIST_HDR_EXT_UID_VALIDITY = 'V', 34 MAILDIR_UIDLIST_HDR_EXT_NEXT_UID = 'N', 35 MAILDIR_UIDLIST_HDR_EXT_GUID = 'G', 36 /* POP3 UIDL format unless overridden by records */ 37 MAILDIR_UIDLIST_HDR_EXT_POP3_UIDL_FORMAT = 'P' 38 }; 39 40 #define MAILDIR_UIDLIST_REC_EXT_KEY_IS_VALID(c) \ 41 ((c) >= 'A' && (c) <= 'Z') 42 enum maildir_uidlist_rec_ext_key { 43 /* Physical message size. If filename also contains ,S=<vsize> this 44 isn't written to uidlist. */ 45 MAILDIR_UIDLIST_REC_EXT_PSIZE = 'S', 46 /* Virtual message size. If filename also contains ,W=<vsize> this 47 isn't written to uidlist. */ 48 MAILDIR_UIDLIST_REC_EXT_VSIZE = 'W', 49 /* POP3 UIDL overriding the default format */ 50 MAILDIR_UIDLIST_REC_EXT_POP3_UIDL = 'P', 51 /* POP3 message ordering number. Lower numbered messages are listed 52 first. Messages without ordering number are listed after them. 53 The idea is to be able to preserve POP3 UIDL list and IMAP UIDs 54 perfectly when migrating from other servers. */ 55 MAILDIR_UIDLIST_REC_EXT_POP3_ORDER = 'O', 56 /* Message GUID (default is the base filename) */ 57 MAILDIR_UIDLIST_REC_EXT_GUID = 'G' 58 }; 59 60 int maildir_uidlist_lock(struct maildir_uidlist *uidlist); 61 int maildir_uidlist_try_lock(struct maildir_uidlist *uidlist); 62 int maildir_uidlist_lock_touch(struct maildir_uidlist *uidlist); 63 void maildir_uidlist_unlock(struct maildir_uidlist *uidlist); 64 bool maildir_uidlist_is_locked(struct maildir_uidlist *uidlist); 65 bool maildir_uidlist_is_read(struct maildir_uidlist *uidlist); 66 /* Returns TRUE if uidlist file is currently open */ 67 bool maildir_uidlist_is_open(struct maildir_uidlist *uidlist); 68 69 struct maildir_uidlist *maildir_uidlist_init(struct maildir_mailbox *mbox); 70 void maildir_uidlist_deinit(struct maildir_uidlist **uidlist); 71 72 /* Returns -1 if error, 0 if file is broken or lost, 1 if ok. If nfs_flush=TRUE 73 and storage has NFS_FLUSH flag set, the NFS attribute cache is flushed to 74 make sure that we see the latest uidlist file. */ 75 int maildir_uidlist_refresh(struct maildir_uidlist *uidlist); 76 /* Like maildir_uidlist_refresh(), but if uidlist isn't opened yet, try to 77 fill in the uidvalidity/nextuid from index file instead. */ 78 int maildir_uidlist_refresh_fast_init(struct maildir_uidlist *uidlist); 79 80 /* Look up uidlist record for given filename. Returns 1 if found, 81 0 if not found, -1 if error */ 82 int maildir_uidlist_lookup(struct maildir_uidlist *uidlist, uint32_t uid, 83 enum maildir_uidlist_rec_flag *flags_r, 84 const char **fname_r); 85 /* Returns extension's value or NULL if it doesn't exist. */ 86 const char * 87 maildir_uidlist_lookup_ext(struct maildir_uidlist *uidlist, uint32_t uid, 88 enum maildir_uidlist_rec_ext_key key); 89 90 uint32_t maildir_uidlist_get_uid_validity(struct maildir_uidlist *uidlist); 91 uint32_t maildir_uidlist_get_next_uid(struct maildir_uidlist *uidlist); 92 int maildir_uidlist_get_mailbox_guid(struct maildir_uidlist *uidlist, 93 guid_128_t mailbox_guid); 94 void maildir_uidlist_set_mailbox_guid(struct maildir_uidlist *uidlist, 95 const guid_128_t mailbox_guid); 96 97 void maildir_uidlist_set_uid_validity(struct maildir_uidlist *uidlist, 98 uint32_t uid_validity); 99 void maildir_uidlist_set_next_uid(struct maildir_uidlist *uidlist, 100 uint32_t next_uid, bool force); 101 102 /* Update extended record. */ 103 void maildir_uidlist_set_ext(struct maildir_uidlist *uidlist, uint32_t uid, 104 enum maildir_uidlist_rec_ext_key key, 105 const char *value); 106 void maildir_uidlist_unset_ext(struct maildir_uidlist *uidlist, uint32_t uid, 107 enum maildir_uidlist_rec_ext_key key); 108 109 /* If uidlist has changed, update it. This is mostly meant to be used with 110 maildir_uidlist_set_ext() */ 111 int maildir_uidlist_update(struct maildir_uidlist *uidlist); 112 113 void maildir_uidlist_set_all_nonsynced(struct maildir_uidlist *uidlist); 114 /* Sync uidlist with what's actually on maildir. Returns same as 115 maildir_uidlist_lock(). */ 116 int maildir_uidlist_sync_init(struct maildir_uidlist *uidlist, 117 enum maildir_uidlist_sync_flags sync_flags, 118 struct maildir_uidlist_sync_ctx **sync_ctx_r); 119 int maildir_uidlist_sync_next(struct maildir_uidlist_sync_ctx *ctx, 120 const char *filename, 121 enum maildir_uidlist_rec_flag flags); 122 int maildir_uidlist_sync_next_uid(struct maildir_uidlist_sync_ctx *ctx, 123 const char *filename, uint32_t uid, 124 enum maildir_uidlist_rec_flag flags, 125 struct maildir_uidlist_rec **rec_r); 126 void maildir_uidlist_sync_remove(struct maildir_uidlist_sync_ctx *ctx, 127 const char *filename); 128 void maildir_uidlist_sync_set_ext(struct maildir_uidlist_sync_ctx *ctx, 129 struct maildir_uidlist_rec *rec, 130 enum maildir_uidlist_rec_ext_key key, 131 const char *value); 132 void maildir_uidlist_update_fname(struct maildir_uidlist *uidlist, 133 const char *filename); 134 const char * 135 maildir_uidlist_sync_get_full_filename(struct maildir_uidlist_sync_ctx *ctx, 136 const char *filename); 137 void maildir_uidlist_sync_recreate(struct maildir_uidlist_sync_ctx *ctx); 138 void maildir_uidlist_sync_finish(struct maildir_uidlist_sync_ctx *ctx); 139 int maildir_uidlist_sync_deinit(struct maildir_uidlist_sync_ctx **ctx, 140 bool success); 141 142 bool maildir_uidlist_get_uid(struct maildir_uidlist *uidlist, 143 const char *filename, uint32_t *uid_r); 144 const char * 145 maildir_uidlist_get_full_filename(struct maildir_uidlist *uidlist, 146 const char *filename); 147 148 void maildir_uidlist_add_flags(struct maildir_uidlist *uidlist, 149 const char *filename, 150 enum maildir_uidlist_rec_flag flags); 151 152 /* List all maildir files. */ 153 struct maildir_uidlist_iter_ctx * 154 maildir_uidlist_iter_init(struct maildir_uidlist *uidlist); 155 bool maildir_uidlist_iter_next(struct maildir_uidlist_iter_ctx *ctx, 156 uint32_t *uid_r, 157 enum maildir_uidlist_rec_flag *flags_r, 158 const char **filename_r); 159 void maildir_uidlist_iter_deinit(struct maildir_uidlist_iter_ctx **ctx); 160 161 #endif 162