mailbox-log.c revision f6d79884d112949fde4e7d9b7fc6a43e24a475b7
/* Copyright (c) 2009-2014 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "ioloop.h"
#include "eacces-error.h"
#include "mailbox-log.h"
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
/* How often to reopen the log file to make sure that the changes are written
to the latest file. The main problem here is if the value is too high the
changes could be written to a file that was already rotated and deleted.
That wouldn't happen in any real world situations though, since the file
rotation time is probably measured in months or years. Still, each session
rarely writes anything here, so the value can just as well be a pretty small
one without any performance problems. */
#define MAILBOX_LOG_REOPEN_SECS (60)
struct mailbox_log {
int fd;
char *gid_origin;
};
struct mailbox_log_iter {
struct mailbox_log *log;
int fd;
const char *filepath;
bool failed;
};
{
struct mailbox_log *log;
return log;
}
{
}
{
}
}
{
}
{
return 0;
/* try to create it */
else
return -1;
}
else {
log->gid_origin));
}
}
return 0;
}
{
return -1;
}
return 0;
i_error("rename(%s, %s) failed: %m",
return -1;
}
return 0;
}
{
}
{
}
const struct mailbox_log_record *rec)
{
/* we don't have to be too strict about appending to the latest log
file. the records' ordering doesn't matter and iteration goes
through both logs anyway. still, if there's a long running session
it shouldn't keep writing to a rotated log forever. */
if (mailbox_log_open(log) < 0)
return -1;
}
/* We don't bother with locking, atomic appends will protect us.
If they don't (NFS), the worst that can happen is that a few
records get overwritten (because they're all the same size).
This whole log isn't supposed to be super-reliable anyway. */
if (ret < 0) {
return -1;
i_error("ftruncate(%s) failed: %m",
}
}
return -1;
}
(void)mailbox_log_rotate_if_needed(log);
return 0;
}
{
}
else
return FALSE;
return TRUE;
return mailbox_log_iter_open_next(iter);
} else {
}
return FALSE;
}
{
struct mailbox_log_iter *iter;
(void)mailbox_log_iter_open_next(iter);
return iter;
}
const struct mailbox_log_record *
{
const struct mailbox_log_record *rec;
return NULL;
if (ret < 0) {
return NULL;
}
if (ret == 0) {
if (!mailbox_log_iter_open_next(iter))
return NULL;
return mailbox_log_iter_next(iter);
}
}
return NULL;
}
return rec;
}
{
}
return ret;
}