/usr/include/dovecot/dbox-file.h is in dovecot-dev 1:2.2.9-1ubuntu2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | #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.
*/
#define DBOX_VERSION 2
#define DBOX_MAGIC_PRE "\001\002"
#define DBOX_MAGIC_POST "\n\001\003\n"
/* 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) */
DBOX_HEADER_MSG_HEADER_SIZE = 'M',
/* Creation UNIX timestamp (hex) */
DBOX_HEADER_CREATE_STAMP = 'C',
/* metadata used by old Dovecot versions */
DBOX_HEADER_OLDV1_APPEND_OFFSET = 'A'
};
/* 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. */
DBOX_METADATA_GUID = 'G',
/* POP3 UIDL overriding the default format */
DBOX_METADATA_POP3_UIDL = 'P',
/* POP3 message ordering (for migrated mails) */
DBOX_METADATA_POP3_ORDER = 'O',
/* Received UNIX timestamp in hex */
DBOX_METADATA_RECEIVED_TIME = 'R',
/* 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. */
DBOX_METADATA_PHYSICAL_SIZE = 'Z',
/* 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> <options> <ref>) */
DBOX_METADATA_EXT_REF = 'X',
/* Mailbox name where this message was originally saved to.
When rebuild finds a message whose mailbox is unknown, it's
placed to this mailbox. */
DBOX_METADATA_ORIG_MAILBOX = 'B',
/* metadata used by old Dovecot versions */
DBOX_METADATA_OLDV1_EXPUNGED = 'E',
DBOX_METADATA_OLDV1_FLAGS = 'F',
DBOX_METADATA_OLDV1_KEYWORDS = 'K',
DBOX_METADATA_OLDV1_SAVE_TIME = 'S',
DBOX_METADATA_OLDV1_SPACE = ' '
};
enum dbox_message_type {
/* Normal message */
DBOX_MESSAGE_TYPE_NORMAL = 'N'
};
struct dbox_message_header {
unsigned char magic_pre[2];
unsigned char type;
unsigned char space1;
unsigned char oldv1_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 {
unsigned char magic_post[sizeof(DBOX_MAGIC_POST)-1];
};
struct dbox_file {
struct dbox_storage *storage;
int refcount;
time_t create_time;
unsigned int file_version;
unsigned int file_header_size;
unsigned int msg_header_size;
const char *cur_path;
char *primary_path, *alt_path;
int fd;
struct istream *input;
#ifdef DBOX_FILE_LOCK_METHOD_FLOCK
struct file_lock *lock;
#else
struct dotlock *lock;
#endif
uoff_t cur_offset;
uoff_t cur_physical_size;
/* Metadata for the currently seeked metadata block. */
pool_t metadata_pool;
ARRAY(const char *) metadata;
uoff_t metadata_read_offset;
unsigned int appending:1;
unsigned int deleted:1;
unsigned int corrupted:1;
};
struct dbox_file_append_context {
struct dbox_file *file;
uoff_t first_append_offset, last_checkpoint_offset, last_flush_offset;
struct ostream *output;
};
#define dbox_file_is_open(file) ((file)->fd != -1)
#define dbox_file_is_in_alt(file) ((file)->cur_path == (file)->alt_path)
void dbox_file_init(struct dbox_file *file);
void dbox_file_unref(struct dbox_file **file);
/* 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. */
int dbox_file_open(struct dbox_file *file, bool *deleted_r);
/* Try to open file only from primary path. */
int dbox_file_open_primary(struct dbox_file *file, bool *notfound_r);
/* Close the file handle from the file, but don't free it. */
void dbox_file_close(struct dbox_file *file);
/* fstat() or stat() the file. If file is already deleted, fails with
errno=ENOENT. */
int dbox_file_stat(struct dbox_file *file, struct stat *st_r);
/* Try to lock the dbox file. Returns 1 if ok, 0 if already locked by someone
else, -1 if error. */
int dbox_file_try_lock(struct dbox_file *file);
void dbox_file_unlock(struct dbox_file *file);
/* Seek to given offset in file. Returns 1 if ok/expunged, 0 if file/offset is
corrupted, -1 if I/O error. */
int dbox_file_seek(struct dbox_file *file, uoff_t offset);
/* Start seeking at the beginning of the file. */
void dbox_file_seek_rewind(struct dbox_file *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. */
int dbox_file_seek_next(struct dbox_file *file, uoff_t *offset_r, bool *last_r);
/* Start appending to dbox file */
struct dbox_file_append_context *dbox_file_append_init(struct dbox_file *file);
/* Finish writing appended mails. */
int dbox_file_append_commit(struct dbox_file_append_context **ctx);
/* Truncate appended mails. */
void dbox_file_append_rollback(struct dbox_file_append_context **ctx);
/* 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. */
int dbox_file_get_append_stream(struct dbox_file_append_context *ctx,
struct ostream **output_r);
/* Call after message has been fully saved. If this isn't done, the writes
since the last checkpoint are truncated. */
void dbox_file_append_checkpoint(struct dbox_file_append_context *ctx);
/* Flush output buffer. */
int dbox_file_append_flush(struct dbox_file_append_context *ctx);
/* Read current message's metadata. Returns 1 if ok, 0 if metadata is
corrupted, -1 if I/O error. */
int dbox_file_metadata_read(struct dbox_file *file);
/* Return wanted metadata value, or NULL if not found. */
const char *dbox_file_metadata_get(struct dbox_file *file,
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. */
uoff_t dbox_file_get_plaintext_size(struct dbox_file *file);
/* 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. */
int dbox_file_fix(struct dbox_file *file, uoff_t start_offset);
/* Delete the given dbox file. Returns 1 if deleted, 0 if file wasn't found
or -1 if error. */
int dbox_file_unlink(struct dbox_file *file);
/* Fill dbox_message_header with given size. */
void dbox_msg_header_fill(struct dbox_message_header *dbox_msg_hdr,
uoff_t message_size);
void dbox_file_set_syscall_error(struct dbox_file *file, const char *function);
void dbox_file_set_corrupted(struct dbox_file *file, const char *reason, ...)
ATTR_FORMAT(2, 3);
/* private: */
const char *dbox_generate_tmp_filename(void);
void dbox_file_free(struct dbox_file *file);
int dbox_file_header_write(struct dbox_file *file, struct ostream *output);
int dbox_file_read_mail_header(struct dbox_file *file, uoff_t *physical_size_r);
int dbox_file_metadata_skip_header(struct dbox_file *file);
#endif
|