maildir-keywords.c revision 54cb36f32da0f2b1225a62e9e5717d521e21aa99
/* Copyright (c) 2005-2007 Dovecot authors, see the included COPYING file */
/* note that everything here depends on uidlist file being locked the whole
time. that's why we don't have any locking of our own, or that we do things
that would be racy otherwise. */
#include "lib.h"
#include "array.h"
#include "ioloop.h"
#include "hash.h"
#include "str.h"
#include "istream.h"
#include "file-dotlock.h"
#include "write-full.h"
#include "nfs-workarounds.h"
#include "maildir-storage.h"
#include "maildir-uidlist.h"
#include "maildir-keywords.h"
#include <stdlib.h>
#include <utime.h>
/* how many seconds to wait before overriding dovecot-keywords.lock */
struct maildir_keywords {
struct maildir_mailbox *mbox;
struct mail_storage *storage;
char *path;
struct dotlock_settings dotlock_settings;
unsigned int synced:1;
unsigned int changed:1;
};
struct maildir_keywords_sync_ctx {
struct maildir_keywords *mk;
struct mail_index *index;
ARRAY_DEFINE(idx_to_chr, char);
unsigned int chridx_to_idx[MAILDIR_MAX_KEYWORDS];
};
{
struct maildir_keywords *mk;
return mk;
}
struct maildir_keywords *
{
struct maildir_keywords *mk;
const char *dir;
return mk;
}
{
}
{
}
{
const char **strp;
/* Remember that we rely on uidlist file locking in here. That's why
we rely on stat()'s timestamp and don't bother handling ESTALE
errors. */
return 0;
}
return -1;
}
/* hasn't changed */
return 0;
}
if (fd == -1) {
return 0;
}
return -1;
}
if (p == NULL) {
/* note that when converting .customflags file this
case happens in the first line. */
continue;
}
*p++ = '\0';
/* shouldn't happen */
continue;
}
/* save it */
}
return -1;
}
return 0;
}
static int
{
void *p;
if (p == NULL) {
return -1;
if (maildir_keywords_sync(mk) < 0)
return -1;
if (p == NULL)
return -1;
}
return POINTER_CAST_TO(p, int)-1;
}
static void
unsigned int chridx)
{
const char **strp;
char *new_name;
}
static int
{
const char *const *keywords;
unsigned int i, count;
int idx;
if (idx >= 0)
return idx;
/* we couldn't open the dovecot-keywords file. */
return -1;
}
/* see if we are full */
for (i = 0; i < count; i++) {
break;
}
return -1;
return i;
}
static const char *
{
const char *const *keywords;
unsigned int count;
return NULL;
if (maildir_keywords_sync(mk) < 0)
return NULL;
}
}
{
const char *const *keywords;
unsigned int i, count;
for (i = 0; i < count; i++) {
}
"write_full(%s) failed: %m", path);
return -1;
}
"fstat(%s) failed: %m", path);
return -1;
}
"fchown(%s) failed: %m", path);
}
}
/* mtime must grow every time */
"utime(%s) failed: %m", path);
return -1;
}
}
"fsync(%s) failed: %m", path);
return -1;
}
return 0;
}
{
const char *lock_path;
int i, fd;
return 0;
for (i = 0;; i++) {
/* we could just create the temp file directly, but doing it
this ways avoids potential problems with overwriting
contents in malicious symlinks */
if (fd != -1)
break;
return -1;
}
/* the control dir doesn't exist. create it unless the whole
mailbox was just deleted. */
return -1;
}
return -1;
}
if (file_dotlock_replace(&dotlock, 0) < 0) {
return -1;
}
return 0;
}
struct maildir_keywords_sync_ctx *
struct mail_index *index)
{
struct maildir_keywords_sync_ctx *ctx;
return ctx;
}
{
t_push();
t_pop();
}
char keyword)
{
const char *name;
/* lookup / create */
/* name is lost. just generate one ourself. */
/* don't create a duplicate name.
keep changing the name until it doesn't exist */
}
}
return idx;
}
unsigned int idx)
{
const char *const *name_p;
char *chr_p;
int chridx;
if (*chr_p != '\0')
return *chr_p;
if (chridx < 0)
return '\0';
return *chr_p;
}