dbox-file.h revision 147a788fea2a88f7125b27226451271d55cf5b01
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina#ifndef DBOX_FILE_H
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina#define DBOX_FILE_H
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* The file begins with a header followed by zero or more messages:
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina <dbox message header>
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina <LF>
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina <message body>
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina <metadata>
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina Metadata block begins with DBOX_MAGIC_POST, followed by zero or more lines
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina in format <key character><value><LF>. The block ends with an empty line.
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina Unknown metadata should be ignored, but preserved when copying.
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina There should be no duplicates for the current metadata, but future
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina extensions may need them so they should be preserved.
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina*/
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina#define DBOX_VERSION 2
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina#define DBOX_MAGIC_PRE "\001\002"
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina#define DBOX_MAGIC_POST "\n\001\003\n"
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* prefer flock(). fcntl() locking currently breaks if trying to access the
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina same file from multiple mail_storages within same process. that's why we
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina fallback to dotlocks. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina#ifdef HAVE_FLOCK
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina# define DBOX_FILE_LOCK_METHOD_FLOCK
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina#endif
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastruct dbox_file;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastruct stat;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaenum dbox_header_key {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Must be sizeof(struct dbox_message_header) when appending (hex) */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DBOX_HEADER_MSG_HEADER_SIZE = 'M',
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Creation UNIX timestamp (hex) */
0e238c259c066cf997aaa940d33d6bda96c15925Sumit Bose DBOX_HEADER_CREATE_STAMP = 'C',
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* metadata used by old Dovecot versions */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DBOX_HEADER_OLDV1_APPEND_OFFSET = 'A'
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina};
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaenum dbox_metadata_key {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Globally unique identifier for the message. Preserved when
a012a71f21bf1a4687e58085f19c18cc5b2bbaddNikolai Kondrashov copying. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DBOX_METADATA_GUID = 'G',
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* POP3 UIDL overriding the default format */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DBOX_METADATA_POP3_UIDL = 'P',
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* POP3 message ordering (for migrated mails) */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DBOX_METADATA_POP3_ORDER = 'O',
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Received UNIX timestamp in hex */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DBOX_METADATA_RECEIVED_TIME = 'R',
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Physical message size in hex. Necessary only if it differs from
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina the dbox_message_header.message_size_hex, for example because the
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina message is compressed. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DBOX_METADATA_PHYSICAL_SIZE = 'Z',
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Virtual message size in hex (line feeds counted as CRLF) */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DBOX_METADATA_VIRTUAL_SIZE = 'V',
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Pointer to external message data. Format is:
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina 1*(<start offset> <byte count> <options> <ref>) */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DBOX_METADATA_EXT_REF = 'X',
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Mailbox name where this message was originally saved to.
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina When rebuild finds a message whose mailbox is unknown, it's
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina placed to this mailbox. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DBOX_METADATA_ORIG_MAILBOX = 'B',
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* metadata used by old Dovecot versions */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DBOX_METADATA_OLDV1_EXPUNGED = 'E',
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DBOX_METADATA_OLDV1_FLAGS = 'F',
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DBOX_METADATA_OLDV1_KEYWORDS = 'K',
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DBOX_METADATA_OLDV1_SAVE_TIME = 'S',
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DBOX_METADATA_OLDV1_SPACE = ' '
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina};
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaenum dbox_message_type {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Normal message */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DBOX_MESSAGE_TYPE_NORMAL = 'N'
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina};
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastruct dbox_message_header {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina unsigned char magic_pre[2];
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina unsigned char type;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina unsigned char space1;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina unsigned char oldv1_uid_hex[8];
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina unsigned char space2;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina unsigned char message_size_hex[16];
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* <space reserved for future extensions, LF is always last> */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina unsigned char save_lf;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina};
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastruct dbox_metadata_header {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina unsigned char magic_post[sizeof(DBOX_MAGIC_POST)-1];
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina};
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastruct dbox_file {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct dbox_storage *storage;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina int refcount;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina time_t create_time;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina unsigned int file_version;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina unsigned int file_header_size;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina unsigned int msg_header_size;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina const char *cur_path;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina char *primary_path, *alt_path;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina int fd;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct istream *input;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina#ifdef DBOX_FILE_LOCK_METHOD_FLOCK
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct file_lock *lock;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina#else
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct dotlock *lock;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina#endif
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina uoff_t cur_offset;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina uoff_t cur_physical_size;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Metadata for the currently seeked metadata block. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina pool_t metadata_pool;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ARRAY(const char *) metadata;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina uoff_t metadata_read_offset;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina unsigned int appending:1;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina unsigned int deleted:1;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina unsigned int corrupted:1;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina};
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastruct dbox_file_append_context {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct dbox_file *file;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina uoff_t first_append_offset, last_checkpoint_offset, last_flush_offset;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct ostream *output;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina};
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina#define dbox_file_is_open(file) ((file)->fd != -1)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina#define dbox_file_is_in_alt(file) ((file)->cur_path == (file)->alt_path)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinavoid dbox_file_init(struct dbox_file *file);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinavoid dbox_file_unref(struct dbox_file **file);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* Open the file. Returns 1 if ok, 0 if file header is corrupted, -1 if error.
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina If file is deleted, deleted_r=TRUE and 1 is returned. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaint dbox_file_open(struct dbox_file *file, bool *deleted_r);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* Try to open file only from primary path. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaint dbox_file_open_primary(struct dbox_file *file, bool *notfound_r);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* Close the file handle from the file, but don't free it. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinavoid dbox_file_close(struct dbox_file *file);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* fstat() or stat() the file. If file is already deleted, fails with
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina errno=ENOENT. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaint dbox_file_stat(struct dbox_file *file, struct stat *st_r);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* Try to lock the dbox file. Returns 1 if ok, 0 if already locked by someone
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina else, -1 if error. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaint dbox_file_try_lock(struct dbox_file *file);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinavoid dbox_file_unlock(struct dbox_file *file);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* Seek to given offset in file. Returns 1 if ok/expunged, 0 if file/offset is
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina corrupted, -1 if I/O error. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaint dbox_file_seek(struct dbox_file *file, uoff_t offset);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* Start seeking at the beginning of the file. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinavoid dbox_file_seek_rewind(struct dbox_file *file);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* Seek to next message after current one. If there are no more messages,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina returns 0 and last_r is set to TRUE. Returns 1 if ok, 0 if file is
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina corrupted, -1 if I/O error. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaint dbox_file_seek_next(struct dbox_file *file, uoff_t *offset_r, bool *last_r);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
7c074ba2f923985ab0d4f9d6a5e01ff3f2f0a7a8Jakub Hrozek/* Start appending to dbox file */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastruct dbox_file_append_context *dbox_file_append_init(struct dbox_file *file);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* Finish writing appended mails. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaint dbox_file_append_commit(struct dbox_file_append_context **ctx);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* Truncate appended mails. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinavoid dbox_file_append_rollback(struct dbox_file_append_context **ctx);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* Get output stream for appending a new message. Returns 1 if ok, 0 if file
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina can't be appended to (old file version or corruption) or -1 if error. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaint dbox_file_get_append_stream(struct dbox_file_append_context *ctx,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct ostream **output_r);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* Call after message has been fully saved. If this isn't done, the writes
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina since the last checkpoint are truncated. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinavoid dbox_file_append_checkpoint(struct dbox_file_append_context *ctx);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* Flush output buffer. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaint dbox_file_append_flush(struct dbox_file_append_context *ctx);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* Read current message's metadata. Returns 1 if ok, 0 if metadata is
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina corrupted, -1 if I/O error. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaint dbox_file_metadata_read(struct dbox_file *file);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* Return wanted metadata value, or NULL if not found. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaconst char *dbox_file_metadata_get(struct dbox_file *file,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina enum dbox_metadata_key key);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* Returns DBOX_METADATA_PHYSICAL_SIZE if set, otherwise physical size from
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina header. They differ only for e.g. compressed mails. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinauoff_t dbox_file_get_plaintext_size(struct dbox_file *file);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* Fix a broken dbox file by rename()ing over it with a fixed file. Everything
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina before start_offset is assumed to be valid and is simply copied. The file
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina is reopened afterwards. Returns 1 if ok, 0 if the resulting file has no
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina mails and was deleted, -1 if I/O error. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaint dbox_file_fix(struct dbox_file *file, uoff_t start_offset);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* Delete the given dbox file. Returns 1 if deleted, 0 if file wasn't found
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina or -1 if error. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaint dbox_file_unlink(struct dbox_file *file);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* Fill dbox_message_header with given size. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinavoid dbox_msg_header_fill(struct dbox_message_header *dbox_msg_hdr,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina uoff_t message_size);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinavoid dbox_file_set_syscall_error(struct dbox_file *file, const char *function);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinavoid dbox_file_set_corrupted(struct dbox_file *file, const char *reason, ...)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ATTR_FORMAT(2, 3);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* private: */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaconst char *dbox_generate_tmp_filename(void);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinavoid dbox_file_free(struct dbox_file *file);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaint dbox_file_header_write(struct dbox_file *file, struct ostream *output);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaint dbox_file_read_mail_header(struct dbox_file *file, uoff_t *physical_size_r);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaint dbox_file_metadata_skip_header(struct dbox_file *file);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina#endif
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina