#ifndef DBOX_FILE_H
#define DBOX_FILE_H
/* The file begins with a header followed by zero or more messages:
<dbox message header>
<LF>
<message body>
<metadata>
Metadata block begins with DBOX_MAGIC_POST, followed by zero or more lines
in format <key character><value><LF>. The block ends with an empty line.
Unknown metadata should be ignored, but preserved when copying.
There should be no duplicates for the current metadata, but future
extensions may need them so they should be preserved.
*/
/* prefer flock(). fcntl() locking currently breaks if trying to access the
same file from multiple mail_storages within same process. that's why we
fallback to dotlocks. */
#ifdef HAVE_FLOCK
# define DBOX_FILE_LOCK_METHOD_FLOCK
#endif
struct dbox_file;
struct stat;
enum dbox_header_key {
/* Must be sizeof(struct dbox_message_header) when appending (hex) */
/* Creation UNIX timestamp (hex) */
/* metadata used by old Dovecot versions */
};
/* NOTE: all valid keys are uppercase characters. if this changes, change
dbox-file-fix.c:dbox_file_match_post_magic() to recognize them */
enum dbox_metadata_key {
/* Globally unique identifier for the message. Preserved when
copying. */
/* POP3 UIDL overriding the default format */
/* POP3 message ordering (for migrated mails) */
/* Received UNIX timestamp in hex */
/* Physical message size in hex. Necessary only if it differs from
the dbox_message_header.message_size_hex, for example because the
message is compressed. */
/* Virtual message size in hex (line feeds counted as CRLF) */
/* Pointer to external message data. Format is:
1*(<start offset> <byte count> <options> <ref>) */
/* Mailbox name where this message was originally saved to.
When rebuild finds a message whose mailbox is unknown, it's
placed to this mailbox. */
/* metadata used by old Dovecot versions */
};
enum dbox_message_type {
/* Normal message */
};
struct dbox_message_header {
unsigned char type;
unsigned char space1;
unsigned char space2;
/* <space reserved for future extensions, LF is always last> */
unsigned char save_lf;
};
struct dbox_metadata_header {
};
struct dbox_file {
int refcount;
unsigned int file_version;
unsigned int file_header_size;
unsigned int msg_header_size;
const char *cur_path;
int fd;
#ifdef DBOX_FILE_LOCK_METHOD_FLOCK
#else
#endif
/* Metadata for the currently seeked metadata block. */
};
struct dbox_file_append_context {
};
/* Open the file. Returns 1 if ok, 0 if file header is corrupted, -1 if error.
If file is deleted, deleted_r=TRUE and 1 is returned. */
/* Try to open file only from primary path. */
/* Close the file handle from the file, but don't free it. */
/* fstat() or stat() the file. If file is already deleted, fails with
errno=ENOENT. */
/* Try to lock the dbox file. Returns 1 if ok, 0 if already locked by someone
else, -1 if error. */
corrupted, -1 if I/O error. */
/* Start seeking at the beginning of the file. */
/* Seek to next message after current one. If there are no more messages,
returns 0 and last_r is set to TRUE. Returns 1 if ok, 0 if file is
corrupted, -1 if I/O error. */
/* Start appending to dbox file */
/* Finish writing appended mails. */
/* Truncate appended mails. */
/* Get output stream for appending a new message. Returns 1 if ok, 0 if file
can't be appended to (old file version or corruption) or -1 if error. */
/* Call after message has been fully saved. If this isn't done, the writes
since the last checkpoint are truncated. */
/* Flush output buffer. */
/* Read current message's metadata. Returns 1 if ok, 0 if metadata is
corrupted, -1 if I/O error. */
/* Return wanted metadata value, or NULL if not found. */
enum dbox_metadata_key key);
/* Returns DBOX_METADATA_PHYSICAL_SIZE if set, otherwise physical size from
header. They differ only for e.g. compressed mails. */
/* Fix a broken dbox file by rename()ing over it with a fixed file. Everything
before start_offset is assumed to be valid and is simply copied. The file
is reopened afterwards. Returns 1 if ok, 0 if the resulting file has no
mails and was deleted, -1 if I/O error. */
/* Delete the given dbox file. Returns 1 if deleted, 0 if file wasn't found
or -1 if error. */
/* Fill dbox_message_header with given size. */
/* private: */
const char *dbox_generate_tmp_filename(void);
#endif