mail-storage.c revision df8a8bb3ce466273ef4239ed0ad7069348e59514
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (C) 2002-2006 Timo Sirainen */
37847ec8eaec9ad55c9df10ae109efe7b37ac573Timo Sirainen/* Message to show to users when critical error occurs */
94d8e51119003d2bc5a100c663f90141f297385dTimo Sirainen "Internal error occurred. Refer to server log for more information."
ef50336eefcb9ba99f73c6af37420eaf8857a39bTimo Sirainen#define CRITICAL_MSG_STAMP CRITICAL_MSG " [%Y-%m-%d %H:%M:%S]"
37847ec8eaec9ad55c9df10ae109efe7b37ac573Timo Sirainen/* 20 * (200+1) < 4096 which is the standard PATH_MAX. Having these settings
ef50336eefcb9ba99f73c6af37420eaf8857a39bTimo Sirainen prevents malicious user from creating eg. "a/a/a/.../a" mailbox name and
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen then start renaming them to larger names from end to beginning, which
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen eventually would start causing the failures when trying to use too
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen long mailbox names. */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenunsigned int mail_storage_mail_index_module_id = 0;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenvoid (*hook_mailbox_opened)(struct mailbox *box) = NULL;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic ARRAY_DEFINE(storages, struct mail_storage *);
de486b59018016977015ef42e6071155b60e82e1Timo Sirainen mail_storage_mail_index_module_id = mail_index_module_id++;
220e21750948941dc6e33b8f11b552fa21d7f81eTimo Sirainenvoid mail_storage_class_register(struct mail_storage *storage_class)
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen /* append it after the list, so the autodetection order is correct */
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainenvoid mail_storage_class_unregister(struct mail_storage *storage_class)
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen unsigned int i, count;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen for (i = 0; i < count; i++) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenvoid mail_storage_parse_env(enum mail_storage_flags *flags_r,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen const char *str;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (str != NULL && (str = strchr(str, '%')) != NULL &&
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen *flags_r |= MAIL_STORAGE_FLAG_KEEP_HEADER_MD5;
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainenstatic struct mail_storage *mail_storage_find(const char *name)
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen unsigned int i, count;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen for (i = 0; i < count; i++) {
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenmail_storage_create(const char *name, const char *data, const char *user,
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen return storage->v.create(data, user, flags, lock_method);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainenmail_storage_create_default(const char *user, enum mail_storage_flags flags,
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen unsigned int i, count;
1701e3f91107051b1704721bf1dc1e32491faaf9Timo Sirainen for (i = 0; i < count; i++) {
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen storage = classes[i]->v.create(NULL, user, flags, lock_method);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenmail_storage_autodetect(const char *data, enum mail_storage_flags flags)
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen unsigned int i, count;
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen for (i = 0; i < count; i++) {
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenmail_storage_create_with_data(const char *data, const char *user,
27586e4785d56aeb76e1fd96af8db799688dc64aTimo Sirainen const char *p, *name;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen return mail_storage_create_default(user, flags, lock_method);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen /* check if we're in the form of mailformat:data
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen (eg. maildir:Maildir) */
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen while (i_isalnum(*p)) p++;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (*p == ':') {
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen /* no autodetection if the storage format is given. */
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk storage = mail_storage_create(name, p+1, user, flags,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen "don't know what to do with it: %s "
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen "(try prefixing it with mbox: or maildir:)",
1701e3f91107051b1704721bf1dc1e32491faaf9Timo Sirainen storage = storage->v.create(data, user, flags,
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainenvoid mail_storage_destroy(struct mail_storage **_storage)
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainenvoid mail_storage_clear_error(struct mail_storage *storage)
02e61e13a8360a9d3ec92c5fa5ae60c0f0181b71Timo Sirainenvoid mail_storage_set_error(struct mail_storage *storage, const char *fmt, ...)
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainenvoid mail_storage_set_syntax_error(struct mail_storage *storage,
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen const char *fmt, ...)
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainenvoid mail_storage_set_internal_error(struct mail_storage *storage)
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen strftime(str, sizeof(str), CRITICAL_MSG_STAMP, tm) > 0 ?
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainenvoid mail_storage_set_critical(struct mail_storage *storage,
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen const char *fmt, ...)
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen /* critical errors may contain sensitive data, so let user
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen see only "Internal error" with a timestamp to make it
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen easier to look from log files the actual error message. */
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainenchar mail_storage_get_hierarchy_sep(struct mail_storage *storage)
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainenvoid mail_storage_set_callbacks(struct mail_storage *storage,
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen storage->v.set_callbacks(storage, callbacks, context);
02e61e13a8360a9d3ec92c5fa5ae60c0f0181b71Timo Sirainenint mail_storage_mailbox_create(struct mail_storage *storage, const char *name,
02e61e13a8360a9d3ec92c5fa5ae60c0f0181b71Timo Sirainen return storage->v.mailbox_create(storage, name, directory);
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainenint mail_storage_mailbox_delete(struct mail_storage *storage, const char *name)
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen return storage->v.mailbox_delete(storage, name);
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainenint mail_storage_mailbox_rename(struct mail_storage *storage,
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen return storage->v.mailbox_rename(storage, oldname, newname);
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainenmail_storage_mailbox_list_init(struct mail_storage *storage,
1433bf361ddb0bba8878c8ada5726d0284edad57Timo Sirainen return storage->v.mailbox_list_init(storage, ref, mask, flags);
94d8e51119003d2bc5a100c663f90141f297385dTimo Sirainenmail_storage_mailbox_list_next(struct mailbox_list_context *ctx)
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen return ctx->storage->v.mailbox_list_next(ctx);
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainenint mail_storage_mailbox_list_deinit(struct mailbox_list_context **_ctx)
94d8e51119003d2bc5a100c663f90141f297385dTimo Sirainen return ctx->storage->v.mailbox_list_deinit(ctx);
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainenint mail_storage_set_subscribed(struct mail_storage *storage,
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen return storage->v.set_subscribed(storage, name, set);
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainenint mail_storage_get_mailbox_name_status(struct mail_storage *storage,
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen return storage->v.get_mailbox_name_status(storage, name, status);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenconst char *mail_storage_get_last_error(struct mail_storage *storage,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return storage->v.get_last_error(storage, syntax_error_r,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenconst char *mail_storage_get_mailbox_path(struct mail_storage *storage,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return storage->v.get_mailbox_path(storage, name, is_file_r);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenconst char *mail_storage_get_mailbox_control_dir(struct mail_storage *storage,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return storage->v.get_mailbox_control_dir(storage, name);
68a4946b12583b88fa802e52ebee45cd96056772Timo Sirainenconst char *mail_storage_get_mailbox_index_dir(struct mail_storage *storage,
c58906589cafc32df4c04ffbef933baadd3f2276Timo Sirainen return storage->v.get_mailbox_index_dir(storage, name);
68a4946b12583b88fa802e52ebee45cd96056772Timo Sirainenstruct mailbox *mailbox_open(struct mail_storage *storage, const char *name,
6dd77763f5451269ace733579cf58f2f3b18bca4Timo Sirainen box = storage->v.mailbox_open(storage, name, input, flags);
6dd77763f5451269ace733579cf58f2f3b18bca4Timo Sirainen if (hook_mailbox_opened != NULL && box != NULL)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstruct mail_storage *mailbox_get_storage(struct mailbox *box)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenconst char *mailbox_get_name(struct mailbox *box)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenbool mailbox_allow_new_keywords(struct mailbox *box)
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainenmailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainenint mailbox_sync_next(struct mailbox_sync_context *ctx,
d02d34e138e32b4266f5a403d6c51d7803bf322fTimo Sirainen return ctx->box->v.sync_next(ctx, sync_rec_r);
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volkint mailbox_sync_deinit(struct mailbox_sync_context **_ctx,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen return ctx->box->v.sync_deinit(ctx, status_r);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenvoid mailbox_notify_changes(struct mailbox *box, unsigned int min_interval,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen mailbox_notify_callback_t *callback, void *context)
0910ea0672c0295c442eb686cc41e98656831f37Timo Sirainen box->v.notify_changes(box, min_interval, callback, context);
490f66d6476d51cc02333d6eb398a5cd94b67f48Timo Sirainenmailbox_keywords_create(struct mailbox_transaction_context *t,
490f66d6476d51cc02333d6eb398a5cd94b67f48Timo Sirainen const char *const keywords[])
490f66d6476d51cc02333d6eb398a5cd94b67f48Timo Sirainen return t->box->v.keywords_create(t, keywords);
490f66d6476d51cc02333d6eb398a5cd94b67f48Timo Sirainenvoid mailbox_keywords_free(struct mailbox_transaction_context *t,
490f66d6476d51cc02333d6eb398a5cd94b67f48Timo Sirainenint mailbox_get_uids(struct mailbox *box, uint32_t uid1, uint32_t uid2,
490f66d6476d51cc02333d6eb398a5cd94b67f48Timo Sirainen return box->v.get_uids(box, uid1, uid2, seq1_r, seq2_r);
490f66d6476d51cc02333d6eb398a5cd94b67f48Timo Sirainenmailbox_header_lookup_init(struct mailbox *box, const char *const headers[])
490f66d6476d51cc02333d6eb398a5cd94b67f48Timo Sirainen return box->v.header_lookup_init(box, headers);
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainenvoid mailbox_header_lookup_deinit(struct mailbox_header_lookup_ctx **_ctx)
d02d34e138e32b4266f5a403d6c51d7803bf322fTimo Sirainen struct mailbox_header_lookup_ctx *ctx = *_ctx;
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volkmailbox_search_init(struct mailbox_transaction_context *t,
c78e7a94528078728cc639b26a1c83e11b4d7e1bTimo Sirainen const char *charset, struct mail_search_arg *args,
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen return t->box->v.search_init(t, charset, args, sort_program);
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainenint mailbox_search_deinit(struct mail_search_context **_ctx)
490f66d6476d51cc02333d6eb398a5cd94b67f48Timo Sirainen return ctx->transaction->box->v.search_deinit(ctx);
490f66d6476d51cc02333d6eb398a5cd94b67f48Timo Sirainenint mailbox_search_next(struct mail_search_context *ctx, struct mail *mail)
c78e7a94528078728cc639b26a1c83e11b4d7e1bTimo Sirainen return ctx->transaction->box->v.search_next(ctx, mail);
490f66d6476d51cc02333d6eb398a5cd94b67f48Timo Sirainenint mailbox_transaction_commit(struct mailbox_transaction_context **_t,
490f66d6476d51cc02333d6eb398a5cd94b67f48Timo Sirainen return t->box->v.transaction_commit(t, flags);
490f66d6476d51cc02333d6eb398a5cd94b67f48Timo Sirainenvoid mailbox_transaction_rollback(struct mailbox_transaction_context **_t)
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainenint mailbox_save_init(struct mailbox_transaction_context *t,
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen enum mail_flags flags, struct mail_keywords *keywords,
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen const char *from_envelope, struct istream *input,
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen struct mail *dest_mail, struct mail_save_context **ctx_r)
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainenint mailbox_save_continue(struct mail_save_context *ctx)
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen return ctx->transaction->box->v.save_continue(ctx);
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainenint mailbox_save_finish(struct mail_save_context **_ctx)
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen return ctx->transaction->box->v.save_finish(ctx);
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainenvoid mailbox_save_cancel(struct mail_save_context **_ctx)
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainenint mailbox_copy(struct mailbox_transaction_context *t, struct mail *mail,
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen enum mail_flags flags, struct mail_keywords *keywords,
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen return t->box->v.copy(t, mail, flags, keywords, dest_mail);
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainenbool mailbox_is_inconsistent(struct mailbox *box)
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainenbool mailbox_name_is_too_large(const char *name, char sep)
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen if (level_len > MAILBOX_MAX_HIERARCHY_NAME_LENGTH)