Mercurial > dovecot > core-2.2
changeset 14674:efd276ab2577
Merged changes from v2.1 tree.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 24 Jun 2012 20:57:06 +0300 |
parents | a77ad2346cf0 (current diff) c257b9c19915 (diff) |
children | f07ba5e7d97d |
files | configure.in src/auth/auth-request.c src/auth/db-ldap.c src/director/director-connection.c src/doveadm/doveadm-log.c src/lib-index/mail-transaction-log-file.c src/lib-mail/message-parser.c src/lib-master/master-instance.c src/lib-master/master-service.c src/lib-storage/index/dbox-multi/mdbox-map.c src/lib-storage/index/imapc/imapc-mailbox.c src/lib-storage/index/imapc/imapc-storage.c src/lib-storage/index/mbox/mbox-mail.c src/lib-storage/index/shared/shared-list.c src/lib-storage/list/mailbox-list-index-status.c src/plugins/quota/quota-maildir.c src/plugins/quota/quota.c |
diffstat | 44 files changed, 337 insertions(+), 106 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgsigs Sun Jun 24 20:48:38 2012 +0300 +++ b/.hgsigs Sun Jun 24 20:57:06 2012 +0300 @@ -46,3 +46,4 @@ 2c21c940e19d97a772128a7f281cea302e157d73 0 iEYEABECAAYFAk+CtkYACgkQyUhSUUBVisknxgCfTJw2YPGJ17HbHRGmbwmCyLqepbMAn17j7IYzUfEU0xkXhCgwEAmk7XO4 469cee314d9c54d2d7101ec9e38579fdc9610eaf 0 iEYEABECAAYFAk+VWqkACgkQyUhSUUBVislnXACfVjPqMmPUvYtXQXwqff0h7N76mZUAn02lPeUCyuyr1TF9e1hGM/sKgmko 7c249e2a82a9cd33ae15ead6443c3499e16da623 0 iEYEABECAAYFAk+nX2sACgkQyUhSUUBVisn7uwCbBD3boxBOGEJ8OYsIJ57n5Cr09FAAoIvhxL6EHRB15AMOw4sPaALJ3/bB +c92fb8b928f69ca01681a2c2976304b7e4bc3afc 0 iEYEABECAAYFAk/FIeIACgkQyUhSUUBVisk4IgCfUiXVXntqzPjJcALYRpqw4Zc7a/0An3HKWwgb6PBCbmvxBfTezNkqjqVK
--- a/.hgtags Sun Jun 24 20:48:38 2012 +0300 +++ b/.hgtags Sun Jun 24 20:57:06 2012 +0300 @@ -83,3 +83,4 @@ 2c21c940e19d97a772128a7f281cea302e157d73 2.1.4 469cee314d9c54d2d7101ec9e38579fdc9610eaf 2.1.5 7c249e2a82a9cd33ae15ead6443c3499e16da623 2.1.6 +c92fb8b928f69ca01681a2c2976304b7e4bc3afc 2.1.7
--- a/NEWS Sun Jun 24 20:48:38 2012 +0300 +++ b/NEWS Sun Jun 24 20:57:06 2012 +0300 @@ -1,3 +1,22 @@ +v2.1.7 2012-05-29 Timo Sirainen <tss@iki.fi> + + * LDAP: Compatibility fix for v2.0: ldap: If attributes contain + ldapAttr=key=template%$ and ldapAttr doesn't exist, skip the key + instead of using "template" value with empty %$ part for the key. + + + pop3: Added pop3_uidl_duplicates setting for changing the behavior + for duplicate UIDLs. + + director: Added "doveadm director ring remove" command. + - director: Don't crash with quickly disconnecting incoming director + connections. + - mdbox: If mail was originally saved to non-INBOX, and namespace + prefix is non-empty, don't assert-crash when rebuilding indexes. + - sdbox: Don't use more fds than necessary when copying mails. + - auth: Fixed crash with DIGEST-MD5 when attempting to do master user + login without master passdbs. + - Several fixes to mail_shared_explicit_inbox=no + - imapc: Use imapc_list_prefix also for listing subscriptions. + v2.1.6 2012-05-07 Timo Sirainen <tss@iki.fi> * Session ID is now included by default in auth and login process
--- a/doc/example-config/conf.d/20-imap.conf Sun Jun 24 20:48:38 2012 +0300 +++ b/doc/example-config/conf.d/20-imap.conf Sun Jun 24 20:57:06 2012 +0300 @@ -18,7 +18,7 @@ # IMAP logout format string: # %i - total number of bytes read from client # %o - total number of bytes sent to client - #imap_logout_format = bytes=%i/%o + #imap_logout_format = in=%i out=%o # Override the IMAP CAPABILITY response. If the value begins with '+', # add the given capabilities on top of the defaults (e.g. +XFOO XBAR).
--- a/src/auth/auth-request.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/auth/auth-request.c Sun Jun 24 20:57:06 2012 +0300 @@ -1258,6 +1258,8 @@ i_assert(*name != '\0'); i_assert(value != NULL); + i_assert(request->passdb != NULL); + if (strcmp(name, "password") == 0) { auth_request_set_password(request, value, default_scheme, FALSE);
--- a/src/auth/db-ldap.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/auth/db-ldap.c Sun Jun 24 20:57:06 2012 +0300 @@ -866,6 +866,7 @@ ret = ldap_start_tls_s(conn->ld, NULL, NULL); if (ret != LDAP_SUCCESS) { if (ret == LDAP_OPERATIONS_ERROR && + conn->set.uris != NULL && strncmp(conn->set.uris, "ldaps:", 6) == 0) { i_fatal("LDAP: Don't use both tls=yes " "and ldaps URI");
--- a/src/auth/password-scheme.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/auth/password-scheme.c Sun Jun 24 20:57:06 2012 +0300 @@ -367,7 +367,7 @@ str = password_generate_md5_crypt(plaintext, password); return strcmp(str, password) == 0 ? 1 : 0; } else if (password_decode(password, "PLAIN-MD5", - &md5_password, &md5_size, &error) < 0) { + &md5_password, &md5_size, &error) <= 0) { *error_r = "Not a valid MD5-CRYPT or PLAIN-MD5 password"; return -1; } else {
--- a/src/director/director-connection.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/director/director-connection.c Sun Jun 24 20:57:06 2012 +0300 @@ -711,7 +711,7 @@ bool weak = TRUE; int ret; - if ((ret = director_cmd_is_seen(conn, &args, &dir_host)) < 0) + if ((ret = director_cmd_is_seen(conn, &args, &dir_host)) != 0) return FALSE; if (str_array_length(args) != 2 ||
--- a/src/director/director.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/director/director.c Sun Jun 24 20:57:06 2012 +0300 @@ -363,6 +363,11 @@ { /* we're synced again when we receive this SYNC back */ dir->sync_seq++; + if (dir->right == NULL && dir->left == NULL) { + /* we're alone. if we're already synced, + don't become unsynced. */ + return; + } director_set_ring_unsynced(dir); if (dir->sync_frozen) {
--- a/src/director/mail-host.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/director/mail-host.c Sun Jun 24 20:57:06 2012 +0300 @@ -110,7 +110,7 @@ i2 = htonl(ip2_arr[i]); for (j = last_bits; j < 32; j++) { - if ((i1 & (1 << j)) != (i2 & (1 << j))) { + if ((i1 & (1U << j)) != (i2 & (1U << j))) { i_error("IP address range too large: %s-%s", net_ip2addr(&ip1), net_ip2addr(&ip2)); return -1;
--- a/src/doveadm/doveadm-instance.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/doveadm/doveadm-instance.c Sun Jun 24 20:57:06 2012 +0300 @@ -5,6 +5,7 @@ #include "doveadm.h" #include "doveadm-print.h" +#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <signal.h> @@ -42,22 +43,45 @@ return found; } -static void cmd_instance_list(int argc ATTR_UNUSED, char *argv[] ATTR_UNUSED) +static void cmd_instance_list(int argc, char *argv[]) { struct master_instance_list *list; struct master_instance_list_iter *iter; const struct master_instance *inst; const char *pidfile_path; + bool show_config = FALSE; + int c; - doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE); - doveadm_print_header("path", "path", DOVEADM_PRINT_HEADER_FLAG_EXPAND); - doveadm_print_header_simple("name"); - doveadm_print_header_simple("last used"); - doveadm_print_header_simple("running"); + while ((c = getopt(argc, argv, "c")) > 0) { + switch (c) { + case 'c': + show_config = TRUE; + break; + default: + help(&doveadm_cmd_instance[0]); + } + } + argv += optind; + + if (!show_config) { + doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE); + doveadm_print_header("path", "path", DOVEADM_PRINT_HEADER_FLAG_EXPAND); + doveadm_print_header_simple("name"); + doveadm_print_header_simple("last used"); + doveadm_print_header_simple("running"); + } list = master_instance_list_init(MASTER_INSTANCE_PATH); iter = master_instance_list_iterate_init(list); while ((inst = master_instance_iterate_list_next(iter)) != NULL) { + if (argv[0] != NULL && strcmp(argv[0], inst->name) != 0) + continue; + + if (show_config) { + printf("%s\n", inst->config_path == NULL ? "" : + inst->config_path); + continue; + } doveadm_print(inst->base_dir); doveadm_print(inst->name); doveadm_print(unixdate2str(inst->last_used)); @@ -95,7 +119,7 @@ } struct doveadm_cmd doveadm_cmd_instance[] = { - { cmd_instance_list, "instance list", "" }, + { cmd_instance_list, "instance list", "[-c] [<name>]" }, { cmd_instance_remove, "instance remove", "<name> | <base dir>" } };
--- a/src/doveadm/doveadm-log.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/doveadm/doveadm-log.c Sun Jun 24 20:57:06 2012 +0300 @@ -23,6 +23,8 @@ #define LOG_ERRORS_FNAME "log-errors" #define LOG_TIMESTAMP_FORMAT "%b %d %H:%M:%S" +extern struct doveadm_cmd doveadm_cmd_log[]; + static void ATTR_NULL(2) cmd_log_test(int argc ATTR_UNUSED, char *argv[] ATTR_UNUSED) { @@ -279,7 +281,7 @@ } } -static void cmd_log_error_write(const char *const *args) +static void cmd_log_error_write(const char *const *args, time_t min_timestamp) { /* <type> <timestamp> <prefix> <text> */ const char *type_prefix = "?"; @@ -298,16 +300,32 @@ i_error("Invalid timestamp: %s", args[1]); t = 0; } - - printf("%s %s%s%s\n", t_strflocaltime(LOG_TIMESTAMP_FORMAT, t), - args[2], type_prefix, args[3]); + if (t >= min_timestamp) { + printf("%s %s%s%s\n", t_strflocaltime(LOG_TIMESTAMP_FORMAT, t), + args[2], type_prefix, args[3]); + } } -static void cmd_log_errors(int argc ATTR_UNUSED, char *argv[] ATTR_UNUSED) +static void cmd_log_errors(int argc, char *argv[]) { struct istream *input; const char *path, *line, *const *args; - int fd; + time_t min_timestamp = 0; + int c, fd; + + while ((c = getopt(argc, argv, "s:")) > 0) { + switch (c) { + case 's': + if (str_to_time(optarg, &min_timestamp) < 0) + i_fatal("Invalid timestamp: %s", optarg); + break; + default: + help(&doveadm_cmd_log[3]); + } + } + argv += optind - 1; + if (argv[1] != NULL) + help(&doveadm_cmd_log[3]); path = t_strconcat(doveadm_settings->base_dir, "/"LOG_ERRORS_FNAME, NULL); @@ -320,7 +338,7 @@ while ((line = i_stream_read_next_line(input)) != NULL) T_BEGIN { args = t_strsplit_tabescaped(line); if (str_array_length(args) == 4) - cmd_log_error_write(args); + cmd_log_error_write(args, min_timestamp); else { i_error("Invalid input from log: %s", line); doveadm_exit_code = EX_PROTOCOL; @@ -333,7 +351,7 @@ { cmd_log_test, "log test", "" }, { cmd_log_reopen, "log reopen", "" }, { cmd_log_find, "log find", "[<dir>]" }, - { cmd_log_errors, "log errors", "" } + { cmd_log_errors, "log errors", "[-s <min_timestamp>]" } }; void doveadm_register_log_commands(void)
--- a/src/doveadm/doveadm-print.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/doveadm/doveadm-print.c Sun Jun 24 20:57:06 2012 +0300 @@ -18,6 +18,7 @@ const struct doveadm_print_vfuncs *v; unsigned int header_idx; + bool print_stream_open; }; static struct doveadm_print_context *ctx; @@ -52,7 +53,7 @@ doveadm_print_header(key_title, key_title, 0); } -void doveadm_print(const char *value) +static void doveadm_print_sticky_headers(void) { const struct doveadm_print_header_context *headers; unsigned int count; @@ -68,7 +69,13 @@ break; } } +} +void doveadm_print(const char *value) +{ + i_assert(!ctx->print_stream_open); + + doveadm_print_sticky_headers(); ctx->v->print(value); ctx->header_idx++; } @@ -82,9 +89,15 @@ void doveadm_print_stream(const void *value, size_t size) { + if (!ctx->print_stream_open) { + doveadm_print_sticky_headers(); + ctx->print_stream_open = TRUE; + } ctx->v->print_stream(value, size); - if (size == 0) + if (size == 0) { ctx->header_idx++; + ctx->print_stream_open = FALSE; + } } void doveadm_print_sticky(const char *key, const char *value)
--- a/src/doveadm/doveadm.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/doveadm/doveadm.c Sun Jun 24 20:57:06 2012 +0300 @@ -5,7 +5,7 @@ #include "str.h" #include "env-util.h" #include "execv-const.h" -#include "master-service.h" +#include "master-service-private.h" #include "master-service-settings.h" #include "settings-parser.h" #include "doveadm-print-private.h" @@ -163,6 +163,8 @@ static void cmd_config(int argc ATTR_UNUSED, char *argv[]) { + env_put(t_strconcat(MASTER_CONFIG_FILE_ENV"=", + master_service_get_config_path(master_service), NULL)); argv[0] = BINDIR"/doveconf"; (void)execv(argv[0], argv); i_fatal("execv(%s) failed: %m", argv[0]);
--- a/src/imap/cmd-delete.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/imap/cmd-delete.c Sun Jun 24 20:57:06 2012 +0300 @@ -8,7 +8,8 @@ struct client *client = cmd->client; struct mail_namespace *ns; struct mailbox *box; - const char *name; + const char *name, *errstr; + enum mail_error error; /* <mailbox> */ if (!client_read_string_args(cmd, 1, &name)) @@ -32,10 +33,17 @@ mailbox_free(&client->mailbox); } - if (mailbox_delete(box) < 0) - client_send_storage_error(cmd, mailbox_get_storage(box)); - else + if (mailbox_delete(box) == 0) client_send_tagline(cmd, "OK Delete completed."); + else { + errstr = mailbox_get_last_error(box, &error); + if (error != MAIL_ERROR_EXISTS) + client_send_storage_error(cmd, mailbox_get_storage(box)); + else { + /* mailbox has children */ + client_send_tagline(cmd, t_strdup_printf("NO %s", errstr)); + } + } mailbox_free(&box); return TRUE; }
--- a/src/lib-charset/charset-iconv.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib-charset/charset-iconv.c Sun Jun 24 20:57:06 2012 +0300 @@ -53,6 +53,20 @@ (void)iconv(t->cd, NULL, NULL, NULL, NULL); } +static int +charset_append_utf8(const void *src, size_t src_size, + buffer_t *dest, bool dtcase) +{ + if (dtcase) + return uni_utf8_to_decomposed_titlecase(src, src_size, dest); + if (!uni_utf8_get_valid_data(src, src_size, dest)) + return -1; + else { + buffer_append(dest, src, src_size); + return 0; + } +} + static bool charset_to_utf8_try(struct charset_translation *t, const unsigned char *src, size_t *src_size, buffer_t *dest, @@ -65,30 +79,15 @@ bool ret = TRUE; if (t->cd == (iconv_t)-1) { - /* no translation needed - just copy it to outbuf uppercased */ - *result = CHARSET_RET_OK; - if (!dtcase) { - buffer_append(dest, src, *src_size); - return TRUE; - } - - if (uni_utf8_to_decomposed_titlecase(src, *src_size, dest) < 0) + /* input is already supposed to be UTF-8 */ + if (charset_append_utf8(src, *src_size, dest, dtcase) < 0) *result = CHARSET_RET_INVALID_INPUT; + else + *result = CHARSET_RET_OK; return TRUE; } - if (!dtcase) { - destleft = buffer_get_size(dest) - dest->used; - if (destleft < *src_size) { - /* The buffer is most likely too small to hold the - output, so increase it at least to the input size. */ - destleft = *src_size; - } - ic_destbuf = buffer_append_space_unsafe(dest, destleft); - } else { - destleft = sizeof(tmpbuf); - ic_destbuf = tmpbuf; - } - + destleft = sizeof(tmpbuf); + ic_destbuf = tmpbuf; srcleft = *src_size; ic_srcbuf = (ICONV_CONST char *) src; @@ -108,17 +107,12 @@ } *src_size -= srcleft; - if (!dtcase) { - /* give back the memory we didn't use */ - buffer_set_used_size(dest, dest->used - destleft); - } else { - size_t tmpsize = sizeof(tmpbuf) - destleft; - - /* we just converted data to UTF-8. it shouldn't be invalid, - but Solaris iconv appears to pass invalid data through - sometimes (e.g. 8 bit characters with UTF-7) */ - (void)uni_utf8_to_decomposed_titlecase(tmpbuf, tmpsize, dest); - } + /* we just converted data to UTF-8. it shouldn't be invalid, but + Solaris iconv appears to pass invalid data through sometimes + (e.g. 8 bit characters with UTF-7) */ + if (charset_append_utf8(tmpbuf, sizeof(tmpbuf) - destleft, + dest, dtcase) < 0) + *result = CHARSET_RET_INVALID_INPUT; return ret; }
--- a/src/lib-dict/dict-file.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib-dict/dict-file.c Sun Jun 24 20:57:06 2012 +0300 @@ -492,7 +492,7 @@ /* refresh once more now that we're locked */ if (file_dict_refresh(dict) < 0) { if (dotlock != NULL) - file_dotlock_delete(&dotlock); + (void)file_dotlock_delete(&dotlock); else { (void)close(fd); file_unlock(&lock); @@ -512,12 +512,20 @@ o_stream_cork(output); iter = hash_table_iterate_init(dict->hash); while (hash_table_iterate(iter, &key, &value)) { - o_stream_send_str(output, key); - o_stream_send(output, "\n", 1); - o_stream_send_str(output, value); - o_stream_send(output, "\n", 1); + (void)o_stream_send_str(output, key); + (void)o_stream_send(output, "\n", 1); + (void)o_stream_send_str(output, value); + (void)o_stream_send(output, "\n", 1); } + o_stream_uncork(output); hash_table_iterate_deinit(&iter); + + if (output->stream_errno != 0) { + i_error("write(%s) failed: %m", temp_path); + o_stream_destroy(&output); + (void)close(fd); + return -1; + } o_stream_destroy(&output); if (dotlock != NULL) {
--- a/src/lib-index/mail-transaction-log-file.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib-index/mail-transaction-log-file.c Sun Jun 24 20:57:06 2012 +0300 @@ -1673,6 +1673,7 @@ file->filepath); return 0; } + i_assert(file->buffer != NULL); return log_file_map_check_offsets(file, start_offset, end_offset); } @@ -1695,9 +1696,11 @@ i_assert(file->buffer == NULL || file->mmap_base != NULL || file->sync_offset >= file->buffer_offset + file->buffer->used); + if (ret <= 0) + return ret; - return ret <= 0 ? ret : - log_file_map_check_offsets(file, start_offset, end_offset); + i_assert(file->buffer != NULL); + return log_file_map_check_offsets(file, start_offset, end_offset); } void mail_transaction_log_file_move_to_memory(struct mail_transaction_log_file
--- a/src/lib-index/mail-transaction-log.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib-index/mail-transaction-log.c Sun Jun 24 20:57:06 2012 +0300 @@ -463,6 +463,7 @@ /* try again */ } + i_assert(ret < 0 || log->head != NULL); return ret; }
--- a/src/lib-master/master-instance.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib-master/master-instance.c Sun Jun 24 20:57:06 2012 +0300 @@ -1,6 +1,7 @@ /* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ #include "lib.h" +#include "abspath.h" #include "array.h" #include "istream.h" #include "ostream.h" @@ -17,6 +18,9 @@ const char *path; ARRAY_DEFINE(instances, struct master_instance); + + unsigned int locked:1; + unsigned int config_paths_changed:1; }; struct master_instance_list_iter { @@ -50,6 +54,22 @@ pool_unref(&list->pool); } +static void +master_instance_update_config_path(struct master_instance_list *list, + struct master_instance *inst) +{ + const char *path, *config_path; + + /* update instance's config path if it has changed */ + path = t_strconcat(inst->base_dir, "/"PACKAGE".conf", NULL); + if (t_readlink(path, &config_path) == 0) { + if (null_strcmp(inst->config_path, config_path) != 0) { + inst->config_path = p_strdup(list->pool, config_path); + list->config_paths_changed = TRUE; + } + } +} + static int master_instance_list_add_line(struct master_instance_list *list, const char *line) @@ -58,9 +78,9 @@ const char *const *args; time_t last_used; - /* <last used> <name> <base dir> */ + /* <last used> <name> <base dir> [<config path>] */ args = t_strsplit_tabescaped(line); - if (str_array_length(args) != 3) + if (str_array_length(args) < 3) return -1; if (str_to_time(args[0], &last_used) < 0) return -1; @@ -69,6 +89,8 @@ inst->last_used = last_used; inst->name = p_strdup(list->pool, args[1]); inst->base_dir = p_strdup(list->pool, args[2]); + inst->config_path = p_strdup_empty(list->pool, args[3]); + master_instance_update_config_path(list, inst); return 0; } @@ -117,6 +139,9 @@ str_tabescape_write(str, inst->name); str_append_c(str, '\t'); str_tabescape_write(str, inst->base_dir); + str_append_c(str, '\t'); + if (inst->config_path != NULL) + str_tabescape_write(str, inst->config_path); str_append_c(str, '\n'); (void)o_stream_send(output, str_data(str), str_len(str)); } @@ -135,6 +160,8 @@ { int fd; + i_assert(!list->locked); + *dotlock_r = NULL; fd = file_dotlock_open_mode(&dotlock_set, list->path, 0, 0644, @@ -147,6 +174,7 @@ file_dotlock_delete(dotlock_r); return -1; } + list->locked = TRUE; return fd; } @@ -156,9 +184,13 @@ const char *lock_path = file_dotlock_get_lock_path(*dotlock); int ret; + i_assert(list->locked); + T_BEGIN { ret = master_instance_list_write(list, fd, lock_path); } T_END; + + list->locked = FALSE; if (ret < 0) { file_dotlock_delete(dotlock); return -1; @@ -168,6 +200,7 @@ file_dotlock_delete(dotlock); return -1; } + list->config_paths_changed = FALSE; return file_dotlock_replace(dotlock, 0); } @@ -201,6 +234,7 @@ inst->base_dir = p_strdup(list->pool, base_dir); } inst->last_used = time(NULL); + master_instance_update_config_path(list, inst); return master_instance_write_finish(list, fd, &dotlock); } @@ -223,6 +257,7 @@ strcmp(orig_inst->base_dir, base_dir) != 0) { /* name already used */ file_dotlock_delete(&dotlock); + list->locked = FALSE; return 0; } @@ -258,11 +293,30 @@ if (i == count) { file_dotlock_delete(&dotlock); + list->locked = FALSE; return 0; } return master_instance_write_finish(list, fd, &dotlock) < 0 ? -1 : 1; } +static int +master_instance_list_refresh_and_update(struct master_instance_list *list) +{ + struct dotlock *dotlock; + int fd; + + if (master_instance_list_refresh(list) < 0) + return -1; + if (list->config_paths_changed && !list->locked) { + /* write new config paths */ + if ((fd = master_instance_write_init(list, &dotlock)) == -1) + return -1; + if (master_instance_write_finish(list, fd, &dotlock) < 0) + return -1; + } + return 0; +} + const struct master_instance * master_instance_list_find_by_name(struct master_instance_list *list, const char *name) @@ -272,7 +326,7 @@ i_assert(*name != '\0'); if (array_count(&list->instances) == 0) - (void)master_instance_list_refresh(list); + (void)master_instance_list_refresh_and_update(list); array_foreach(&list->instances, inst) { if (strcmp(inst->name, name) == 0) @@ -288,7 +342,7 @@ iter = i_new(struct master_instance_list_iter, 1); iter->list = list; - (void)master_instance_list_refresh(list); + (void)master_instance_list_refresh_and_update(list); return iter; }
--- a/src/lib-master/master-instance.h Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib-master/master-instance.h Sun Jun 24 20:57:06 2012 +0300 @@ -9,6 +9,7 @@ time_t last_used; const char *name; const char *base_dir; + const char *config_path; }; struct master_instance_list *master_instance_list_init(const char *path);
--- a/src/lib-master/master-service.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib-master/master-service.c Sun Jun 24 20:57:06 2012 +0300 @@ -359,7 +359,6 @@ if (!get_instance_config(arg, &path)) i_fatal("Unknown instance name: %s", arg); service->config_path = i_strdup(path); - service->keep_environment = TRUE; break; case 'k': service->keep_environment = TRUE;
--- a/src/lib-ssl-iostream/iostream-openssl.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib-ssl-iostream/iostream-openssl.c Sun Jun 24 20:57:06 2012 +0300 @@ -246,7 +246,7 @@ *_ssl_io = NULL; i_assert(ssl_io->refcount > 0); - if (--ssl_io->refcount >= 0) + if (--ssl_io->refcount > 0) return; ssl_iostream_free(ssl_io); @@ -388,7 +388,8 @@ return 0; } if (ssl_io->closed) { - errno = ssl_io->plain_stream_errno; + errno = ssl_io->plain_stream_errno != 0 ? + ssl_io->plain_stream_errno : EPIPE; return -1; } return 1; @@ -396,7 +397,8 @@ ssl_io->want_read = TRUE; (void)ssl_iostream_bio_sync(ssl_io); if (ssl_io->closed) { - errno = ssl_io->plain_stream_errno; + errno = ssl_io->plain_stream_errno != 0 ? + ssl_io->plain_stream_errno : EPIPE; return -1; } return ssl_io->want_read ? 0 : 1; @@ -406,6 +408,7 @@ errstr = ssl_iostream_error(); errno = EINVAL; } else if (ret != 0) { + i_assert(errno != 0); errstr = strerror(errno); } else { /* EOF. */ @@ -500,6 +503,7 @@ const char *dnsname; bool dns_names = FALSE; unsigned int i, count; + int ret; cert = SSL_get_peer_certificate(ssl); i_assert(cert != NULL); @@ -517,14 +521,15 @@ } } sk_GENERAL_NAME_pop_free(gnames, GENERAL_NAME_free); - X509_free(cert); /* verify against CommonName only when there wasn't any DNS SubjectAltNames */ if (dns_names) - return i < count ? 0 : -1; - - return strcmp(get_cname(cert), verify_name) == 0 ? 0 : -1; + ret = i < count ? 0 : -1; + else + ret = strcmp(get_cname(cert), verify_name) == 0 ? 0 : -1; + X509_free(cert); + return ret; } int ssl_iostream_cert_match_name(struct ssl_iostream *ssl_io,
--- a/src/lib-ssl-iostream/istream-openssl.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib-ssl-iostream/istream-openssl.c Sun Jun 24 20:57:06 2012 +0300 @@ -21,6 +21,7 @@ { struct ssl_istream *sstream = (struct ssl_istream *)stream; + i_free(sstream->istream.w_buffer); ssl_iostream_unref(&sstream->ssl_io); } @@ -38,6 +39,7 @@ if (ret <= 0) { if (ret < 0) { /* handshake failed */ + i_assert(errno != 0); stream->istream.stream_errno = errno; } return ret;
--- a/src/lib-ssl-iostream/ostream-openssl.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib-ssl-iostream/ostream-openssl.c Sun Jun 24 20:57:06 2012 +0300 @@ -24,7 +24,8 @@ sstream->ssl_io->ssl_output = NULL; ssl_iostream_unref(&sstream->ssl_io); - i_free(sstream->buffer); + if (sstream->buffer != NULL) + buffer_free(&sstream->buffer); } static size_t
--- a/src/lib-storage/index/dbox-multi/mdbox-map-private.h Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib-storage/index/dbox-multi/mdbox-map-private.h Sun Jun 24 20:57:06 2012 +0300 @@ -57,6 +57,7 @@ unsigned int map_refreshed:1; unsigned int locked:1; unsigned int success:1; + unsigned int failed:1; }; int mdbox_map_view_lookup_rec(struct mdbox_map *map,
--- a/src/lib-storage/index/dbox-multi/mdbox-map.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib-storage/index/dbox-multi/mdbox-map.c Sun Jun 24 20:57:06 2012 +0300 @@ -517,11 +517,13 @@ void mdbox_map_atomic_set_failed(struct mdbox_map_atomic_context *atomic) { atomic->success = FALSE; + atomic->failed = TRUE; } void mdbox_map_atomic_set_success(struct mdbox_map_atomic_context *atomic) { - atomic->success = TRUE; + if (!atomic->failed) + atomic->success = TRUE; } int mdbox_map_atomic_finish(struct mdbox_map_atomic_context **_atomic) @@ -593,7 +595,7 @@ mail_index_reset_error(ctx->atomic->map->index); return -1; } - ctx->atomic->success = TRUE; + mdbox_map_atomic_set_success(ctx->atomic); return 0; } @@ -1365,6 +1367,21 @@ return 0; } +int mdbox_map_append_flush(struct mdbox_map_append_context *ctx) +{ + struct dbox_file_append_context **file_appends; + unsigned int i, count; + + i_assert(ctx->trans == NULL); + + file_appends = array_get_modifiable(&ctx->file_appends, &count); + for (i = 0; i < count; i++) { + if (dbox_file_append_flush(file_appends[i]) < 0) + return -1; + } + return 0; +} + int mdbox_map_append_commit(struct mdbox_map_append_context *ctx) { struct dbox_file_append_context **file_appends; @@ -1377,7 +1394,7 @@ if (dbox_file_append_commit(&file_appends[i]) < 0) return -1; } - ctx->atomic->success = TRUE; + mdbox_map_atomic_set_success(ctx->atomic); return 0; }
--- a/src/lib-storage/index/dbox-multi/mdbox-map.h Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib-storage/index/dbox-multi/mdbox-map.h Sun Jun 24 20:57:06 2012 +0300 @@ -115,6 +115,8 @@ int mdbox_map_append_move(struct mdbox_map_append_context *ctx, const ARRAY_TYPE(uint32_t) *map_uids, const ARRAY_TYPE(seq_range) *expunge_map_uids); +/* Flush/fsync appends. */ +int mdbox_map_append_flush(struct mdbox_map_append_context *ctx); /* Returns 0 if ok, -1 if error. */ int mdbox_map_append_commit(struct mdbox_map_append_context *ctx); void mdbox_map_append_free(struct mdbox_map_append_context **ctx);
--- a/src/lib-storage/index/dbox-multi/mdbox-save.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib-storage/index/dbox-multi/mdbox-save.c Sun Jun 24 20:57:06 2012 +0300 @@ -287,6 +287,12 @@ i_assert(ctx->ctx.finished); + /* flush/fsync writes to m.* files before locking the map */ + if (mdbox_map_append_flush(ctx->append_ctx) < 0) { + mdbox_transaction_save_rollback(_ctx); + return -1; + } + /* make sure the map gets locked */ if (mdbox_map_atomic_lock(ctx->atomic) < 0) { mdbox_transaction_save_rollback(_ctx);
--- a/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c Sun Jun 24 20:57:06 2012 +0300 @@ -605,6 +605,7 @@ if (ret > 0 && !deleted && dbox_file_metadata_read(file) > 0) { mailbox = dbox_file_metadata_get(file, DBOX_METADATA_ORIG_MAILBOX); + mailbox = mailbox_list_get_vname(ctx->default_list, mailbox); mailbox = t_strdup(mailbox); } dbox_file_unref(&file); @@ -623,7 +624,7 @@ there. */ created = FALSE; box = ctx->prev_msg.box != NULL && - strcmp(mailbox, ctx->prev_msg.box->name) == 0 ? + strcmp(mailbox, ctx->prev_msg.box->vname) == 0 ? ctx->prev_msg.box : NULL; while (box == NULL) { box = mailbox_alloc(ctx->default_list, mailbox,
--- a/src/lib-storage/index/imapc/imapc-mailbox.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib-storage/index/imapc/imapc-mailbox.c Sun Jun 24 20:57:06 2012 +0300 @@ -338,7 +338,7 @@ mail_index_update_flags(mbox->delayed_sync_trans, lseq, MODIFY_REPLACE, flags); } - if (seen_flags) T_BEGIN { + if (seen_flags) { ARRAY_TYPE(keyword_indexes) old_kws; struct mail_keywords *kw; @@ -354,7 +354,7 @@ lseq, MODIFY_REPLACE, kw); } mail_index_keywords_unref(&kw); - } T_END; + } imapc_mailbox_idle_notify(mbox); }
--- a/src/lib-storage/index/imapc/imapc-storage.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib-storage/index/imapc/imapc-storage.c Sun Jun 24 20:57:06 2012 +0300 @@ -275,6 +275,19 @@ imapc_client_deinit(&storage->client); } +static void imapc_storage_add_list(struct mail_storage *_storage, + struct mailbox_list *_list) +{ + struct imapc_storage *storage = (struct imapc_storage *)_storage; + struct imapc_mailbox_list *list = (struct imapc_mailbox_list *)_list; + + i_assert(storage->list != NULL); + i_assert(storage->list->sep != '\0'); + + list->storage = storage; + list->sep = storage->list->sep; +} + void imapc_storage_register_untagged(struct imapc_storage *storage, const char *name, imapc_storage_callback_t *callback) @@ -753,7 +766,7 @@ imapc_storage_alloc, imapc_storage_create, imapc_storage_destroy, - NULL, + imapc_storage_add_list, imapc_storage_get_list_settings, NULL, imapc_mailbox_alloc,
--- a/src/lib-storage/index/mbox/mbox-mail.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib-storage/index/mbox/mbox-mail.c Sun Jun 24 20:57:06 2012 +0300 @@ -241,6 +241,8 @@ int trailer_size; int ret = 1; + *next_offset_r = (uoff_t)-1; + hdr = mail_index_get_header(mail->mail.mail.transaction->view); if (mail->mail.mail.seq > hdr->messages_count) { /* we're appending a new message */ @@ -342,8 +344,6 @@ mail->mail.mail.uid); } } - if (ret <= 0) - next_offset = (uoff_t)-1; raw_stream = mbox->mbox_stream; hdr_offset = istream_raw_mbox_get_header_offset(raw_stream);
--- a/src/lib-storage/index/mbox/mbox-save.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib-storage/index/mbox/mbox-save.c Sun Jun 24 20:57:06 2012 +0300 @@ -666,6 +666,7 @@ ctx->finished = TRUE; if (!ctx->failed) { + i_assert(ctx->output != NULL); T_BEGIN { if (mbox_write_content_length(ctx) < 0 || mbox_append_lf(ctx) < 0)
--- a/src/lib-storage/index/shared/shared-list.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib-storage/index/shared/shared-list.c Sun Jun 24 20:57:06 2012 +0300 @@ -43,8 +43,12 @@ const char *name; name = mailbox_list_get_storage_name(*list, vname); - if (shared_storage_get_namespace(&ns, &name) < 0) - return -1; + if (*name == '\0' && (ns->flags & NAMESPACE_FLAG_AUTOCREATED) == 0) { + /* trying to access the shared/ prefix itself */ + } else { + if (shared_storage_get_namespace(&ns, &name) < 0) + return -1; + } *list = ns->list; *storage_r = ns->storage; return 0;
--- a/src/lib-storage/mail-search-register-imap.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib-storage/mail-search-register-imap.c Sun Jun 24 20:57:06 2012 +0300 @@ -259,6 +259,8 @@ /* <hdr-name> <string> */ if (mail_search_parse_string(ctx->parser, &hdr_name) < 0) return NULL; + if (mail_search_build_get_utf8(ctx, hdr_name, &hdr_name) < 0) + return NULL; return arg_new_header(ctx, SEARCH_HEADER, t_str_ucase(hdr_name)); }
--- a/src/lib/primes.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib/primes.c Sun Jun 24 20:57:06 2012 +0300 @@ -41,7 +41,7 @@ unsigned int i; for (i = 31; i > PRIME_SKIP_COUNT; i--) { - if ((num & (1 << i)) != 0) + if ((num & (1U << i)) != 0) return primes[i - PRIME_SKIP_COUNT]; } return primes[0];
--- a/src/lib/restrict-access.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib/restrict-access.c Sun Jun 24 20:57:06 2012 +0300 @@ -126,7 +126,7 @@ i_fatal("getgroups() failed: %m"); /* @UNSAFE */ - gid_list = t_new(gid_t, gid_count); + gid_list = t_new(gid_t, gid_count+1); /* +1 in case gid_count=0 */ if ((ret = getgroups(gid_count, gid_list)) < 0) i_fatal("getgroups() failed: %m");
--- a/src/lib/utc-mktime.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/lib/utc-mktime.c Sun Jun 24 20:57:06 2012 +0300 @@ -33,7 +33,7 @@ #ifdef TIME_T_SIGNED t = 0; #else - t = 1 << (TIME_T_MAX_BITS - 1); + t = (time_t)1 << (TIME_T_MAX_BITS - 1); #endif for (bits = TIME_T_MAX_BITS - 2;; bits--) { try_tm = gmtime(&t);
--- a/src/master/service-monitor.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/master/service-monitor.c Sun Jun 24 20:57:06 2012 +0300 @@ -237,19 +237,27 @@ static void service_drop_connections(struct service_listener *l) { struct service *service = l->service; + const char *limit_name; unsigned int limit; int fd; if (service->last_drop_warning + SERVICE_DROP_WARN_INTERVAL_SECS < ioloop_time) { service->last_drop_warning = ioloop_time; - limit = service->process_limit > 1 ? - service->process_limit : service->client_limit; + if (service->process_limit > 1) { + limit_name = "process_limit"; + limit = service->process_limit; + } else if (service->set->service_count == 1) { + i_assert(service->client_limit == 1); + limit_name = "client_limit/service_count"; + limit = 1; + } else { + limit_name = "client_limit"; + limit = service->client_limit; + } i_warning("service(%s): %s (%u) reached, " "client connections are being dropped", - service->set->name, - service->process_limit > 1 ? - "process_limit" : "client_limit", limit); + service->set->name, limit_name, limit); } if (service->type == SERVICE_TYPE_LOGIN) {
--- a/src/plugins/fts-squat/fts-backend-squat.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/plugins/fts-squat/fts-backend-squat.c Sun Jun 24 20:57:06 2012 +0300 @@ -452,9 +452,10 @@ &result->maybe_uids); if (ret < 0) return -1; - if (ret > 0) + if (ret > 0) { args->match_always = TRUE; - first = FALSE; + first = FALSE; + } } return 0; }
--- a/src/plugins/fts-squat/squat-uidlist.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/plugins/fts-squat/squat-uidlist.c Sun Jun 24 20:57:06 2012 +0300 @@ -1416,6 +1416,7 @@ squat_uidlist_set_corrupted(uidlist, "uidlist not found"); return -1; } + i_assert(uidlist->cur_block_end_indexes != NULL); if (unlikely(idx > 0 && uidlist->cur_block_end_indexes[idx-1] > uid_list_idx)) { squat_uidlist_set_corrupted(uidlist, "broken block list"); @@ -1430,6 +1431,7 @@ return -1; /* find the uidlist inside the block */ + i_assert(uidlist->cur_block_offsets != NULL); p = CONST_PTR_OFFSET(uidlist->data, uidlist->cur_block_offsets[idx]); end = CONST_PTR_OFFSET(uidlist->data, uidlist->data_size);
--- a/src/plugins/quota/quota-maildir.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/plugins/quota/quota-maildir.c Sun Jun 24 20:57:06 2012 +0300 @@ -546,12 +546,15 @@ !CMP_DEV_T(st1.st_dev, st2.st_dev); } -static int maildirsize_read(struct maildir_quota_root *root) +static int maildirsize_read(struct maildir_quota_root *root, bool *retry) { char buf[5120+1]; unsigned int i, size; + bool retry_estale = *retry; int ret; + *retry = FALSE; + if (!maildirsize_has_changed(root)) return 1; @@ -562,8 +565,10 @@ size = 0; while ((ret = read(root->fd, buf + size, sizeof(buf)-1 - size)) != 0) { if (ret < 0) { - if (errno == ESTALE) + if (errno == ESTALE && retry_estale) { + *retry = TRUE; break; + } i_error("read(%s) failed: %m", root->maildirsize_path); break; } @@ -644,14 +649,20 @@ static int maildirquota_read_limits(struct maildir_quota_root *root) { - int ret; + bool retry = TRUE; + int ret, n = 0; if (!maildirquota_limits_init(root)) return 1; - T_BEGIN { - ret = maildirsize_read(root); - } T_END; + do { + if (n == NFS_ESTALE_RETRY_COUNT) + retry = FALSE; + T_BEGIN { + ret = maildirsize_read(root, &retry); + } T_END; + n++; + } while (ret == -1 && retry); return ret; }
--- a/src/plugins/quota/quota.c Sun Jun 24 20:48:38 2012 +0300 +++ b/src/plugins/quota/quota.c Sun Jun 24 20:57:06 2012 +0300 @@ -638,7 +638,7 @@ for (i = 0; i < count; i++) { path2 = mailbox_list_get_root_path(namespaces[i]->list, MAILBOX_LIST_PATH_TYPE_MAILBOX); - if (strcmp(path, path2) == 0) { + if (path2 != NULL && strcmp(path, path2) == 0) { /* duplicate */ return; }