Mercurial > dovecot > original-hg > dovecot-1.2
view src/lib-storage/mail-storage.c @ 903:fd8888f6f037 HEAD
Naming style changes, finally got tired of most of the typedefs. Also the
previous enum -> macro change reverted so that we don't use the highest bit
anymore, that's incompatible with old indexes so they will be rebuilt.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 05 Jan 2003 15:09:51 +0200 |
parents | 39e0b536e708 |
children | 340dea0150bf |
line wrap: on
line source
/* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" #include "ioloop.h" #include "mail-storage.h" #include <time.h> #include <ctype.h> /* Message to show to users when critical error occurs */ #define CRITICAL_MSG "Internal error [%Y-%m-%d %H:%M:%S]" struct mail_storage_list { struct mail_storage_list *next; struct mail_storage *storage; }; static struct mail_storage_list *storages = NULL; void mail_storage_class_register(struct mail_storage *storage_class) { struct mail_storage_list *list, **pos; list = i_new(struct mail_storage_list, 1); list->storage = storage_class; /* append it after the list, so the autodetection order is correct */ pos = &storages; while (*pos != NULL) pos = &(*pos)->next; *pos = list; } void mail_storage_class_unregister(struct mail_storage *storage_class) { struct mail_storage_list **list, *next; for (list = &storages; *list != NULL; list = &(*list)->next) { if ((*list)->storage == storage_class) { next = (*list)->next; (*list)->storage->free((*list)->storage); i_free(*list); *list = next; } } } struct mail_storage *mail_storage_create(const char *name, const char *data, const char *user) { struct mail_storage_list *list; i_assert(name != NULL); for (list = storages; list != NULL; list = list->next) { if (strcasecmp(list->storage->name, name) == 0) return list->storage->create(data, user); } return NULL; } struct mail_storage *mail_storage_create_default(const char *user) { struct mail_storage_list *list; struct mail_storage *storage; for (list = storages; list != NULL; list = list->next) { storage = list->storage->create(NULL, user); if (storage != NULL) return storage; } return NULL; } static struct mail_storage *mail_storage_autodetect(const char *data) { struct mail_storage_list *list; for (list = storages; list != NULL; list = list->next) { if (list->storage->autodetect(data)) return list->storage; } return NULL; } struct mail_storage *mail_storage_create_with_data(const char *data, const char *user) { struct mail_storage *storage; const char *p, *name; if (data == NULL || *data == '\0') return mail_storage_create_default(user); /* check if we're in the form of mailformat:data (eg. maildir:Maildir) */ p = data; while (i_isalnum(*p)) p++; if (*p == ':') { name = t_strdup_until(data, p); storage = mail_storage_create(name, p+1, user); } else { storage = mail_storage_autodetect(data); if (storage != NULL) storage = storage->create(data, user); } return storage; } void mail_storage_destroy(struct mail_storage *storage) { i_assert(storage != NULL); i_free(storage->dir); i_free(storage); } void mail_storage_clear_error(struct mail_storage *storage) { i_free(storage->error); storage->error = NULL; storage->syntax_error = FALSE; } void mail_storage_set_error(struct mail_storage *storage, const char *fmt, ...) { va_list va; i_free(storage->error); if (fmt == NULL) storage->error = NULL; else { va_start(va, fmt); storage->error = i_strdup_vprintf(fmt, va); storage->syntax_error = FALSE; va_end(va); } } void mail_storage_set_syntax_error(struct mail_storage *storage, const char *fmt, ...) { va_list va; i_free(storage->error); if (fmt == NULL) storage->error = NULL; else { va_start(va, fmt); storage->error = i_strdup_vprintf(fmt, va); storage->syntax_error = TRUE; va_end(va); } } void mail_storage_set_internal_error(struct mail_storage *storage) { struct tm *tm; char str[256]; tm = localtime(&ioloop_time); storage->error = strftime(str, sizeof(str), CRITICAL_MSG, tm) > 0 ? i_strdup(str) : i_strdup("Internal error"); storage->syntax_error = FALSE; } void mail_storage_set_critical(struct mail_storage *storage, const char *fmt, ...) { va_list va; i_free(storage->error); if (fmt == NULL) storage->error = NULL; else { va_start(va, fmt); i_error("%s", t_strdup_vprintf(fmt, va)); va_end(va); /* critical errors may contain sensitive data, so let user see only "Internal error" with a timestamp to make it easier to look from log files the actual error message. */ mail_storage_set_internal_error(storage); } } const char *mail_storage_get_last_error(struct mail_storage *storage, int *syntax) { if (syntax != NULL) *syntax = storage->syntax_error; return storage->error; } int mail_storage_is_inconsistency_error(struct mailbox *box) { return box->inconsistent; }