mail-custom-flags.c revision 742111fa99a5b852c9645080573d5853be3907a7
/* Copyright (C) 2002 Timo Sirainen */
#include "lib.h"
#include "file-lock.h"
#include "mmap-util.h"
#include "write-full.h"
#include "imap-util.h"
#include "mail-index.h"
#include "mail-index-util.h"
#include "mail-custom-flags.h"
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
/* Header is simply a counter which is increased every time the file is
updated. This allows other processes to easily notice if there's been
any changes. */
#define COUNTER_SIZE 4
struct mail_custom_flags {
struct mail_index *index;
char *filepath;
int fd;
int lock_type;
char sync_counter[COUNTER_SIZE];
char *custom_flags[MAIL_CUSTOM_FLAGS_COUNT];
void *mmap_base;
unsigned int syncing:1;
unsigned int noupdate:1;
unsigned int changed:1;
};
const char *function)
{
return FALSE;
}
return FALSE;
}
{
}
}
return TRUE;
}
{
int failed;
return FALSE;
/* make sure it's still empty after locking */
/* write the header - it's a 4 byte counter as hex */
}
}
return FALSE;
return !failed;
}
{
unsigned int num;
int i;
return;
for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++) {
}
}
/* this loop skips the first line, which is the header */
if (*data != '\n') {
data++;
continue;
}
/* beginning of line, get the index */
break;
data++;
continue;
num = 0;
data++;
}
if (num < MAIL_CUSTOM_FLAGS_COUNT) {
/* get the name */
continue;
data++;
i_warning("Error in custom flags file %s: "
num);
}
}
}
}
{
return TRUE;
if (mcf->mmap_length != 0 &&
return TRUE;
/* file modified, resync */
if (!update_mmap(mcf))
return FALSE;
/* it's broken, rewrite header */
return FALSE;
}
if (!custom_flags_init(mcf))
return FALSE;
if (!update_mmap(mcf))
return FALSE;
}
return TRUE;
}
{
return TRUE;
/* FIXME: possibility to use .lock file instead */
return FALSE;
}
}
if (!custom_flags_check_sync(mcf)) {
return FALSE;
}
/* syncing may have changed locking, do it again */
return FALSE;
}
}
return TRUE;
}
{
struct mail_custom_flags *mcf;
const char *path;
int fd;
fd = -1;
else {
if (fd == -1)
}
if (fd != -1) {
if (!update_mmap(mcf)) {
}
/* we just created it, write the header */
}
}
}
return TRUE;
}
{
int i;
for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++)
}
}
}
{
int i;
for (i = COUNTER_SIZE-1; i >= 0; i--) {
break;
}
/* digit wrapped, update next one */
} else {
mcf->sync_counter[i]++;
break;
}
}
return TRUE;
}
{
const char *buf;
/* first update the sync counter */
if (!custom_flags_update_counter(mcf))
return FALSE;
/* add the flag */
if (pos < 0)
"changed by someone while we were"
return FALSE;
}
/* don't add the \n prefix */
buf++;
len--;
}
if (!update_mmap(mcf))
return FALSE;
return TRUE;
}
{
unsigned int num;
if (*data != '\n') {
data++;
continue;
}
/* beginning of line, get the index */
break;
num = 0;
data++;
}
/* remove this line */
data++;
return FALSE;
}
return TRUE;
}
}
return FALSE;
}
{
int i;
for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++) {
return i;
}
return -1;
}
enum mail_flags used_flags)
{
unsigned int i;
for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++) {
custom_flags_remove(mcf, i);
}
}
}
{
struct mail_index_record *rec;
enum mail_flags used_flags;
used_flags = 0;
}
return used_flags;
}
int index_hint)
{
int i, first_empty;
return index_hint;
}
/* check existing flags */
for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++) {
return i;
}
}
return -1;
/* unlock + write lock, don't directly change from
read -> write lock to prevent deadlocking */
return -1;
/* list may have already changed between the lock changes,
check again */
}
/* new flag, add it. first find the first free flag, note that
unlock+lock might have just changed it. */
if (first_empty == -1) {
/* all custom flags are used, see if some of them are unused */
if (first_empty == -1) {
/* everything is in use */
return -1;
}
}
return -1;
return first_empty;
}
enum mail_flags *flags,
const char *custom_flags[], unsigned int count)
{
int i, idx;
if ((*flags & MAIL_CUSTOM_FLAGS_MASK) == 0)
return 1;
return -1;
if (idx == -1) {
return 0;
}
}
}
return -1;
return 1;
}
{
return (const char **) mcf->custom_flags;
}
{
return FALSE;
else {
return TRUE;
}
}