mail-storage.h revision 4945c8a753cdfa19fdedc62049a8ee1890618706
#ifndef MAIL_STORAGE_H
#define MAIL_STORAGE_H
struct message_size;
#include "seq-range-array.h"
#include "file-lock.h"
#include "guid.h"
#include "mail-types.h"
#include "mail-error.h"
#include "mail-namespace.h"
#include "mailbox-list.h"
#include "mailbox-attribute.h"
/* If some operation is taking long, call notify_ok every n seconds. */
#define MAIL_STORAGE_STAYALIVE_SECS 15
enum mail_storage_flags {
/* Remember message headers' MD5 sum */
/* Don't try to autodetect anything, require that the given data
contains all the necessary information. */
/* Don't autocreate any directories. If they don't exist,
fail to create the storage. */
MAIL_STORAGE_FLAG_NO_AUTOCREATE = 0x04,
/* Don't verify existence or accessibility of any directories.
Create the storage in any case. */
};
enum mailbox_flags {
/* Mailbox must not be modified even if asked */
MAILBOX_FLAG_READONLY = 0x01,
MAILBOX_FLAG_SAVEONLY = 0x02,
/* Remove MAIL_RECENT flags when syncing */
MAILBOX_FLAG_DROP_RECENT = 0x04,
/* Don't create index files for the mailbox */
MAILBOX_FLAG_NO_INDEX_FILES = 0x10,
/* Keep mailbox exclusively locked all the time while it's open */
MAILBOX_FLAG_KEEP_LOCKED = 0x20,
/* Enable if mailbox is used for serving POP3. This allows making
better caching decisions. */
MAILBOX_FLAG_POP3_SESSION = 0x40,
/* Enable if mailbox is used for saving a mail delivery using MDA.
This causes ACL plugin to use POST right rather than INSERT. */
MAILBOX_FLAG_POST_SESSION = 0x80,
/* Force opening mailbox and ignoring any ACLs */
MAILBOX_FLAG_IGNORE_ACLS = 0x100,
/* Open mailbox even if it's already marked as deleted */
MAILBOX_FLAG_OPEN_DELETED = 0x200,
/* Mailbox is opened for deletion, which should be performed as
efficiently as possible, even allowing the mailbox state to become
inconsistent. For example this disables lazy_expunge plugin and
quota updates (possibly resulting in broken quota). and This is
useful for example when deleting entire user accounts. */
MAILBOX_FLAG_DELETE_UNSAFE = 0x400,
/* Mailbox is used for caching purposes. Some of the mails may be
stubs, which exist in the index but that don't have a mail body.
The backend shouldn't treat it as corruption if a mail body isn't
found. */
MAILBOX_FLAG_USE_STUBS = 0x800,
};
enum mailbox_feature {
/* Enable tracking modsequences */
MAILBOX_FEATURE_CONDSTORE = 0x01,
/* Enable tracking expunge modsequences */
MAILBOX_FEATURE_QRESYNC = 0x02
};
enum mailbox_existence {
};
enum mailbox_status_items {
STATUS_MESSAGES = 0x01,
STATUS_RECENT = 0x02,
STATUS_UIDNEXT = 0x04,
STATUS_UIDVALIDITY = 0x08,
STATUS_UNSEEN = 0x10,
STATUS_FIRST_UNSEEN_SEQ = 0x20,
STATUS_KEYWORDS = 0x40,
STATUS_HIGHESTMODSEQ = 0x80,
STATUS_PERMANENT_FLAGS = 0x200,
STATUS_FIRST_RECENT_UID = 0x400,
STATUS_LAST_CACHED_SEQ = 0x800,
STATUS_HIGHESTPVTMODSEQ = 0x2000,
/* status items that must not be looked up with
mailbox_get_open_status(), because they can return failure. */
#define MAILBOX_STATUS_FAILING_ITEMS \
};
enum mailbox_metadata_items {
MAILBOX_METADATA_GUID = 0x01,
MAILBOX_METADATA_VIRTUAL_SIZE = 0x02,
MAILBOX_METADATA_CACHE_FIELDS = 0x04,
MAILBOX_METADATA_PRECACHE_FIELDS = 0x08,
MAILBOX_METADATA_PHYSICAL_SIZE = 0x20,
/* metadata items that require mailbox to be synced at least once. */
#define MAILBOX_METADATA_SYNC_ITEMS \
};
enum mailbox_search_result_flags {
/* Update search results whenever the mailbox view is synced.
Expunged messages are removed even without this flag. */
/* Queue changes so _sync() can be used. */
};
enum mail_sort_type {
MAIL_SORT_ARRIVAL = 0x0001,
MAIL_SORT_CC = 0x0002,
MAIL_SORT_DATE = 0x0004,
MAIL_SORT_FROM = 0x0008,
MAIL_SORT_SIZE = 0x0010,
MAIL_SORT_SUBJECT = 0x0020,
MAIL_SORT_TO = 0x0040,
MAIL_SORT_RELEVANCY = 0x0080,
MAIL_SORT_DISPLAYFROM = 0x0100,
MAIL_SORT_DISPLAYTO = 0x0200,
MAIL_SORT_POP3_ORDER = 0x0400,
/* Maximum size for sort program (each one separately + END) */
MAIL_SORT_MASK = 0x0fff,
};
enum mail_fetch_field {
MAIL_FETCH_FLAGS = 0x00000001,
MAIL_FETCH_MESSAGE_PARTS = 0x00000002,
MAIL_FETCH_STREAM_HEADER = 0x00000004,
MAIL_FETCH_STREAM_BODY = 0x00000008,
MAIL_FETCH_DATE = 0x00000010,
MAIL_FETCH_RECEIVED_DATE = 0x00000020,
MAIL_FETCH_SAVE_DATE = 0x00000040,
MAIL_FETCH_PHYSICAL_SIZE = 0x00000080,
MAIL_FETCH_VIRTUAL_SIZE = 0x00000100,
/* Set has_nuls / has_no_nuls fields */
MAIL_FETCH_NUL_STATE = 0x00000200,
MAIL_FETCH_STREAM_BINARY = 0x00000400,
/* specials: */
MAIL_FETCH_IMAP_BODY = 0x00001000,
MAIL_FETCH_IMAP_BODYSTRUCTURE = 0x00002000,
MAIL_FETCH_IMAP_ENVELOPE = 0x00004000,
MAIL_FETCH_FROM_ENVELOPE = 0x00008000,
MAIL_FETCH_HEADER_MD5 = 0x00010000,
MAIL_FETCH_STORAGE_ID = 0x00020000,
MAIL_FETCH_UIDL_BACKEND = 0x00040000,
MAIL_FETCH_MAILBOX_NAME = 0x00080000,
MAIL_FETCH_SEARCH_RELEVANCY = 0x00100000,
MAIL_FETCH_GUID = 0x00200000,
MAIL_FETCH_POP3_ORDER = 0x00400000,
MAIL_FETCH_REFCOUNT = 0x00800000,
MAIL_FETCH_BODY_SNIPPET = 0x01000000
};
enum mailbox_transaction_flags {
/* Hide changes done in this transaction from next view sync */
MAILBOX_TRANSACTION_FLAG_HIDE = 0x01,
/* External transaction. Should be used for copying and appends,
but nothing else. */
is done only if it can be done easily. */
MAILBOX_TRANSACTION_FLAG_REFRESH = 0x08,
/* Don't update caching decisions no matter what we do in this
transaction (useful for e.g. precaching) */
/* Sync transaction describes changes to mailbox that already happened
to another mailbox with whom we're syncing with (dsync) */
MAILBOX_TRANSACTION_FLAG_SYNC = 0x20,
/* Don't trigger any notifications for this transaction. This
especially means the notify plugin. This would normally be used only
with _FLAG_SYNC. */
/* Append fills in an existing stub mail for the specified UID,
instead of saving a new mail. This requires mailbox to be opened
with MAILBOX_FLAG_USE_STUBS. */
};
enum mailbox_sync_flags {
/* Make sure we sync all external changes done to mailbox */
MAILBOX_SYNC_FLAG_FULL_READ = 0x01,
/* Make sure we write all our internal changes into the mailbox */
MAILBOX_SYNC_FLAG_FULL_WRITE = 0x02,
/* If it's not too much trouble, check if there are some changes */
MAILBOX_SYNC_FLAG_FAST = 0x04,
/* Don't sync expunges from our view */
MAILBOX_SYNC_FLAG_NO_EXPUNGES = 0x08,
/* If mailbox is currently inconsistent, fix it instead of failing. */
/* Syncing after an EXPUNGE command. This is just an informational
flag for plugins. */
MAILBOX_SYNC_FLAG_EXPUNGE = 0x80,
/* Force doing a full resync of indexes. */
MAILBOX_SYNC_FLAG_FORCE_RESYNC = 0x100,
/* FIXME: kludge until something better comes along:
Request full text search index optimization */
MAILBOX_SYNC_FLAG_OPTIMIZE = 0x400
};
enum mailbox_sync_type {
MAILBOX_SYNC_TYPE_EXPUNGE = 0x01,
MAILBOX_SYNC_TYPE_FLAGS = 0x02,
MAILBOX_SYNC_TYPE_MODSEQ = 0x04
};
struct message_part;
struct mail_namespace;
struct mail_storage;
struct mail_search_args;
struct mail_search_result;
struct mail_keywords;
struct mail_save_context;
struct mailbox;
struct mailbox_transaction_context;
struct mailbox_status {
/* 0 if no private index (STATUS_HIGHESTPVTMODSEQ) */
/* NULL-terminated array of keywords (STATUS_KEYWORDS) */
/* These flags can be permanently modified (STATUS_PERMANENT_FLAGS) */
enum mail_flags permanent_flags;
/* These flags can be modified (STATUS_PERMANENT_FLAGS) */
enum mail_flags flags;
/* All keywords can be permanently modified (STATUS_PERMANENT_FLAGS) */
bool permanent_keywords:1;
/* More keywords can be created (STATUS_PERMANENT_FLAGS) */
bool allow_new_keywords:1;
/* Modseqs aren't permanent (index is in memory) (STATUS_HIGHESTMODSEQ) */
bool nonpermanent_modseqs:1;
/* Modseq tracking has never been enabled for this mailbox
yet. (STATUS_HIGHESTMODSEQ) */
bool no_modseq_tracking:1;
/* Messages have GUIDs (always set) */
bool have_guids:1;
/* mailbox_save_set_guid() works (always set) */
bool have_save_guids:1;
/* GUIDs are always 128bit (always set) */
bool have_only_guid128:1;
};
struct mailbox_cache_field {
const char *name;
int decision; /* enum mail_cache_decision_type */
/* last_used is unchanged, if it's (time_t)-1 */
};
struct mailbox_metadata {
/* sum of virtual size of all messages in mailbox */
/* sum of physical size of all messages in mailbox */
/* timestamp of when the first message was saved.
(time_t)-1 if there are no mails in the mailbox. */
/* Fields that have "temp" or "yes" caching decision. */
/* Fields that should be precached */
/* imapc backend returns this based on the remote NAMESPACE reply,
while currently other backends return "" and type the same as the
mailbox's real namespace type */
const char *backend_ns_prefix;
};
struct mailbox_update {
/* All non-zero fields are changed. */
/* Modify caching decisions, terminated by name=NULL */
const struct mailbox_cache_field *cache_updates;
};
struct mail_transaction_commit_changes {
/* Unreference the pool to free memory used by these changes. */
/* UIDVALIDITY for assigned UIDs. */
/* UIDs assigned to saved messages. Not necessarily ascending.
If UID assignment wasn't required (e.g. LDA), this array may also be
empty. Otherwise all of the saved mails got an UID. */
/* number of modseq changes that couldn't be changed as requested */
unsigned int ignored_modseq_changes;
/* TRUE if anything actually changed with this commit */
bool changed;
/* User doesn't have read ACL for the mailbox, so don't show the
uid_validity / saved_uids. */
bool no_read_perm;
};
struct mailbox_sync_rec {
enum mailbox_sync_type type;
};
struct mailbox_sync_status {
/* There are expunges that haven't been synced yet */
bool sync_delayed_expunges:1;
};
struct mailbox_expunge_rec {
/* IMAP UID */
/* 128 bit GUID. If the actual GUID has a different size, this
contains last bits of its SHA1 sum. */
};
enum mail_lookup_abort {
/* Perform everything no matter what it takes */
/* Abort if the operation can't be done fully using cache file */
};
struct mail {
/* always set */
struct mailbox_transaction_context *transaction;
bool expunged:1;
/* If the lookup is aborted, error is set to MAIL_ERROR_NOTPOSSIBLE */
};
struct mail_storage_callbacks {
/* "* OK <text>" */
void *context);
/* "* NO <text>" */
void *context);
};
struct mailbox_virtual_pattern {
struct mail_namespace *ns;
const char *pattern;
};
void mail_storage_init(void);
void mail_storage_deinit(void);
/* register all mail storages */
void mail_storage_register_all(void);
/* Register mail storage class with given name - all methods that are NULL
are set to default methods */
/* Find mail storage class by name */
/* Create a new instance of registered mail storage class with given
storage-specific data. If driver is NULL, it's tried to be autodetected
from ns location. If ns location is NULL, it uses the first storage that
exists. The storage is put into ns->storage. */
ATTR_NULL(2);
struct mail_storage **storage_r,
/* Returns the mail storage settings. */
const struct mail_storage_settings *
/* Set storage callback functions to use. */
struct mail_storage_callbacks *callbacks,
/* Purge storage's mailboxes (freeing disk space from expunged mails),
if supported by the storage. Otherwise just a no-op. */
/* Returns the error message of last occurred error. */
const char * ATTR_NOWARN_UNUSED_RESULT
/* Wrapper for mail_storage_get_last_error(); */
const char * ATTR_NOWARN_UNUSED_RESULT
ATTR_NULL(2);
/* Wrapper for mail_storage_get_last_error(); */
/* Save the last error until it's popped. This is useful for cases where the
storage has already failed, but the cleanup code path changes the error to
something else unwanted. */
/* Returns TRUE if mailboxes are files. */
/* Initialize mailbox without actually opening any files or verifying that
it exists. Note that append and copy may open the selected mailbox again
with possibly different readonly-state. */
enum mailbox_flags flags);
/* Like mailbox_alloc(), but use mailbox GUID. */
const guid_128_t guid,
enum mailbox_flags flags);
/* Get mailbox existence state. If auto_boxes=FALSE, return
MAILBOX_EXISTENCE_NONE for autocreated mailboxes that haven't been
physically created yet */
enum mailbox_existence *existence_r);
/* Open the mailbox. If this function isn't called explicitly, it's also called
internally by lib-storage when necessary. */
/* Open mailbox as read-only using the given stream as input. */
/* Close mailbox. Same as if mailbox was freed and re-allocated. */
/* Close and free the mailbox. */
const struct mail_namespace *ns2,
/* Returns TRUE if the mailbox is user's INBOX or another user's shared INBOX */
/* Change mailbox_verify_create_name() to not verify new mailbox name
restrictions (but still check that it's a valid existing name). This is
mainly used by dsync to make sure the sync works even though the original
name isn't valid anymore. */
/* Returns -1 if mailbox_create() is guaranteed to fail because the mailbox
name is invalid, 0 not. The error message contains a reason. */
/* Create a mailbox. Returns failure if it already exists. Mailbox name is
allowed to contain multiple new nonexistent hierarchy levels. If directory
is TRUE, the mailbox should be created so that it can contain children. The
mailbox itself doesn't have to be created as long as it shows up in LIST.
If update is non-NULL, its contents are used to set initial mailbox
metadata. */
/* Update existing mailbox's metadata. */
/* Delete mailbox (and its parent directory, if it has no siblings) */
/* Delete mailbox, but only if it's empty. If it's not, fails with
MAIL_ERROR_EXISTS. */
/* Rename mailbox (and its children). Renaming across different mailbox lists
is possible only between private namespaces and storages of the same type.
If the rename fails, the error is set to src's storage. */
/* Subscribe/unsubscribe mailbox. Subscribing to
nonexistent mailboxes is optional. */
/* Returns TRUE if mailbox is subscribed, FALSE if not. This function
doesn't refresh the subscriptions list, but assumes that it's been done by
e.g. mailbox_list_iter*(). */
/* Enable the given feature for the mailbox. */
/* Returns all enabled features. */
enum mailbox_feature
/* Returns storage of given mailbox */
/* Return namespace of given mailbox. */
struct mail_namespace *
/* Returns the storage's settings. */
const struct mail_storage_settings *
/* Returns the mailbox's settings, or NULL if there are none. */
const struct mailbox_settings *
/* Returns the (virtual) name of the given mailbox. */
/* Returns the backend name of given mailbox. */
/* Returns TRUE if mailbox is read-only. */
/* Returns TRUE if two mailboxes point to the same physical mailbox. */
/* Returns TRUE if mailbox is now in inconsistent state, meaning that
the message IDs etc. may have changed - only way to recover this
would be to fully close the mailbox and reopen it. With IMAP
connection this would mean a forced disconnection since we can't
do forced CLOSE. */
/* Gets the mailbox status information. If mailbox isn't opened yet, try to
return the results from mailbox list indexes. Otherwise the mailbox is
opened and synced. If the mailbox is already opened, no syncing is done
automatically. */
struct mailbox_status *status_r);
/* Gets the mailbox status, requires that mailbox is already opened. */
enum mailbox_status_items items,
struct mailbox_status *status_r);
/* Gets mailbox metadata */
struct mailbox_metadata *metadata_r);
/* Returns a mask of flags that are private to user in this mailbox
(as opposed to flags shared between users). */
/* Synchronize the mailbox. */
struct mailbox_sync_context *
struct mailbox_sync_rec *sync_rec_r);
struct mailbox_sync_status *status_r);
/* One-step mailbox synchronization. Use this if you don't care about
changes. */
/* Call given callback function when something changes in the mailbox. */
ATTR_NULL(3);
struct mailbox_transaction_context *
enum mailbox_transaction_flags flags);
int mailbox_transaction_commit(struct mailbox_transaction_context **t);
struct mailbox_transaction_context **t,
struct mail_transaction_commit_changes *changes_r);
void mailbox_transaction_rollback(struct mailbox_transaction_context **t);
/* Return the number of active transactions for the mailbox. */
modseq is larger than max_modseq. Save those messages' sequences to the
given array. */
void mailbox_transaction_set_max_modseq(struct mailbox_transaction_context *t,
struct mailbox *
mailbox_transaction_get_mailbox(const struct mailbox_transaction_context *t)
/* Convert uid range to sequence range. */
/* Convert sequence range to uid range. If sequences contain
(uint32_t)-1 to specify "*", they're preserved. */
/* Get list of messages' that have been expunged after prev_modseq and that
exist in uids_filter range. UIDs that have been expunged after the last
mailbox sync aren't returned. Returns TRUE if ok, FALSE if modseq is lower
than we can check for (but expunged_uids is still set as best as it can). */
/* Same as mailbox_get_expunges(), but return only list of UIDs. Not caring
about GUIDs is slightly faster. */
/* Initialize header lookup for given headers. */
struct mailbox_header_lookup_ctx *
/* Initialize new search request. If sort_program is non-NULL, the messages are
returned in the requested order, otherwise from first to last. */
mailbox_search_init(struct mailbox_transaction_context *t,
struct mail_search_args *args,
const enum mail_sort_type *sort_program,
struct mailbox_header_lookup_ctx *wanted_headers);
/* Deinitialize search request. */
/* Search the next message. Returns TRUE if found, FALSE if not. */
/* Like mailbox_search_next(), but don't spend too much time searching.
Returns FALSE with tryagain_r=FALSE if finished, and tryagain_r=TRUE if
more results will be returned by calling the function again. */
/* Returns TRUE if some messages were already expunged and we couldn't
determine correctly if those messages should have been returned in this
search. */
/* Remember the search result for future use. This must be called before the
first mailbox_search_next*() call. */
struct mail_search_result *
enum mailbox_search_result_flags flags);
/* Free memory used by search result. */
/* A simplified API for searching and saving the result. */
int mailbox_search_result_build(struct mailbox_transaction_context *t,
struct mail_search_args *args,
struct mail_search_result **result_r);
/* Return all messages' UIDs in the search result. */
const ARRAY_TYPE(seq_range) *
/* Return messages that have been removed and added since the last sync call.
This function must not be called if search result wasn't saved with
_QUEUE_SYNC flag. */
/* Build mail_keywords from NULL-terminated keywords list. Any duplicate
keywords are removed. Returns 0 if successful, -1 if there are invalid
keywords (error is set). */
struct mail_keywords **keywords_r);
/* Like mailbox_keywords_create(), except ignore invalid keywords. */
struct mail_keywords *
const char *const keywords[]);
struct mail_keywords *
/* Returns TRUE if keyword is valid, FALSE and error if not. */
const char **error_r);
/* Initialize saving a new mail. You must not try to save more than one mail
at a time. */
struct mail_save_context *
mailbox_save_alloc(struct mailbox_transaction_context *t);
/* Set the flags and keywords. Nothing is set by default. */
enum mail_flags flags,
struct mail_keywords *keywords);
/* Copy flags and keywords from given mail. */
/* Set message's modseq to be at least min_modseq. */
/* If received date isn't specified the current time is used. timezone_offset
specifies the preferred timezone in minutes, but it may be ignored if
backend doesn't support storing it. */
/* Set the "message saved" date. This should be set only when you're
replicating/restoring an existing mailbox. */
/* Set the envelope sender. This is currently used only with mbox files to
specify the address in From_-line. */
const char *envelope);
/* Set message's UID. If UID is smaller than the current next_uid, it's given
a new UID anyway. */
/* Set globally unique ID for the saved mail. A new GUID is generated by
default. This function should usually be called only when copying an
existing mail (or restoring a mail from backup). */
/* Set message's POP3 UIDL, if the backend supports it. */
const char *uidl);
/* Specify ordering for POP3 messages. The default is to add them to the end
of the mailbox. Not all backends support this. */
unsigned int order);
/* If dest_mail is set, the saved message can be accessed using it. Note that
setting it may require mailbox syncing, so don't set it unless you need
it. Also you shouldn't try to access it before mailbox_save_finish() is
called. */
/* Begin saving the message. All mail_save_set_*() calls must have been called
before this function. If the save initialization fails, the context is freed
and -1 is returned. After beginning the save you should keep calling
i_stream_read() and calling mailbox_save_continue() as long as there's
more input. */
struct mailbox_transaction_context *
/* Copy the given message. You'll need to specify the flags etc. using the
mailbox_save_*() functions. */
/* Move the given message. This is usually equivalent to copy+expunge,
but without enforcing quota. */
/* Same as mailbox_copy(), but treat the message as if it's being saved,
not copied. (For example: New mail delivered to multiple maildirs, with
each mails being hard link copies.) */
struct mailbox_header_lookup_ctx *wanted_headers)
ATTR_NULL(3);
/* Returns TRUE if successful, FALSE if message doesn't exist.
mail_*() functions shouldn't be called if FALSE is returned. */
after the next mail_set_seq/uid(). */
enum mail_fetch_field fields,
struct mailbox_header_lookup_ctx *headers)
ATTR_NULL(3);
/* Returns message's flags */
/* Returns message's keywords */
/* Returns message's keywords */
/* Returns message's modseq */
/* Returns message's private modseq, or 0 if message hasn't had any
private flag changes. This is useful only for shared mailboxes that have
a private index defined. */
/* Returns message's MIME parts */
/* Get the Date-header of the mail. Timezone is in minutes. date=0 if it
wasn't found or it was invalid. */
/* Get the time when the mail was received (IMAP INTERNALDATE). */
/* Get the time when the mail was saved into this mailbox. This time may not
always be entirely reliable. */
/* Get the space used by the mail as seen by the reader. Linefeeds are always
counted as being CR+LF. */
/* Get the size of the stream returned by mail_get_stream(). */
/* Get value for single header field, or NULL if header wasn't found.
Returns 1 if header was found, 0 if not, -1 if error. */
const char **value_r);
/* Like mail_get_first_header(), but decode MIME encoded words to UTF-8.
Also multiline headers are returned unfolded.
Do not use this function for getting structured fields (e.g. address fields),
because decoding may break the structuring. Instead parse them first and
only afterwards decode the encoded words. */
const char **value_r);
/* Return a NULL-terminated list of values for each found field.
Returns 1 if headers were found, 0 if not (value_r==NULL) or -1 if error. */
const char *const **value_r);
/* Like mail_get_headers(), but decode MIME encoded words to UTF-8.
Also multiline headers are returned unfolded.
Do not use for structured fields (see mail_get_first_header_utf8()). */
const char *const **value_r);
/* Returns stream containing specified headers. The returned stream will be
automatically freed when the mail is closed, or when another
mail_get_header_stream() call is made (so you can't have multiple header
streams open at the same time). */
struct mailbox_header_lookup_ctx *headers,
/* Returns input stream pointing to beginning of message header.
hdr_size and body_size are updated unless they're NULL. The returned stream
is destroyed automatically, don't unreference it. */
/* Same as mail_get_stream(), but specify a reason why the mail is being read.
This can be useful for debugging purposes. */
struct message_size *body_size,
/* Similar to mail_get_stream(), but the stream may or may not contain the
message body. */
/* Same as mail_get_hdr_stream(), but specify a reason why the header is being
read. This can be useful for debugging purposes. */
struct message_size *hdr_size,
/* Returns the message part's body decoded to 8bit binary. If the
Content-Transfer-Encoding isn't supported, returns -1 and sets error to
MAIL_ERROR_CONVERSION. If the part refers to a multipart, all of its
children are returned decoded. */
/* Like mail_get_binary_stream(), but only return the size. */
unsigned int *lines_r);
/* Get any of the "special" fields. Unhandled specials are returned as "". */
const char **value_r);
/* Returns the mail for the physical message. Normally this is the mail itself,
but in virtual mailboxes it points to the backend mailbox. */
/* Update message flags. */
enum mail_flags flags);
/* Update message keywords. */
struct mail_keywords *keywords);
/* Update message's modseq to be at least min_modseq. */
/* Update message's private modseq to be at least min_pvt_modseq. */
/* Update message's POP3 UIDL (if possible). */
/* Expunge this message. Sequence numbers don't change until commit. */
/* Add missing fields to cache. */
/* Mark a cached field corrupted and have it recalculated. */
enum mail_fetch_field field,
const char *reason);
/* Return 128 bit GUID using input string. If guid is already 128 bit hex
encoded, it's returned as-is. Otherwise SHA1 sum is taken and its last
128 bits are returned. */
/* Parse a human-writable string into a timestamp. utc_r controls whether
the returned timestamp should be treated as an exact UTC time (TRUE), or
whether this is a human-given date where the timestamp could be adjusted
by the matched mails' timezones (see MAIL_SEARCH_ARG_FLAG_USE_TZ).
Returns 0 and timestamp on success, -1 if the string couldn't be parsed.
Currently supported string formats: yyyy-mm-dd (utc=FALSE),
imap date (utc=FALSE), unix timestamp (utc=TRUE), interval (e.g. n days,
utc=TRUE). */
bool *utc_r);
#endif