dbox-file.h revision 777ff25e82e0305e2696bcbe3c6e0274e3e8ce10
#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 a line containing
zero or more spaces. The spaces can be used for writing more headers.
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.
*/
#define DBOX_VERSION 1
#define DBOX_MAGIC_PRE "\001\002"
#define DBOX_MAGIC_POST "\n\001\003\n"
/* If file_id has this flag set, the file is a single file with file_id=UID. */
#define DBOX_FILE_ID_FLAG_UID 0x80000000
enum dbox_header_key {
/* Offset for appending next message. In %08x format so it can be
updated without moving data in header. If messages have been
expunged and file must not be appended anymore, the value is filled
with 'X'. */
DBOX_HEADER_APPEND_OFFSET = 'A',
/* Must be sizeof(struct dbox_message_header) when appending (hex) */
DBOX_HEADER_MSG_HEADER_SIZE = 'M',
/* Creation UNIX timestamp (hex) */
DBOX_HEADER_CREATE_STAMP = 'C'
};
enum dbox_metadata_flags {
};
enum dbox_metadata_key {
/* metadata used by old Dovecot versions */
DBOX_METADATA_OLD_EXPUNGED = 'E',
DBOX_METADATA_OLD_FLAGS = 'F',
DBOX_METADATA_OLD_KEYWORDS = 'K',
/* Globally unique identifier for the message. Preserved when
copying. */
DBOX_METADATA_GUID = 'G',
/* POP3 UIDL overriding the default format */
DBOX_METADATA_POP3_UIDL = 'P',
/* Received UNIX timestamp in hex */
DBOX_METADATA_RECEIVED_TIME = 'R',
/* Saved UNIX timestamp in hex */
DBOX_METADATA_SAVE_TIME = 'S',
/* Virtual message size in hex (line feeds counted as CRLF) */
DBOX_METADATA_VIRTUAL_SIZE = 'V',
/* Pointer to external message data. Format is:
1*(<start offset> <byte count> <ref>) */
DBOX_METADATA_EXT_REF = 'X',
/* End of metadata block. The spaces can be used for writing more
metadata. */
DBOX_METADATA_SPACE = ' '
};
enum dbox_message_type {
/* Normal message */
DBOX_MESSAGE_TYPE_NORMAL = 'N',
/* Parts of the message exists outside the following data.
See the metadata for how to find them. */
};
struct dbox_message_header {
unsigned char magic_pre[2];
unsigned char type;
unsigned char space1;
unsigned char uid_hex[8];
unsigned char space2;
unsigned char message_size_hex[16];
/* <space reserved for future extensions, LF is always last> */
unsigned char save_lf;
};
struct dbox_metadata_header {
};
struct dbox_file {
struct dbox_mailbox *mbox;
int refcount;
unsigned int file_id;
unsigned int file_header_size;
unsigned int msg_header_size;
unsigned int append_offset_header_pos;
unsigned int append_count;
char *fname;
char *current_path;
int fd;
/* Metadata for the currently seeked metadata block. */
ARRAY_DEFINE(metadata, const char *);
unsigned int alt_path:1;
unsigned int maildir_file:1;
unsigned int nonappendable:1;
unsigned int deleted:1;
};
extern char dbox_mail_flag_chars[DBOX_METADATA_FLAGS_COUNT];
struct dbox_file *
/* Free all currently opened files. */
/* Assign a newly created file (file_id=0) a new id. */
/* If file_id is 0, open the file, otherwise create it. Returns 1 if ok,
0 if read_header=TRUE and opened file was broken, -1 if error. If file is
deleted, deleted_r=TRUE and 1 is returned. */
bool *deleted_r);
/* Open the file's fd if it's currently closed. Assumes that the file exists. */
/* Close the file handle from the file, but don't free it. */
call this function for a non-opened file. */
/* Seek to given offset in file and return the message's input stream, UID
-1 if I/O error. */
/* Seek to next message after given offset, or to first message if offset=0.
If there are no more messages, uid_r is set to 0. Returns 1 if ok, 0 if
/* Returns TRUE if mail_size bytes can be appended to the file. */
/* Get output stream for appending a new message. Returns 1 if ok, 0 if
file can't be appended to (limits reached, expunges, corrupted) or
-1 if error. If 0 is returned, index is also updated. */
/* Returns the next offset for append a message. dbox_file_get_append_stream()
must have been called for this file already at least once. */
/* Truncate file to append_offset */
/* Finish appending the current mail. */
corrupted, -1 if I/O error. If message has already been expunged,
expunged_r=TRUE and 1 is returned. */
bool *expunged_r);
/* Like dbox_file_metadata_seek(), but the offset points to beginning of the
message. The function internally reads the message header to find the
metadata offset. */
bool *expunged_r);
/* Return wanted metadata value, or NULL if not found. */
enum dbox_metadata_key key);
/* Write all metadata to output stream. Returns 0 if ok, -1 if I/O error. */
/* Move the file to alt path or back. */
#endif