1 #ifndef MAIL_STORAGE_H
2 #define MAIL_STORAGE_H
3 
4 struct message_size;
5 
6 #include "seq-range-array.h"
7 #include "file-lock.h"
8 #include "guid.h"
9 #include "mail-types.h"
10 #include "mail-error.h"
11 #include "mail-index.h"
12 #include "mail-namespace.h"
13 #include "mailbox-list.h"
14 #include "mailbox-attribute.h"
15 
16 /* If some operation is taking long, call notify_ok every n seconds. */
17 #define MAIL_STORAGE_STAYALIVE_SECS 15
18 
19 #define MAIL_KEYWORD_HAS_ATTACHMENT "$HasAttachment"
20 #define MAIL_KEYWORD_HAS_NO_ATTACHMENT "$HasNoAttachment"
21 
22 enum mail_storage_flags {
23 	/* Remember message headers' MD5 sum */
24 	MAIL_STORAGE_FLAG_KEEP_HEADER_MD5	= 0x01,
25 	/* Don't try to autodetect anything, require that the given data
26 	   contains all the necessary information. */
27 	MAIL_STORAGE_FLAG_NO_AUTODETECTION	= 0x02,
28 	/* Don't autocreate any directories. If they don't exist,
29 	   fail to create the storage. */
30 	MAIL_STORAGE_FLAG_NO_AUTOCREATE		= 0x04,
31 	/* Don't verify existence or accessibility of any directories.
32 	   Create the storage in any case. */
33 	MAIL_STORAGE_FLAG_NO_AUTOVERIFY		= 0x08
34 };
35 
36 enum mailbox_flags {
37 	/* Mailbox must not be modified even if asked */
38 	MAILBOX_FLAG_READONLY		= 0x01,
39 	/* Only saving/copying mails to mailbox works. */
40 	MAILBOX_FLAG_SAVEONLY		= 0x02,
41 	/* Remove MAIL_RECENT flags when syncing */
42 	MAILBOX_FLAG_DROP_RECENT	= 0x04,
43 	/* Don't create index files for the mailbox */
44 	MAILBOX_FLAG_NO_INDEX_FILES	= 0x10,
45 	/* Keep mailbox exclusively locked all the time while it's open */
46 	MAILBOX_FLAG_KEEP_LOCKED	= 0x20,
47 	/* Enable if mailbox is used for serving POP3. This allows making
48 	   better caching decisions. */
49 	MAILBOX_FLAG_POP3_SESSION	= 0x40,
50 	/* Enable if mailbox is used for saving a mail delivery using MDA.
51 	   This causes ACL plugin to use POST right rather than INSERT. */
52 	MAILBOX_FLAG_POST_SESSION	= 0x80,
53 	/* Force opening mailbox and ignoring any ACLs */
54 	MAILBOX_FLAG_IGNORE_ACLS	= 0x100,
55 	/* Open mailbox even if it's already marked as deleted */
56 	MAILBOX_FLAG_OPEN_DELETED	= 0x200,
57 	/* Mailbox is opened for deletion, which should be performed as
58 	   efficiently as possible, even allowing the mailbox state to become
59 	   inconsistent. For example this disables lazy_expunge plugin and
60 	   quota updates (possibly resulting in broken quota). and This is
61 	   useful for example when deleting entire user accounts. */
62 	MAILBOX_FLAG_DELETE_UNSAFE	= 0x400,
63 	/* Mailbox is created implicitly if it does not exist. */
64 	MAILBOX_FLAG_AUTO_CREATE	= 0x1000,
65 	/* Mailbox is subscribed to implicitly when it is created automatically */
66 	MAILBOX_FLAG_AUTO_SUBSCRIBE	= 0x2000,
67 	/* Run fsck for mailbox index before doing anything else. This may be
68 	   useful in fixing index corruption errors that aren't otherwise
69 	   detected and that are causing the full mailbox opening to fail. */
70 	MAILBOX_FLAG_FSCK		= 0x4000,
71 	/* Interpret name argument for mailbox_alloc_for_user() as a SPECIAL-USE
72 	   flag. */
73 	MAILBOX_FLAG_SPECIAL_USE	= 0x8000,
74 	/* Mailbox is opened for reading/writing attributes. This allows ACL
75 	   plugin to determine correctly whether the mailbox should be allowed
76 	   to be opened. */
77 	MAILBOX_FLAG_ATTRIBUTE_SESSION	= 0x10000,
78 };
79 
80 enum mailbox_feature {
81 	/* Enable tracking modsequences */
82 	MAILBOX_FEATURE_CONDSTORE	= 0x01,
83 };
84 
85 enum mailbox_existence {
86 	MAILBOX_EXISTENCE_NONE,
87 	MAILBOX_EXISTENCE_NOSELECT,
88 	MAILBOX_EXISTENCE_SELECT
89 };
90 
91 enum mailbox_status_items {
92 	STATUS_MESSAGES		= 0x01,
93 	STATUS_RECENT		= 0x02,
94 	STATUS_UIDNEXT		= 0x04,
95 	STATUS_UIDVALIDITY	= 0x08,
96 	STATUS_UNSEEN		= 0x10,
97 	STATUS_FIRST_UNSEEN_SEQ	= 0x20,
98 	STATUS_KEYWORDS		= 0x40,
99 	STATUS_HIGHESTMODSEQ	= 0x80,
100 	STATUS_PERMANENT_FLAGS	= 0x200,
101 	STATUS_FIRST_RECENT_UID	= 0x400,
102 	STATUS_LAST_CACHED_SEQ	= 0x800,
103 	STATUS_CHECK_OVER_QUOTA	= 0x1000, /* return error if over quota */
104 	STATUS_HIGHESTPVTMODSEQ	= 0x2000,
105 	/* status items that must not be looked up with
106 	   mailbox_get_open_status(), because they can return failure. */
107 #define MAILBOX_STATUS_FAILING_ITEMS \
108 	(STATUS_LAST_CACHED_SEQ | STATUS_CHECK_OVER_QUOTA)
109 };
110 
111 enum mailbox_metadata_items {
112 	MAILBOX_METADATA_GUID			= 0x01,
113 	MAILBOX_METADATA_VIRTUAL_SIZE		= 0x02,
114 	MAILBOX_METADATA_CACHE_FIELDS		= 0x04,
115 	MAILBOX_METADATA_PRECACHE_FIELDS	= 0x08,
116 	MAILBOX_METADATA_BACKEND_NAMESPACE	= 0x10,
117 	MAILBOX_METADATA_PHYSICAL_SIZE		= 0x20,
118 	MAILBOX_METADATA_FIRST_SAVE_DATE	= 0x40
119 	/* metadata items that require mailbox to be synced at least once. */
120 #define MAILBOX_METADATA_SYNC_ITEMS \
121 	(MAILBOX_METADATA_VIRTUAL_SIZE | MAILBOX_METADATA_PHYSICAL_SIZE | \
122 	 MAILBOX_METADATA_FIRST_SAVE_DATE)
123 };
124 
125 enum mailbox_search_result_flags {
126 	/* Update search results whenever the mailbox view is synced.
127 	   Expunged messages are removed even without this flag. */
128 	MAILBOX_SEARCH_RESULT_FLAG_UPDATE	= 0x01,
129 	/* Queue changes so _sync() can be used. */
130 	MAILBOX_SEARCH_RESULT_FLAG_QUEUE_SYNC	= 0x02
131 };
132 
133 enum mail_sort_type {
134 	MAIL_SORT_ARRIVAL	= 0x0001,
135 	MAIL_SORT_CC		= 0x0002,
136 	MAIL_SORT_DATE		= 0x0004,
137 	MAIL_SORT_FROM		= 0x0008,
138 	MAIL_SORT_SIZE		= 0x0010,
139 	MAIL_SORT_SUBJECT	= 0x0020,
140 	MAIL_SORT_TO		= 0x0040,
141 	MAIL_SORT_RELEVANCY	= 0x0080,
142 	MAIL_SORT_DISPLAYFROM	= 0x0100,
143 	MAIL_SORT_DISPLAYTO	= 0x0200,
144 	MAIL_SORT_POP3_ORDER	= 0x0400,
145 /* Maximum size for sort program (each one separately + END) */
146 #define MAX_SORT_PROGRAM_SIZE (11 + 1)
147 
148 	MAIL_SORT_MASK		= 0x0fff,
149 	MAIL_SORT_FLAG_REVERSE	= 0x1000, /* reverse this mask type */
150 
151 	MAIL_SORT_END		= 0x0000 /* ends sort program */
152 };
153 
154 enum mail_fetch_field {
155 	MAIL_FETCH_FLAGS		= 0x00000001,
156 	MAIL_FETCH_MESSAGE_PARTS	= 0x00000002,
157 
158 	MAIL_FETCH_STREAM_HEADER	= 0x00000004,
159 	MAIL_FETCH_STREAM_BODY		= 0x00000008,
160 
161 	MAIL_FETCH_DATE			= 0x00000010,
162 	MAIL_FETCH_RECEIVED_DATE	= 0x00000020,
163 	MAIL_FETCH_SAVE_DATE		= 0x00000040,
164 	MAIL_FETCH_PHYSICAL_SIZE	= 0x00000080,
165 	MAIL_FETCH_VIRTUAL_SIZE		= 0x00000100,
166 
167 	/* Set has_nuls / has_no_nuls fields */
168 	MAIL_FETCH_NUL_STATE		= 0x00000200,
169 
170 	MAIL_FETCH_STREAM_BINARY	= 0x00000400,
171 
172 	/* specials: */
173 	MAIL_FETCH_IMAP_BODY		= 0x00001000,
174 	MAIL_FETCH_IMAP_BODYSTRUCTURE	= 0x00002000,
175 	MAIL_FETCH_IMAP_ENVELOPE	= 0x00004000,
176 	MAIL_FETCH_FROM_ENVELOPE	= 0x00008000,
177 	MAIL_FETCH_HEADER_MD5		= 0x00010000,
178 	MAIL_FETCH_STORAGE_ID		= 0x00020000,
179 	MAIL_FETCH_UIDL_BACKEND		= 0x00040000,
180 	MAIL_FETCH_MAILBOX_NAME		= 0x00080000,
181 	MAIL_FETCH_SEARCH_RELEVANCY	= 0x00100000,
182 	MAIL_FETCH_GUID			= 0x00200000,
183 	MAIL_FETCH_POP3_ORDER		= 0x00400000,
184 	MAIL_FETCH_REFCOUNT		= 0x00800000,
185 	MAIL_FETCH_BODY_SNIPPET		= 0x01000000,
186 	MAIL_FETCH_REFCOUNT_ID		= 0x02000000,
187 };
188 
189 enum mailbox_transaction_flags {
190 	/* Hide changes done in this transaction from next view sync */
191 	MAILBOX_TRANSACTION_FLAG_HIDE		= 0x01,
192 	/* External transaction. Should be used for copying and appends,
193 	   but nothing else. */
194 	MAILBOX_TRANSACTION_FLAG_EXTERNAL	= 0x02,
195 	/* Always assign UIDs to messages when saving/copying. Normally this
196 	   is done only if it can be done easily. */
197 	MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS	= 0x04,
198 	/* Refresh the index so lookups return latest flags/modseqs */
199 	MAILBOX_TRANSACTION_FLAG_REFRESH	= 0x08,
200 	/* Don't update caching decisions no matter what we do in this
201 	   transaction (useful for e.g. precaching) */
202 	MAILBOX_TRANSACTION_FLAG_NO_CACHE_DEC	= 0x10,
203 	/* Sync transaction describes changes to mailbox that already happened
204 	   to another mailbox with whom we're syncing with (dsync) */
205 	MAILBOX_TRANSACTION_FLAG_SYNC		= 0x20,
206 	/* Don't trigger any notifications for this transaction. This
207 	   especially means the notify plugin. This would normally be used only
208 	   with _FLAG_SYNC. */
209 	MAILBOX_TRANSACTION_FLAG_NO_NOTIFY	= 0x40,
210 };
211 
212 enum mailbox_sync_flags {
213 	/* Make sure we sync all external changes done to mailbox */
214 	MAILBOX_SYNC_FLAG_FULL_READ		= 0x01,
215 	/* Make sure we write all our internal changes into the mailbox */
216 	MAILBOX_SYNC_FLAG_FULL_WRITE		= 0x02,
217 	/* If it's not too much trouble, check if there are some changes */
218 	MAILBOX_SYNC_FLAG_FAST			= 0x04,
219 
220 	/* Don't sync expunges from our view */
221 	MAILBOX_SYNC_FLAG_NO_EXPUNGES		= 0x08,
222 	/* If mailbox is currently inconsistent, fix it instead of failing. */
223 	MAILBOX_SYNC_FLAG_FIX_INCONSISTENT	= 0x40,
224 	/* Syncing after an EXPUNGE command. This is just an informational
225 	   flag for plugins. */
226 	MAILBOX_SYNC_FLAG_EXPUNGE		= 0x80,
227 	/* Force doing a full resync of indexes. */
228 	MAILBOX_SYNC_FLAG_FORCE_RESYNC		= 0x100,
229 	/* FIXME: kludge until something better comes along:
230 	   Request full text search index optimization */
231 	MAILBOX_SYNC_FLAG_OPTIMIZE		= 0x400
232 };
233 
234 enum mailbox_sync_type {
235 	MAILBOX_SYNC_TYPE_EXPUNGE	= 0x01,
236 	MAILBOX_SYNC_TYPE_FLAGS		= 0x02,
237 	MAILBOX_SYNC_TYPE_MODSEQ	= 0x04
238 };
239 
240 struct message_part;
241 struct mail_namespace;
242 struct mail_storage;
243 struct mail_search_args;
244 struct mail_search_result;
245 struct mail_keywords;
246 struct mail_save_context;
247 struct mailbox;
248 struct mailbox_transaction_context;
249 
250 struct mailbox_status {
251 	uint32_t messages; /* STATUS_MESSAGES */
252 	uint32_t recent; /* STATUS_RECENT */
253 	uint32_t unseen; /* STATUS_UNSEEN */
254 
255 	uint32_t uidvalidity; /* STATUS_UIDVALIDITY */
256 	uint32_t uidnext; /* STATUS_UIDNEXT */
257 
258 	uint32_t first_unseen_seq; /* STATUS_FIRST_UNSEEN_SEQ */
259 	uint32_t first_recent_uid; /* STATUS_FIRST_RECENT_UID */
260 	uint32_t last_cached_seq; /* STATUS_LAST_CACHED_SEQ */
261 	uint64_t highest_modseq; /* STATUS_HIGHESTMODSEQ */
262 	/* 0 if no private index (STATUS_HIGHESTPVTMODSEQ) */
263 	uint64_t highest_pvt_modseq;
264 
265 	/* NULL-terminated array of keywords (STATUS_KEYWORDS) */
266 	const ARRAY_TYPE(keywords) *keywords;
267 
268 	/* These flags can be permanently modified (STATUS_PERMANENT_FLAGS) */
269 	enum mail_flags permanent_flags;
270 	/* These flags can be modified (STATUS_PERMANENT_FLAGS) */
271 	enum mail_flags flags;
272 
273 	/* All keywords can be permanently modified (STATUS_PERMANENT_FLAGS) */
274 	bool permanent_keywords:1;
275 	/* More keywords can be created (STATUS_PERMANENT_FLAGS) */
276 	bool allow_new_keywords:1;
277 	/* Modseqs aren't permanent (index is in memory) (STATUS_HIGHESTMODSEQ) */
278 	bool nonpermanent_modseqs:1;
279 	/* Modseq tracking has never been enabled for this mailbox
280 	   yet. (STATUS_HIGHESTMODSEQ) */
281 	bool no_modseq_tracking:1;
282 
283 	/* Messages have GUIDs (always set) */
284 	bool have_guids:1;
285 	/* mailbox_save_set_guid() works (always set) */
286 	bool have_save_guids:1;
287 	/* GUIDs are always 128bit (always set) */
288 	bool have_only_guid128:1;
289 };
290 
291 struct mailbox_cache_field {
292 	const char *name;
293 	int decision; /* enum mail_cache_decision_type */
294 	/* last_used is unchanged, if it's (time_t)-1 */
295 	time_t last_used;
296 };
297 ARRAY_DEFINE_TYPE(mailbox_cache_field, struct mailbox_cache_field);
298 
299 struct mailbox_metadata {
300 	guid_128_t guid;
301 	/* sum of virtual size of all messages in mailbox */
302 	uint64_t virtual_size;
303 	/* sum of physical size of all messages in mailbox */
304 	uint64_t physical_size;
305 	/* timestamp of when the first message was saved.
306 	   (time_t)-1 if there are no mails in the mailbox. */
307 	time_t first_save_date;
308 
309 	/* Fields that have "temp" or "yes" caching decision. */
310 	const ARRAY_TYPE(mailbox_cache_field) *cache_fields;
311 	/* Fields that should be precached */
312 	enum mail_fetch_field precache_fields;
313 
314 	/* imapc backend returns this based on the remote NAMESPACE reply,
315 	   while currently other backends return "" and type the same as the
316 	   mailbox's real namespace type */
317 	const char *backend_ns_prefix;
318 	enum mail_namespace_type backend_ns_type;
319 };
320 
321 struct mailbox_update {
322 	/* All non-zero fields are changed. */
323 	guid_128_t mailbox_guid;
324 	uint32_t uid_validity;
325 	uint32_t min_next_uid;
326 	uint32_t min_first_recent_uid;
327 	uint64_t min_highest_modseq;
328 	uint64_t min_highest_pvt_modseq;
329 	/* Modify caching decisions, terminated by name=NULL */
330 	const struct mailbox_cache_field *cache_updates;
331 };
332 
333 struct mail_transaction_commit_changes {
334 	/* Unreference the pool to free memory used by these changes. */
335 	pool_t pool;
336 
337 	/* UIDVALIDITY for assigned UIDs. */
338 	uint32_t uid_validity;
339 	/* UIDs assigned to saved messages. Not necessarily ascending.
340 	   If UID assignment wasn't required (e.g. LDA), this array may also be
341 	   empty. Otherwise all of the saved mails got an UID. */
342 	ARRAY_TYPE(seq_range) saved_uids;
343 
344 	/* number of modseq changes that couldn't be changed as requested */
345 	unsigned int ignored_modseq_changes;
346 
347 	/* Changes that occurred within this transaction */
348 	enum mail_index_transaction_change changes_mask;
349 	/* User doesn't have read ACL for the mailbox, so don't show the
350 	   uid_validity / saved_uids. */
351 	bool no_read_perm;
352 };
353 
354 struct mailbox_sync_rec {
355 	uint32_t seq1, seq2;
356 	enum mailbox_sync_type type;
357 };
358 struct mailbox_sync_status {
359 	/* There are expunges that haven't been synced yet */
360 	bool sync_delayed_expunges:1;
361 };
362 
363 struct mailbox_expunge_rec {
364 	/* IMAP UID */
365 	uint32_t uid;
366 	/* 128 bit GUID. If the actual GUID has a different size, this
367 	   contains last bits of its SHA1 sum. */
368 	guid_128_t guid_128;
369 };
370 ARRAY_DEFINE_TYPE(mailbox_expunge_rec, struct mailbox_expunge_rec);
371 
372 enum mail_lookup_abort {
373 	/* Perform everything no matter what it takes */
374 	MAIL_LOOKUP_ABORT_NEVER = 0,
375 	/* Abort if the operation would require reading message header/body or
376 	   otherwise opening the mail file (e.g. with dbox metadata is read by
377 	   opening and reading the file). This still allows somewhat fast
378 	   operations to be performed, such as stat()ing a file. */
379 	MAIL_LOOKUP_ABORT_READ_MAIL,
380 	/* Abort if the operation can't be done fully using cache file */
381 	MAIL_LOOKUP_ABORT_NOT_IN_CACHE,
382 	/* Abort if the operation can't be done fully using cache file.
383 	 * During this lookup all cache lookups that have "no" decision
384 	 * will be changed to "tmp". This way the field will start to be
385 	 * cached in the future. */
386 	MAIL_LOOKUP_ABORT_NOT_IN_CACHE_START_CACHING,
387 };
388 
389 enum mail_access_type {
390 	MAIL_ACCESS_TYPE_DEFAULT = 0,
391 	/* Mail is being used for searching */
392 	MAIL_ACCESS_TYPE_SEARCH,
393 	/* Mail is being used for sorting results */
394 	MAIL_ACCESS_TYPE_SORT,
395 };
396 
397 struct mail {
398 	/* always set */
399 	struct mailbox *box;
400 	struct mailbox_transaction_context *transaction;
401 	struct event *event;
402 	uint32_t seq, uid;
403 
404 	bool expunged:1;
405 	bool saving:1; /* This mail is still being saved */
406 	bool has_nuls:1; /* message data is known to contain NULs */
407 	bool has_no_nuls:1; /* -''- known to not contain NULs */
408 
409 	/* Mail's header/body stream was opened within this request.
410 	   If lookup_abort!=MAIL_LOOKUP_ABORT_NEVER, this can't become TRUE. */
411 	bool mail_stream_opened:1;
412 	/* Mail's fast metadata was accessed within this request, e.g. the mail
413 	   file was stat()ed. If mail_stream_opened==TRUE, this value isn't
414 	   accurate anymore, because some backends may always set this when
415 	   stream is opened and some don't. If lookup_abort is
416 	   MAIL_LOOKUP_ABORT_NOT_IN_CACHE, this can't become TRUE. */
417 	bool mail_metadata_accessed:1;
418 
419 	enum mail_access_type access_type;
420 
421 	/* If the lookup is aborted, error is set to MAIL_ERROR_NOTPOSSIBLE */
422 	enum mail_lookup_abort lookup_abort;
423 };
424 
425 struct mail_storage_callbacks {
426 	/* "* OK <text>" */
427 	void (*notify_ok)(struct mailbox *mailbox, const char *text,
428 			  void *context);
429 	/* "* NO <text>" */
430 	void (*notify_no)(struct mailbox *mailbox, const char *text,
431 			  void *context);
432 
433 };
434 
435 struct mailbox_virtual_pattern {
436 	struct mail_namespace *ns;
437 	const char *pattern;
438 };
439 ARRAY_DEFINE_TYPE(mailbox_virtual_patterns, struct mailbox_virtual_pattern);
440 ARRAY_DEFINE_TYPE(mail_storage, struct mail_storage *);
441 ARRAY_DEFINE_TYPE(mailboxes, struct mailbox *);
442 
443 extern ARRAY_TYPE(mail_storage) mail_storage_classes;
444 
445 typedef void mailbox_notify_callback_t(struct mailbox *box, void *context);
446 
447 void mail_storage_init(void);
448 void mail_storage_deinit(void);
449 
450 /* register all mail storages */
451 void mail_storage_register_all(void);
452 
453 /* Register mail storage class with given name - all methods that are NULL
454    are set to default methods */
455 void mail_storage_class_register(struct mail_storage *storage_class);
456 void mail_storage_class_unregister(struct mail_storage *storage_class);
457 /* Find mail storage class by name */
458 struct mail_storage *mail_storage_find_class(const char *name);
459 
460 /* Create a new instance of registered mail storage class with given
461    storage-specific data. If driver is NULL, it's tried to be autodetected
462    from ns location. If ns location is NULL, it uses the first storage that
463    exists. The storage is put into ns->storage. */
464 int mail_storage_create(struct mail_namespace *ns, const char *driver,
465 			enum mail_storage_flags flags, const char **error_r)
466 	ATTR_NULL(2);
467 int mail_storage_create_full(struct mail_namespace *ns, const char *driver,
468 			     const char *data, enum mail_storage_flags flags,
469 			     struct mail_storage **storage_r,
470 			     const char **error_r) ATTR_NULL(2);
471 void mail_storage_unref(struct mail_storage **storage);
472 
473 /* Returns the mail storage settings. */
474 const struct mail_storage_settings *
475 mail_storage_get_settings(struct mail_storage *storage) ATTR_PURE;
476 struct mail_user *mail_storage_get_user(struct mail_storage *storage) ATTR_PURE;
477 
478 /* Set storage callback functions to use. */
479 void mail_storage_set_callbacks(struct mail_storage *storage,
480 				struct mail_storage_callbacks *callbacks,
481 				void *context) ATTR_NULL(3);
482 
483 /* Purge storage's mailboxes (freeing disk space from expunged mails),
484    if supported by the storage. Otherwise just a no-op. */
485 int mail_storage_purge(struct mail_storage *storage);
486 
487 /* Returns the error message of last occurred error. */
488 const char * ATTR_NOWARN_UNUSED_RESULT
489 mail_storage_get_last_error(struct mail_storage *storage,
490 			    enum mail_error *error_r) ATTR_NULL(2);
491 /* Wrapper for mail_storage_get_last_error(); */
492 const char * ATTR_NOWARN_UNUSED_RESULT
493 mailbox_get_last_error(struct mailbox *box, enum mail_error *error_r)
494 	ATTR_NULL(2);
495 /* Wrapper for mail_storage_get_last_error(); */
496 enum mail_error mailbox_get_last_mail_error(struct mailbox *box);
497 
498 const char * ATTR_NOWARN_UNUSED_RESULT
499 mail_storage_get_last_internal_error(struct mail_storage *storage,
500 				     enum mail_error *error_r) ATTR_NULL(2);
501 /* Wrapper for mail_storage_get_last_internal_error(); */
502 const char * ATTR_NOWARN_UNUSED_RESULT
503 mailbox_get_last_internal_error(struct mailbox *box,
504 				enum mail_error *error_r) ATTR_NULL(2);
505 
506 /* Save the last error until it's popped. This is useful for cases where the
507    storage has already failed, but the cleanup code path changes the error to
508    something else unwanted. */
509 void mail_storage_last_error_push(struct mail_storage *storage);
510 void mail_storage_last_error_pop(struct mail_storage *storage);
511 
512 /* Returns TRUE if mailboxes are files. */
513 bool mail_storage_is_mailbox_file(struct mail_storage *storage) ATTR_PURE;
514 
515 /* Initialize mailbox without actually opening any files or verifying that
516    it exists. Note that append and copy may open the selected mailbox again
517    with possibly different readonly-state. */
518 struct mailbox *mailbox_alloc(struct mailbox_list *list, const char *vname,
519 			      enum mailbox_flags flags);
520 /* Like mailbox_alloc(), but use mailbox GUID. */
521 struct mailbox *mailbox_alloc_guid(struct mailbox_list *list,
522 				   const guid_128_t guid,
523 				   enum mailbox_flags flags);
524 /* Initialize mailbox for a particular user without actually opening any files
525    or verifying that it exists. The mname parameter is normally equal to the
526    mailbox vname, except when the MAILBOX_FLAG_SPECIAL_USE flag is set, in which
527    case it is the special-use flag. */
528 struct mailbox *
529 mailbox_alloc_for_user(struct mail_user *user, const char *mname,
530 		       enum mailbox_flags flags);
531 
532 /* Set a human-readable reason for why this mailbox is being accessed.
533    This is used for logging purposes. */
534 void mailbox_set_reason(struct mailbox *box, const char *reason);
535 /* Get mailbox existence state. If auto_boxes=FALSE, return
536    MAILBOX_EXISTENCE_NONE for autocreated mailboxes that haven't been
537    physically created yet */
538 int mailbox_exists(struct mailbox *box, bool auto_boxes,
539 		   enum mailbox_existence *existence_r);
540 /* Open the mailbox. If this function isn't called explicitly, it's also called
541    internally by lib-storage when necessary. */
542 int mailbox_open(struct mailbox *box);
543 /* Open mailbox as read-only using the given stream as input. */
544 int mailbox_open_stream(struct mailbox *box, struct istream *input);
545 /* Close mailbox. Same as if mailbox was freed and re-allocated. */
546 void mailbox_close(struct mailbox *box);
547 /* Close and free the mailbox. */
548 void mailbox_free(struct mailbox **box);
549 
550 /* Returns TRUE if box1 points to the same mailbox as ns2/vname2. */
551 bool mailbox_equals(const struct mailbox *box1,
552 		    const struct mail_namespace *ns2,
553 		    const char *vname2) ATTR_PURE;
554 /* Returns TRUE if the mailbox is user's INBOX or another user's shared INBOX */
555 bool mailbox_is_any_inbox(struct mailbox *box);
556 
557 /* Returns TRUE if the mailbox has the specified special use flag assigned. */
558 bool mailbox_has_special_use(struct mailbox *box, const char *special_use);
559 
560 /* Change mailbox_verify_create_name() to not verify new mailbox name
561    restrictions (but still check that it's a valid existing name). This is
562    mainly used by dsync to make sure the sync works even though the original
563    name isn't valid anymore. */
564 void mailbox_skip_create_name_restrictions(struct mailbox *box, bool set);
565 /* Returns -1 if mailbox_create() is guaranteed to fail because the mailbox
566    name is invalid, 0 not. The error message contains a reason. */
567 int mailbox_verify_create_name(struct mailbox *box);
568 /* Create a mailbox. Returns failure if it already exists. Mailbox name is
569    allowed to contain multiple new nonexistent hierarchy levels. If directory
570    is TRUE, the mailbox should be created so that it can contain children. The
571    mailbox itself doesn't have to be created as long as it shows up in LIST.
572    If update is non-NULL, its contents are used to set initial mailbox
573    metadata. */
574 int mailbox_create(struct mailbox *box, const struct mailbox_update *update,
575 		   bool directory) ATTR_NULL(2);
576 /* Update existing mailbox's metadata. */
577 int mailbox_update(struct mailbox *box, const struct mailbox_update *update);
578 /* Delete mailbox (and its parent directory, if it has no siblings) */
579 int mailbox_delete(struct mailbox *box);
580 /* Delete mailbox, but only if it's empty. If it's not, fails with
581    MAIL_ERROR_EXISTS. */
582 int mailbox_delete_empty(struct mailbox *box);
583 /* Rename mailbox (and its children). Renaming across different mailbox lists
584    is possible only between private namespaces and storages of the same type.
585    If the rename fails, the error is set to src's storage. */
586 int mailbox_rename(struct mailbox *src, struct mailbox *dest);
587 /* Subscribe/unsubscribe mailbox. Subscribing to
588    nonexistent mailboxes is optional. */
589 int mailbox_set_subscribed(struct mailbox *box, bool set);
590 /* Returns TRUE if mailbox is subscribed, FALSE if not. This function
591    doesn't refresh the subscriptions list, but assumes that it's been done by
592    e.g. mailbox_list_iter*(). */
593 bool mailbox_is_subscribed(struct mailbox *box);
594 
595 /* Enable the given feature for the mailbox. */
596 int mailbox_enable(struct mailbox *box, enum mailbox_feature features);
597 /* Returns all enabled features. */
598 enum mailbox_feature
599 mailbox_get_enabled_features(struct mailbox *box) ATTR_PURE;
600 
601 /* Returns storage of given mailbox */
602 struct mail_storage *mailbox_get_storage(const struct mailbox *box) ATTR_PURE;
603 /* Return namespace of given mailbox. */
604 struct mail_namespace *
605 mailbox_get_namespace(const struct mailbox *box) ATTR_PURE;
606 /* Returns the storage's settings. */
607 const struct mail_storage_settings *
608 mailbox_get_settings(struct mailbox *box) ATTR_PURE;
609 /* Returns the mailbox's settings, or NULL if there are none. */
610 const struct mailbox_settings *
611 mailbox_settings_find(struct mail_namespace *ns, const char *vname);
612 
613 /* Returns the (virtual) name of the given mailbox. */
614 const char *mailbox_get_vname(const struct mailbox *box) ATTR_PURE;
615 /* Returns the backend name of given mailbox. */
616 const char *mailbox_get_name(const struct mailbox *box) ATTR_PURE;
617 
618 /* Returns TRUE if mailbox is read-only. */
619 bool mailbox_is_readonly(struct mailbox *box);
620 /* Returns TRUE if two mailboxes point to the same physical mailbox. */
621 bool mailbox_backends_equal(const struct mailbox *box1,
622 			    const struct mailbox *box2);
623 /* Returns TRUE if mailbox is now in inconsistent state, meaning that
624    the message IDs etc. may have changed - only way to recover this
625    would be to fully close the mailbox and reopen it. With IMAP
626    connection this would mean a forced disconnection since we can't
627    do forced CLOSE. */
628 bool mailbox_is_inconsistent(struct mailbox *box);
629 
630 /* Gets the mailbox status information. If mailbox isn't opened yet, try to
631    return the results from mailbox list indexes. Otherwise the mailbox is
632    opened and synced. If the mailbox is already opened, no syncing is done
633    automatically. */
634 int mailbox_get_status(struct mailbox *box, enum mailbox_status_items items,
635 		       struct mailbox_status *status_r);
636 /* Gets the mailbox status, requires that mailbox is already opened. */
637 void mailbox_get_open_status(struct mailbox *box,
638 			     enum mailbox_status_items items,
639 			     struct mailbox_status *status_r);
640 /* Gets mailbox metadata */
641 int mailbox_get_metadata(struct mailbox *box, enum mailbox_metadata_items items,
642 			 struct mailbox_metadata *metadata_r);
643 /* Returns a mask of flags that are private to user in this mailbox
644    (as opposed to flags shared between users). */
645 enum mail_flags mailbox_get_private_flags_mask(struct mailbox *box);
646 
647 /* Synchronize the mailbox. */
648 struct mailbox_sync_context *
649 mailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags);
650 bool mailbox_sync_next(struct mailbox_sync_context *ctx,
651 		       struct mailbox_sync_rec *sync_rec_r);
652 int mailbox_sync_deinit(struct mailbox_sync_context **ctx,
653 			struct mailbox_sync_status *status_r);
654 /* One-step mailbox synchronization. Use this if you don't care about
655    changes. */
656 int mailbox_sync(struct mailbox *box, enum mailbox_sync_flags flags);
657 
658 /* Call given callback function when something changes in the mailbox. */
659 void mailbox_notify_changes(struct mailbox *box,
660 			    mailbox_notify_callback_t *callback, void *context)
661 	ATTR_NULL(3);
662 #define mailbox_notify_changes(box, callback, context) \
663 	  mailbox_notify_changes(box, (mailbox_notify_callback_t *)callback, \
664 		(void *)((char *)context - CALLBACK_TYPECHECK(callback, \
665 			void (*)(struct mailbox *, typeof(context)))))
666 void mailbox_notify_changes_stop(struct mailbox *box);
667 
668 struct mailbox_transaction_context *
669 mailbox_transaction_begin(struct mailbox *box,
670 			  enum mailbox_transaction_flags flags,
671 			  const char *reason);
672 int mailbox_transaction_commit(struct mailbox_transaction_context **t);
673 int mailbox_transaction_commit_get_changes(
674 	struct mailbox_transaction_context **t,
675 	struct mail_transaction_commit_changes *changes_r);
676 void mailbox_transaction_rollback(struct mailbox_transaction_context **t);
677 /* Return the number of active transactions for the mailbox. */
678 unsigned int mailbox_transaction_get_count(const struct mailbox *box) ATTR_PURE;
679 /* When committing transaction, drop flag/keyword updates for messages whose
680    modseq is larger than max_modseq. Save those messages' sequences to the
681    given array. */
682 void mailbox_transaction_set_max_modseq(struct mailbox_transaction_context *t,
683 					uint64_t max_modseq,
684 					ARRAY_TYPE(seq_range) *seqs);
685 
686 struct mailbox *
687 mailbox_transaction_get_mailbox(const struct mailbox_transaction_context *t)
688 	ATTR_PURE;
689 
690 /* Convert uid range to sequence range. */
691 void mailbox_get_seq_range(struct mailbox *box, uint32_t uid1, uint32_t uid2,
692 			   uint32_t *seq1_r, uint32_t *seq2_r);
693 /* Convert sequence range to uid range. If sequences contain
694    (uint32_t)-1 to specify "*", they're preserved. */
695 void mailbox_get_uid_range(struct mailbox *box,
696 			   const ARRAY_TYPE(seq_range) *seqs,
697 			   ARRAY_TYPE(seq_range) *uids);
698 /* Get list of messages' that have been expunged after prev_modseq and that
699    exist in uids_filter range. UIDs that have been expunged after the last
700    mailbox sync aren't returned. Returns TRUE if ok, FALSE if modseq is lower
701    than we can check for (but expunged_uids is still set as best as it can). */
702 bool mailbox_get_expunges(struct mailbox *box, uint64_t prev_modseq,
703 			  const ARRAY_TYPE(seq_range) *uids_filter,
704 			  ARRAY_TYPE(mailbox_expunge_rec) *expunges);
705 /* Same as mailbox_get_expunges(), but return only list of UIDs. Not caring
706    about GUIDs is slightly faster. */
707 bool mailbox_get_expunged_uids(struct mailbox *box, uint64_t prev_modseq,
708 			       const ARRAY_TYPE(seq_range) *uids_filter,
709 			       ARRAY_TYPE(seq_range) *expunged_uids);
710 
711 /* Initialize header lookup for given headers. */
712 struct mailbox_header_lookup_ctx *
713 mailbox_header_lookup_init(struct mailbox *box, const char *const headers[]);
714 void mailbox_header_lookup_ref(struct mailbox_header_lookup_ctx *ctx);
715 void mailbox_header_lookup_unref(struct mailbox_header_lookup_ctx **ctx);
716 /* Merge two header lookups. */
717 struct mailbox_header_lookup_ctx *
718 mailbox_header_lookup_merge(const struct mailbox_header_lookup_ctx *hdr1,
719 			    const struct mailbox_header_lookup_ctx *hdr2);
720 
721 /* Initialize new search request. If sort_program is non-NULL, the messages are
722    returned in the requested order, otherwise from first to last. */
723 struct mail_search_context * ATTR_NULL(3, 5)
724 mailbox_search_init(struct mailbox_transaction_context *t,
725 		    struct mail_search_args *args,
726 		    const enum mail_sort_type *sort_program,
727 		    enum mail_fetch_field wanted_fields,
728 		    struct mailbox_header_lookup_ctx *wanted_headers);
729 /* Deinitialize search request. */
730 int mailbox_search_deinit(struct mail_search_context **ctx);
731 /* Search the next message. Returns TRUE if found, FALSE if not. */
732 bool mailbox_search_next(struct mail_search_context *ctx, struct mail **mail_r);
733 /* Like mailbox_search_next(), but don't spend too much time searching.
734    Returns FALSE with tryagain_r=FALSE if finished, and tryagain_r=TRUE if
735    more results will be returned by calling the function again. */
736 bool mailbox_search_next_nonblock(struct mail_search_context *ctx,
737 				  struct mail **mail_r, bool *tryagain_r);
738 /* Returns TRUE if some messages were already expunged and we couldn't
739    determine correctly if those messages should have been returned in this
740    search. */
741 bool mailbox_search_seen_lost_data(struct mail_search_context *ctx);
742 /* Detach the given mail from the search context. This allows the mail to live
743    even after mail_search_context has been freed. */
744 void mailbox_search_mail_detach(struct mail_search_context *ctx,
745 				struct mail *mail);
746 
747 /* Remember the search result for future use. This must be called before the
748    first mailbox_search_next*() call. */
749 struct mail_search_result *
750 mailbox_search_result_save(struct mail_search_context *ctx,
751 			   enum mailbox_search_result_flags flags);
752 /* Free memory used by search result. */
753 void mailbox_search_result_free(struct mail_search_result **result);
754 /* A simplified API for searching and saving the result. */
755 int mailbox_search_result_build(struct mailbox_transaction_context *t,
756 				struct mail_search_args *args,
757 				enum mailbox_search_result_flags flags,
758 				struct mail_search_result **result_r);
759 /* Return all messages' UIDs in the search result. */
760 const ARRAY_TYPE(seq_range) *
761 mailbox_search_result_get(struct mail_search_result *result);
762 /* Return messages that have been removed and added since the last sync call.
763    This function must not be called if search result wasn't saved with
764    _QUEUE_SYNC flag. */
765 void mailbox_search_result_sync(struct mail_search_result *result,
766 				ARRAY_TYPE(seq_range) *removed_uids,
767 				ARRAY_TYPE(seq_range) *added_uids);
768 
769 /* Build mail_keywords from NULL-terminated keywords list. Any duplicate
770    keywords are removed. Returns 0 if successful, -1 if there are invalid
771    keywords (error is set). */
772 int mailbox_keywords_create(struct mailbox *box, const char *const keywords[],
773 			    struct mail_keywords **keywords_r);
774 /* Like mailbox_keywords_create(), except ignore invalid keywords. */
775 struct mail_keywords *
776 mailbox_keywords_create_valid(struct mailbox *box,
777 			      const char *const keywords[]);
778 struct mail_keywords *
779 mailbox_keywords_create_from_indexes(struct mailbox *box,
780 				     const ARRAY_TYPE(keyword_indexes) *idx);
781 /* Return union of two mail_keywords. They must be created in the same
782    mailbox. */
783 struct mail_keywords *mailbox_keywords_merge(struct mail_keywords *keywords1,
784 					     struct mail_keywords *keywords2);
785 void mailbox_keywords_ref(struct mail_keywords *keywords);
786 void mailbox_keywords_unref(struct mail_keywords **keywords);
787 /* Returns TRUE if keyword is valid, FALSE and error if not. */
788 bool mailbox_keyword_is_valid(struct mailbox *box, const char *keyword,
789 			      const char **error_r);
790 
791 /* Initialize saving a new mail. You must not try to save more than one mail
792    at a time. */
793 struct mail_save_context *
794 mailbox_save_alloc(struct mailbox_transaction_context *t);
795 /* Set the flags and keywords. Nothing is set by default. */
796 void mailbox_save_set_flags(struct mail_save_context *ctx,
797 			    enum mail_flags flags,
798 			    struct mail_keywords *keywords);
799 /* Copy flags and keywords from given mail. */
800 void mailbox_save_copy_flags(struct mail_save_context *ctx, struct mail *mail);
801 /* Set message's modseq to be at least min_modseq. */
802 void mailbox_save_set_min_modseq(struct mail_save_context *ctx,
803 				 uint64_t min_modseq);
804 /* If received date isn't specified the current time is used. timezone_offset
805    specifies the preferred timezone in minutes, but it may be ignored if
806    backend doesn't support storing it. */
807 void mailbox_save_set_received_date(struct mail_save_context *ctx,
808 				    time_t received_date, int timezone_offset);
809 /* Set the "message saved" date. This should be set only when you're
810    replicating/restoring an existing mailbox. */
811 void mailbox_save_set_save_date(struct mail_save_context *ctx,
812 				time_t save_date);
813 /* Set the envelope sender. This is currently used only with mbox files to
814    specify the address in From_-line. */
815 void mailbox_save_set_from_envelope(struct mail_save_context *ctx,
816 				    const char *envelope);
817 /* Set message's UID. If UID is smaller than the current next_uid, it's given
818    a new UID anyway. */
819 void mailbox_save_set_uid(struct mail_save_context *ctx, uint32_t uid);
820 /* Set globally unique ID for the saved mail. A new GUID is generated by
821    default. This function should usually be called only when copying an
822    existing mail (or restoring a mail from backup). */
823 void mailbox_save_set_guid(struct mail_save_context *ctx, const char *guid);
824 /* Set message's POP3 UIDL, if the backend supports it. */
825 void mailbox_save_set_pop3_uidl(struct mail_save_context *ctx,
826 				const char *uidl);
827 /* Specify ordering for POP3 messages. The default is to add them to the end
828    of the mailbox. Not all backends support this. */
829 void mailbox_save_set_pop3_order(struct mail_save_context *ctx,
830 				 unsigned int order);
831 /* Returns the destination mail */
832 struct mail *mailbox_save_get_dest_mail(struct mail_save_context *ctx);
833 /* Begin saving the message. All mail_save_set_*() calls must have been called
834    before this function. If the save initialization fails, the context is freed
835    and -1 is returned. After beginning the save you should keep calling
836    i_stream_read() and calling mailbox_save_continue() as long as there's
837    more input. */
838 int mailbox_save_begin(struct mail_save_context **ctx, struct istream *input);
839 int mailbox_save_continue(struct mail_save_context *ctx);
840 int mailbox_save_finish(struct mail_save_context **ctx);
841 void mailbox_save_cancel(struct mail_save_context **ctx);
842 
843 struct mailbox_transaction_context *
844 mailbox_save_get_transaction(struct mail_save_context *ctx);
845 
846 /* Copy the given message. You'll need to specify the flags etc. using the
847    mailbox_save_*() functions. */
848 int mailbox_copy(struct mail_save_context **ctx, struct mail *mail);
849 /* Move the given message. This is usually equivalent to copy+expunge,
850    but without enforcing quota. */
851 int mailbox_move(struct mail_save_context **ctx, struct mail *mail);
852 /* Same as mailbox_copy(), but treat the message as if it's being saved,
853    not copied. (For example: New mail delivered to multiple maildirs, with
854    each mails being hard link copies.) */
855 int mailbox_save_using_mail(struct mail_save_context **ctx, struct mail *mail);
856 
857 struct mail *mail_alloc(struct mailbox_transaction_context *t,
858 			enum mail_fetch_field wanted_fields,
859 			struct mailbox_header_lookup_ctx *wanted_headers)
860 	ATTR_NULL(3);
861 void mail_free(struct mail **mail);
862 void mail_set_seq(struct mail *mail, uint32_t seq);
863 /* Returns TRUE if successful, FALSE if message doesn't exist.
864    mail_*() functions shouldn't be called if FALSE is returned. */
865 bool mail_set_uid(struct mail *mail, uint32_t uid);
866 
867 /* Add wanted fields/headers on top of existing ones. These will be forgotten
868    after the next mail_set_seq/uid() that closes the existing mail. Note that
869    it's valid to call this function while there is no mail assigned
870    (mail->seq==0), i.e. this is called before any mail_set_seq/uid() or after
871    mail.close(). */
872 void mail_add_temp_wanted_fields(struct mail *mail,
873 				 enum mail_fetch_field fields,
874 				 struct mailbox_header_lookup_ctx *headers)
875 	ATTR_NULL(3);
876 
877 /* Returns message's flags */
878 enum mail_flags mail_get_flags(struct mail *mail);
879 /* Returns message's keywords */
880 const char *const *mail_get_keywords(struct mail *mail);
881 /* Returns message's keywords */
882 const ARRAY_TYPE(keyword_indexes) *mail_get_keyword_indexes(struct mail *mail);
883 /* Returns message's modseq */
884 uint64_t mail_get_modseq(struct mail *mail);
885 /* Returns message's private modseq, or 0 if message hasn't had any
886    private flag changes. This is useful only for shared mailboxes that have
887    a private index defined. */
888 uint64_t mail_get_pvt_modseq(struct mail *mail);
889 
890 /* Returns message's MIME parts */
891 int mail_get_parts(struct mail *mail, struct message_part **parts_r);
892 
893 /* Get the Date-header of the mail. Timezone is in minutes. date=0 if it
894    wasn't found or it was invalid. */
895 int mail_get_date(struct mail *mail, time_t *date_r, int *timezone_r);
896 /* Get the time when the mail was received (IMAP INTERNALDATE). */
897 int mail_get_received_date(struct mail *mail, time_t *date_r);
898 /* Get the time when the mail was saved into this mailbox. This returns -1 on
899    error, 0 if a real save date is not supported and a fall-back date is used,
900    and 1 when a save date was successfully retrieved. */
901 int mail_get_save_date(struct mail *mail, time_t *date_r);
902 
903 /* Get the space used by the mail as seen by the reader. Linefeeds are always
904    counted as being CR+LF. */
905 int mail_get_virtual_size(struct mail *mail, uoff_t *size_r);
906 /* Get the size of the stream returned by mail_get_stream(). */
907 int mail_get_physical_size(struct mail *mail, uoff_t *size_r);
908 
909 /* Get value for single header field, or NULL if header wasn't found.
910    Returns 1 if header was found, 0 if not, -1 if error. */
911 int mail_get_first_header(struct mail *mail, const char *field,
912 			  const char **value_r);
913 /* Like mail_get_first_header(), but decode MIME encoded words to UTF-8.
914    Also multiline headers are returned unfolded.
915 
916    Do not use this function for getting structured fields (e.g. address fields),
917    because decoding may break the structuring. Instead parse them first and
918    only afterwards decode the encoded words. */
919 int mail_get_first_header_utf8(struct mail *mail, const char *field,
920 			       const char **value_r);
921 /* Return a NULL-terminated list of values for each found field.
922    Returns 1 if headers were found, 0 if not (value_r[0]==NULL) or
923    -1 if error. */
924 int mail_get_headers(struct mail *mail, const char *field,
925 		     const char *const **value_r);
926 /* Like mail_get_headers(), but decode MIME encoded words to UTF-8.
927    Also multiline headers are returned unfolded.
928    Do not use for structured fields (see mail_get_first_header_utf8()). */
929 int mail_get_headers_utf8(struct mail *mail, const char *field,
930 			  const char *const **value_r);
931 /* Returns stream containing specified headers. The returned stream will be
932    automatically freed when the mail is closed, or when another
933    mail_get_header_stream() call is made (so you can't have multiple header
934    streams open at the same time). */
935 int mail_get_header_stream(struct mail *mail,
936 			   struct mailbox_header_lookup_ctx *headers,
937 			   struct istream **stream_r);
938 /* Returns input stream pointing to beginning of message header.
939    hdr_size and body_size are updated unless they're NULL. The returned stream
940    is destroyed automatically, don't unreference it. */
941 int mail_get_stream(struct mail *mail, struct message_size *hdr_size,
942 		    struct message_size *body_size, struct istream **stream_r)
943 	ATTR_NULL(2, 3);
944 /* Same as mail_get_stream(), but specify a reason why the mail is being read.
945    This can be useful for debugging purposes. */
946 int mail_get_stream_because(struct mail *mail, struct message_size *hdr_size,
947 			    struct message_size *body_size,
948 			    const char *reason, struct istream **stream_r)
949 	ATTR_NULL(2, 3);
950 /* Similar to mail_get_stream(), but the stream may or may not contain the
951    message body. */
952 int mail_get_hdr_stream(struct mail *mail, struct message_size *hdr_size,
953 			struct istream **stream_r) ATTR_NULL(2);
954 /* Same as mail_get_hdr_stream(), but specify a reason why the header is being
955    read. This can be useful for debugging purposes. */
956 int mail_get_hdr_stream_because(struct mail *mail,
957 				struct message_size *hdr_size,
958 				const char *reason, struct istream **stream_r);
959 /* Returns the message part's body decoded to 8bit binary. If the
960    Content-Transfer-Encoding isn't supported, returns -1 and sets error to
961    MAIL_ERROR_CONVERSION. If the part refers to a multipart, all of its
962    children are returned decoded. Note that the returned stream must be
963    unreferenced, unlike mail_get_*stream*() which automatically free it. */
964 int mail_get_binary_stream(struct mail *mail, const struct message_part *part,
965 			   bool include_hdr, uoff_t *size_r,
966 			   bool *binary_r, struct istream **stream_r);
967 /* Like mail_get_binary_stream(), but only return the size. */
968 int mail_get_binary_size(struct mail *mail, const struct message_part *part,
969 			 bool include_hdr, uoff_t *size_r,
970 			 unsigned int *lines_r);
971 
972 /* Get any of the "special" fields. Unhandled specials are returned as "". */
973 int mail_get_special(struct mail *mail, enum mail_fetch_field field,
974 		     const char **value_r);
975 /* Returns the mail for the physical message. Normally this is the mail itself,
976    but in virtual mailboxes it points to the backend mailbox. */
977 int mail_get_backend_mail(struct mail *mail, struct mail **real_mail_r);
978 
979 /* Retrieve and parse the value of the Message-ID header field. Returns 1 if the
980    header was found and it contains a valid message ID, 0 if the header was not
981    found or no valid message ID was contained in it, and -1 if an error occurred
982    while retrieving the header. Returns the message ID value including '<' and
983    '>' in the *value_r return parameter or NULL if the header wasn't found or
984    its value was invalid. */
985 int mail_get_message_id(struct mail *mail, const char **value_r);
986 
987 /* Update message flags. */
988 void mail_update_flags(struct mail *mail, enum modify_type modify_type,
989 		       enum mail_flags flags);
990 /* Update message keywords. */
991 void mail_update_keywords(struct mail *mail, enum modify_type modify_type,
992 			  struct mail_keywords *keywords);
993 /* Update message's modseq to be at least min_modseq. */
994 void mail_update_modseq(struct mail *mail, uint64_t min_modseq);
995 /* Update message's private modseq to be at least min_pvt_modseq. */
996 void mail_update_pvt_modseq(struct mail *mail, uint64_t min_pvt_modseq);
997 
998 /* Update message's POP3 UIDL (if possible). */
999 void mail_update_pop3_uidl(struct mail *mail, const char *uidl);
1000 /* Expunge this message. Sequence numbers don't change until commit. */
1001 void mail_expunge(struct mail *mail);
1002 
1003 /* Add missing fields to cache. */
1004 int mail_precache(struct mail *mail);
1005 /* Mark a cached field corrupted and have it recalculated. */
1006 void mail_set_cache_corrupted(struct mail *mail,
1007 			      enum mail_fetch_field field,
1008 			      const char *reason);
1009 
1010 /* Return 128 bit GUID using input string. If guid is already 128 bit hex
1011    encoded, it's returned as-is. Otherwise SHA1 sum is taken and its last
1012    128 bits are returned. */
1013 void mail_generate_guid_128_hash(const char *guid, guid_128_t guid_128_r);
1014 
1015 /* Parse a human-writable string into a timestamp. utc_r controls whether
1016    the returned timestamp should be treated as an exact UTC time (TRUE), or
1017    whether this is a human-given date where the timestamp could be adjusted
1018    by the matched mails' timezones (see MAIL_SEARCH_ARG_FLAG_USE_TZ).
1019 
1020    Returns 0 and timestamp on success, -1 if the string couldn't be parsed.
1021    Currently supported string formats: yyyy-mm-dd (utc=FALSE),
1022    imap date (utc=FALSE), unix timestamp (utc=TRUE), interval (e.g. n days,
1023    utc=TRUE). */
1024 int mail_parse_human_timestamp(const char *str, time_t *timestamp_r,
1025 			       bool *utc_r);
1026 
1027 #endif
1028