maildir-uidlist.c revision d656ea23231ca1232b2dae327cea83bb44c6f6ff
5cad3e82e8c017bc189c4cecc00541ec19a2a6e2Julian Kornberger/* Copyright (c) 2003-2010 Dovecot authors, see the included COPYING file */
5cad3e82e8c017bc189c4cecc00541ec19a2a6e2Julian Kornberger Version 1 format has been used for most versions of Dovecot up to v1.0.x.
5cad3e82e8c017bc189c4cecc00541ec19a2a6e2Julian Kornberger It's also compatible with Courier IMAP's courierimapuiddb file.
5cad3e82e8c017bc189c4cecc00541ec19a2a6e2Julian Kornberger The format is:
5cad3e82e8c017bc189c4cecc00541ec19a2a6e2Julian Kornberger header: 1 <uid validity> <next uid>
5cad3e82e8c017bc189c4cecc00541ec19a2a6e2Julian Kornberger entry: <uid> <filename>
5cad3e82e8c017bc189c4cecc00541ec19a2a6e2Julian Kornberger Version 2 format was written by a few development Dovecot versions, but
5cad3e82e8c017bc189c4cecc00541ec19a2a6e2Julian Kornberger v1.0.x still parses the format. The format has <flags> field after <uid>.
5cad3e82e8c017bc189c4cecc00541ec19a2a6e2Julian Kornberger Version 3 format is an extensible format used by Dovecot v1.1 and later.
5cad3e82e8c017bc189c4cecc00541ec19a2a6e2Julian Kornberger It's also parsed by v1.0.2 (and later). The format is:
5cad3e82e8c017bc189c4cecc00541ec19a2a6e2Julian Kornberger header: 3 [<key><value> ...]
5cad3e82e8c017bc189c4cecc00541ec19a2a6e2Julian Kornberger entry: <uid> [<key><value> ...] :<filename>
f5a01e37663bdf559d6e251191b5097dd6f28ea5Julian Kornberger See enum maildir_uidlist_*_ext_key for used keys.
#include "hash.h"
#include "istream.h"
#include "ostream.h"
#include "str.h"
#include "hex-binary.h"
#include "file-dotlock.h"
#include "close-keep-errno.h"
#include "nfs-workarounds.h"
#include "eacces-error.h"
#include "maildir-storage.h"
#include "maildir-filename.h"
#include "maildir-uidlist.h"
#include <stdio.h>
#include <stdlib.h>
struct maildir_uidlist_rec {
char *filename;
struct maildir_uidlist {
char *path;
int fd;
unsigned int lock_count;
unsigned int change_counter;
unsigned int version;
unsigned int hdr_next_uid;
struct maildir_uidlist_sync_ctx {
unsigned int new_files_count;
unsigned int finish_change_counter;
struct maildir_uidlist_iter_ctx {
unsigned int change_counter;
bool refresh_when_locked)
int i, ret;
if (ret > 0)
if (ret == 0) {
path);
if (refresh) {
return TRUE;
const char *control_dir;
return uidlist;
const char *fmt, ...)
return idx;
const char **line_p,
line++;
return FALSE;
return TRUE;
const char *line)
unsigned int count;
uid = 0;
line++;
line);
return FALSE;
return FALSE;
return FALSE;
return TRUE;
return FALSE;
bool ret;
T_BEGIN {
rec);
} T_END;
if (!ret) {
return FALSE;
return FALSE;
return TRUE;
return FALSE;
return TRUE;
const char *line,
unsigned int *uid_validity_r,
unsigned int *next_uid_r)
char key;
const char *value;
switch (key) {
const char *line;
int ret;
case UIDLIST_VERSION:
T_BEGIN {
&next_uid);
} T_END;
if (ret < 0)
const char *line;
last_read_offset = 0;
if (ret > 0) {
ret = 0;
orig_uid_validity != 0) {
if (ret == 0) {
} else if (ret > 0) {
} else if (!*retry_r) {
if (ret <= 0) {
return ret;
int ret;
bool recreated;
int ret;
if (ret <= 0) {
if (!recreated)
bool retry;
int ret;
if (!retry)
if (ret >= 0) {
return ret;
int ret;
return ret;
const char **fname_r)
int ret;
return ret;
int ret;
return NULL;
if (*p == (unsigned char)key)
return NULL;
const char *value)
unsigned int len;
if (*p != (unsigned char)key)
p += len;
const char *value)
int ret;
if (ret <= 0) {
if (ret < 0)
T_BEGIN {
} T_END;
const char *strp;
unsigned int len;
int ret;
if (ret < 0) {
unsigned int i, count;
seq++;
seq++; i++;
for (; i < count; i++)
if (ret == 0) {
if (ret < 0) {
if (ret < 0)
return ret;
int ret;
return ret;
unsigned int min_rewrite_count;
return FALSE;
return TRUE;
return FALSE;
return TRUE;
return TRUE;
bool nonsynced)
unsigned int i, count;
if (nonsynced) {
for (i = 0; i < count; i++)
for (i = 0; i < count; i++)
bool *locked_r)
int ret;
if (ret <= 0) {
return ret;
bool locked;
int ret;
if (ret <= 0)
return ret;
unsigned int count;
if (uid != 0) {
unsigned char *ret;
return NULL;
T_BEGIN {
unsigned int len;
} T_END;
return ret;
const char *filename,
const char *p, *dir;
MAILDIR_UIDLIST_REC_FLAG_MOVED)) == 0) {
if (uid != 0) {
const char *filename)
unsigned int idx;
const char *value)
const char *filename)
return FALSE;
return TRUE;
const char *filename)
T_BEGIN {
} T_END;
bool success)
int ret;
if (!success)
return ret;
const char *filename,
struct maildir_uidlist_iter_ctx *
unsigned int count;
return ctx;
idx++;
idx--;
return FALSE;
return TRUE;
const char **filename_r)
return FALSE;
return TRUE;