dbox-index.h revision 777ff25e82e0305e2696bcbe3c6e0274e3e8ce10
#ifndef DBOX_INDEX_H
#define DBOX_INDEX_H
/* The file begins with a header followed by zero or more records:
<file id> <status><expunges><dirty> [<status-specific data>]<LF>
<expunges> contains either '0' = no or 'E' = file contains messages marked
as expunged, which should be removed when possible.
<dirty> contains either '0' = no or 'D' = file contains messages that don't
have up-to-date metadata. When expunge copies message data to a new file,
the dirty state should be flushed for the copied messages (or the dirty
state should be copied).
<expunges> and <dirty> can be written without locking the record, so syncing
can update them even while messages are being appended to the file.
If status-specific data isn't specified for the given status, it should be
ignored. Especially 'U' status may contain different kinds of data.
*/
struct dbox_file;
struct dbox_index_append_context;
#define DBOX_INDEX_VERSION '1'
enum dbox_index_file_status {
/* File can be appended to as long as <expunges> is zero. It must be
locked when expunging. status-specific data contains a %08x lock
timestamp. */
/* File is currently being appended to. If this record can be locked,
the append crashed and this file should be opened for fixing
(truncate non-committed appends from the file). */
/* File can't be appended to. */
/* File contains only a single message. It can't be appended to
and it can be expunged by unlinking the file. */
/* The file has already been unlinked, this record should be removed. */
/* File is a maildir file. Status-specific data contains
old: <uid> <filename>
new: <uid> [<maildir extra field>] :<filename>
*/
};
enum dbox_index_file_lock_status {
/* File was locked (ret=1) */
/* File didn't have appendable status (ret=1) */
/* File was already locked by someone else (ret=0) */
/* File is already unlinked (ret=0) */
};
struct dbox_index_file_header {
/* DBOX_INDEX_VERSION */
unsigned char version;
unsigned char space_1;
/* Current UIDVALIDITY */
unsigned char uid_validity_hex[8];
unsigned char space_2;
/* Next available message UID */
unsigned char next_uid_hex[8];
unsigned char space_3;
/* Next available <file id> */
unsigned char next_file_id_hex[8];
};
struct dbox_index_record {
unsigned int file_id;
unsigned int file_offset;
enum dbox_index_file_status status;
const char *data;
unsigned int expunges:1;
unsigned int dirty:1;
unsigned int locked:1;
};
struct dbox_index_record *
/* Try to lock a file record. Only appendable files are actually locked.
Returns 1 if lock acquired or not needed, 0 if we failed to get a lock or
file is unlinked, -1 if error. lock_status_r is set if 0 or 1 is returned. */
struct dbox_index_append_context *
/* Request file for saving a new message with given size. If an existing file
can be used, the record is locked and updated in index. Returns 0 if ok,
-1 if error. */
/* Assign file_ids to all appended files. */
/* Returns 0 if ok, -1 if error. */
#endif