# HG changeset patch # User Timo Sirainen # Date 1365109996 -10800 # Node ID 249305f71c73e32d6a9efcd4a5781f5c14bac4dc # Parent c67d787164fac7183912dbe7f1868e207b68a1a5# Parent c42846219939599484b587d5346d13774715ad41 Merged changes from v2.1 tree. diff -r c67d787164fa -r 249305f71c73 .hgsigs --- a/.hgsigs Thu Apr 04 23:35:27 2013 +0300 +++ b/.hgsigs Fri Apr 05 00:13:16 2013 +0300 @@ -58,6 +58,7 @@ b314c97d4bbffd01b20f8492592aa422c13e3d55 0 iEYEABECAAYFAlEJlGMACgkQyUhSUUBVismNdQCgggPP/dt1duU1CMYfkpE4Kyc9Ju0An0kphokRqrtppkeqg7pF1JR01Mgq fc75811f3c08d80ed339cbb4d37c66f549542ba7 0 iEYEABECAAYFAlEU+CEACgkQyUhSUUBViskh9QCgnqPHUkNvtOioWxo4W7fXjCFLVAwAnR9Z26jgBpoejXDkgwT07wdfYiL3 018de2aa893a040256cb8cd92b1fc9f3f2bbd09f 0 iEYEABECAAYFAlEmOJEACgkQyUhSUUBVismawgCfbfY6KuH+/AauPkRZs4ish20YeV8Ani5DMLh02DUyJvDIpVPJMmTn2Mu/ +582108c190f88597c5215279cb66f74673144c9b 0 iEUEABECAAYFAlFd69UACgkQyUhSUUBVisk/aQCYyYU9JcDM3SrTZu1oJuS26IAnZACeM400zLRROTaM6QYBVKTqTnfpuBY= 508d46f858153c85ae777e87e1c5143a534a51fe 0 iEYEABECAAYFAlErhDkACgkQyUhSUUBViskRdwCeJ61F0qLZ/3xxIQruTujzo0AEWK0An3PH7nkTY7ouyBdUr0QCra5KLXEZ e62fa121f4a2db3348fd79bb176dd363cc1224bf 0 iEYEABECAAYFAlErsAwACgkQyUhSUUBVismarACbBffm3XY21sfkTsbmF8o8udtRZk4An0ofYy2VminZ3S8EFApHymk/UpNv 11bd79bf4866b0d728b25717134a6ba972505746 0 iEYEABECAAYFAlFKFqsACgkQyUhSUUBVismbSwCdHgMYWjcwcTM7fD4v6wTd/8/8ZEsAn2THId1zYspMTEMtDg0rlrvjlht4 diff -r c67d787164fa -r 249305f71c73 .hgtags --- a/.hgtags Thu Apr 04 23:35:27 2013 +0300 +++ b/.hgtags Fri Apr 05 00:13:16 2013 +0300 @@ -95,6 +95,7 @@ b314c97d4bbffd01b20f8492592aa422c13e3d55 2.1.14 fc75811f3c08d80ed339cbb4d37c66f549542ba7 2.1.15 018de2aa893a040256cb8cd92b1fc9f3f2bbd09f 2.2.beta2 +582108c190f88597c5215279cb66f74673144c9b 2.1.16 508d46f858153c85ae777e87e1c5143a534a51fe 2.2.rc1 e62fa121f4a2db3348fd79bb176dd363cc1224bf 2.2.rc2 11bd79bf4866b0d728b25717134a6ba972505746 2.2.rc3 diff -r c67d787164fa -r 249305f71c73 NEWS diff -r c67d787164fa -r 249305f71c73 configure.ac --- a/configure.ac Thu Apr 04 23:35:27 2013 +0300 +++ b/configure.ac Fri Apr 05 00:13:16 2013 +0300 @@ -297,6 +297,9 @@ AC_DEFINE_UNQUOTED(DOVECOT_STRING, "$PACKAGE_STRING", Dovecot string) AC_DEFINE_UNQUOTED(DOVECOT_VERSION, "$PACKAGE_VERSION", Dovecot version) +AC_DEFINE([DOVECOT_VERSION_MAJOR], regexp(AC_PACKAGE_VERSION, [^\([0-9]+\)\.\([0-9]+\)], [\1]), [Dovecot major version]) +AC_DEFINE([DOVECOT_VERSION_MINOR], regexp(AC_PACKAGE_VERSION, [^\([0-9]+\)\.\([0-9]+\)], [\2]), [Dovecot minor version]) + AC_CHECK_HEADERS(strings.h stdint.h unistd.h dirent.h malloc.h inttypes.h \ sys/uio.h sys/sysmacros.h sys/resource.h sys/select.h libgen.h \ sys/quota.h sys/fs/ufs_quota.h ufs/ufs/quota.h jfs/quota.h \ diff -r c67d787164fa -r 249305f71c73 src/auth/auth-request.c --- a/src/auth/auth-request.c Thu Apr 04 23:35:27 2013 +0300 +++ b/src/auth/auth-request.c Fri Apr 05 00:13:16 2013 +0300 @@ -1304,6 +1304,18 @@ return TRUE; } +static void +auth_request_passdb_import(struct auth_request *request, const char *args, + const char *key_prefix, const char *default_scheme) +{ + const char *const *arg, *field; + + for (arg = t_strsplit(args, "\t"); *arg != NULL; arg++) { + field = t_strconcat(key_prefix, *arg, NULL); + auth_request_set_field_keyvalue(request, field, default_scheme); + } +} + void auth_request_set_field(struct auth_request *request, const char *name, const char *value, const char *default_scheme) @@ -1350,6 +1362,17 @@ request->passdb_password = NULL; auth_fields_add(request->extra_fields, name, value, 0); return; + } else if (strcmp(name, "passdb_import") == 0) { + auth_request_passdb_import(request, value, "", default_scheme); + return; + if (strcmp(name, "userdb_userdb_import") == 0) { + /* we need can't put the whole userdb_userdb_import + value to extra_cache_fields or it doesn't work + properly. so handle this explicitly. */ + auth_request_passdb_import(request, value, + "userdb_", default_scheme); + return; + } } else { /* these fields are returned to client */ auth_fields_add(request->extra_fields, name, value, 0); @@ -1422,6 +1445,24 @@ } } +static void +auth_request_userdb_import(struct auth_request *request, const char *args) +{ + const char *key, *value, *const *arg; + + for (arg = t_strsplit(args, "\t"); *arg != NULL; arg++) { + value = strchr(*arg, '='); + if (value == NULL) { + key = *arg; + value = ""; + } else { + key = t_strdup_until(*arg, value); + value++; + } + auth_request_set_userdb_field(request, key, value); + } +} + void auth_request_set_userdb_field(struct auth_request *request, const char *name, const char *value) { @@ -1451,7 +1492,7 @@ auth_request_set_uidgid_file(request, value); return; } else if (strcmp(name, "userdb_import") == 0) { - auth_fields_import(request->userdb_reply, value, 0); + auth_request_userdb_import(request, value); return; } else if (strcmp(name, "system_user") == 0) { /* FIXME: the system_user is for backwards compatibility */ diff -r c67d787164fa -r 249305f71c73 src/doveadm/Makefile.am --- a/src/doveadm/Makefile.am Thu Apr 04 23:35:27 2013 +0300 +++ b/src/doveadm/Makefile.am Fri Apr 05 00:13:16 2013 +0300 @@ -61,6 +61,7 @@ common = \ doveadm-mail.c \ doveadm-mail-altmove.c \ + doveadm-mail-batch.c \ doveadm-mail-expunge.c \ doveadm-mail-fetch.c \ doveadm-mail-import.c \ diff -r c67d787164fa -r 249305f71c73 src/doveadm/doveadm-dump-log.c diff -r c67d787164fa -r 249305f71c73 src/doveadm/doveadm-mail-batch.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doveadm/doveadm-mail-batch.c Fri Apr 05 00:13:16 2013 +0300 @@ -0,0 +1,162 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "array.h" +#include "doveadm-mail.h" + +#include + +struct batch_cmd_context { + struct doveadm_mail_cmd_context ctx; + ARRAY(struct doveadm_mail_cmd_context *) commands; +}; + +static int cmd_batch_prerun(struct doveadm_mail_cmd_context *_ctx, + struct mail_storage_service_user *service_user, + const char **error_r) +{ + struct batch_cmd_context *ctx = (struct batch_cmd_context *)_ctx; + struct doveadm_mail_cmd_context *const *cmdp; + int ret = 0; + + array_foreach(&ctx->commands, cmdp) { + if ((*cmdp)->v.prerun != NULL && + (*cmdp)->v.prerun(*cmdp, service_user, error_r) < 0) { + ret = -1; + break; + } + } + return ret; +} + +static int cmd_batch_run(struct doveadm_mail_cmd_context *_ctx, + struct mail_user *user) +{ + struct batch_cmd_context *ctx = (struct batch_cmd_context *)_ctx; + struct doveadm_mail_cmd_context *const *cmdp; + int ret = 0; + + array_foreach(&ctx->commands, cmdp) { + if ((*cmdp)->v.run(*cmdp, user) < 0) { + ret = -1; + break; + } + } + return ret; +} + +static void +cmd_batch_add(struct batch_cmd_context *batchctx, + int argc, const char *const *argv) +{ + struct doveadm_mail_cmd_context *subctx; + const struct doveadm_mail_cmd *cmd; + const char *getopt_args; + int c; + + cmd = doveadm_mail_cmd_find_from_argv(argv[0], &argc, &argv); + if (cmd == NULL) { + i_fatal_status(EX_USAGE, "doveadm batch: Unknown subcommand %s", + argv[1]); + } + + subctx = doveadm_mail_cmd_init(cmd, doveadm_settings); + subctx->full_args = argv + 1; + subctx->service_flags |= batchctx->ctx.service_flags; + + optind = 1; + getopt_args = subctx->getopt_args != NULL ? subctx->getopt_args : ""; + while ((c = getopt(argc, (void *)argv, getopt_args)) > 0) { + if (subctx->v.parse_arg == NULL || + !subctx->v.parse_arg(subctx, c)) + doveadm_mail_help(cmd); + } + argv += optind; + if (argv[0] != NULL && cmd->usage_args == NULL) { + i_fatal_status(EX_USAGE, "doveadm %s: Unknown parameter: %s", + cmd->name, argv[0]); + } + subctx->args = argv; + if (subctx->v.preinit != NULL) + subctx->v.preinit(subctx); + array_append(&batchctx->commands, &subctx, 1); +} + +static void +cmd_batch_preinit(struct doveadm_mail_cmd_context *_ctx) +{ + const char *const *args = _ctx->args; + struct batch_cmd_context *ctx = (struct batch_cmd_context *)_ctx; + ARRAY_TYPE(const_string) sep_args; + const char *sep = args[0]; + unsigned int i, start; + int argc; + const char *const *argv; + + if (sep == NULL || args[1] == NULL) + doveadm_mail_help_name("batch"); + args++; + + p_array_init(&ctx->commands, _ctx->pool, 8); + p_array_init(&sep_args, _ctx->pool, 16); + for (i = start = 0;; i++) { + if (args[i] != NULL && strcmp(args[i], sep) != 0) { + array_append(&sep_args, &args[i], 1); + continue; + } + if (i > start) { + (void)array_append_space(&sep_args); + argc = i - start; + argv = array_idx(&sep_args, start); + cmd_batch_add(ctx, argc, argv); + start = i+1; + } + if (args[i] == NULL) + break; + } + (void)array_append_space(&sep_args); +} + +static void +cmd_batch_init(struct doveadm_mail_cmd_context *_ctx, + const char *const args[] ATTR_UNUSED) +{ + struct batch_cmd_context *ctx = (struct batch_cmd_context *)_ctx; + struct doveadm_mail_cmd_context *const *cmdp; + struct batch_cmd_context *subctx; + + array_foreach(&ctx->commands, cmdp) { + subctx = (struct batch_cmd_context *)*cmdp; + subctx->ctx.storage_service = _ctx->storage_service; + if (subctx->ctx.v.init != NULL) + subctx->ctx.v.init(&subctx->ctx, subctx->ctx.args); + } +} + +static void cmd_batch_deinit(struct doveadm_mail_cmd_context *_ctx) +{ + struct batch_cmd_context *ctx = (struct batch_cmd_context *)_ctx; + struct doveadm_mail_cmd_context *const *cmdp; + + array_foreach(&ctx->commands, cmdp) { + if ((*cmdp)->v.deinit != NULL) + (*cmdp)->v.deinit(*cmdp); + } +} + +static struct doveadm_mail_cmd_context *cmd_batch_alloc(void) +{ + struct batch_cmd_context *ctx; + + ctx = doveadm_mail_cmd_alloc(struct batch_cmd_context); + ctx->ctx.v.preinit = cmd_batch_preinit; + ctx->ctx.v.init = cmd_batch_init; + ctx->ctx.v.prerun = cmd_batch_prerun; + ctx->ctx.v.run = cmd_batch_run; + ctx->ctx.v.deinit = cmd_batch_deinit; + return &ctx->ctx; +} + +struct doveadm_mail_cmd cmd_batch = { + cmd_batch_alloc, "batch", " [ [..]]" +}; diff -r c67d787164fa -r 249305f71c73 src/doveadm/doveadm-mail-index.c diff -r c67d787164fa -r 249305f71c73 src/doveadm/doveadm-mail.c --- a/src/doveadm/doveadm-mail.c Thu Apr 04 23:35:27 2013 +0300 +++ b/src/doveadm/doveadm-mail.c Fri Apr 05 00:13:16 2013 +0300 @@ -539,59 +539,78 @@ } static bool -doveadm_mail_try_run_multi_word(const struct doveadm_mail_cmd *cmd, - const char *cmdname, int argc, char *argv[]) +doveadm_mail_cmd_try_find_multi_word(const struct doveadm_mail_cmd *cmd, + const char *cmdname, int *argc, + const char *const **argv) { unsigned int len; - if (argc < 2) + if (*argc < 2) return FALSE; + *argc -= 1; + *argv += 1; - len = strlen(argv[1]); - if (strncmp(cmdname, argv[1], len) != 0) + len = strlen((*argv)[0]); + if (strncmp(cmdname, (*argv)[0], len) != 0) return FALSE; if (cmdname[len] == ' ') { /* more args */ - return doveadm_mail_try_run_multi_word(cmd, cmdname + len + 1, - argc - 1, argv + 1); + return doveadm_mail_cmd_try_find_multi_word(cmd, cmdname + len + 1, + argc, argv); } if (cmdname[len] != '\0') return FALSE; /* match */ - doveadm_mail_cmd(cmd, argc - 1, argv + 1); return TRUE; } -bool doveadm_mail_try_run(const char *cmd_name, int argc, char *argv[]) +const struct doveadm_mail_cmd * +doveadm_mail_cmd_find_from_argv(const char *cmd_name, int *argc, + const char *const **argv) { const struct doveadm_mail_cmd *cmd; unsigned int cmd_name_len; + const char *const *orig_argv; + int orig_argc; - i_assert(argc > 0); + i_assert(*argc > 0); cmd_name_len = strlen(cmd_name); array_foreach(&doveadm_mail_cmds, cmd) { - if (strcmp(cmd->name, cmd_name) == 0) { - doveadm_mail_cmd(cmd, argc, argv); - return TRUE; - } + if (strcmp(cmd->name, cmd_name) == 0) + return cmd; /* see if it matches a multi-word command */ if (strncmp(cmd->name, cmd_name, cmd_name_len) == 0 && cmd->name[cmd_name_len] == ' ') { const char *subcmd = cmd->name + cmd_name_len + 1; - if (doveadm_mail_try_run_multi_word(cmd, subcmd, - argc, argv)) - return TRUE; + orig_argc = *argc; + orig_argv = *argv; + if (doveadm_mail_cmd_try_find_multi_word(cmd, subcmd, + argc, argv)) + return cmd; + *argc = orig_argc; + *argv = orig_argv; } } return FALSE; } +bool doveadm_mail_try_run(const char *cmd_name, int argc, char *argv[]) +{ + const struct doveadm_mail_cmd *cmd; + + cmd = doveadm_mail_cmd_find_from_argv(cmd_name, &argc, (void *)&argv); + if (cmd == NULL) + return FALSE; + doveadm_mail_cmd(cmd, argc, argv); + return TRUE; +} + void doveadm_mail_register_cmd(const struct doveadm_mail_cmd *cmd) { /* for now we'll just assume that cmd will be permanently in memory */ @@ -684,6 +703,7 @@ &cmd_mailbox_subscribe, &cmd_mailbox_unsubscribe, &cmd_mailbox_status, + &cmd_batch, &cmd_dsync_backup, &cmd_dsync_mirror, &cmd_dsync_server diff -r c67d787164fa -r 249305f71c73 src/doveadm/doveadm-mail.h --- a/src/doveadm/doveadm-mail.h Thu Apr 04 23:35:27 2013 +0300 +++ b/src/doveadm/doveadm-mail.h Fri Apr 05 00:13:16 2013 +0300 @@ -97,6 +97,9 @@ void doveadm_mail_init(void); void doveadm_mail_deinit(void); +const struct doveadm_mail_cmd * +doveadm_mail_cmd_find_from_argv(const char *cmd_name, int *argc, + const char *const **argv); struct doveadm_mail_cmd_context * doveadm_mail_cmd_init(const struct doveadm_mail_cmd *cmd, const struct doveadm_settings *set); @@ -147,5 +150,6 @@ extern struct doveadm_mail_cmd cmd_mailbox_subscribe; extern struct doveadm_mail_cmd cmd_mailbox_unsubscribe; extern struct doveadm_mail_cmd cmd_mailbox_status; +struct doveadm_mail_cmd cmd_batch; #endif diff -r c67d787164fa -r 249305f71c73 src/indexer/master-connection.c diff -r c67d787164fa -r 249305f71c73 src/lib-index/mail-index-modseq.c diff -r c67d787164fa -r 249305f71c73 src/lib-index/mail-index-sync-update.c diff -r c67d787164fa -r 249305f71c73 src/lib-index/mail-index-transaction-update.c --- a/src/lib-index/mail-index-transaction-update.c Thu Apr 04 23:35:27 2013 +0300 +++ b/src/lib-index/mail-index-transaction-update.c Fri Apr 05 00:13:16 2013 +0300 @@ -896,8 +896,8 @@ struct mail_index_transaction_ext_hdr_update *hdr; size_t new_size; - i_assert(offset <= (uint16_t)-1 && size <= (uint16_t)-1 && - offset + size <= (uint16_t)-1); + i_assert(offset <= (uint32_t)-1 && size <= (uint32_t)-1 && + offset + size <= (uint32_t)-1); if (!array_is_created(&t->ext_hdr_updates)) i_array_init(&t->ext_hdr_updates, ext_id + 2); diff -r c67d787164fa -r 249305f71c73 src/lib-index/mail-transaction-log.h diff -r c67d787164fa -r 249305f71c73 src/lib-master/mountpoint-list.c --- a/src/lib-master/mountpoint-list.c Thu Apr 04 23:35:27 2013 +0300 +++ b/src/lib-master/mountpoint-list.c Fri Apr 05 00:13:16 2013 +0300 @@ -56,6 +56,8 @@ "/sys", "/proc", "/var/run", + "/var/tmp", + "/tmp", "/run", #ifdef __APPLE__ "/Volumes", diff -r c67d787164fa -r 249305f71c73 src/lib-storage/index/cydir/cydir-storage.c --- a/src/lib-storage/index/cydir/cydir-storage.c Thu Apr 04 23:35:27 2013 +0300 +++ b/src/lib-storage/index/cydir/cydir-storage.c Fri Apr 05 00:13:16 2013 +0300 @@ -67,7 +67,7 @@ /* exists, open it */ } else if (errno == ENOENT) { mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name)); + T_MAIL_ERR_MAILBOX_NOT_FOUND(box->vname)); return -1; } else if (errno == EACCES) { mail_storage_set_critical(box->storage, "%s", diff -r c67d787164fa -r 249305f71c73 src/lib-storage/index/dbox-common/dbox-storage.c --- a/src/lib-storage/index/dbox-common/dbox-storage.c Thu Apr 04 23:35:27 2013 +0300 +++ b/src/lib-storage/index/dbox-common/dbox-storage.c Fri Apr 05 00:13:16 2013 +0300 @@ -202,7 +202,7 @@ ; else if (errno == ENOENT || errno == ENAMETOOLONG) { mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name)); + T_MAIL_ERR_MAILBOX_NOT_FOUND(box->vname)); return -1; } else if (errno == EACCES) { mail_storage_set_critical(box->storage, "%s", diff -r c67d787164fa -r 249305f71c73 src/lib-storage/index/maildir/maildir-storage.c --- a/src/lib-storage/index/maildir/maildir-storage.c Thu Apr 04 23:35:27 2013 +0300 +++ b/src/lib-storage/index/maildir/maildir-storage.c Fri Apr 05 00:13:16 2013 +0300 @@ -367,7 +367,7 @@ if (errno == ENOENT || errno == ENAMETOOLONG) { mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name)); + T_MAIL_ERR_MAILBOX_NOT_FOUND(box->vname)); return -1; } else { mail_storage_set_critical(box->storage, diff -r c67d787164fa -r 249305f71c73 src/lib-storage/index/mbox/mbox-storage.c --- a/src/lib-storage/index/mbox/mbox-storage.c Thu Apr 04 23:35:27 2013 +0300 +++ b/src/lib-storage/index/mbox/mbox-storage.c Fri Apr 05 00:13:16 2013 +0300 @@ -484,7 +484,7 @@ return -1; } else if (ENOTFOUND(errno)) { mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name)); + T_MAIL_ERR_MAILBOX_NOT_FOUND(box->vname)); return -1; } else if (mail_storage_set_error_from_errno(box->storage)) { return -1; diff -r c67d787164fa -r 249305f71c73 src/lib-storage/index/pop3c/pop3c-storage.c --- a/src/lib-storage/index/pop3c/pop3c-storage.c Thu Apr 04 23:35:27 2013 +0300 +++ b/src/lib-storage/index/pop3c/pop3c-storage.c Fri Apr 05 00:13:16 2013 +0300 @@ -164,7 +164,7 @@ if (strcmp(box->name, "INBOX") != 0) { mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name)); + T_MAIL_ERR_MAILBOX_NOT_FOUND(box->vname)); return -1; } diff -r c67d787164fa -r 249305f71c73 src/lib-storage/index/raw/raw-storage.c --- a/src/lib-storage/index/raw/raw-storage.c Thu Apr 04 23:35:27 2013 +0300 +++ b/src/lib-storage/index/raw/raw-storage.c Fri Apr 05 00:13:16 2013 +0300 @@ -161,7 +161,7 @@ if (ENOTFOUND(errno)) { mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name)); + T_MAIL_ERR_MAILBOX_NOT_FOUND(box->vname)); } else if (!mail_storage_set_error_from_errno(box->storage)) { mail_storage_set_critical(box->storage, "open(%s) failed: %m", path); diff -r c67d787164fa -r 249305f71c73 src/lib-storage/list/mailbox-list-delete.c --- a/src/lib-storage/list/mailbox-list-delete.c Thu Apr 04 23:35:27 2013 +0300 +++ b/src/lib-storage/list/mailbox-list-delete.c Fri Apr 05 00:13:16 2013 +0300 @@ -69,7 +69,7 @@ continue; } mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); + T_MAILBOX_LIST_ERR_NOT_FOUND(list, name)); return -1; } if (errno == EXDEV) { @@ -126,7 +126,7 @@ return 0; else if (ENOTFOUND(errno)) { mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); + T_MAILBOX_LIST_ERR_NOT_FOUND(list, name)); return -1; } else { if (!mailbox_list_set_error_from_errno(list)) { @@ -154,7 +154,7 @@ if (dir == NULL) { if (errno == ENOENT) { mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); + T_MAILBOX_LIST_ERR_NOT_FOUND(list, name)); } else { if (!mailbox_list_set_error_from_errno(list)) { mailbox_list_set_critical(list, @@ -342,7 +342,7 @@ if (errno == ENOENT) { mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); + T_MAILBOX_LIST_ERR_NOT_FOUND(list, name)); } else if (errno == EISDIR || errno == EPERM) { /* Solaris */ mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE, diff -r c67d787164fa -r 249305f71c73 src/lib-storage/list/mailbox-list-fs.c --- a/src/lib-storage/list/mailbox-list-fs.c Thu Apr 04 23:35:27 2013 +0300 +++ b/src/lib-storage/list/mailbox-list-fs.c Fri Apr 05 00:13:16 2013 +0300 @@ -275,7 +275,7 @@ if (errno == ENOENT || errno == ENOTDIR) { mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); + T_MAILBOX_LIST_ERR_NOT_FOUND(list, name)); } else if (errno == ENOTEMPTY || errno == EEXIST) { /* mbox workaround: if only .imap/ directory is preventing the deletion, remove it */ @@ -458,7 +458,7 @@ if (rename(oldpath, newpath) < 0) { if (ENOTFOUND(errno)) { mailbox_list_set_error(oldlist, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(oldname)); + T_MAILBOX_LIST_ERR_NOT_FOUND(oldlist, oldname)); } else if (!mailbox_list_set_error_from_errno(oldlist)) { mailbox_list_set_critical(oldlist, "rename(%s, %s) failed: %m", oldpath, newpath); diff -r c67d787164fa -r 249305f71c73 src/lib-storage/list/mailbox-list-maildir.c --- a/src/lib-storage/list/mailbox-list-maildir.c Thu Apr 04 23:35:27 2013 +0300 +++ b/src/lib-storage/list/mailbox-list-maildir.c Fri Apr 05 00:13:16 2013 +0300 @@ -263,7 +263,7 @@ "Mailbox exists"); } else if (errno == ENOENT || errno == ENOTDIR) { mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); + T_MAILBOX_LIST_ERR_NOT_FOUND(list, name)); } else { mailbox_list_set_critical(list, "stat(%s) failed: %m", path); } @@ -450,7 +450,7 @@ return -1; if (!found && ret == 0) { mailbox_list_set_error(oldlist, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(oldname)); + T_MAILBOX_LIST_ERR_NOT_FOUND(oldlist, oldname)); return -1; } diff -r c67d787164fa -r 249305f71c73 src/lib-storage/mailbox-list-private.h --- a/src/lib-storage/mailbox-list-private.h Thu Apr 04 23:35:27 2013 +0300 +++ b/src/lib-storage/mailbox-list-private.h Fri Apr 05 00:13:16 2013 +0300 @@ -16,6 +16,10 @@ #define MAILBOX_LOG_FILE_NAME "dovecot.mailbox.log" +#define T_MAILBOX_LIST_ERR_NOT_FOUND(list, name) \ + t_strdup_printf(MAIL_ERRSTR_MAILBOX_NOT_FOUND, \ + mailbox_list_get_vname(list, name)) + struct stat; struct dirent; struct imap_match_glob; diff -r c67d787164fa -r 249305f71c73 src/lib/macros.h --- a/src/lib/macros.h Thu Apr 04 23:35:27 2013 +0300 +++ b/src/lib/macros.h Fri Apr 05 00:13:16 2013 +0300 @@ -207,4 +207,12 @@ #define i_unreached() \ i_panic("file %s: line %d: unreached", __FILE__, __LINE__) +/* Convenience macros to test the versions of dovecot. */ +#if defined DOVECOT_VERSION_MAJOR && defined DOVECOT_VERSION_MINOR +# define DOVECOT_PREREQ(maj, min) \ + ((DOVECOT_VERSION_MAJOR << 16) + DOVECOT_VERSION_MINOR >= ((maj) << 16) + (min)) +#else +# define DOVECOT_PREREQ(maj, min) 0 #endif + +#endif diff -r c67d787164fa -r 249305f71c73 src/plugins/acl/acl-mailbox.c --- a/src/plugins/acl/acl-mailbox.c Thu Apr 04 23:35:27 2013 +0300 +++ b/src/plugins/acl/acl-mailbox.c Fri Apr 05 00:13:16 2013 +0300 @@ -151,7 +151,7 @@ MAIL_ERRSTR_NO_PERMISSION); } else if (ret == 0) { mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name)); + T_MAIL_ERR_MAILBOX_NOT_FOUND(box->vname)); } } diff -r c67d787164fa -r 249305f71c73 src/plugins/quota/quota-status.c --- a/src/plugins/quota/quota-status.c Thu Apr 04 23:35:27 2013 +0300 +++ b/src/plugins/quota/quota-status.c Fri Apr 05 00:13:16 2013 +0300 @@ -21,6 +21,7 @@ struct connection conn; char *recipient; + uoff_t size; }; static enum quota_protocol protocol; @@ -42,7 +43,8 @@ i_free_and_null(client->recipient); } -static int quota_check(struct mail_user *user, const char **error_r) +static int +quota_check(struct mail_user *user, uoff_t mail_size, const char **error_r) { struct quota_user *quser = QUOTA_USER_CONTEXT(user); struct mail_namespace *ns; @@ -60,7 +62,7 @@ box = mailbox_alloc(ns->list, "INBOX", 0); ctx = quota_transaction_begin(box); - ret = quota_test_alloc(ctx, 1, &too_large); + ret = quota_test_alloc(ctx, I_MAX(1, mail_size), &too_large); quota_transaction_rollback(&ctx); mailbox_free(&box); @@ -77,7 +79,7 @@ struct mail_storage_service_input input; struct mail_storage_service_user *service_user; struct mail_user *user; - const char *error; + const char *value = NULL, *error; int ret; if (client->recipient == NULL) { @@ -92,21 +94,31 @@ &service_user, &user, &error); restrict_access_allow_coredumps(TRUE); if (ret == 0) { - o_stream_send_str(client->conn.output, - "action=REJECT Unknown user\n\n"); + value = mail_user_plugin_getenv(user, "quota_status_nouser"); + if (value == NULL) + value = "REJECT Unknown user"; } else if (ret > 0) { - if ((ret = quota_check(user, &error)) > 0) - o_stream_send_str(client->conn.output, "action=OK\n\n"); - else if (ret == 0) { - o_stream_send_str(client->conn.output, t_strdup_printf( - "action=552 5.2.2 %s\n\n", error)); + if ((ret = quota_check(user, client->size, &error)) > 0) { + /* under quota */ + value = mail_user_plugin_getenv(user, "quota_status_success"); + if (value == NULL) + value = "OK"; + } else if (ret == 0) { + /* over quota */ + value = mail_user_plugin_getenv(user, "quota_status_overquota"); + if (value == NULL) + value = t_strdup_printf("552 5.2.2 %s\n\n", error); } mail_user_unref(&user); mail_storage_service_user_free(&service_user); } if (ret < 0) { + /* temporary failure */ o_stream_send_str(client->conn.output, t_strdup_printf( "action=DEFER_IF_PERMIT %s\n\n", error)); + } else { + o_stream_send_str(client->conn.output, + t_strdup_printf("action=%s\n\n", value)); } } @@ -124,6 +136,10 @@ if (client->recipient == NULL && strncmp(line, "recipient=", 10) == 0) client->recipient = i_strdup(line + 10); + else if (strncmp(line, "size=", 5) == 0) { + if (str_to_uoff(line+5, &client->size) < 0) + client->size = 0; + } return 1; } diff -r c67d787164fa -r 249305f71c73 src/plugins/virtual/virtual-config.c --- a/src/plugins/virtual/virtual-config.c Thu Apr 04 23:35:27 2013 +0300 +++ b/src/plugins/virtual/virtual-config.c Fri Apr 05 00:13:16 2013 +0300 @@ -379,7 +379,7 @@ "Virtual mailbox missing configuration file"); } else if (errno == ENOENT) { mail_storage_set_error(storage, MAIL_ERROR_NOTFOUND, - T_MAIL_ERR_MAILBOX_NOT_FOUND(mbox->box.name)); + T_MAIL_ERR_MAILBOX_NOT_FOUND(mbox->box.vname)); } else { mail_storage_set_critical(storage, "stat(%s) failed: %m", box_path);