Mercurial > dovecot > original-hg > dovecot-1.2
view src/lib-storage/mail-storage.c @ 2322:aae574ed7f4c HEAD
Broke mailbox_sync() into iterator.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 12 Jul 2004 14:35:50 +0300 |
parents | 1c1ed4494aa4 |
children | 7d02e2a7672d |
line wrap: on
line source
/* Copyright (C) 2002-2003 Timo Sirainen */ #include "lib.h" #include "ioloop.h" #include "mail-storage-private.h" #include <stdlib.h> #include <time.h> #include <ctype.h> /* Message to show to users when critical error occurs */ #define CRITICAL_MSG \ "Internal error occured. Error report written to server log." #define CRITICAL_MSG_STAMP CRITICAL_MSG " [%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; int full_filesystem_access = FALSE; void mail_storage_init(void) { full_filesystem_access = getenv("FULL_FILESYSTEM_ACCESS") != NULL; } void mail_storage_deinit(void) { struct mail_storage_list *next; while (storages != NULL) { next = storages->next; i_free(storages); storages = next; } } 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; mail_storage_destroy((*list)->storage); i_free(*list); *list = next; } } } struct mail_storage * mail_storage_create(const char *name, const char *data, const char *user, const char *namespace, char hierarchy_sep) { 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, namespace, hierarchy_sep); } } return NULL; } struct mail_storage * mail_storage_create_default(const char *user, const char *namespace, char hierarchy_sep) { struct mail_storage_list *list; struct mail_storage *storage; for (list = storages; list != NULL; list = list->next) { storage = list->storage->create(NULL, user, namespace, hierarchy_sep); 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, const char *namespace, char hierarchy_sep) { struct mail_storage *storage; const char *p, *name; if (data == NULL || *data == '\0') { return mail_storage_create_default(user, namespace, hierarchy_sep); } /* 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, namespace, hierarchy_sep); } else { storage = mail_storage_autodetect(data); if (storage != NULL) { storage = storage->create(data, user, namespace, hierarchy_sep); } } return storage; } void mail_storage_destroy(struct mail_storage *storage) { i_assert(storage != NULL); storage->destroy(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); i_free(storage->error); storage->error = strftime(str, sizeof(str), CRITICAL_MSG_STAMP, tm) > 0 ? i_strdup(str) : i_strdup(CRITICAL_MSG); 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); } } char mail_storage_get_hierarchy_sep(struct mail_storage *storage) { return storage->hierarchy_sep; } void mail_storage_set_callbacks(struct mail_storage *storage, struct mail_storage_callbacks *callbacks, void *context) { storage->set_callbacks(storage, callbacks, context); } int mail_storage_mailbox_create(struct mail_storage *storage, const char *name, int directory) { return storage->mailbox_create(storage, name, directory); } int mail_storage_mailbox_delete(struct mail_storage *storage, const char *name) { return storage->mailbox_delete(storage, name); } int mail_storage_mailbox_rename(struct mail_storage *storage, const char *oldname, const char *newname) { return storage->mailbox_rename(storage, oldname, newname); } struct mailbox_list_context * mail_storage_mailbox_list_init(struct mail_storage *storage, const char *mask, enum mailbox_list_flags flags) { return storage->mailbox_list_init(storage, mask, flags); } struct mailbox_list * mail_storage_mailbox_list_next(struct mailbox_list_context *ctx) { return ctx->storage->mailbox_list_next(ctx); } int mail_storage_mailbox_list_deinit(struct mailbox_list_context *ctx) { return ctx->storage->mailbox_list_deinit(ctx); } int mail_storage_set_subscribed(struct mail_storage *storage, const char *name, int set) { return storage->set_subscribed(storage, name, set); } int mail_storage_get_mailbox_name_status(struct mail_storage *storage, const char *name, enum mailbox_name_status *status) { return storage->get_mailbox_name_status(storage, name, status); } const char *mail_storage_get_last_error(struct mail_storage *storage, int *syntax_error_r) { return storage->get_last_error(storage, syntax_error_r); } struct mailbox *mailbox_open(struct mail_storage *storage, const char *name, enum mailbox_open_flags flags) { return storage->mailbox_open(storage, name, flags); } int mailbox_close(struct mailbox *box) { return box->close(box); } struct mail_storage *mailbox_get_storage(struct mailbox *box) { return box->storage; } const char *mailbox_get_name(struct mailbox *box) { return box->name; } int mailbox_is_readonly(struct mailbox *box) { return box->is_readonly(box); } int mailbox_allow_new_keywords(struct mailbox *box) { return box->allow_new_keywords(box); } int mailbox_get_status(struct mailbox *box, enum mailbox_status_items items, struct mailbox_status *status) { return box->get_status(box, items, status); } struct mailbox_sync_context * mailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags) { return box->sync_init(box, flags); } int mailbox_sync_next(struct mailbox_sync_context *ctx, struct mailbox_sync_rec *sync_rec_r) { return ctx->box->sync_next(ctx, sync_rec_r); } int mailbox_sync_deinit(struct mailbox_sync_context *ctx, struct mailbox_status *status_r) { return ctx->box->sync_deinit(ctx, status_r); } void mailbox_notify_changes(struct mailbox *box, unsigned int min_interval, mailbox_notify_callback_t *callback, void *context) { box->notify_changes(box, min_interval, callback, context); } struct mail *mailbox_fetch(struct mailbox_transaction_context *t, uint32_t seq, enum mail_fetch_field wanted_fields) { return t->box->fetch(t, seq, wanted_fields); } int mailbox_get_uids(struct mailbox *box, uint32_t uid1, uint32_t uid2, uint32_t *seq1_r, uint32_t *seq2_r) { return box->get_uids(box, uid1, uid2, seq1_r, seq2_r); } int mailbox_search_get_sorting(struct mailbox *box, enum mail_sort_type *sort_program) { return box->search_get_sorting(box, sort_program); } struct mail_search_context * mailbox_search_init(struct mailbox_transaction_context *t, const char *charset, struct mail_search_arg *args, const enum mail_sort_type *sort_program, enum mail_fetch_field wanted_fields, const char *const wanted_headers[]) { return t->box->search_init(t, charset, args, sort_program, wanted_fields, wanted_headers); } int mailbox_search_deinit(struct mail_search_context *ctx) { return ctx->box->search_deinit(ctx); } struct mail *mailbox_search_next(struct mail_search_context *ctx) { return ctx->box->search_next(ctx); } struct mailbox_transaction_context * mailbox_transaction_begin(struct mailbox *box, int hide) { return box->transaction_begin(box, hide); } int mailbox_transaction_commit(struct mailbox_transaction_context *t) { return t->box->transaction_commit(t); } void mailbox_transaction_rollback(struct mailbox_transaction_context *t) { t->box->transaction_rollback(t); } int mailbox_save(struct mailbox_transaction_context *t, const struct mail_full_flags *flags, time_t received_date, int timezone_offset, const char *from_envelope, struct istream *data, struct mail **mail_r) { return t->box->save(t, flags, received_date, timezone_offset, from_envelope, data, mail_r); } int mailbox_copy(struct mailbox_transaction_context *t, struct mail *mail, struct mail **dest_mail_r) { return t->box->copy(t, mail, dest_mail_r); } int mailbox_is_inconsistent(struct mailbox *box) { return box->is_inconsistent(box); }