From dovecot at dovecot.org Sat Oct 1 16:39:57 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 01 Oct 2011 16:39:57 +0300 Subject: dovecot-2.1: auth: If password data isn't valid for specified sc... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/c9894346b1a3 changeset: 13566:c9894346b1a3 user: Timo Sirainen date: Sat Oct 01 16:48:17 2011 +0300 description: auth: If password data isn't valid for specified scheme, give a better error message. diffstat: src/auth/auth-request.c | 6 +++--- src/auth/passdb.c | 9 +++++---- src/auth/password-scheme.c | 35 +++++++++++++++++++++++++++-------- src/auth/password-scheme.h | 3 ++- 4 files changed, 37 insertions(+), 16 deletions(-) diffs (163 lines): diff -r 1fd1321e55f4 -r c9894346b1a3 src/auth/auth-request.c --- a/src/auth/auth-request.c Fri Sep 30 19:02:31 2011 +0300 +++ b/src/auth/auth-request.c Sat Oct 01 16:48:17 2011 +0300 @@ -1509,12 +1509,12 @@ } ret = password_decode(crypted_password, scheme, - &raw_password, &raw_password_size); + &raw_password, &raw_password_size, &error); if (ret <= 0) { if (ret < 0) { auth_request_log_error(request, subsystem, - "Password in passdb is not in expected scheme %s", - scheme); + "Password data is not valid for scheme %s: %s", + scheme, error); } else { auth_request_log_error(request, subsystem, "Unknown scheme %s", scheme); diff -r 1fd1321e55f4 -r c9894346b1a3 src/auth/passdb.c --- a/src/auth/passdb.c Fri Sep 30 19:02:31 2011 +0300 +++ b/src/auth/passdb.c Sat Oct 01 16:48:17 2011 +0300 @@ -64,7 +64,7 @@ const unsigned char **credentials_r, size_t *size_r) { const char *wanted_scheme = auth_request->credentials_scheme; - const char *plaintext, *username; + const char *plaintext, *username, *error; int ret; if (auth_request->prefer_plain_credentials && @@ -74,12 +74,13 @@ wanted_scheme = ""; } - ret = password_decode(input, input_scheme, credentials_r, size_r); + ret = password_decode(input, input_scheme, + credentials_r, size_r, &error); if (ret <= 0) { if (ret < 0) { auth_request_log_error(auth_request, "password", - "Password in passdb is not in expected scheme %s", - input_scheme); + "Password data is not valid for scheme %s: %s", + input_scheme, error); } else { auth_request_log_error(auth_request, "password", "Unknown scheme %s", input_scheme); diff -r 1fd1321e55f4 -r c9894346b1a3 src/auth/password-scheme.c --- a/src/auth/password-scheme.c Fri Sep 30 19:02:31 2011 +0300 +++ b/src/auth/password-scheme.c Sat Oct 01 16:48:17 2011 +0300 @@ -132,16 +132,22 @@ } int password_decode(const char *password, const char *scheme, - const unsigned char **raw_password_r, size_t *size_r) + const unsigned char **raw_password_r, size_t *size_r, + const char **error_r) { const struct password_scheme *s; enum password_encoding encoding; buffer_t *buf; unsigned int len; + bool guessed_encoding; + + *error_r = NULL; s = password_scheme_lookup(scheme, &encoding); - if (s == NULL) + if (s == NULL) { + *error_r = "Unknown scheme"; return 0; + } len = strlen(password); if (encoding != PW_ENCODING_NONE && s->raw_password_len != 0 && @@ -150,8 +156,11 @@ base64 and hex encodings. the only problem is distinguishing 2 character strings, but there shouldn't be any that short raw_password_lens. */ - encoding = len == s->raw_password_len * 2 ? PW_ENCODING_HEX : - PW_ENCODING_BASE64; + encoding = len == s->raw_password_len * 2 ? + PW_ENCODING_HEX : PW_ENCODING_BASE64; + guessed_encoding = TRUE; + } else { + guessed_encoding = FALSE; } switch (encoding) { @@ -167,14 +176,20 @@ *size_r = buf->used; break; } + if (!guessed_encoding) { + *error_r = "Input isn't valid HEX encoded data"; + return -1; + } /* fall through, just in case it was base64-encoded after all. some input lengths produce matching hex and base64 encoded lengths. */ case PW_ENCODING_BASE64: buf = buffer_create_dynamic(pool_datastack_create(), MAX_BASE64_DECODED_SIZE(len)); - if (base64_decode(password, len, NULL, buf) < 0) + if (base64_decode(password, len, NULL, buf) < 0) { + *error_r = "Input isn't valid base64 encoded data"; return -1; + } *raw_password_r = buf->data; *size_r = buf->used; @@ -182,6 +197,9 @@ } if (s->raw_password_len != *size_r && s->raw_password_len != 0) { /* password has invalid length */ + *error_r = t_strdup_printf( + "Input length isn't valid (%u instead of %u)", + (unsigned int)*size_r, s->raw_password_len); return -1; } return 1; @@ -282,7 +300,8 @@ schemes = array_get(&password_schemes, &count); for (i = 0; i < count; i++) { if (password_decode(crypted_password, schemes[i]->name, - &raw_password, &raw_password_size) <= 0) + &raw_password, &raw_password_size, + &error) <= 0) continue; if (password_verify(plain_password, user, schemes[i]->name, @@ -332,7 +351,7 @@ md5_verify(const char *plaintext, const char *user, const unsigned char *raw_password, size_t size, const char **error_r) { - const char *password, *str; + const char *password, *str, *error; const unsigned char *md5_password; size_t md5_size; @@ -342,7 +361,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) < 0) { + &md5_password, &md5_size, &error) < 0) { *error_r = "Not a valid MD5-CRYPT or PLAIN-MD5 password"; return -1; } else { diff -r 1fd1321e55f4 -r c9894346b1a3 src/auth/password-scheme.h --- a/src/auth/password-scheme.h Fri Sep 30 19:02:31 2011 +0300 +++ b/src/auth/password-scheme.h Sat Oct 01 16:48:17 2011 +0300 @@ -39,7 +39,8 @@ /* Decode encoded (base64/hex) password to raw form. Returns 1 if ok, 0 if scheme is unknown, -1 if password is invalid. */ int password_decode(const char *password, const char *scheme, - const unsigned char **raw_password_r, size_t *size_r); + const unsigned char **raw_password_r, size_t *size_r, + const char **error_r); /* Create password with wanted scheme out of plaintext password and username. Potential base64/hex directives are ignored in scheme. Returns FALSE if From dovecot at dovecot.org Sat Oct 1 16:41:11 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 01 Oct 2011 16:41:11 +0300 Subject: dovecot-2.0: auth: If password data isn't valid for specified sc... Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/dfb38f346e8c changeset: 12942:dfb38f346e8c user: Timo Sirainen date: Sat Oct 01 16:49:30 2011 +0300 description: auth: If password data isn't valid for specified scheme, give a better error message. diffstat: src/auth/auth-request.c | 7 ++++--- src/auth/passdb.c | 9 +++++---- src/auth/password-scheme.c | 36 ++++++++++++++++++++++++++++-------- src/auth/password-scheme.h | 3 ++- 4 files changed, 39 insertions(+), 16 deletions(-) diffs (176 lines): diff -r 9007d5de0e87 -r dfb38f346e8c src/auth/auth-request.c --- a/src/auth/auth-request.c Fri Sep 30 19:03:49 2011 +0300 +++ b/src/auth/auth-request.c Sat Oct 01 16:49:30 2011 +0300 @@ -1468,6 +1468,7 @@ { const unsigned char *raw_password; size_t raw_password_size; + const char *error; int ret; if (request->skip_password_check) { @@ -1488,12 +1489,12 @@ } ret = password_decode(crypted_password, scheme, - &raw_password, &raw_password_size); + &raw_password, &raw_password_size, &error); if (ret <= 0) { if (ret < 0) { auth_request_log_error(request, subsystem, - "Password in passdb is not in expected scheme %s", - scheme); + "Password data is not valid for scheme %s: %s", + scheme, error); } else { auth_request_log_error(request, subsystem, "Unknown scheme %s", scheme); diff -r 9007d5de0e87 -r dfb38f346e8c src/auth/passdb.c --- a/src/auth/passdb.c Fri Sep 30 19:03:49 2011 +0300 +++ b/src/auth/passdb.c Sat Oct 01 16:49:30 2011 +0300 @@ -63,7 +63,7 @@ const unsigned char **credentials_r, size_t *size_r) { const char *wanted_scheme = auth_request->credentials_scheme; - const char *plaintext, *username; + const char *plaintext, *username, *error; int ret; if (auth_request->prefer_plain_credentials && @@ -73,12 +73,13 @@ wanted_scheme = ""; } - ret = password_decode(input, input_scheme, credentials_r, size_r); + ret = password_decode(input, input_scheme, + credentials_r, size_r, &error); if (ret <= 0) { if (ret < 0) { auth_request_log_error(auth_request, "password", - "Password in passdb is not in expected scheme %s", - input_scheme); + "Password data is not valid for scheme %s: %s", + input_scheme, error); } else { auth_request_log_error(auth_request, "password", "Unknown scheme %s", input_scheme); diff -r 9007d5de0e87 -r dfb38f346e8c src/auth/password-scheme.c --- a/src/auth/password-scheme.c Fri Sep 30 19:03:49 2011 +0300 +++ b/src/auth/password-scheme.c Sat Oct 01 16:49:30 2011 +0300 @@ -127,16 +127,22 @@ } int password_decode(const char *password, const char *scheme, - const unsigned char **raw_password_r, size_t *size_r) + const unsigned char **raw_password_r, size_t *size_r, + const char **error_r) { const struct password_scheme *s; enum password_encoding encoding; buffer_t *buf; unsigned int len; + bool guessed_encoding; + + *error_r = NULL; s = password_scheme_lookup(scheme, &encoding); - if (s == NULL) + if (s == NULL) { + *error_r = "Unknown scheme"; return 0; + } len = strlen(password); if (encoding != PW_ENCODING_NONE && s->raw_password_len != 0 && @@ -145,8 +151,11 @@ base64 and hex encodings. the only problem is distinguishing 2 character strings, but there shouldn't be any that short raw_password_lens. */ - encoding = len == s->raw_password_len * 2 ? PW_ENCODING_HEX : - PW_ENCODING_BASE64; + encoding = len == s->raw_password_len * 2 ? + PW_ENCODING_HEX : PW_ENCODING_BASE64; + guessed_encoding = TRUE; + } else { + guessed_encoding = FALSE; } switch (encoding) { @@ -162,14 +171,20 @@ *size_r = buf->used; break; } + if (!guessed_encoding) { + *error_r = "Input isn't valid HEX encoded data"; + return -1; + } /* fall through, just in case it was base64-encoded after all. some input lengths produce matching hex and base64 encoded lengths. */ case PW_ENCODING_BASE64: buf = buffer_create_dynamic(pool_datastack_create(), MAX_BASE64_DECODED_SIZE(len)); - if (base64_decode(password, len, NULL, buf) < 0) + if (base64_decode(password, len, NULL, buf) < 0) { + *error_r = "Input isn't valid base64 encoded data"; return -1; + } *raw_password_r = buf->data; *size_r = buf->used; @@ -177,6 +192,9 @@ } if (s->raw_password_len != *size_r && s->raw_password_len != 0) { /* password has invalid length */ + *error_r = t_strdup_printf( + "Input length isn't valid (%u instead of %u)", + (unsigned int)*size_r, s->raw_password_len); return -1; } return 1; @@ -272,11 +290,13 @@ unsigned int i, count; const unsigned char *raw_password; size_t raw_password_size; + const char *error; schemes = array_get(&password_schemes, &count); for (i = 0; i < count; i++) { if (password_decode(crypted_password, schemes[i]->name, - &raw_password, &raw_password_size) <= 0) + &raw_password, &raw_password_size, + &error) <= 0) continue; if (password_verify(plain_password, user, schemes[i]->name, @@ -324,7 +344,7 @@ md5_verify(const char *plaintext, const char *user, const unsigned char *raw_password, size_t size) { - const char *password, *str; + const char *password, *str, *error; const unsigned char *md5_password; size_t md5_size; @@ -334,7 +354,7 @@ str = password_generate_md5_crypt(plaintext, password); return strcmp(str, password) == 0; } else if (password_decode(password, "PLAIN-MD5", - &md5_password, &md5_size) < 0) { + &md5_password, &md5_size, &error) < 0) { i_error("md5_verify(%s): Not a valid MD5-CRYPT or " "PLAIN-MD5 password", user); return FALSE; diff -r 9007d5de0e87 -r dfb38f346e8c src/auth/password-scheme.h --- a/src/auth/password-scheme.h Fri Sep 30 19:03:49 2011 +0300 +++ b/src/auth/password-scheme.h Sat Oct 01 16:49:30 2011 +0300 @@ -36,7 +36,8 @@ /* Decode encoded (base64/hex) password to raw form. Returns 1 if ok, 0 if scheme is unknown, -1 if password is invalid. */ int password_decode(const char *password, const char *scheme, - const unsigned char **raw_password_r, size_t *size_r); + const unsigned char **raw_password_r, size_t *size_r, + const char **error_r); /* Create password with wanted scheme out of plaintext password and username. Potential base64/hex directives are ignored in scheme. Returns FALSE if From dovecot at dovecot.org Sat Oct 1 16:57:36 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 01 Oct 2011 16:57:36 +0300 Subject: dovecot-2.0: doveadm: Compile fix for previous auth change. Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/e5d4f165e50c changeset: 12943:e5d4f165e50c user: Timo Sirainen date: Sat Oct 01 17:05:58 2011 +0300 description: doveadm: Compile fix for previous auth change. diffstat: src/doveadm/doveadm-pw.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (15 lines): diff -r dfb38f346e8c -r e5d4f165e50c src/doveadm/doveadm-pw.c --- a/src/doveadm/doveadm-pw.c Sat Oct 01 16:49:30 2011 +0300 +++ b/src/doveadm/doveadm-pw.c Sat Oct 01 17:05:58 2011 +0300 @@ -93,8 +93,10 @@ if (Vflag == 1) { const unsigned char *raw_password; size_t size; + const char *error; - if (password_decode(hash, scheme, &raw_password, &size) <= 0) { + if (password_decode(hash, scheme, &raw_password, &size, + &error) <= 0) { fprintf(stderr, "reverse decode check failed\n"); exit(2); } From dovecot at dovecot.org Sat Oct 1 16:57:45 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 01 Oct 2011 16:57:45 +0300 Subject: dovecot-2.1: doveadm: Compile fix for previous auth change. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/c126a88546f8 changeset: 13567:c126a88546f8 user: Timo Sirainen date: Sat Oct 01 17:06:04 2011 +0300 description: doveadm: Compile fix for previous auth change. diffstat: src/doveadm/doveadm-pw.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r c9894346b1a3 -r c126a88546f8 src/doveadm/doveadm-pw.c --- a/src/doveadm/doveadm-pw.c Sat Oct 01 16:48:17 2011 +0300 +++ b/src/doveadm/doveadm-pw.c Sat Oct 01 17:06:04 2011 +0300 @@ -95,7 +95,8 @@ size_t size; const char *error; - if (password_decode(hash, scheme, &raw_password, &size) <= 0) { + if (password_decode(hash, scheme, &raw_password, &size, + &error) <= 0) { fprintf(stderr, "reverse decode check failed\n"); exit(2); } From dovecot at dovecot.org Sat Oct 1 17:00:55 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 01 Oct 2011 17:00:55 +0300 Subject: dovecot-2.1: Added ssl_protocols setting. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/406a1d52390b changeset: 13568:406a1d52390b user: Timo Sirainen date: Sat Oct 01 17:09:00 2011 +0300 description: Added ssl_protocols setting. diffstat: doc/example-config/conf.d/10-ssl.conf | 3 + src/login-common/login-settings.c | 2 + src/login-common/login-settings.h | 1 + src/login-common/ssl-proxy-openssl.c | 61 ++++++++++++++++++++++++++++++++++- 4 files changed, 66 insertions(+), 1 deletions(-) diffs (155 lines): diff -r c126a88546f8 -r 406a1d52390b doc/example-config/conf.d/10-ssl.conf --- a/doc/example-config/conf.d/10-ssl.conf Sat Oct 01 17:06:04 2011 +0300 +++ b/doc/example-config/conf.d/10-ssl.conf Sat Oct 01 17:09:00 2011 +0300 @@ -37,5 +37,8 @@ # entirely. #ssl_parameters_regenerate = 168 +# SSL protocols to use +#ssl_protocols = !SSLv2 + # SSL ciphers to use #ssl_cipher_list = ALL:!LOW:!SSLv2:!EXP:!aNULL diff -r c126a88546f8 -r 406a1d52390b src/login-common/login-settings.c --- a/src/login-common/login-settings.c Sat Oct 01 17:06:04 2011 +0300 +++ b/src/login-common/login-settings.c Sat Oct 01 17:09:00 2011 +0300 @@ -31,6 +31,7 @@ DEF(SET_STR, ssl_key), DEF(SET_STR, ssl_key_password), DEF(SET_STR, ssl_cipher_list), + DEF(SET_STR, ssl_protocols), DEF(SET_STR, ssl_cert_username_field), DEF(SET_BOOL, ssl_verify_client_cert), DEF(SET_BOOL, auth_ssl_require_client_cert), @@ -60,6 +61,7 @@ .ssl_key = "", .ssl_key_password = "", .ssl_cipher_list = "ALL:!LOW:!SSLv2:!EXP:!aNULL", + .ssl_protocols = "!SSLv2", .ssl_cert_username_field = "commonName", .ssl_verify_client_cert = FALSE, .auth_ssl_require_client_cert = FALSE, diff -r c126a88546f8 -r 406a1d52390b src/login-common/login-settings.h --- a/src/login-common/login-settings.h Sat Oct 01 17:06:04 2011 +0300 +++ b/src/login-common/login-settings.h Sat Oct 01 17:09:00 2011 +0300 @@ -13,6 +13,7 @@ const char *ssl_key; const char *ssl_key_password; const char *ssl_cipher_list; + const char *ssl_protocols; const char *ssl_cert_username_field; bool ssl_verify_client_cert; bool auth_ssl_require_client_cert; diff -r c126a88546f8 -r 406a1d52390b src/login-common/ssl-proxy-openssl.c --- a/src/login-common/ssl-proxy-openssl.c Sat Oct 01 17:06:04 2011 +0300 +++ b/src/login-common/ssl-proxy-openssl.c Sat Oct 01 17:09:00 2011 +0300 @@ -87,6 +87,7 @@ const char *key; const char *ca; const char *cipher_list; + const char *protocols; bool verify_client_cert; }; @@ -136,6 +137,8 @@ return 1; if (null_strcmp(ctx1->cipher_list, ctx2->cipher_list) != 0) return 1; + if (null_strcmp(ctx1->protocols, ctx2->protocols) != 0) + return 1; return ctx1->verify_client_cert == ctx2->verify_client_cert ? 0 : 1; } @@ -603,6 +606,7 @@ lookup_ctx.key = set->ssl_key; lookup_ctx.ca = set->ssl_ca; lookup_ctx.cipher_list = set->ssl_cipher_list; + lookup_ctx.protocols = set->ssl_protocols; lookup_ctx.verify_client_cert = set->ssl_verify_client_cert; ctx = hash_table_lookup(ssl_servers, &lookup_ctx); @@ -924,7 +928,9 @@ X509_STORE *store; STACK_OF(X509_NAME) *xnames = NULL; - SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2); + /* enable all SSL workarounds */ + SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL); + if (*set->ssl_ca != '\0') { /* set trusted CA certs */ store = SSL_CTX_get_cert_store(ssl_ctx); @@ -1091,6 +1097,57 @@ } #endif +enum { + DOVECOT_SSL_PROTO_SSLv2 = 0x01, + DOVECOT_SSL_PROTO_SSLv3 = 0x02, + DOVECOT_SSL_PROTO_TLSv1 = 0x04, + DOVECOT_SSL_PROTO_ALL = 0x07 +}; + +static void +ssl_proxy_ctx_set_protocols(struct ssl_server_context *ssl_ctx, + const char *protocols) +{ + const char *const *tmp; + int proto, op = 0, include = 0, exclude = 0; + bool neg; + + tmp = t_strsplit_spaces(protocols, " "); + for (; *tmp != NULL; tmp++) { + const char *name = *tmp; + + if (*name != '!') + neg = FALSE; + else { + name++; + neg = TRUE; + } + if (strcasecmp(name, SSL_TXT_SSLV2) == 0) + proto = DOVECOT_SSL_PROTO_SSLv2; + else if (strcasecmp(name, SSL_TXT_SSLV3) == 0) + proto = DOVECOT_SSL_PROTO_SSLv3; + else if (strcasecmp(name, SSL_TXT_TLSV1) == 0) + proto = DOVECOT_SSL_PROTO_TLSv1; + else { + i_fatal("Invalid ssl_protocols setting: " + "Unknown protocol '%s'", name); + } + if (neg) + exclude |= proto; + else + include |= proto; + } + if (include != 0) { + /* exclude everything, except those that are included + (and let excludes still override those) */ + exclude |= DOVECOT_SSL_PROTO_ALL & ~include; + } + if ((exclude & DOVECOT_SSL_PROTO_SSLv2) != 0) op |= SSL_OP_NO_SSLv2; + if ((exclude & DOVECOT_SSL_PROTO_SSLv3) != 0) op |= SSL_OP_NO_SSLv3; + if ((exclude & DOVECOT_SSL_PROTO_TLSv1) != 0) op |= SSL_OP_NO_TLSv1; + SSL_CTX_set_options(ssl_ctx->ctx, op); +} + static struct ssl_server_context * ssl_server_context_init(const struct login_settings *set) { @@ -1106,6 +1163,7 @@ ctx->key = p_strdup(pool, set->ssl_key); ctx->ca = p_strdup(pool, set->ssl_ca); ctx->cipher_list = p_strdup(pool, set->ssl_cipher_list); + ctx->protocols = p_strdup(pool, set->ssl_protocols); ctx->verify_client_cert = set->ssl_verify_client_cert; ctx->ctx = ssl_ctx = SSL_CTX_new(SSLv23_server_method()); @@ -1117,6 +1175,7 @@ i_fatal("Can't set cipher list to '%s': %s", ctx->cipher_list, ssl_last_error()); } + ssl_proxy_ctx_set_protocols(ctx, ctx->protocols); if (ssl_proxy_ctx_use_certificate_chain(ctx->ctx, ctx->cert) != 1) { i_fatal("Can't load ssl_cert: %s", From dovecot at dovecot.org Sat Oct 1 17:26:18 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 01 Oct 2011 17:26:18 +0300 Subject: dovecot-2.1: module_dir_load*(): Support filtering and ignoring ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/976e414d5bf4 changeset: 13569:976e414d5bf4 user: Timo Sirainen date: Sat Oct 01 17:22:44 2011 +0300 description: module_dir_load*(): Support filtering and ignoring missing modules. diffstat: src/lib/module-dir.c | 11 ++++++++--- src/lib/module-dir.h | 6 ++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diffs (58 lines): diff -r 406a1d52390b -r 976e414d5bf4 src/lib/module-dir.c --- a/src/lib/module-dir.c Sat Oct 01 17:09:00 2011 +0300 +++ b/src/lib/module-dir.c Sat Oct 01 17:22:44 2011 +0300 @@ -263,8 +263,13 @@ return strcmp(s1, s2); } -static bool module_want_load(const char **names, const char *name) +static bool module_want_load(const struct module_dir_load_settings *set, + const char **names, const char *name) { + if (set->filter_callback != NULL) { + if (!set->filter_callback(name, set->filter_context)) + return FALSE; + } if (names == NULL) return TRUE; @@ -412,7 +417,7 @@ name = names_p[i]; stripped_name = module_file_get_name(name); suffixless_name = module_name_drop_suffix(stripped_name); - if (!module_want_load(module_names, suffixless_name) || + if (!module_want_load(set, module_names, suffixless_name) || module_is_loaded(old_modules, suffixless_name)) module = NULL; else { @@ -428,7 +433,7 @@ } } T_END; - if (module_names != NULL) { + if (module_names != NULL && !set->ignore_missing) { /* make sure all modules were found */ for (; *module_names != NULL; module_names++) { if (**module_names != '\0') { diff -r 406a1d52390b -r 976e414d5bf4 src/lib/module-dir.h --- a/src/lib/module-dir.h Sat Oct 01 17:09:00 2011 +0300 +++ b/src/lib/module-dir.h Sat Oct 01 17:22:44 2011 +0300 @@ -11,12 +11,18 @@ /* Setting name used in plugin dependency error message */ const char *setting_name; + /* If non-NULL, load only modules where filter_callback returns TRUE */ + bool (*filter_callback)(const char *name, void *context); + void *filter_context; + /* Require all plugins to have _init() function */ unsigned int require_init_funcs:1; /* Enable debug logging */ unsigned int debug:1; /* If dlopen() fails for some modules, silently skip it. */ unsigned int ignore_dlopen_errors:1; + /* Don't fail if some specified modules weren't found */ + unsigned int ignore_missing:1; }; struct module { From dovecot at dovecot.org Sat Oct 1 17:26:18 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 01 Oct 2011 17:26:18 +0300 Subject: dovecot-2.1: auth: Renamed passdb_imap plugin to authdb_imap. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/f53cf5670adf changeset: 13570:f53cf5670adf user: Timo Sirainen date: Sat Oct 01 17:24:09 2011 +0300 description: auth: Renamed passdb_imap plugin to authdb_imap. diffstat: src/auth/Makefile.am | 10 +++++----- src/auth/passdb-imap.c | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diffs (55 lines): diff -r 976e414d5bf4 -r f53cf5670adf src/auth/Makefile.am --- a/src/auth/Makefile.am Sat Oct 01 17:22:44 2011 +0300 +++ b/src/auth/Makefile.am Sat Oct 01 17:24:09 2011 +0300 @@ -15,7 +15,7 @@ auth_module_LTLIBRARIES = \ $(GSSAPI_LIB) \ $(LDAP_LIB) \ - libpassdb_imap.la + libauthdb_imap.la pkglibexecdir = $(libexecdir)/dovecot @@ -159,15 +159,15 @@ libauthdb_ldap_la_SOURCES = $(ldap_sources) endif -libpassdb_imap_la_LDFLAGS = -module -avoid-version -libpassdb_imap_la_LIBADD = \ +libauthdb_imap_la_LDFLAGS = -module -avoid-version +libauthdb_imap_la_LIBADD = \ ../lib-imap-client/libimap_client.la \ ../lib-ssl-iostream/libssl_iostream.la -libpassdb_imap_la_CPPFLAGS = \ +libauthdb_imap_la_CPPFLAGS = \ $(AM_CPPFLAGS) \ -I$(top_srcdir)/src/lib-imap \ -I$(top_srcdir)/src/lib-imap-client -libpassdb_imap_la_SOURCES = passdb-imap.c +libauthdb_imap_la_SOURCES = passdb-imap.c pkginc_libdir=$(pkgincludedir) pkginc_lib_HEADERS = $(headers) diff -r 976e414d5bf4 -r f53cf5670adf src/auth/passdb-imap.c --- a/src/auth/passdb-imap.c Sat Oct 01 17:22:44 2011 +0300 +++ b/src/auth/passdb-imap.c Sat Oct 01 17:24:09 2011 +0300 @@ -177,15 +177,15 @@ NULL }; -void passdb_imap_init(void); -void passdb_imap_deinit(void); +void authdb_imap_init(void); +void authdb_imap_deinit(void); -void passdb_imap_init(void) +void authdb_imap_init(void) { passdb_register_module(&passdb_imap_plugin); } -void passdb_imap_deinit(void) +void authdb_imap_deinit(void) { passdb_unregister_module(&passdb_imap_plugin); } From dovecot at dovecot.org Sat Oct 1 17:26:18 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 01 Oct 2011 17:26:18 +0300 Subject: dovecot-2.1: auth: Lazily load authdb_* and mech_* plugins only ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/695e9d58ed17 changeset: 13571:695e9d58ed17 user: Timo Sirainen date: Sat Oct 01 17:34:39 2011 +0300 description: auth: Lazily load authdb_* and mech_* plugins only when they're needed. diffstat: src/auth/auth-common.h | 1 + src/auth/main.c | 26 ++++++++++++++++++++++++++ src/auth/mech.c | 13 +++++++++---- src/auth/passdb.c | 5 +++++ src/auth/userdb.c | 5 +++++ 5 files changed, 46 insertions(+), 4 deletions(-) diffs (120 lines): diff -r f53cf5670adf -r 695e9d58ed17 src/auth/auth-common.h --- a/src/auth/auth-common.h Sat Oct 01 17:24:09 2011 +0300 +++ b/src/auth/auth-common.h Sat Oct 01 17:34:39 2011 +0300 @@ -9,5 +9,6 @@ extern struct auth_penalty *auth_penalty; void auth_refresh_proctitle(void); +void auth_module_load(const char *names); #endif diff -r f53cf5670adf -r 695e9d58ed17 src/auth/main.c --- a/src/auth/main.c Sat Oct 01 17:24:09 2011 +0300 +++ b/src/auth/main.c Sat Oct 01 17:34:39 2011 +0300 @@ -148,6 +148,16 @@ } } +static bool auth_module_filter(const char *name, void *context ATTR_UNUSED) +{ + if (strncmp(name, "authdb_", 7) == 0 || + strncmp(name, "mech_", 5) == 0) { + /* this is lazily loaded */ + return FALSE; + } + return TRUE; +} + static void main_preinit(void) { struct module_dir_load_settings mod_set; @@ -173,6 +183,7 @@ mod_set.version = master_service_get_version_string(master_service); mod_set.require_init_funcs = TRUE; mod_set.debug = global_auth_settings->debug; + mod_set.filter_callback = auth_module_filter; modules = module_dir_load(AUTH_MODULE_DIR, NULL, &mod_set); module_dir_init(modules); @@ -191,6 +202,21 @@ restrict_access_allow_coredumps(TRUE); } +void auth_module_load(const char *names) +{ + struct module_dir_load_settings mod_set; + + memset(&mod_set, 0, sizeof(mod_set)); + mod_set.version = master_service_get_version_string(master_service); + mod_set.require_init_funcs = TRUE; + mod_set.debug = global_auth_settings->debug; + mod_set.ignore_missing = TRUE; + + modules = module_dir_load_missing(modules, AUTH_MODULE_DIR, names, + &mod_set); + module_dir_init(modules); +} + static void main_init(void) { process_start_time = ioloop_time; diff -r f53cf5670adf -r 695e9d58ed17 src/auth/mech.c --- a/src/auth/mech.c Sat Oct 01 17:24:09 2011 +0300 +++ b/src/auth/mech.c Sat Oct 01 17:34:39 2011 +0300 @@ -127,17 +127,22 @@ mechanisms = t_strsplit_spaces(set->mechanisms, " "); for (; *mechanisms != NULL; mechanisms++) { - if (strcasecmp(*mechanisms, "ANONYMOUS") == 0) { + const char *name = *mechanisms; + + if (strcasecmp(name, "ANONYMOUS") == 0) { if (*set->anonymous_username == '\0') { i_fatal("ANONYMOUS listed in mechanisms, " "but anonymous_username not set"); } } - mech = mech_module_find(*mechanisms); + mech = mech_module_find(name); if (mech == NULL) { - i_fatal("Unknown authentication mechanism '%s'", - *mechanisms); + /* maybe it's a plugin. try to load it. */ + auth_module_load(t_strconcat("mech_", name, NULL)); + mech = mech_module_find(name); } + if (mech == NULL) + i_fatal("Unknown authentication mechanism '%s'", name); mech_register_add(reg, mech); } diff -r f53cf5670adf -r 695e9d58ed17 src/auth/passdb.c --- a/src/auth/passdb.c Sat Oct 01 17:24:09 2011 +0300 +++ b/src/auth/passdb.c Sat Oct 01 17:34:39 2011 +0300 @@ -191,6 +191,11 @@ unsigned int idx; iface = passdb_interface_find(set->driver); + if (iface == NULL) { + /* maybe it's a plugin. try to load it. */ + auth_module_load(t_strconcat("authdb_", set->driver, NULL)); + iface = passdb_interface_find(set->driver); + } if (iface == NULL) i_fatal("Unknown passdb driver '%s'", set->driver); if (iface->verify_plain == NULL) { diff -r f53cf5670adf -r 695e9d58ed17 src/auth/userdb.c --- a/src/auth/userdb.c Sat Oct 01 17:24:09 2011 +0300 +++ b/src/auth/userdb.c Sat Oct 01 17:34:39 2011 +0300 @@ -137,6 +137,11 @@ unsigned int idx; iface = userdb_interface_find(set->driver); + if (iface == NULL) { + /* maybe it's a plugin. try to load it. */ + auth_module_load(t_strconcat("authdb_", set->driver, NULL)); + iface = userdb_interface_find(set->driver); + } if (iface == NULL) i_fatal("Unknown userdb driver '%s'", set->driver); if (iface->lookup == NULL) { From dovecot at dovecot.org Sat Oct 1 17:32:51 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 01 Oct 2011 17:32:51 +0300 Subject: dovecot-2.1: imapc: Make sure mail cache is freed when mailbox i... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/967a53c3ef5e changeset: 13572:967a53c3ef5e user: Timo Sirainen date: Sat Oct 01 17:41:12 2011 +0300 description: imapc: Make sure mail cache is freed when mailbox is closed. diffstat: src/lib-storage/index/imapc/imapc-storage.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 695e9d58ed17 -r 967a53c3ef5e src/lib-storage/index/imapc/imapc-storage.c --- a/src/lib-storage/index/imapc/imapc-storage.c Sat Oct 01 17:34:39 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-storage.c Sat Oct 01 17:41:12 2011 +0300 @@ -463,6 +463,7 @@ timeout_remove(&mbox->to_idle_delay); if (mbox->to_idle_check != NULL) timeout_remove(&mbox->to_idle_check); + imapc_mail_cache_free(&mbox->prev_mail_cache); return index_storage_mailbox_close(box); } From dovecot at dovecot.org Sat Oct 1 17:39:15 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 01 Oct 2011 17:39:15 +0300 Subject: dovecot-2.1: imapc: Make sure "is mail expunged?" NOOP is sent t... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/4cfe3f14bb46 changeset: 13573:4cfe3f14bb46 user: Timo Sirainen date: Sat Oct 01 17:47:35 2011 +0300 description: imapc: Make sure "is mail expunged?" NOOP is sent to correct connection. (Although currently there are never more than a single connection.) diffstat: src/lib-storage/index/imapc/imapc-mail.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r 967a53c3ef5e -r 4cfe3f14bb46 src/lib-storage/index/imapc/imapc-mail.c --- a/src/lib-storage/index/imapc/imapc-mail.c Sat Oct 01 17:41:12 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mail.c Sat Oct 01 17:47:35 2011 +0300 @@ -74,8 +74,8 @@ /* we may be running against a server that hasn't bothered sending us an EXPUNGE. see if NOOP sends it. */ imapc_simple_context_init(&sctx, mbox->storage); - imapc_client_cmdf(mbox->storage->client, imapc_simple_callback, - &sctx, "NOOP"); + imapc_client_mailbox_cmdf(mbox->client_box, + imapc_simple_callback, &sctx, "NOOP"); imapc_simple_run(&sctx); return !imapc_msgmap_uid_to_rseq(msgmap, _mail->uid, &rseq); From dovecot at dovecot.org Sat Oct 1 17:47:11 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 01 Oct 2011 17:47:11 +0300 Subject: dovecot-2.1: imapc: Don't assert-crash when receiving 0 size lit... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/037e963c9a34 changeset: 13574:037e963c9a34 user: Timo Sirainen date: Sat Oct 01 17:54:57 2011 +0300 description: imapc: Don't assert-crash when receiving 0 size literal. diffstat: src/lib-imap-client/imapc-connection.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diffs (11 lines): diff -r 4cfe3f14bb46 -r 037e963c9a34 src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Sat Oct 01 17:47:35 2011 +0300 +++ b/src/lib-imap-client/imapc-connection.c Sat Oct 01 17:54:57 2011 +0300 @@ -366,7 +366,6 @@ const struct imap_arg *parent_arg; unsigned int idx; - i_assert(size > 0); i_assert(conn->literal.fd == -1); if (size <= IMAPC_MAX_INLINE_LITERAL_SIZE || From dovecot at dovecot.org Sat Oct 1 17:47:11 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 01 Oct 2011 17:47:11 +0300 Subject: dovecot-2.1: imapc: Changed imapc_client_mailbox_cmd() parameter... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/a418589173c8 changeset: 13575:a418589173c8 user: Timo Sirainen date: Sat Oct 01 17:55:18 2011 +0300 description: imapc: Changed imapc_client_mailbox_cmd() parameter order to be same as in _cmdf(). diffstat: src/lib-imap-client/imapc-client.c | 3 +-- src/lib-imap-client/imapc-client.h | 3 +-- src/lib-storage/index/imapc/imapc-mail-fetch.c | 6 +++--- src/lib-storage/index/imapc/imapc-mail.c | 4 ++-- src/lib-storage/index/imapc/imapc-storage.c | 9 +++++---- src/lib-storage/index/imapc/imapc-sync.c | 10 +++++----- 6 files changed, 17 insertions(+), 18 deletions(-) diffs (111 lines): diff -r 037e963c9a34 -r a418589173c8 src/lib-imap-client/imapc-client.c --- a/src/lib-imap-client/imapc-client.c Sat Oct 01 17:54:57 2011 +0300 +++ b/src/lib-imap-client/imapc-client.c Sat Oct 01 17:55:18 2011 +0300 @@ -345,9 +345,8 @@ } void imapc_client_mailbox_cmd(struct imapc_client_mailbox *box, - const char *cmd, imapc_command_callback_t *callback, - void *context) + void *context, const char *cmd) { struct imapc_client_command_context *ctx; struct imapc_command_reply reply; diff -r 037e963c9a34 -r a418589173c8 src/lib-imap-client/imapc-client.h --- a/src/lib-imap-client/imapc-client.h Sat Oct 01 17:54:57 2011 +0300 +++ b/src/lib-imap-client/imapc-client.h Sat Oct 01 17:55:18 2011 +0300 @@ -133,9 +133,8 @@ void imapc_client_mailbox_close(struct imapc_client_mailbox **box); void imapc_client_mailbox_disconnect(struct imapc_client_mailbox *box); void imapc_client_mailbox_cmd(struct imapc_client_mailbox *box, - const char *cmd, imapc_command_callback_t *callback, - void *context); + void *context, const char *cmd); void imapc_client_mailbox_cmdf(struct imapc_client_mailbox *box, imapc_command_callback_t *callback, void *context, const char *cmd_fmt, ...) diff -r 037e963c9a34 -r a418589173c8 src/lib-storage/index/imapc/imapc-mail-fetch.c --- a/src/lib-storage/index/imapc/imapc-mail-fetch.c Sat Oct 01 17:54:57 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mail-fetch.c Sat Oct 01 17:55:18 2011 +0300 @@ -102,9 +102,9 @@ if (mail->fetch_count++ == 0) array_append(&mbox->fetch_mails, &mail, 1); - imapc_client_mailbox_cmdf(mbox->client_box, - imapc_mail_prefetch_callback, - mail, "%1s", str_c(str)); + imapc_client_mailbox_cmd(mbox->client_box, + imapc_mail_prefetch_callback, + mail, str_c(str)); mail->imail.data.prefetch_sent = TRUE; return 0; } diff -r 037e963c9a34 -r a418589173c8 src/lib-storage/index/imapc/imapc-mail.c --- a/src/lib-storage/index/imapc/imapc-mail.c Sat Oct 01 17:54:57 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mail.c Sat Oct 01 17:55:18 2011 +0300 @@ -74,8 +74,8 @@ /* we may be running against a server that hasn't bothered sending us an EXPUNGE. see if NOOP sends it. */ imapc_simple_context_init(&sctx, mbox->storage); - imapc_client_mailbox_cmdf(mbox->client_box, - imapc_simple_callback, &sctx, "NOOP"); + imapc_client_mailbox_cmd(mbox->client_box, + imapc_simple_callback, &sctx, "NOOP"); imapc_simple_run(&sctx); return !imapc_msgmap_uid_to_rseq(msgmap, _mail->uid, &rseq); diff -r 037e963c9a34 -r a418589173c8 src/lib-storage/index/imapc/imapc-storage.c --- a/src/lib-storage/index/imapc/imapc-storage.c Sat Oct 01 17:54:57 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-storage.c Sat Oct 01 17:55:18 2011 +0300 @@ -614,8 +614,8 @@ static void imapc_idle_timeout(struct imapc_mailbox *mbox) { - imapc_client_mailbox_cmd(mbox->client_box, "NOOP", - imapc_noop_callback, mbox->storage); + imapc_client_mailbox_cmd(mbox->client_box, + imapc_noop_callback, mbox->storage, "NOOP"); } static void imapc_idle_noop_callback(const struct imapc_command_reply *reply, @@ -645,8 +645,9 @@ don't notice changes immediately, we'll force them to check here by sending a NOOP. this helps with clients that break IDLE when clicking "get mail". */ - imapc_client_mailbox_cmd(mbox->client_box, "NOOP", - imapc_idle_noop_callback, mbox); + imapc_client_mailbox_cmd(mbox->client_box, + imapc_idle_noop_callback, mbox, + "NOOP"); } else { /* remote server doesn't support IDLE. check for changes with NOOP every once in a while. */ diff -r 037e963c9a34 -r a418589173c8 src/lib-storage/index/imapc/imapc-sync.c --- a/src/lib-storage/index/imapc/imapc-sync.c Sat Oct 01 17:54:57 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-sync.c Sat Oct 01 17:55:18 2011 +0300 @@ -39,8 +39,8 @@ static void imapc_sync_cmd(struct imapc_sync_context *ctx, const char *cmd) { ctx->sync_command_count++; - imapc_client_mailbox_cmd(ctx->mbox->client_box, cmd, - imapc_sync_callback, ctx); + imapc_client_mailbox_cmd(ctx->mbox->client_box, + imapc_sync_callback, ctx, cmd); } static void @@ -400,9 +400,9 @@ if ((capabilities & IMAPC_CAPABILITY_IDLE) == 0) { /* IDLE not supported. do NOOP to get latest changes before starting sync. */ - imapc_client_mailbox_cmdf(mbox->client_box, - imapc_noop_stop_callback, - mbox->storage, "NOOP"); + imapc_client_mailbox_cmd(mbox->client_box, + imapc_noop_stop_callback, + mbox->storage, "NOOP"); imapc_storage_run(mbox->storage); } From dovecot at dovecot.org Sun Oct 2 15:55:02 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 15:55:02 +0300 Subject: dovecot-2.1: mailbox list index: Minor code cleanup. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/967ad9ad37ff changeset: 13576:967ad9ad37ff user: Timo Sirainen date: Sun Oct 02 15:39:45 2011 +0300 description: mailbox list index: Minor code cleanup. diffstat: src/lib-storage/list/index-mailbox-list-status.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r a418589173c8 -r 967ad9ad37ff src/lib-storage/list/index-mailbox-list-status.c --- a/src/lib-storage/list/index-mailbox-list-status.c Sat Oct 01 17:55:18 2011 +0300 +++ b/src/lib-storage/list/index-mailbox-list-status.c Sun Oct 02 15:39:45 2011 +0300 @@ -130,7 +130,8 @@ if (ret <= 0) return ret; - ret = index_list_get_view_status(box, view, seq, items, status_r, NULL); + ret = index_list_get_view_status(box, view, seq, items, + status_r, NULL) ? 1 : 0; mail_index_view_close(&view); return ret; } From dovecot at dovecot.org Sun Oct 2 15:55:02 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 15:55:02 +0300 Subject: dovecot-2.1: lda/lmtp: Moved raw user creation code to common ra... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/5bd6c0fbfef1 changeset: 13577:5bd6c0fbfef1 user: Timo Sirainen date: Sun Oct 02 16:03:10 2011 +0300 description: lda/lmtp: Moved raw user creation code to common raw_storage_create_from_set() diffstat: src/lda/main.c | 18 +++--------------- src/lib-storage/index/raw/raw-storage.c | 27 +++++++++++++++++++++++++++ src/lib-storage/index/raw/raw-storage.h | 4 ++++ src/lmtp/client.c | 24 +++--------------------- 4 files changed, 37 insertions(+), 36 deletions(-) diffs (129 lines): diff -r 967ad9ad37ff -r 5bd6c0fbfef1 src/lda/main.c --- a/src/lda/main.c Sun Oct 02 15:39:45 2011 +0300 +++ b/src/lda/main.c Sun Oct 02 16:03:10 2011 +0300 @@ -213,7 +213,6 @@ struct mail_storage_service_input service_input; struct mail_user *raw_mail_user; struct mail_namespace *raw_ns; - struct mail_namespace_settings raw_ns_set; struct mail_storage *storage; struct mailbox *box; struct raw_mailbox *raw_box; @@ -371,21 +370,10 @@ /* create a separate mail user for the internal namespace */ sets = master_service_settings_get_others(master_service); - raw_mail_user = mail_user_alloc(user, ctx.dest_user->set_info, sets[0]); - raw_mail_user->autocreated = TRUE; - mail_user_set_home(raw_mail_user, "/"); - if (mail_user_init(raw_mail_user, &errstr) < 0) - i_fatal("Raw user initialization failed: %s", errstr); + raw_mail_user = + raw_storage_create_from_set(ctx.dest_user->set_info, sets[0]); + raw_ns = raw_mail_user->namespaces; - memset(&raw_ns_set, 0, sizeof(raw_ns_set)); - raw_ns_set.location = ":LAYOUT=none"; - raw_ns_set.separator = "/"; - - raw_ns = mail_namespaces_init_empty(raw_mail_user); - raw_ns->flags |= NAMESPACE_FLAG_NOQUOTA | NAMESPACE_FLAG_NOACL; - raw_ns->set = &raw_ns_set; - if (mail_storage_create(raw_ns, "raw", 0, &errstr) < 0) - i_fatal("Couldn't create internal raw storage: %s", errstr); if (path == NULL) { input = create_raw_stream(&ctx, 0, &mtime); i_stream_set_name(input, "stdin"); diff -r 967ad9ad37ff -r 5bd6c0fbfef1 src/lib-storage/index/raw/raw-storage.c --- a/src/lib-storage/index/raw/raw-storage.c Sun Oct 02 15:39:45 2011 +0300 +++ b/src/lib-storage/index/raw/raw-storage.c Sun Oct 02 16:03:10 2011 +0300 @@ -12,6 +12,33 @@ extern struct mail_storage raw_storage; extern struct mailbox raw_mailbox; +struct mail_user * +raw_storage_create_from_set(const struct setting_parser_info *set_info, + const struct mail_user_settings *set) +{ + struct mail_user *user; + struct mail_namespace *ns; + struct mail_namespace_settings *ns_set; + const char *error; + + user = mail_user_alloc("raw mail user", set_info, set); + user->autocreated = TRUE; + mail_user_set_home(user, "/"); + if (mail_user_init(user, &error) < 0) + i_fatal("Raw user initialization failed: %s", error); + + ns_set = p_new(user->pool, struct mail_namespace_settings, 1); + ns_set->location = ":LAYOUT=none"; + ns_set->separator = "/"; + + ns = mail_namespaces_init_empty(user); + ns->flags |= NAMESPACE_FLAG_NOQUOTA | NAMESPACE_FLAG_NOACL; + ns->set = ns_set; + if (mail_storage_create(ns, "raw", 0, &error) < 0) + i_fatal("Couldn't create internal raw storage: %s", error); + return user; +} + static struct mail_storage *raw_storage_alloc(void) { struct raw_storage *storage; diff -r 967ad9ad37ff -r 5bd6c0fbfef1 src/lib-storage/index/raw/raw-storage.h --- a/src/lib-storage/index/raw/raw-storage.h Sun Oct 02 15:39:45 2011 +0300 +++ b/src/lib-storage/index/raw/raw-storage.h Sun Oct 02 16:03:10 2011 +0300 @@ -24,4 +24,8 @@ extern struct mail_vfuncs raw_mail_vfuncs; +struct mail_user * +raw_storage_create_from_set(const struct setting_parser_info *set_info, + const struct mail_user_settings *set); + #endif diff -r 967ad9ad37ff -r 5bd6c0fbfef1 src/lmtp/client.c --- a/src/lmtp/client.c Sun Oct 02 15:39:45 2011 +0300 +++ b/src/lmtp/client.c Sun Oct 02 16:03:10 2011 +0300 @@ -13,6 +13,7 @@ #include "mail-namespace.h" #include "mail-storage.h" #include "mail-storage-service.h" +#include "raw-storage.h" #include "main.h" #include "lda-settings.h" #include "lmtp-settings.h" @@ -123,30 +124,11 @@ static void client_raw_user_create(struct client *client) { - struct mail_namespace *raw_ns; - struct mail_namespace_settings *raw_ns_set; - const char *error; void **sets; sets = master_service_settings_get_others(master_service); - - client->raw_mail_user = mail_user_alloc("raw user", - client->user_set_info, sets[0]); - client->raw_mail_user->autocreated = TRUE; - mail_user_set_home(client->raw_mail_user, "/"); - if (mail_user_init(client->raw_mail_user, &error) < 0) - i_fatal("Raw user initialization failed: %s", error); - - raw_ns_set = p_new(client->raw_mail_user->pool, - struct mail_namespace_settings, 1); - raw_ns_set->location = ":LAYOUT=none"; - raw_ns_set->separator = "/"; - - raw_ns = mail_namespaces_init_empty(client->raw_mail_user); - raw_ns->flags |= NAMESPACE_FLAG_NOQUOTA | NAMESPACE_FLAG_NOACL; - raw_ns->set = raw_ns_set; - if (mail_storage_create(raw_ns, "raw", 0, &error) < 0) - i_fatal("Couldn't create internal raw storage: %s", error); + client->raw_mail_user = + raw_storage_create_from_set(client->user_set_info, sets[0]); } static void client_read_settings(struct client *client) From dovecot at dovecot.org Sun Oct 2 16:25:00 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 16:25:00 +0300 Subject: dovecot-2.0: istream-seekable: Memory leak fix. Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/dd6460d046e7 changeset: 12944:dd6460d046e7 user: Timo Sirainen date: Sun Oct 02 16:32:59 2011 +0300 description: istream-seekable: Memory leak fix. diffstat: src/lib/istream-seekable.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r e5d4f165e50c -r dd6460d046e7 src/lib/istream-seekable.c --- a/src/lib/istream-seekable.c Sat Oct 01 17:05:58 2011 +0300 +++ b/src/lib/istream-seekable.c Sun Oct 02 16:32:59 2011 +0300 @@ -54,6 +54,7 @@ i_stream_unref(&sstream->input[i]); i_free(sstream->temp_path); + i_free(sstream->input); } static void From dovecot at dovecot.org Sun Oct 2 16:28:02 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 16:28:02 +0300 Subject: dovecot-2.1: ioloop: Memory leak fix on ioloop destroy. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/f41a3dd03be2 changeset: 13579:f41a3dd03be2 user: Timo Sirainen date: Sun Oct 02 16:33:51 2011 +0300 description: ioloop: Memory leak fix on ioloop destroy. diffstat: src/lib/ioloop.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r 7f7724f28d78 -r f41a3dd03be2 src/lib/ioloop.c --- a/src/lib/ioloop.c Sun Oct 02 16:32:59 2011 +0300 +++ b/src/lib/ioloop.c Sun Oct 02 16:33:51 2011 +0300 @@ -474,6 +474,9 @@ if (ioloop->handler_context != NULL) io_loop_handler_deinit(ioloop); + if (ioloop->cur_ctx != NULL) + io_loop_context_deactivate(ioloop->cur_ctx); + /* ->prev won't work unless loops are destroyed in create order */ i_assert(ioloop == current_ioloop); current_ioloop = current_ioloop->prev; From dovecot at dovecot.org Sun Oct 2 16:28:02 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 16:28:02 +0300 Subject: dovecot-2.1: istream-seekable: Memory leak fix. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/7f7724f28d78 changeset: 13578:7f7724f28d78 user: Timo Sirainen date: Sun Oct 02 16:32:59 2011 +0300 description: istream-seekable: Memory leak fix. diffstat: src/lib/istream-seekable.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 5bd6c0fbfef1 -r 7f7724f28d78 src/lib/istream-seekable.c --- a/src/lib/istream-seekable.c Sun Oct 02 16:03:10 2011 +0300 +++ b/src/lib/istream-seekable.c Sun Oct 02 16:32:59 2011 +0300 @@ -54,6 +54,7 @@ i_stream_unref(&sstream->input[i]); i_free(sstream->temp_path); + i_free(sstream->input); } static void From dovecot at dovecot.org Sun Oct 2 16:28:02 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 16:28:02 +0300 Subject: dovecot-2.1: lib-storage: Keep mail_user referenced while storag... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/b7995a25c052 changeset: 13580:b7995a25c052 user: Timo Sirainen date: Sun Oct 02 16:34:41 2011 +0300 description: lib-storage: Keep mail_user referenced while storage objects exist. This allows unreferencing mail_user after mailbox_alloc() and having it freed on mailbox_free(). diffstat: src/lib-storage/mail-storage.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diffs (25 lines): diff -r f41a3dd03be2 -r b7995a25c052 src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Sun Oct 02 16:33:51 2011 +0300 +++ b/src/lib-storage/mail-storage.c Sun Oct 02 16:34:41 2011 +0300 @@ -419,7 +419,8 @@ { i_assert(storage->refcount > 0); - storage->obj_refcount++; + if (storage->obj_refcount++ == 0) + mail_user_ref(storage->user); } void mail_storage_obj_unref(struct mail_storage *storage) @@ -427,7 +428,10 @@ i_assert(storage->refcount > 0); i_assert(storage->obj_refcount > 0); - storage->obj_refcount--; + if (--storage->obj_refcount == 0) { + struct mail_user *user = storage->user; + mail_user_unref(&user); + } } void mail_storage_clear_error(struct mail_storage *storage) From dovecot at dovecot.org Sun Oct 2 16:28:02 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 16:28:02 +0300 Subject: dovecot-2.1: lda/lmtp: Moved common raw mailbox allocation code ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/ac9fecc9202e changeset: 13581:ac9fecc9202e user: Timo Sirainen date: Sun Oct 02 16:35:22 2011 +0300 description: lda/lmtp: Moved common raw mailbox allocation code to raw-storage. diffstat: src/lda/main.c | 33 +++++++---------------- src/lib-storage/index/raw/raw-storage.c | 46 +++++++++++++++++++++++++++++++++ src/lib-storage/index/raw/raw-storage.h | 7 +++++ src/lmtp/commands.c | 11 ++----- 4 files changed, 66 insertions(+), 31 deletions(-) diffs (173 lines): diff -r b7995a25c052 -r ac9fecc9202e src/lda/main.c --- a/src/lda/main.c Sun Oct 02 16:34:41 2011 +0300 +++ b/src/lda/main.c Sun Oct 02 16:35:22 2011 +0300 @@ -212,14 +212,13 @@ struct mail_storage_service_user *service_user; struct mail_storage_service_input service_input; struct mail_user *raw_mail_user; - struct mail_namespace *raw_ns; struct mail_storage *storage; struct mailbox *box; - struct raw_mailbox *raw_box; struct istream *input; struct mailbox_transaction_context *t; struct mailbox_header_lookup_ctx *headers_ctx; const char *user_source = "", *destaddr_source = ""; + const char *envelope_sender; void **sets; uid_t process_euid; bool stderr_rejection = FALSE; @@ -372,35 +371,24 @@ sets = master_service_settings_get_others(master_service); raw_mail_user = raw_storage_create_from_set(ctx.dest_user->set_info, sets[0]); - raw_ns = raw_mail_user->namespaces; + envelope_sender = ctx.src_envelope_sender != NULL ? + ctx.src_envelope_sender : DEFAULT_ENVELOPE_SENDER; if (path == NULL) { input = create_raw_stream(&ctx, 0, &mtime); i_stream_set_name(input, "stdin"); - box = mailbox_alloc(raw_ns->list, "Dovecot Delivery Mail", - MAILBOX_FLAG_NO_INDEX_FILES); - if (mailbox_open_stream(box, input) < 0) { - i_fatal("Can't open delivery mail as raw: %s", - mailbox_get_last_error(box, &error)); - } + ret = raw_mailbox_alloc_stream(raw_mail_user, input, mtime, + envelope_sender, &box); i_stream_unref(&input); } else { - mtime = (time_t)-1; - box = mailbox_alloc(raw_ns->list, path, - MAILBOX_FLAG_NO_INDEX_FILES); - if (mailbox_open(box) < 0) { - i_fatal("Can't open delivery mail as raw: %s", - mailbox_get_last_error(box, &error)); - } + ret = raw_mailbox_alloc_path(raw_mail_user, path, (time_t)-1, + envelope_sender, &box); } - if (mailbox_sync(box, 0) < 0) { - i_fatal("Can't sync delivery mail: %s", + if (ret < 0) { + i_fatal("Can't open delivery mail as raw: %s", mailbox_get_last_error(box, &error)); } - raw_box = (struct raw_mailbox *)box; - raw_box->envelope_sender = ctx.src_envelope_sender != NULL ? - ctx.src_envelope_sender : DEFAULT_ENVELOPE_SENDER; - raw_box->mtime = mtime; + mail_user_unref(&raw_mail_user); t = mailbox_transaction_begin(box, 0); headers_ctx = mailbox_header_lookup_init(box, wanted_headers); @@ -468,7 +456,6 @@ mailbox_free(&box); mail_user_unref(&ctx.dest_user); - mail_user_unref(&raw_mail_user); mail_deliver_session_deinit(&ctx.session); mail_storage_service_user_free(&service_user); diff -r b7995a25c052 -r ac9fecc9202e src/lib-storage/index/raw/raw-storage.c --- a/src/lib-storage/index/raw/raw-storage.c Sun Oct 02 16:34:41 2011 +0300 +++ b/src/lib-storage/index/raw/raw-storage.c Sun Oct 02 16:35:22 2011 +0300 @@ -39,6 +39,52 @@ return user; } +static int +raw_mailbox_alloc_common(struct mail_user *user, struct istream *input, + const char *path, time_t received_time, + const char *envelope_sender, struct mailbox **box_r) +{ + struct mail_namespace *ns = user->namespaces; + struct mailbox *box; + struct raw_mailbox *raw_box; + const char *name; + + name = path != NULL ? path : i_stream_get_name(input); + box = *box_r = mailbox_alloc(ns->list, name, + MAILBOX_FLAG_NO_INDEX_FILES); + if (input != NULL) { + if (mailbox_open_stream(box, input) < 0) + return -1; + } else { + if (mailbox_open(box) < 0) + return -1; + } + if (mailbox_sync(box, 0) < 0) + return -1; + + i_assert(strcmp(box->storage->name, RAW_STORAGE_NAME) == 0); + raw_box = (struct raw_mailbox *)box; + raw_box->envelope_sender = envelope_sender; + raw_box->mtime = received_time; + return 0; +} + +int raw_mailbox_alloc_stream(struct mail_user *user, struct istream *input, + time_t received_time, const char *envelope_sender, + struct mailbox **box_r) +{ + return raw_mailbox_alloc_common(user, input, NULL, received_time, + envelope_sender, box_r); +} + +int raw_mailbox_alloc_path(struct mail_user *user, const char *path, + time_t received_time, const char *envelope_sender, + struct mailbox **box_r) +{ + return raw_mailbox_alloc_common(user, NULL, path, received_time, + envelope_sender, box_r); +} + static struct mail_storage *raw_storage_alloc(void) { struct raw_storage *storage; diff -r b7995a25c052 -r ac9fecc9202e src/lib-storage/index/raw/raw-storage.h --- a/src/lib-storage/index/raw/raw-storage.h Sun Oct 02 16:34:41 2011 +0300 +++ b/src/lib-storage/index/raw/raw-storage.h Sun Oct 02 16:35:22 2011 +0300 @@ -28,4 +28,11 @@ raw_storage_create_from_set(const struct setting_parser_info *set_info, const struct mail_user_settings *set); +int raw_mailbox_alloc_stream(struct mail_user *user, struct istream *input, + time_t received_time, const char *envelope_sender, + struct mailbox **box_r); +int raw_mailbox_alloc_path(struct mail_user *user, const char *path, + time_t received_time, const char *envelope_sender, + struct mailbox **box_r); + #endif diff -r b7995a25c052 -r ac9fecc9202e src/lmtp/commands.c --- a/src/lmtp/commands.c Sun Oct 02 16:34:41 2011 +0300 +++ b/src/lmtp/commands.c Sun Oct 02 16:35:22 2011 +0300 @@ -626,23 +626,18 @@ NULL }; struct mailbox *box; - struct raw_mailbox *raw_box; struct mailbox_header_lookup_ctx *headers_ctx; enum mail_error error; - box = mailbox_alloc(client->raw_mail_user->namespaces->list, - "Dovecot Delivery Mail", - MAILBOX_FLAG_NO_INDEX_FILES); - if (mailbox_open_stream(box, input) < 0 || - mailbox_sync(box, 0) < 0) { + if (raw_mailbox_alloc_stream(client->raw_mail_user, input, + (time_t)-1, client->state.mail_from, + &box) < 0) { i_error("Can't open delivery mail as raw: %s", mailbox_get_last_error(box, &error)); mailbox_free(&box); client_rcpt_fail_all(client); return -1; } - raw_box = (struct raw_mailbox *)box; - raw_box->envelope_sender = client->state.mail_from; client->state.raw_box = box; client->state.raw_trans = mailbox_transaction_begin(box, 0); From dovecot at dovecot.org Sun Oct 2 16:39:22 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 16:39:22 +0300 Subject: dovecot-2.1: lda: Code cleanups Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/020d2092f2f7 changeset: 13582:020d2092f2f7 user: Timo Sirainen date: Sun Oct 02 16:47:25 2011 +0300 description: lda: Code cleanups diffstat: src/lda/main.c | 139 ++++++++++++++++++++++++++++++++------------------------ 1 files changed, 80 insertions(+), 59 deletions(-) diffs (174 lines): diff -r ac9fecc9202e -r 020d2092f2f7 src/lda/main.c --- a/src/lda/main.c Sun Oct 02 16:35:22 2011 +0300 +++ b/src/lda/main.c Sun Oct 02 16:47:25 2011 +0300 @@ -167,6 +167,75 @@ return input; } +static struct mail * +lda_raw_mail_open(struct mail_deliver_context *ctx, const char *path) +{ + struct mail_user *raw_mail_user; + struct mailbox *box; + struct mailbox_transaction_context *t; + struct mail *mail; + struct mailbox_header_lookup_ctx *headers_ctx; + struct istream *input; + void **sets; + const char *envelope_sender; + time_t mtime; + int ret; + + sets = master_service_settings_get_others(master_service); + raw_mail_user = + raw_storage_create_from_set(ctx->dest_user->set_info, sets[0]); + + envelope_sender = ctx->src_envelope_sender != NULL ? + ctx->src_envelope_sender : DEFAULT_ENVELOPE_SENDER; + if (path == NULL) { + input = create_raw_stream(ctx, 0, &mtime); + i_stream_set_name(input, "stdin"); + ret = raw_mailbox_alloc_stream(raw_mail_user, input, mtime, + envelope_sender, &box); + i_stream_unref(&input); + } else { + ret = raw_mailbox_alloc_path(raw_mail_user, path, (time_t)-1, + envelope_sender, &box); + } + if (ret < 0) { + i_fatal("Can't open delivery mail as raw: %s", + mailbox_get_last_error(box, NULL)); + } + mail_user_unref(&raw_mail_user); + + t = mailbox_transaction_begin(box, 0); + headers_ctx = mailbox_header_lookup_init(box, wanted_headers); + mail = mail_alloc(t, 0, headers_ctx); + mailbox_header_lookup_unref(&headers_ctx); + mail_set_seq(mail, 1); + return mail; +} + +static void +lda_set_dest_addr(struct mail_deliver_context *ctx, const char *user, + const char *destaddr_source) +{ + if (ctx->dest_addr == NULL && + *ctx->set->lda_original_recipient_header != '\0') { + ctx->dest_addr = mail_deliver_get_address(ctx->src_mail, + ctx->set->lda_original_recipient_header); + destaddr_source = t_strconcat( + ctx->set->lda_original_recipient_header, " header", NULL); + } + if (ctx->dest_addr == NULL) { + ctx->dest_addr = strchr(user, '@') != NULL ? user : + t_strconcat(user, "@", ctx->set->hostname, NULL); + destaddr_source = "user at hostname"; + } + if (ctx->final_dest_addr == NULL) + ctx->final_dest_addr = ctx->dest_addr; + + if (ctx->dest_user->mail_debug) { + i_debug("Destination address: %s (source: %s)", + ctx->dest_addr, destaddr_source); + } +} + static void failure_exit_callback(int *status) { /* we want all our exit codes to be sysexits.h compatible. @@ -211,18 +280,10 @@ struct mail_storage_service_ctx *storage_service; struct mail_storage_service_user *service_user; struct mail_storage_service_input service_input; - struct mail_user *raw_mail_user; struct mail_storage *storage; - struct mailbox *box; - struct istream *input; - struct mailbox_transaction_context *t; - struct mailbox_header_lookup_ctx *headers_ctx; const char *user_source = "", *destaddr_source = ""; - const char *envelope_sender; - void **sets; uid_t process_euid; bool stderr_rejection = FALSE; - time_t mtime; int ret, c; enum mail_error error; @@ -367,54 +428,8 @@ user_source); } - /* create a separate mail user for the internal namespace */ - sets = master_service_settings_get_others(master_service); - raw_mail_user = - raw_storage_create_from_set(ctx.dest_user->set_info, sets[0]); - - envelope_sender = ctx.src_envelope_sender != NULL ? - ctx.src_envelope_sender : DEFAULT_ENVELOPE_SENDER; - if (path == NULL) { - input = create_raw_stream(&ctx, 0, &mtime); - i_stream_set_name(input, "stdin"); - ret = raw_mailbox_alloc_stream(raw_mail_user, input, mtime, - envelope_sender, &box); - i_stream_unref(&input); - } else { - ret = raw_mailbox_alloc_path(raw_mail_user, path, (time_t)-1, - envelope_sender, &box); - } - if (ret < 0) { - i_fatal("Can't open delivery mail as raw: %s", - mailbox_get_last_error(box, &error)); - } - mail_user_unref(&raw_mail_user); - - t = mailbox_transaction_begin(box, 0); - headers_ctx = mailbox_header_lookup_init(box, wanted_headers); - ctx.src_mail = mail_alloc(t, 0, headers_ctx); - mailbox_header_lookup_unref(&headers_ctx); - mail_set_seq(ctx.src_mail, 1); - - if (ctx.dest_addr == NULL && - *ctx.set->lda_original_recipient_header != '\0') { - ctx.dest_addr = mail_deliver_get_address(ctx.src_mail, - ctx.set->lda_original_recipient_header); - destaddr_source = t_strconcat( - ctx.set->lda_original_recipient_header, " header", NULL); - } - if (ctx.dest_addr == NULL) { - ctx.dest_addr = strchr(user, '@') != NULL ? user : - t_strconcat(user, "@", ctx.set->hostname, NULL); - destaddr_source = "user at hostname"; - } - if (ctx.final_dest_addr == NULL) - ctx.final_dest_addr = ctx.dest_addr; - - if (ctx.dest_user->mail_debug) { - i_debug("Destination address: %s (source: %s)", - ctx.dest_addr, destaddr_source); - } + ctx.src_mail = lda_raw_mail_open(&ctx, path); + lda_set_dest_addr(&ctx, user, destaddr_source); if (mail_deliver(&ctx, &storage) < 0) { if (storage == NULL) { @@ -451,9 +466,15 @@ /* ok, rejection sent */ } - mail_free(&ctx.src_mail); - mailbox_transaction_rollback(&t); - mailbox_free(&box); + { + struct mailbox_transaction_context *t = + ctx.src_mail->transaction; + struct mailbox *box = ctx.src_mail->box; + + mail_free(&ctx.src_mail); + mailbox_transaction_rollback(&t); + mailbox_free(&box); + } mail_user_unref(&ctx.dest_user); mail_deliver_session_deinit(&ctx.session); From dovecot at dovecot.org Sun Oct 2 16:43:19 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 16:43:19 +0300 Subject: dovecot-2.1: lmtp: Code cleanup. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/93cba8e84546 changeset: 13583:93cba8e84546 user: Timo Sirainen date: Sun Oct 02 16:51:40 2011 +0300 description: lmtp: Code cleanup. diffstat: src/lmtp/client.c | 13 ++++++++----- src/lmtp/client.h | 2 -- src/lmtp/commands.c | 7 +++---- 3 files changed, 11 insertions(+), 11 deletions(-) diffs (62 lines): diff -r 020d2092f2f7 -r 93cba8e84546 src/lmtp/client.c --- a/src/lmtp/client.c Sun Oct 02 16:47:25 2011 +0300 +++ b/src/lmtp/client.c Sun Oct 02 16:51:40 2011 +0300 @@ -291,12 +291,15 @@ mail_storage_service_user_free(&rcpt->service_user); } - if (client->state.raw_mail != NULL) + if (client->state.raw_mail != NULL) { + struct mailbox_transaction_context *raw_trans = + client->state.raw_mail->transaction; + struct mailbox *raw_box = client->state.raw_mail->box; + mail_free(&client->state.raw_mail); - if (client->state.raw_trans != NULL) - mailbox_transaction_rollback(&client->state.raw_trans); - if (client->state.raw_box != NULL) - mailbox_free(&client->state.raw_box); + mailbox_transaction_rollback(&raw_trans); + mailbox_free(&raw_box); + } if (client->state.mail_data != NULL) buffer_free(&client->state.mail_data); diff -r 020d2092f2f7 -r 93cba8e84546 src/lmtp/client.h --- a/src/lmtp/client.h Sun Oct 02 16:47:25 2011 +0300 +++ b/src/lmtp/client.h Sun Oct 02 16:51:40 2011 +0300 @@ -27,8 +27,6 @@ struct ostream *mail_data_output; const char *added_headers; - struct mailbox *raw_box; - struct mailbox_transaction_context *raw_trans; struct mail *raw_mail; struct mail_user *dest_user; diff -r 020d2092f2f7 -r 93cba8e84546 src/lmtp/commands.c --- a/src/lmtp/commands.c Sun Oct 02 16:47:25 2011 +0300 +++ b/src/lmtp/commands.c Sun Oct 02 16:51:40 2011 +0300 @@ -626,6 +626,7 @@ NULL }; struct mailbox *box; + struct mailbox_transaction_context *trans; struct mailbox_header_lookup_ctx *headers_ctx; enum mail_error error; @@ -639,12 +640,10 @@ return -1; } - client->state.raw_box = box; - client->state.raw_trans = mailbox_transaction_begin(box, 0); + trans = mailbox_transaction_begin(box, 0); headers_ctx = mailbox_header_lookup_init(box, wanted_headers); - client->state.raw_mail = mail_alloc(client->state.raw_trans, - 0, headers_ctx); + client->state.raw_mail = mail_alloc(trans, 0, headers_ctx); mailbox_header_lookup_unref(&headers_ctx); mail_set_seq(client->state.raw_mail, 1); return 0; From dovecot at dovecot.org Sun Oct 2 16:47:48 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 16:47:48 +0300 Subject: dovecot-2.1: mailbox list indexes: Use storage names instead of ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/e06e178c8fd1 changeset: 13584:e06e178c8fd1 user: Timo Sirainen date: Sun Oct 02 16:55:45 2011 +0300 description: mailbox list indexes: Use storage names instead of virtual names. diffstat: src/lib-storage/list/index-mailbox-list-status.c | 4 ++-- src/lib-storage/list/index-mailbox-list.c | 13 ++++++++----- src/lib-storage/list/index-mailbox-list.h | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diffs (78 lines): diff -r 93cba8e84546 -r e06e178c8fd1 src/lib-storage/list/index-mailbox-list-status.c --- a/src/lib-storage/list/index-mailbox-list-status.c Sun Oct 02 16:51:40 2011 +0300 +++ b/src/lib-storage/list/index-mailbox-list-status.c Sun Oct 02 16:55:45 2011 +0300 @@ -33,7 +33,7 @@ if (index_mailbox_list_refresh(box->list) < 0) return -1; - node = index_mailbox_list_lookup(box->list, box->vname); + node = index_mailbox_list_lookup(box->list, box->name); if (node == NULL) { /* mailbox not found */ return 0; @@ -248,7 +248,7 @@ struct mailbox_status status; uint32_t seq, seq1, seq2; - node = index_mailbox_list_lookup(box->list, box->vname); + node = index_mailbox_list_lookup(box->list, box->name); if (node == NULL) { index_mailbox_list_refresh_later(box->list); return; diff -r 93cba8e84546 -r e06e178c8fd1 src/lib-storage/list/index-mailbox-list.c --- a/src/lib-storage/list/index-mailbox-list.c Sun Oct 02 16:51:40 2011 +0300 +++ b/src/lib-storage/list/index-mailbox-list.c Sun Oct 02 16:55:45 2011 +0300 @@ -106,7 +106,7 @@ } struct index_mailbox_node * -index_mailbox_list_lookup(struct mailbox_list *list, const char *vname) +index_mailbox_list_lookup(struct mailbox_list *list, const char *name) { struct index_mailbox_list *ilist = INDEX_LIST_CONTEXT(list); struct index_mailbox_node *node; @@ -118,8 +118,8 @@ unsigned int i; char sep[2]; - sep[0] = mail_namespace_get_sep(list->ns); sep[1] = '\0'; - path = t_strsplit(vname, sep); + sep[0] = mailbox_list_get_hierarchy_sep(list); sep[1] = '\0'; + path = t_strsplit(name, sep); node = ilist->mailbox_tree; for (i = 0;; i++) { node = index_mailbox_node_find_sibling(node, path[i]); @@ -289,7 +289,7 @@ memset(&sync_ctx, 0, sizeof(sync_ctx)); sync_ctx.ilist = ilist; - sync_ctx.sep[0] = mail_namespace_get_sep(list->ns); + sync_ctx.sep[0] = mailbox_list_get_hierarchy_sep(list); if (mail_index_sync_begin(ilist->index, &sync_ctx.sync_ctx, &sync_ctx.view, &sync_ctx.trans, MAIL_INDEX_SYNC_FLAG_AVOID_FLAG_UPDATES) < 0) @@ -326,8 +326,11 @@ flags |= MAILBOX_LIST_INDEX_FLAG_NOINFERIORS; T_BEGIN { + const char *name = + mailbox_list_get_storage_name(info->ns->list, + info->name); seq = index_mailbox_list_sync_name(&sync_ctx, - info->name, flags); + name, flags); } T_END; mail_index_update_flags(sync_ctx.trans, seq, diff -r 93cba8e84546 -r e06e178c8fd1 src/lib-storage/list/index-mailbox-list.h --- a/src/lib-storage/list/index-mailbox-list.h Sun Oct 02 16:51:40 2011 +0300 +++ b/src/lib-storage/list/index-mailbox-list.h Sun Oct 02 16:55:45 2011 +0300 @@ -97,7 +97,7 @@ &mailbox_list_module_register); struct index_mailbox_node * -index_mailbox_list_lookup(struct mailbox_list *list, const char *vname); +index_mailbox_list_lookup(struct mailbox_list *list, const char *name); int index_mailbox_list_refresh(struct mailbox_list *list); void index_mailbox_list_refresh_later(struct mailbox_list *list); From dovecot at dovecot.org Sun Oct 2 16:51:53 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 16:51:53 +0300 Subject: dovecot-2.1: mailbox list indexes: Disable index files for share... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/37c4e282a605 changeset: 13585:37c4e282a605 user: Timo Sirainen date: Sun Oct 02 16:59:51 2011 +0300 description: mailbox list indexes: Disable index files for shared/public namespaces. diffstat: src/lib-storage/list/index-mailbox-list.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-) diffs (20 lines): diff -r e06e178c8fd1 -r 37c4e282a605 src/lib-storage/list/index-mailbox-list.c --- a/src/lib-storage/list/index-mailbox-list.c Sun Oct 02 16:55:45 2011 +0300 +++ b/src/lib-storage/list/index-mailbox-list.c Sun Oct 02 16:59:51 2011 +0300 @@ -807,8 +807,15 @@ MODULE_CONTEXT_SET(list, index_mailbox_list_module, ilist); return; } - if (*dir == '\0') + if (*dir == '\0') { + /* in-memory indexes */ dir = NULL; + } else if (list->ns->type != NAMESPACE_PRIVATE) { + /* don't create index files for shared/public mailboxes. + their indexes may be shared between multiple users, + each of which may have different ACLs */ + dir = NULL; + } ilist = p_new(list->pool, struct index_mailbox_list, 1); ilist->module_ctx.super = list->v; From dovecot at dovecot.org Sun Oct 2 17:04:42 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 17:04:42 +0300 Subject: dovecot-2.1: Renamed index-mailbox-list* to mailbox-list-index* Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/8800d0429b7c changeset: 13586:8800d0429b7c user: Timo Sirainen date: Sun Oct 02 17:12:58 2011 +0300 description: Renamed index-mailbox-list* to mailbox-list-index* diffstat: src/lib-storage/list/Makefile.am | 6 +- src/lib-storage/list/index-mailbox-list-status.c | 392 ---------- src/lib-storage/list/index-mailbox-list.c | 870 ---------------------- src/lib-storage/list/index-mailbox-list.h | 111 -- src/lib-storage/list/mailbox-list-index-status.c | 392 ++++++++++ src/lib-storage/list/mailbox-list-index.c | 876 +++++++++++++++++++++++ src/lib-storage/list/mailbox-list-index.h | 111 ++ src/lib-storage/register/Makefile.am | 4 +- 8 files changed, 1384 insertions(+), 1378 deletions(-) diffs (truncated from 2823 to 300 lines): diff -r 37c4e282a605 -r 8800d0429b7c src/lib-storage/list/Makefile.am --- a/src/lib-storage/list/Makefile.am Sun Oct 02 16:59:51 2011 +0300 +++ b/src/lib-storage/list/Makefile.am Sun Oct 02 17:12:58 2011 +0300 @@ -9,12 +9,12 @@ -I$(top_srcdir)/src/lib-storage/index libstorage_list_la_SOURCES = \ - index-mailbox-list.c \ - index-mailbox-list-status.c \ mailbox-list-delete.c \ mailbox-list-fs.c \ mailbox-list-fs-flags.c \ mailbox-list-fs-iter.c \ + mailbox-list-index.c \ + mailbox-list-index-status.c \ mailbox-list-maildir.c \ mailbox-list-maildir-iter.c \ mailbox-list-none.c \ @@ -22,9 +22,9 @@ subscription-file.c headers = \ - index-mailbox-list.h \ mailbox-list-delete.h \ mailbox-list-fs.h \ + mailbox-list-index.h \ mailbox-list-maildir.h \ mailbox-list-subscriptions.h \ subscription-file.h diff -r 37c4e282a605 -r 8800d0429b7c src/lib-storage/list/index-mailbox-list-status.c --- a/src/lib-storage/list/index-mailbox-list-status.c Sun Oct 02 16:59:51 2011 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,392 +0,0 @@ -/* Copyright (c) 2006-2011 Dovecot authors, see the included COPYING file */ - -#include "lib.h" -#include "array.h" -#include "mail-index-modseq.h" -#include "mail-storage-private.h" -#include "index-mailbox-list.h" - -#define INDEX_LIST_STORAGE_CONTEXT(obj) \ - MODULE_CONTEXT(obj, index_list_storage_module) - -#define CACHED_STATUS_ITEMS \ - (STATUS_MESSAGES | STATUS_UNSEEN | STATUS_RECENT | \ - STATUS_UIDNEXT | STATUS_UIDVALIDITY | STATUS_HIGHESTMODSEQ) - -struct index_list_mailbox { - union mailbox_module_context module_ctx; -}; - -static MODULE_CONTEXT_DEFINE_INIT(index_list_storage_module, - &mail_storage_module_register); - -static int -index_list_mailbox_open_view(struct mailbox *box, - struct mail_index_view **view_r, uint32_t *seq_r) -{ - struct index_mailbox_list *ilist = INDEX_LIST_CONTEXT(box->list); - struct index_mailbox_node *node; - struct mail_index_view *view; - uint32_t seq; - int ret; - - if (index_mailbox_list_refresh(box->list) < 0) - return -1; - - node = index_mailbox_list_lookup(box->list, box->name); - if (node == NULL) { - /* mailbox not found */ - return 0; - } - - view = mail_index_view_open(ilist->index); - if (!mail_index_lookup_seq(view, node->uid, &seq)) { - /* our in-memory tree is out of sync */ - ret = 1; - } else T_BEGIN { - ret = box->v.list_index_has_changed == NULL ? 0 : - box->v.list_index_has_changed(box, view, seq); - } T_END; - - if (ret != 0) { - /* error / mailbox has changed. we'll need to sync it. */ - index_mailbox_list_refresh_later(box->list); - mail_index_view_close(&view); - return ret < 0 ? -1 : 0; - } - - *view_r = view; - *seq_r = seq; - return 1; -} - -static bool -index_list_get_view_status(struct mailbox *box, struct mail_index_view *view, - uint32_t seq, enum mailbox_status_items items, - struct mailbox_status *status_r, - uint8_t *mailbox_guid) -{ - struct index_mailbox_list *ilist = INDEX_LIST_CONTEXT(box->list); - const void *data; - bool expunged; - bool ret = TRUE; - - if ((items & STATUS_UIDVALIDITY) != 0 || mailbox_guid != NULL) { - const struct mailbox_list_index_record *rec; - - mail_index_lookup_ext(view, seq, ilist->ext_id, - &data, &expunged); - rec = data; - if (rec == NULL || rec->uid_validity == 0) - ret = FALSE; - else { - status_r->uidvalidity = rec->uid_validity; - memcpy(mailbox_guid, rec->guid, GUID_128_SIZE); - } - } - - if ((items & (STATUS_MESSAGES | STATUS_UNSEEN | - STATUS_RECENT | STATUS_UIDNEXT)) != 0) { - const struct mailbox_list_index_msgs_record *rec; - - mail_index_lookup_ext(view, seq, ilist->msgs_ext_id, - &data, &expunged); - rec = data; - if (rec == NULL || rec->uidnext == 0) - ret = FALSE; - else { - status_r->messages = rec->messages; - status_r->unseen = rec->unseen; - status_r->recent = rec->recent; - status_r->uidnext = rec->uidnext; - } - } - if ((items & STATUS_HIGHESTMODSEQ) != 0) { - const uint64_t *rec; - - mail_index_lookup_ext(view, seq, ilist->hmodseq_ext_id, - &data, &expunged); - rec = data; - if (rec == NULL || *rec == 0) - ret = FALSE; - else - status_r->highest_modseq = *rec; - } - return ret; -} - -static int -index_list_get_cached_status(struct mailbox *box, - enum mailbox_status_items items, - struct mailbox_status *status_r) -{ - struct mail_index_view *view; - uint32_t seq; - int ret; - - memset(status_r, 0, sizeof(*status_r)); - - ret = index_list_mailbox_open_view(box, &view, &seq); - if (ret <= 0) - return ret; - - ret = index_list_get_view_status(box, view, seq, items, - status_r, NULL) ? 1 : 0; - mail_index_view_close(&view); - return ret; -} - -static int -index_list_get_status(struct mailbox *box, enum mailbox_status_items items, - struct mailbox_status *status_r) -{ - struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box); - - if ((items & ~CACHED_STATUS_ITEMS) == 0 && !box->opened) { - if (index_list_get_cached_status(box, items, status_r) > 0) - return 0; - /* nonsynced / error, fallback to doing it the slow way */ - } - return ibox->module_ctx.super.get_status(box, items, status_r); -} - -static int -index_list_update(struct mailbox *box, struct mail_index_view *view, - uint32_t seq, const struct mailbox_status *status) -{ - struct index_mailbox_list *ilist = INDEX_LIST_CONTEXT(box->list); - struct mail_index_transaction *trans; - struct mail_index_transaction_commit_result result; - struct mailbox_metadata metadata; - struct mailbox_status old_status; - guid_128_t mailbox_guid; - bool rec_changed, msgs_changed, hmodseq_changed; - - if (mailbox_get_metadata(box, MAILBOX_METADATA_GUID, &metadata) < 0) - memset(&metadata, 0, sizeof(metadata)); - - memset(&old_status, 0, sizeof(old_status)); - (void)index_list_get_view_status(box, view, seq, CACHED_STATUS_ITEMS, - &old_status, mailbox_guid); - - rec_changed = old_status.uidvalidity != status->uidvalidity || - memcmp(metadata.guid, mailbox_guid, sizeof(metadata.guid)) == 0; - msgs_changed = old_status.messages != status->messages || - old_status.unseen != status->unseen || - old_status.recent != status->recent || - old_status.uidnext != status->uidnext; - /* update highest-modseq only if they're ever been used */ - if (old_status.highest_modseq == status->highest_modseq) { - hmodseq_changed = FALSE; - } else if ((box->enabled_features & MAILBOX_FEATURE_CONDSTORE) != 0 || - old_status.highest_modseq != 0) { - hmodseq_changed = TRUE; - } else { - const void *data; - bool expunged; - - mail_index_lookup_ext(view, seq, ilist->hmodseq_ext_id, - &data, &expunged); - hmodseq_changed = data != NULL; - } - - if (hmodseq_changed && - old_status.highest_modseq != status->highest_modseq) - hmodseq_changed = TRUE; - - if (!rec_changed && !msgs_changed && !hmodseq_changed) - return 0; - - trans = mail_index_transaction_begin(view, - MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL); - - if (rec_changed) { - struct mailbox_list_index_record rec; - const void *old_data; - bool expunged; - - mail_index_lookup_ext(view, seq, ilist->ext_id, - &old_data, &expunged); - i_assert(old_data != NULL); - memcpy(&rec, old_data, sizeof(rec)); - - rec.uid_validity = status->uidvalidity; - memcpy(rec.guid, mailbox_guid, sizeof(rec.guid)); - mail_index_update_ext(trans, seq, ilist->ext_id, &rec, NULL); - } - - if (msgs_changed) { - struct mailbox_list_index_msgs_record msgs; - - memset(&msgs, 0, sizeof(msgs)); - msgs.messages = status->messages; - msgs.unseen = status->unseen; - msgs.recent = status->recent; - msgs.uidnext = status->uidnext; - - mail_index_update_ext(trans, seq, ilist->msgs_ext_id, - &msgs, NULL); - } - if (hmodseq_changed) { - mail_index_update_ext(trans, seq, ilist->hmodseq_ext_id, - &status->highest_modseq, NULL); - } - - if (box->v.list_index_update_sync != NULL) - box->v.list_index_update_sync(box, trans, seq); - - return mail_index_transaction_commit_full(&trans, &result); -} - -static void -index_list_update_mailbox(struct mailbox *box, struct mail_index_view *view) -{ - struct index_mailbox_list *ilist = INDEX_LIST_CONTEXT(box->list); - struct index_mailbox_node *node; - const struct mail_index_header *hdr; - struct mail_index_view *list_view; - struct mailbox_status status; - uint32_t seq, seq1, seq2; - - node = index_mailbox_list_lookup(box->list, box->name); - if (node == NULL) { - index_mailbox_list_refresh_later(box->list); - return; - } - - list_view = mail_index_view_open(ilist->index); - if (!mail_index_lookup_seq(list_view, node->uid, &seq)) - index_mailbox_list_refresh_later(box->list); - else { - /* get STATUS info using the given view, rather than - using whatever state the mailbox is currently in */ - hdr = mail_index_get_header(view); - - memset(&status, 0, sizeof(status)); - status.messages = hdr->messages_count; - status.unseen = hdr->messages_count - hdr->seen_messages_count; From dovecot at dovecot.org Sun Oct 2 17:10:13 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 17:10:13 +0300 Subject: dovecot-2.1: mailbox list indexes: Moved iteration code to separ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/cd7b56e965d2 changeset: 13587:cd7b56e965d2 user: Timo Sirainen date: Sun Oct 02 17:18:31 2011 +0300 description: mailbox list indexes: Moved iteration code to separate file. diffstat: src/lib-storage/list/Makefile.am | 1 + src/lib-storage/list/mailbox-list-index-iter.c | 172 +++++++++++++++++++++++++ src/lib-storage/list/mailbox-list-index.c | 169 ------------------------ src/lib-storage/list/mailbox-list-index.h | 8 + 4 files changed, 181 insertions(+), 169 deletions(-) diffs (truncated from 395 to 300 lines): diff -r 8800d0429b7c -r cd7b56e965d2 src/lib-storage/list/Makefile.am --- a/src/lib-storage/list/Makefile.am Sun Oct 02 17:12:58 2011 +0300 +++ b/src/lib-storage/list/Makefile.am Sun Oct 02 17:18:31 2011 +0300 @@ -14,6 +14,7 @@ mailbox-list-fs-flags.c \ mailbox-list-fs-iter.c \ mailbox-list-index.c \ + mailbox-list-index-iter.c \ mailbox-list-index-status.c \ mailbox-list-maildir.c \ mailbox-list-maildir-iter.c \ diff -r 8800d0429b7c -r cd7b56e965d2 src/lib-storage/list/mailbox-list-index-iter.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-storage/list/mailbox-list-index-iter.c Sun Oct 02 17:18:31 2011 +0300 @@ -0,0 +1,172 @@ +/* Copyright (c) 2006-2011 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "str.h" +#include "imap-match.h" +#include "mail-storage.h" +#include "mailbox-list-subscriptions.h" +#include "mailbox-list-index.h" + +struct mailbox_list_iterate_context * +mailbox_list_index_iter_init(struct mailbox_list *list, + const char *const *patterns, + enum mailbox_list_iter_flags flags) +{ + struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(list); + struct mailbox_list_index_iterate_context *ctx; + char ns_sep = mail_namespace_get_sep(list->ns); + + ctx = i_new(struct mailbox_list_index_iterate_context, 1); + ctx->ctx.list = list; + ctx->ctx.flags = flags; + ctx->ctx.glob = imap_match_init_multiple(default_pool, patterns, + TRUE, ns_sep); + array_create(&ctx->ctx.module_contexts, default_pool, sizeof(void *), 5); + ctx->sep = ns_sep; + + if (mailbox_list_index_refresh(ctx->ctx.list) < 0) { + /* no indexing */ + ctx->backend_ctx = ilist->module_ctx.super. + iter_init(list, patterns, flags); + } else { + /* listing mailboxes from index */ + ctx->info.ns = list->ns; + ctx->path = str_new(default_pool, 128); + ctx->next_node = ilist->mailbox_tree; + ilist->iter_refcount++; + } + return &ctx->ctx; +} + +static void +mailbox_list_index_update_info(struct mailbox_list_index_iterate_context *ctx) +{ + struct mailbox_list_index_node *node = ctx->next_node; + struct mailbox *box; + + str_truncate(ctx->path, ctx->parent_len); + if (str_len(ctx->path) > 0) + str_append_c(ctx->path, ctx->sep); + str_append(ctx->path, node->name); + + ctx->info.name = str_c(ctx->path); + ctx->info.flags = 0; + if ((node->flags & MAILBOX_LIST_INDEX_FLAG_NONEXISTENT) != 0) + ctx->info.flags |= MAILBOX_NONEXISTENT; + else if ((node->flags & MAILBOX_LIST_INDEX_FLAG_NOSELECT) != 0) + ctx->info.flags |= MAILBOX_NOSELECT; + if ((node->flags & MAILBOX_LIST_INDEX_FLAG_NOINFERIORS) != 0) + ctx->info.flags |= MAILBOX_NOINFERIORS; + ctx->info.flags |= node->children != NULL ? + MAILBOX_CHILDREN : MAILBOX_NOCHILDREN; + + if ((ctx->ctx.flags & (MAILBOX_LIST_ITER_SELECT_SUBSCRIBED | + MAILBOX_LIST_ITER_RETURN_SUBSCRIBED)) != 0) { + mailbox_list_set_subscription_flags(ctx->ctx.list, + ctx->info.name, + &ctx->info.flags); + } + + box = mailbox_alloc(ctx->ctx.list, ctx->info.name, 0); + mailbox_list_index_status_set_info_flags(box, node->uid, + &ctx->info.flags); + mailbox_free(&box); +} + +static void +mailbox_list_index_update_next(struct mailbox_list_index_iterate_context *ctx, + bool follow_children) +{ + struct mailbox_list_index_node *node = ctx->next_node; + + if (node->children != NULL && follow_children) { + ctx->parent_len = str_len(ctx->path); + ctx->next_node = node->children; + } else { + while (node->next == NULL) { + node = node->parent; + if (node != NULL) { + ctx->parent_len -= strlen(node->name); + if (node->parent != NULL) + ctx->parent_len--; + } + if (node == NULL) { + /* last one */ + ctx->next_node = NULL; + return; + } + } + ctx->next_node = node->next; + } +} + +static bool +iter_subscriptions_ok(struct mailbox_list_index_iterate_context *ctx) +{ + if ((ctx->ctx.flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) == 0) + return TRUE; + + if ((ctx->info.flags & MAILBOX_SUBSCRIBED) != 0) + return TRUE; + + if ((ctx->ctx.flags & MAILBOX_LIST_ITER_SELECT_RECURSIVEMATCH) != 0 && + (ctx->info.flags & MAILBOX_CHILD_SUBSCRIBED) != 0) + return TRUE; + return FALSE; +} + +const struct mailbox_info * +mailbox_list_index_iter_next(struct mailbox_list_iterate_context *_ctx) +{ + struct mailbox_list_index_iterate_context *ctx = + (struct mailbox_list_index_iterate_context *)_ctx; + struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(_ctx->list); + bool follow_children; + enum imap_match_result match; + + if (ctx->backend_ctx != NULL) { + /* index isn't being used */ + return ilist->module_ctx.super.iter_next(ctx->backend_ctx); + } + + /* listing mailboxes from index */ + while (ctx->next_node != NULL) { + mailbox_list_index_update_info(ctx); + match = imap_match(_ctx->glob, ctx->info.name); + + follow_children = (match & (IMAP_MATCH_YES | + IMAP_MATCH_CHILDREN)) != 0; + if (match == IMAP_MATCH_YES && iter_subscriptions_ok(ctx)) { + mailbox_list_index_update_next(ctx, TRUE); + return &ctx->info; + } else if ((_ctx->flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0 && + (ctx->info.flags & MAILBOX_CHILD_SUBSCRIBED) == 0) { + /* listing only subscriptions, but there are no + subscribed children. */ + follow_children = FALSE; + } + mailbox_list_index_update_next(ctx, follow_children); + } + return NULL; +} + +int mailbox_list_index_iter_deinit(struct mailbox_list_iterate_context *_ctx) +{ + struct mailbox_list_index_iterate_context *ctx = + (struct mailbox_list_index_iterate_context *)_ctx; + struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(_ctx->list); + int ret = ctx->failed ? -1 : 0; + + if (ctx->backend_ctx != NULL) + ret = ilist->module_ctx.super.iter_deinit(ctx->backend_ctx); + else { + i_assert(ilist->iter_refcount > 0); + ilist->iter_refcount--; + str_free(&ctx->path); + } + + imap_match_deinit(&ctx->ctx.glob); + array_free(&ctx->ctx.module_contexts); + i_free(ctx); + return ret; +} diff -r 8800d0429b7c -r cd7b56e965d2 src/lib-storage/list/mailbox-list-index.c --- a/src/lib-storage/list/mailbox-list-index.c Sun Oct 02 17:12:58 2011 +0300 +++ b/src/lib-storage/list/mailbox-list-index.c Sun Oct 02 17:18:31 2011 +0300 @@ -2,13 +2,10 @@ #include "lib.h" #include "ioloop.h" -#include "str.h" #include "hash.h" -#include "imap-match.h" #include "mail-index.h" #include "mail-storage.h" #include "mail-storage-hooks.h" -#include "mailbox-list-subscriptions.h" #include "mailbox-list-index.h" struct mailbox_list_index_sync_context { @@ -551,172 +548,6 @@ mail_index_view_close(&view); } -static struct mailbox_list_iterate_context * -mailbox_list_index_iter_init(struct mailbox_list *list, - const char *const *patterns, - enum mailbox_list_iter_flags flags) -{ - struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(list); - struct mailbox_list_index_iterate_context *ctx; - char ns_sep = mail_namespace_get_sep(list->ns); - - ctx = i_new(struct mailbox_list_index_iterate_context, 1); - ctx->ctx.list = list; - ctx->ctx.flags = flags; - ctx->ctx.glob = imap_match_init_multiple(default_pool, patterns, - TRUE, ns_sep); - array_create(&ctx->ctx.module_contexts, default_pool, sizeof(void *), 5); - ctx->sep = ns_sep; - - if (mailbox_list_index_refresh(ctx->ctx.list) < 0) { - /* no indexing */ - mail_index_mark_corrupted(ilist->index); - ctx->backend_ctx = ilist->module_ctx.super. - iter_init(list, patterns, flags); - } else { - /* listing mailboxes from index */ - ctx->info.ns = list->ns; - ctx->path = str_new(default_pool, 128); - ctx->next_node = ilist->mailbox_tree; - ilist->iter_refcount++; - } - return &ctx->ctx; -} - -static void -mailbox_list_index_update_info(struct mailbox_list_index_iterate_context *ctx) -{ - struct mailbox_list_index_node *node = ctx->next_node; - struct mailbox *box; - - str_truncate(ctx->path, ctx->parent_len); - if (str_len(ctx->path) > 0) - str_append_c(ctx->path, ctx->sep); - str_append(ctx->path, node->name); - - ctx->info.name = str_c(ctx->path); - ctx->info.flags = 0; - if ((node->flags & MAILBOX_LIST_INDEX_FLAG_NONEXISTENT) != 0) - ctx->info.flags |= MAILBOX_NONEXISTENT; - else if ((node->flags & MAILBOX_LIST_INDEX_FLAG_NOSELECT) != 0) - ctx->info.flags |= MAILBOX_NOSELECT; - if ((node->flags & MAILBOX_LIST_INDEX_FLAG_NOINFERIORS) != 0) - ctx->info.flags |= MAILBOX_NOINFERIORS; - ctx->info.flags |= node->children != NULL ? - MAILBOX_CHILDREN : MAILBOX_NOCHILDREN; - - if ((ctx->ctx.flags & (MAILBOX_LIST_ITER_SELECT_SUBSCRIBED | - MAILBOX_LIST_ITER_RETURN_SUBSCRIBED)) != 0) { - mailbox_list_set_subscription_flags(ctx->ctx.list, - ctx->info.name, - &ctx->info.flags); - } - - box = mailbox_alloc(ctx->ctx.list, ctx->info.name, 0); - mailbox_list_index_status_set_info_flags(box, node->uid, - &ctx->info.flags); - mailbox_free(&box); -} - -static void -mailbox_list_index_update_next(struct mailbox_list_index_iterate_context *ctx, - bool follow_children) -{ - struct mailbox_list_index_node *node = ctx->next_node; - - if (node->children != NULL && follow_children) { - ctx->parent_len = str_len(ctx->path); - ctx->next_node = node->children; - } else { - while (node->next == NULL) { - node = node->parent; - if (node != NULL) { - ctx->parent_len -= strlen(node->name); - if (node->parent != NULL) - ctx->parent_len--; - } - if (node == NULL) { - /* last one */ - ctx->next_node = NULL; - return; - } - } - ctx->next_node = node->next; - } From dovecot at dovecot.org Sun Oct 2 17:26:51 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 17:26:51 +0300 Subject: dovecot-2.1: mailbox list indexes: Moved syncing code to separat... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/940ddec22822 changeset: 13588:940ddec22822 user: Timo Sirainen date: Sun Oct 02 17:34:49 2011 +0300 description: mailbox list indexes: Moved syncing code to separate file. diffstat: src/lib-storage/list/Makefile.am | 1 + src/lib-storage/list/mailbox-list-index-sync.c | 308 ++++++++++++++++++++++ src/lib-storage/list/mailbox-list-index.c | 345 +----------------------- src/lib-storage/list/mailbox-list-index.h | 11 + 4 files changed, 343 insertions(+), 322 deletions(-) diffs (truncated from 752 to 300 lines): diff -r cd7b56e965d2 -r 940ddec22822 src/lib-storage/list/Makefile.am --- a/src/lib-storage/list/Makefile.am Sun Oct 02 17:18:31 2011 +0300 +++ b/src/lib-storage/list/Makefile.am Sun Oct 02 17:34:49 2011 +0300 @@ -16,6 +16,7 @@ mailbox-list-index.c \ mailbox-list-index-iter.c \ mailbox-list-index-status.c \ + mailbox-list-index-sync.c \ mailbox-list-maildir.c \ mailbox-list-maildir-iter.c \ mailbox-list-none.c \ diff -r cd7b56e965d2 -r 940ddec22822 src/lib-storage/list/mailbox-list-index-sync.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-storage/list/mailbox-list-index-sync.c Sun Oct 02 17:34:49 2011 +0300 @@ -0,0 +1,308 @@ +/* Copyright (c) 2006-2011 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "ioloop.h" +#include "hash.h" +#include "mail-index.h" +#include "mailbox-list-index.h" + +struct mailbox_list_index_sync_context { + struct mailbox_list_index *ilist; + char sep[2]; + uint32_t next_uid; + + struct mail_index_sync_ctx *sync_ctx; + struct mail_index_view *view; + struct mail_index_transaction *trans; +}; + +static void +node_add_to_index(struct mailbox_list_index_sync_context *ctx, + const struct mailbox_list_index_node *node, uint32_t *seq_r) +{ + struct mailbox_list_index_record irec; + uint32_t seq; + + memset(&irec, 0, sizeof(irec)); + irec.name_id = node->name_id; + if (node->parent != NULL) + irec.parent_uid = node->parent->uid; + + mail_index_append(ctx->trans, node->uid, &seq); + mail_index_update_flags(ctx->trans, seq, MODIFY_REPLACE, + (enum mail_flags)MAILBOX_LIST_INDEX_FLAG_NONEXISTENT); + mail_index_update_ext(ctx->trans, seq, ctx->ilist->ext_id, &irec, NULL); + + *seq_r = seq; +} + +static struct mailbox_list_index_node * +mailbox_list_index_node_add(struct mailbox_list_index_sync_context *ctx, + struct mailbox_list_index_node *parent, + const char *name, uint32_t *seq_r) +{ + struct mailbox_list_index_node *node; + char *dup_name; + + node = p_new(ctx->ilist->mailbox_pool, + struct mailbox_list_index_node, 1); + node->flags = MAILBOX_LIST_INDEX_FLAG_NONEXISTENT | + MAILBOX_LIST_INDEX_FLAG_MARKED; + /* we don't bother doing name deduplication here, even though it would + be possible. */ + node->name = dup_name = p_strdup(ctx->ilist->mailbox_pool, name); + node->name_id = ++ctx->ilist->highest_name_id; + node->uid = ctx->next_uid++; + + if (parent != NULL) { + node->parent = parent; + node->next = parent->children; + parent->children = node; + } else { + node->next = ctx->ilist->mailbox_tree; + ctx->ilist->mailbox_tree = node; + } + hash_table_insert(ctx->ilist->mailbox_hash, + POINTER_CAST(node->uid), node); + hash_table_insert(ctx->ilist->mailbox_names, + POINTER_CAST(node->name_id), dup_name); + + node_add_to_index(ctx, node, seq_r); + return node; +} + +static uint32_t +mailbox_list_index_sync_name(struct mailbox_list_index_sync_context *ctx, + const char *name, + enum mailbox_list_index_flags flags) +{ + const char *const *path; + struct mailbox_list_index_node *node, *parent; + unsigned int i; + uint32_t seq = 0; + + path = t_strsplit(name, ctx->sep); + node = ctx->ilist->mailbox_tree; parent = NULL; + for (i = 0; path[i] != NULL; i++) { + node = mailbox_list_index_node_find_sibling(node, path[i]); + if (node == NULL) + break; + node->flags |= MAILBOX_LIST_INDEX_FLAG_MARKED; + parent = node; + node = node->children; + } + + node = parent; + if (path[i] == NULL) { + if (!mail_index_lookup_seq(ctx->view, node->uid, &seq)) + i_panic("mailbox list index: lost uid=%u", node->uid); + } else { + for (; path[i] != NULL; i++) { + node = mailbox_list_index_node_add(ctx, node, path[i], + &seq); + } + } + + node->flags = flags | MAILBOX_LIST_INDEX_FLAG_MARKED; + return seq; +} + +static void +get_existing_name_ids(ARRAY_TYPE(uint32_t) *ids, + const struct mailbox_list_index_node *node) +{ + for (; node != NULL; node = node->next) { + if ((node->flags & MAILBOX_LIST_INDEX_FLAG_MARKED) != 0) { + if (node->children != NULL) + get_existing_name_ids(ids, node->children); + array_append(ids, &node->name_id, 1); + } + } +} + +static int uint32_cmp(const uint32_t *p1, const uint32_t *p2) +{ + return *p1 < *p2 ? -1 : + (*p1 > *p2 ? 1 : 0); +} + +static void +mailbox_list_index_sync_names(struct mailbox_list_index_sync_context *ctx) +{ + struct mailbox_list_index *ilist = ctx->ilist; + ARRAY_TYPE(uint32_t) existing_name_ids; + buffer_t *buf; + const void *ext_data; + size_t ext_size; + const char *name; + const uint32_t *id_p; + uint32_t prev_id = 0; + + t_array_init(&existing_name_ids, 64); + get_existing_name_ids(&existing_name_ids, ilist->mailbox_tree); + array_sort(&existing_name_ids, uint32_cmp); + + buf = buffer_create_dynamic(pool_datastack_create(), 1024); + buffer_append_zero(buf, sizeof(struct mailbox_list_index_header)); + + array_foreach(&existing_name_ids, id_p) { + if (*id_p != prev_id) { + buffer_append(buf, id_p, sizeof(*id_p)); + name = hash_table_lookup(ilist->mailbox_names, + POINTER_CAST(*id_p)); + buffer_append(buf, name, strlen(name) + 1); + prev_id = *id_p; + } + } + buffer_append_zero(buf, sizeof(*id_p)); + + mail_index_get_header_ext(ctx->view, ilist->ext_id, + &ext_data, &ext_size); + if (nearest_power(ext_size) != nearest_power(buf->used)) { + mail_index_ext_resize(ctx->trans, ilist->ext_id, + nearest_power(buf->used), + sizeof(struct mailbox_list_index_record), + sizeof(uint32_t)); + } + mail_index_update_header_ext(ctx->trans, ilist->ext_id, + 0, buf->data, buf->used); +} + +static void +mailbox_list_index_node_unmark_recursive(struct mailbox_list_index_node *node) +{ + while (node != NULL) { + if (node->children != NULL) + mailbox_list_index_node_unmark_recursive(node->children); + + node->flags &= ~MAILBOX_LIST_INDEX_FLAG_MARKED; + node = node->next; + } +} + +static void +mailbox_list_index_node_unlink(struct mailbox_list_index_sync_context *sync_ctx, + struct mailbox_list_index_node *node) +{ + struct mailbox_list_index_node **prev; + + prev = node->parent == NULL ? + &sync_ctx->ilist->mailbox_tree : + &node->parent->children; + + while (*prev != node) + prev = &(*prev)->next; + *prev = node->next; +} + +static void +mailbox_list_index_nodes_expunge(struct mailbox_list_index_sync_context *sync_ctx, + struct mailbox_list_index_node *node) +{ + uint32_t seq; + + while (node != NULL) { + if (node->children != NULL) { + mailbox_list_index_nodes_expunge(sync_ctx, + node->children); + } + + if ((node->flags & MAILBOX_LIST_INDEX_FLAG_MARKED) == 0) { + if (mail_index_lookup_seq(sync_ctx->view, node->uid, + &seq)) + mail_index_expunge(sync_ctx->trans, seq); + mailbox_list_index_node_unlink(sync_ctx, node); + } + node = node->next; + } +} + +int mailbox_list_index_sync(struct mailbox_list *list) +{ + struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(list); + struct mailbox_list_index_sync_context sync_ctx; + struct mailbox_list_iterate_context *iter; + const struct mail_index_header *hdr; + const struct mailbox_info *info; + const char *patterns[2]; + enum mailbox_list_index_flags flags; + uint32_t seq, orig_highest_name_id; + int ret = 0; + + mailbox_list_index_reset(ilist); + + memset(&sync_ctx, 0, sizeof(sync_ctx)); + sync_ctx.ilist = ilist; + sync_ctx.sep[0] = mailbox_list_get_hierarchy_sep(list); + if (mail_index_sync_begin(ilist->index, &sync_ctx.sync_ctx, + &sync_ctx.view, &sync_ctx.trans, + MAIL_INDEX_SYNC_FLAG_AVOID_FLAG_UPDATES) < 0) + return -1; + + if (mailbox_list_index_read(ilist, sync_ctx.view, TRUE) < 0) { + mail_index_sync_rollback(&sync_ctx.sync_ctx); + return -1; + } + orig_highest_name_id = ilist->highest_name_id; + + hdr = mail_index_get_header(sync_ctx.view); + sync_ctx.next_uid = hdr->next_uid; + + if (hdr->uid_validity == 0) { + uint32_t uid_validity = ioloop_time; + + mail_index_update_header(sync_ctx.trans, + offsetof(struct mail_index_header, uid_validity), + &uid_validity, sizeof(uid_validity), TRUE); + } + + mailbox_list_index_node_unmark_recursive(ilist->mailbox_tree); + + patterns[0] = "*"; patterns[1] = NULL; + iter = ilist->module_ctx.super.iter_init(list, patterns, 0); + while ((info = ilist->module_ctx.super.iter_next(iter)) != NULL) { + flags = 0; + if ((info->flags & MAILBOX_NONEXISTENT) != 0) + flags |= MAILBOX_LIST_INDEX_FLAG_NONEXISTENT; + if ((info->flags & MAILBOX_NOSELECT) != 0) + flags |= MAILBOX_LIST_INDEX_FLAG_NOSELECT; + if ((info->flags & MAILBOX_NOINFERIORS) != 0) + flags |= MAILBOX_LIST_INDEX_FLAG_NOINFERIORS; + + T_BEGIN { + const char *name = + mailbox_list_get_storage_name(info->ns->list, + info->name); + seq = mailbox_list_index_sync_name(&sync_ctx, + name, flags); + } T_END; + + mail_index_update_flags(sync_ctx.trans, seq, + MODIFY_REPLACE, (enum mail_flags)flags); + } + if (ilist->module_ctx.super.iter_deinit(iter) < 0) + ret = -1; + From dovecot at dovecot.org Sun Oct 2 17:40:02 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 17:40:02 +0300 Subject: dovecot-2.1: mailbox list indexes: Error handling fixes. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/75679aca405a changeset: 13589:75679aca405a user: Timo Sirainen date: Sun Oct 02 17:48:23 2011 +0300 description: mailbox list indexes: Error handling fixes. diffstat: src/lib-storage/list/mailbox-list-index-status.c | 12 ++++++++---- src/lib-storage/list/mailbox-list-index-sync.c | 19 ++++++++++--------- src/lib-storage/list/mailbox-list-index.c | 18 ++++++++++++++---- src/lib-storage/list/mailbox-list-index.h | 5 +++-- 4 files changed, 35 insertions(+), 19 deletions(-) diffs (157 lines): diff -r 940ddec22822 -r 75679aca405a src/lib-storage/list/mailbox-list-index-status.c --- a/src/lib-storage/list/mailbox-list-index-status.c Sun Oct 02 17:34:49 2011 +0300 +++ b/src/lib-storage/list/mailbox-list-index-status.c Sun Oct 02 17:48:23 2011 +0300 @@ -21,8 +21,8 @@ &mail_storage_module_register); static int -index_list_mailbox_open_view(struct mailbox *box, - struct mail_index_view **view_r, uint32_t *seq_r) +index_list_open_view(struct mailbox *box, struct mail_index_view **view_r, + uint32_t *seq_r) { struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(box->list); struct mailbox_list_index_node *node; @@ -126,7 +126,7 @@ memset(status_r, 0, sizeof(*status_r)); - ret = index_list_mailbox_open_view(box, &view, &seq); + ret = index_list_open_view(box, &view, &seq); if (ret <= 0) return ret; @@ -235,7 +235,11 @@ if (box->v.list_index_update_sync != NULL) box->v.list_index_update_sync(box, trans, seq); - return mail_index_transaction_commit_full(&trans, &result); + if (mail_index_transaction_commit_full(&trans, &result) < 0) { + mailbox_list_index_set_index_error(box->list); + return -1; + } + return 0; } static void diff -r 940ddec22822 -r 75679aca405a src/lib-storage/list/mailbox-list-index-sync.c --- a/src/lib-storage/list/mailbox-list-index-sync.c Sun Oct 02 17:34:49 2011 +0300 +++ b/src/lib-storage/list/mailbox-list-index-sync.c Sun Oct 02 17:48:23 2011 +0300 @@ -227,7 +227,6 @@ const char *patterns[2]; enum mailbox_list_index_flags flags; uint32_t seq, orig_highest_name_id; - int ret = 0; mailbox_list_index_reset(ilist); @@ -236,10 +235,11 @@ sync_ctx.sep[0] = mailbox_list_get_hierarchy_sep(list); if (mail_index_sync_begin(ilist->index, &sync_ctx.sync_ctx, &sync_ctx.view, &sync_ctx.trans, - MAIL_INDEX_SYNC_FLAG_AVOID_FLAG_UPDATES) < 0) + MAIL_INDEX_SYNC_FLAG_AVOID_FLAG_UPDATES) < 0) { + mailbox_list_index_set_index_error(list); return -1; - - if (mailbox_list_index_read(ilist, sync_ctx.view, TRUE) < 0) { + } + if (mailbox_list_index_parse(ilist, sync_ctx.view, TRUE) < 0) { mail_index_sync_rollback(&sync_ctx.sync_ctx); return -1; } @@ -280,10 +280,7 @@ mail_index_update_flags(sync_ctx.trans, seq, MODIFY_REPLACE, (enum mail_flags)flags); } - if (ilist->module_ctx.super.iter_deinit(iter) < 0) - ret = -1; - - if (ret < 0) { + if (ilist->module_ctx.super.iter_deinit(iter) < 0) { mail_index_sync_rollback(&sync_ctx.sync_ctx); return -1; } @@ -304,5 +301,9 @@ &new_hdr.refresh_flag, sizeof(new_hdr.refresh_flag)); } - return mail_index_sync_commit(&sync_ctx.sync_ctx); + if (mail_index_sync_commit(&sync_ctx.sync_ctx) < 0) { + mailbox_list_index_set_index_error(list); + return -1; + } + return 0; } diff -r 940ddec22822 -r 75679aca405a src/lib-storage/list/mailbox-list-index.c --- a/src/lib-storage/list/mailbox-list-index.c Sun Oct 02 17:34:49 2011 +0300 +++ b/src/lib-storage/list/mailbox-list-index.c Sun Oct 02 17:48:23 2011 +0300 @@ -9,6 +9,14 @@ struct mailbox_list_index_module mailbox_list_index_module = MODULE_CONTEXT_INIT(&mailbox_list_module_register); +void mailbox_list_index_set_index_error(struct mailbox_list *list) +{ + struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(list); + + mailbox_list_set_internal_error(list); + mail_index_reset_error(ilist->index); +} + void mailbox_list_index_reset(struct mailbox_list_index *ilist) { hash_table_clear(ilist->mailbox_names, FALSE); @@ -158,8 +166,8 @@ return 0; } -int mailbox_list_index_read(struct mailbox_list_index *ilist, - struct mail_index_view *view, bool force) +int mailbox_list_index_parse(struct mailbox_list_index *ilist, + struct mail_index_view *view, bool force) { const struct mail_index_header *hdr; int ret; @@ -211,8 +219,10 @@ return 0; } - if (mail_index_refresh(ilist->index) < 0) + if (mail_index_refresh(ilist->index) < 0) { + mailbox_list_index_set_index_error(list); return -1; + } view = mail_index_view_open(ilist->index); if (ilist->mailbox_tree == NULL || @@ -220,7 +230,7 @@ /* refresh list of mailboxes */ ret = mailbox_list_index_sync(list); } else { - ret = mailbox_list_index_read(ilist, view, FALSE); + ret = mailbox_list_index_parse(ilist, view, FALSE); } mail_index_view_close(&view); return ret; diff -r 940ddec22822 -r 75679aca405a src/lib-storage/list/mailbox-list-index.h --- a/src/lib-storage/list/mailbox-list-index.h Sun Oct 02 17:34:49 2011 +0300 +++ b/src/lib-storage/list/mailbox-list-index.h Sun Oct 02 17:48:23 2011 +0300 @@ -99,6 +99,7 @@ extern MODULE_CONTEXT_DEFINE(mailbox_list_index_module, &mailbox_list_module_register); +void mailbox_list_index_set_index_error(struct mailbox_list *list); struct mailbox_list_index_node * mailbox_list_index_lookup(struct mailbox_list *list, const char *name); @@ -109,8 +110,8 @@ mailbox_list_index_node_find_sibling(struct mailbox_list_index_node *node, const char *name); void mailbox_list_index_reset(struct mailbox_list_index *ilist); -int mailbox_list_index_read(struct mailbox_list_index *ilist, - struct mail_index_view *view, bool force); +int mailbox_list_index_parse(struct mailbox_list_index *ilist, + struct mail_index_view *view, bool force); int mailbox_list_index_sync(struct mailbox_list *list); struct mailbox_list_iterate_context * From dovecot at dovecot.org Sun Oct 2 18:04:45 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 18:04:45 +0300 Subject: dovecot-2.1: mailbox list indexes: Code cleanups. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/6912969d94e8 changeset: 13590:6912969d94e8 user: Timo Sirainen date: Sun Oct 02 18:12:05 2011 +0300 description: mailbox list indexes: Code cleanups. diffstat: src/lib-storage/list/mailbox-list-index-sync.c | 68 ++++++++++++++----------- src/lib-storage/list/mailbox-list-index.c | 6 +- src/lib-storage/list/mailbox-list-index.h | 2 +- 3 files changed, 43 insertions(+), 33 deletions(-) diffs (253 lines): diff -r 75679aca405a -r 6912969d94e8 src/lib-storage/list/mailbox-list-index-sync.c --- a/src/lib-storage/list/mailbox-list-index-sync.c Sun Oct 02 17:48:23 2011 +0300 +++ b/src/lib-storage/list/mailbox-list-index-sync.c Sun Oct 02 18:12:05 2011 +0300 @@ -47,7 +47,7 @@ node = p_new(ctx->ilist->mailbox_pool, struct mailbox_list_index_node, 1); node->flags = MAILBOX_LIST_INDEX_FLAG_NONEXISTENT | - MAILBOX_LIST_INDEX_FLAG_MARKED; + MAILBOX_LIST_INDEX_FLAG_SYNC_EXISTS; /* we don't bother doing name deduplication here, even though it would be possible. */ node->name = dup_name = p_strdup(ctx->ilist->mailbox_pool, name); @@ -82,28 +82,32 @@ uint32_t seq = 0; path = t_strsplit(name, ctx->sep); + /* find the last node that exists in the path */ node = ctx->ilist->mailbox_tree; parent = NULL; for (i = 0; path[i] != NULL; i++) { node = mailbox_list_index_node_find_sibling(node, path[i]); if (node == NULL) break; - node->flags |= MAILBOX_LIST_INDEX_FLAG_MARKED; + + node->flags |= MAILBOX_LIST_INDEX_FLAG_SYNC_EXISTS; parent = node; node = node->children; } node = parent; if (path[i] == NULL) { + /* the entire path exists */ if (!mail_index_lookup_seq(ctx->view, node->uid, &seq)) i_panic("mailbox list index: lost uid=%u", node->uid); } else { + /* create missing parts of the path */ for (; path[i] != NULL; i++) { node = mailbox_list_index_node_add(ctx, node, path[i], &seq); } } - node->flags = flags | MAILBOX_LIST_INDEX_FLAG_MARKED; + node->flags = flags | MAILBOX_LIST_INDEX_FLAG_SYNC_EXISTS; return seq; } @@ -112,7 +116,7 @@ const struct mailbox_list_index_node *node) { for (; node != NULL; node = node->next) { - if ((node->flags & MAILBOX_LIST_INDEX_FLAG_MARKED) != 0) { + if ((node->flags & MAILBOX_LIST_INDEX_FLAG_SYNC_EXISTS) != 0) { if (node->children != NULL) get_existing_name_ids(ids, node->children); array_append(ids, &node->name_id, 1); @@ -131,64 +135,66 @@ { struct mailbox_list_index *ilist = ctx->ilist; ARRAY_TYPE(uint32_t) existing_name_ids; - buffer_t *buf; + buffer_t *hdr_buf; const void *ext_data; size_t ext_size; const char *name; const uint32_t *id_p; uint32_t prev_id = 0; + /* get all existing name IDs sorted */ t_array_init(&existing_name_ids, 64); get_existing_name_ids(&existing_name_ids, ilist->mailbox_tree); array_sort(&existing_name_ids, uint32_cmp); - buf = buffer_create_dynamic(pool_datastack_create(), 1024); - buffer_append_zero(buf, sizeof(struct mailbox_list_index_header)); + hdr_buf = buffer_create_dynamic(pool_datastack_create(), 1024); + buffer_append_zero(hdr_buf, sizeof(struct mailbox_list_index_header)); + /* add existing names to header (with deduplication) */ array_foreach(&existing_name_ids, id_p) { if (*id_p != prev_id) { - buffer_append(buf, id_p, sizeof(*id_p)); + buffer_append(hdr_buf, id_p, sizeof(*id_p)); name = hash_table_lookup(ilist->mailbox_names, POINTER_CAST(*id_p)); - buffer_append(buf, name, strlen(name) + 1); + buffer_append(hdr_buf, name, strlen(name) + 1); prev_id = *id_p; } } - buffer_append_zero(buf, sizeof(*id_p)); + buffer_append_zero(hdr_buf, sizeof(*id_p)); + /* make sure header size is ok in index and update it */ mail_index_get_header_ext(ctx->view, ilist->ext_id, &ext_data, &ext_size); - if (nearest_power(ext_size) != nearest_power(buf->used)) { + if (nearest_power(ext_size) != nearest_power(hdr_buf->used)) { mail_index_ext_resize(ctx->trans, ilist->ext_id, - nearest_power(buf->used), + nearest_power(hdr_buf->used), sizeof(struct mailbox_list_index_record), sizeof(uint32_t)); } mail_index_update_header_ext(ctx->trans, ilist->ext_id, - 0, buf->data, buf->used); + 0, hdr_buf->data, hdr_buf->used); } static void -mailbox_list_index_node_unmark_recursive(struct mailbox_list_index_node *node) +mailbox_list_index_node_clear_exists(struct mailbox_list_index_node *node) { while (node != NULL) { if (node->children != NULL) - mailbox_list_index_node_unmark_recursive(node->children); + mailbox_list_index_node_clear_exists(node->children); - node->flags &= ~MAILBOX_LIST_INDEX_FLAG_MARKED; + node->flags &= ~MAILBOX_LIST_INDEX_FLAG_SYNC_EXISTS; node = node->next; } } static void -mailbox_list_index_node_unlink(struct mailbox_list_index_sync_context *sync_ctx, +mailbox_list_index_node_unlink(struct mailbox_list_index *ilist, struct mailbox_list_index_node *node) { struct mailbox_list_index_node **prev; prev = node->parent == NULL ? - &sync_ctx->ilist->mailbox_tree : - &node->parent->children; + &ilist->mailbox_tree : &node->parent->children; while (*prev != node) prev = &(*prev)->next; @@ -196,22 +202,20 @@ } static void -mailbox_list_index_nodes_expunge(struct mailbox_list_index_sync_context *sync_ctx, - struct mailbox_list_index_node *node) +sync_expunge_nonexistent(struct mailbox_list_index_sync_context *sync_ctx, + struct mailbox_list_index_node *node) { uint32_t seq; while (node != NULL) { - if (node->children != NULL) { - mailbox_list_index_nodes_expunge(sync_ctx, - node->children); - } + if (node->children != NULL) + sync_expunge_nonexistent(sync_ctx, node->children); - if ((node->flags & MAILBOX_LIST_INDEX_FLAG_MARKED) == 0) { + if ((node->flags & MAILBOX_LIST_INDEX_FLAG_SYNC_EXISTS) == 0) { if (mail_index_lookup_seq(sync_ctx->view, node->uid, &seq)) mail_index_expunge(sync_ctx->trans, seq); - mailbox_list_index_node_unlink(sync_ctx, node); + mailbox_list_index_node_unlink(sync_ctx->ilist, node); } node = node->next; } @@ -239,6 +243,7 @@ mailbox_list_index_set_index_error(list); return -1; } + /* re-parse mailbox list now that it's refreshed and locked */ if (mailbox_list_index_parse(ilist, sync_ctx.view, TRUE) < 0) { mail_index_sync_rollback(&sync_ctx.sync_ctx); return -1; @@ -249,6 +254,7 @@ sync_ctx.next_uid = hdr->next_uid; if (hdr->uid_validity == 0) { + /* first time indexing, set uidvalidity */ uint32_t uid_validity = ioloop_time; mail_index_update_header(sync_ctx.trans, @@ -256,7 +262,8 @@ &uid_validity, sizeof(uid_validity), TRUE); } - mailbox_list_index_node_unmark_recursive(ilist->mailbox_tree); + /* clear EXISTS-flags, so after sync we know what can be expunged */ + mailbox_list_index_node_clear_exists(ilist->mailbox_tree); patterns[0] = "*"; patterns[1] = NULL; iter = ilist->module_ctx.super.iter_init(list, patterns, 0); @@ -285,14 +292,15 @@ return -1; } - mailbox_list_index_nodes_expunge(&sync_ctx, ilist->mailbox_tree); + sync_expunge_nonexistent(&sync_ctx, ilist->mailbox_tree); if (orig_highest_name_id != ilist->highest_name_id) { - /* new names added */ + /* new names added. this implicitly resets refresh flag */ T_BEGIN { mailbox_list_index_sync_names(&sync_ctx); } T_END; } else { + /* we're synced, reset refresh flag */ struct mailbox_list_index_header new_hdr; new_hdr.refresh_flag = 0; diff -r 75679aca405a -r 6912969d94e8 src/lib-storage/list/mailbox-list-index.c --- a/src/lib-storage/list/mailbox-list-index.c Sun Oct 02 17:48:23 2011 +0300 +++ b/src/lib-storage/list/mailbox-list-index.c Sun Oct 02 18:12:05 2011 +0300 @@ -19,6 +19,8 @@ void mailbox_list_index_reset(struct mailbox_list_index *ilist) { + i_assert(ilist->iter_refcount == 0); + hash_table_clear(ilist->mailbox_names, FALSE); hash_table_clear(ilist->mailbox_hash, FALSE); p_clear(ilist->mailbox_pool); @@ -49,8 +51,6 @@ unsigned int i; char sep[2]; - (void)mailbox_list_index_refresh(list); - sep[0] = mailbox_list_get_hierarchy_sep(list); sep[1] = '\0'; path = t_strsplit(name, sep); node = ilist->mailbox_tree; @@ -172,6 +172,8 @@ const struct mail_index_header *hdr; int ret; + i_assert(ilist->iter_refcount == 0); + hdr = mail_index_get_header(view); if (!force && hdr->log_file_seq == ilist->sync_log_file_seq && diff -r 75679aca405a -r 6912969d94e8 src/lib-storage/list/mailbox-list-index.h --- a/src/lib-storage/list/mailbox-list-index.h Sun Oct 02 17:48:23 2011 +0300 +++ b/src/lib-storage/list/mailbox-list-index.h Sun Oct 02 18:12:05 2011 +0300 @@ -19,7 +19,7 @@ MAILBOX_LIST_INDEX_FLAG_NOINFERIORS = MAIL_ANSWERED, /* set during syncing for mailboxes that still exist */ - MAILBOX_LIST_INDEX_FLAG_MARKED + MAILBOX_LIST_INDEX_FLAG_SYNC_EXISTS = MAIL_FLAGGED }; struct mailbox_list_index_header { From dovecot at dovecot.org Sun Oct 2 18:22:11 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 18:22:11 +0300 Subject: dovecot-2.1: mailbox list indexes: Added comment. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/612b8a73ada7 changeset: 13591:612b8a73ada7 user: Timo Sirainen date: Sun Oct 02 18:30:32 2011 +0300 description: mailbox list indexes: Added comment. diffstat: src/lib-storage/list/mailbox-list-index.h | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+), 0 deletions(-) diffs (31 lines): diff -r 6912969d94e8 -r 612b8a73ada7 src/lib-storage/list/mailbox-list-index.h --- a/src/lib-storage/list/mailbox-list-index.h Sun Oct 02 18:12:05 2011 +0300 +++ b/src/lib-storage/list/mailbox-list-index.h Sun Oct 02 18:30:32 2011 +0300 @@ -1,6 +1,27 @@ #ifndef MAILBOX_LIST_INDEX_H #define MAILBOX_LIST_INDEX_H +/* Mailbox list index basically contains: + + Header contains ID => name mapping. The name isn't the full mailbox name, + but rather each hierarchy level has its own ID and name. For example a + mailbox name "foo/bar" (with '/' as separator) would have separate IDs for + "foo" and "bar" names. + + The records contain { parent_uid, uid, name_id } field that can be used to + build the whole mailbox tree. parent_uid=0 means root, otherwise it's the + parent node's uid. + + Each record also contains GUID for each selectable mailbox. If a mailbox + is recreated using the same name, its GUID also changes. Note however that + the UID doesn't change, because the UID refers to the mailbox name, not to + the mailbox itself. + + The records may contain also extensions for allowing mailbox_get_status() + to return values directly from the mailbox list index. Storage backends + may also add their own extensions to figure out if a record is up to date. +*/ + #include "module-context.h" #include "mailbox-list-private.h" From dovecot at dovecot.org Sun Oct 2 18:31:29 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 18:31:29 +0300 Subject: dovecot-2.1: lib-storage: Mailbox list index's ext_id shouldn't ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/d9b0cd5b77b5 changeset: 13592:d9b0cd5b77b5 user: Timo Sirainen date: Sun Oct 02 18:39:49 2011 +0300 description: lib-storage: Mailbox list index's ext_id shouldn't be cached in mail_storage. It's mailbox_list-specific, not mail_storage-specific. The easiest fix was to just cache it into mailbox rather than create a new index_mailbox_list. diffstat: src/lib-storage/index/index-storage.c | 1 + src/lib-storage/index/index-storage.h | 1 + src/lib-storage/index/index-sync.c | 24 ++++++++++----------- src/lib-storage/index/maildir/maildir-storage.c | 2 +- src/lib-storage/index/maildir/maildir-storage.h | 3 +- src/lib-storage/index/maildir/maildir-sync-index.c | 22 +++++++++----------- src/lib-storage/mail-storage-private.h | 1 - 7 files changed, 25 insertions(+), 29 deletions(-) diffs (188 lines): diff -r 612b8a73ada7 -r d9b0cd5b77b5 src/lib-storage/index/index-storage.c --- a/src/lib-storage/index/index-storage.c Sun Oct 02 18:30:32 2011 +0300 +++ b/src/lib-storage/index/index-storage.c Sun Oct 02 18:39:49 2011 +0300 @@ -298,6 +298,7 @@ box->pool, sizeof(void *), 5); ibox = p_new(box->pool, struct index_mailbox_context, 1); + ibox->list_index_sync_ext_id = (uint32_t)-1; ibox->index_flags = MAIL_INDEX_OPEN_FLAG_CREATE | mail_storage_settings_to_index_flags(box->storage->set); ibox->next_lock_notify = time(NULL) + LOCK_NOTIFY_INTERVAL; diff -r 612b8a73ada7 -r d9b0cd5b77b5 src/lib-storage/index/index-storage.h --- a/src/lib-storage/index/index-storage.h Sun Oct 02 18:30:32 2011 +0300 +++ b/src/lib-storage/index/index-storage.h Sun Oct 02 18:39:49 2011 +0300 @@ -42,6 +42,7 @@ uint32_t vsize_hdr_ext_id; time_t sync_last_check; + uint32_t list_index_sync_ext_id; }; #define INDEX_STORAGE_CONTEXT(obj) \ diff -r 612b8a73ada7 -r d9b0cd5b77b5 src/lib-storage/index/index-sync.c --- a/src/lib-storage/index/index-sync.c Sun Oct 02 18:30:32 2011 +0300 +++ b/src/lib-storage/index/index-sync.c Sun Oct 02 18:39:49 2011 +0300 @@ -443,18 +443,19 @@ return ret; } -static unsigned int -index_storage_list_get_ext_id(struct mail_storage *storage, - struct mail_index_view *view) +static uint32_t +index_list_get_ext_id(struct mailbox *box, struct mail_index_view *view) { - if (storage->list_sync_ext_id == (uint32_t)-1) { - storage->list_sync_ext_id = + struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box); + + if (ibox->list_index_sync_ext_id == (uint32_t)-1) { + ibox->list_index_sync_ext_id = mail_index_ext_register(mail_index_view_get_index(view), "index sync", 0, sizeof(struct index_storage_list_index_record), sizeof(uint32_t)); } - return storage->list_sync_ext_id; + return ibox->list_index_sync_ext_id; } int index_storage_list_index_has_changed(struct mailbox *box, @@ -471,7 +472,7 @@ if (mail_index_is_in_memory(mail_index_view_get_index(list_view))) return 1; - ext_id = index_storage_list_get_ext_id(box->storage, list_view); + ext_id = index_list_get_ext_id(box, list_view); mail_index_lookup_ext(list_view, seq, ext_id, &data, &expunged); rec = data; @@ -512,7 +513,7 @@ return; /* get the current record */ - ext_id = index_storage_list_get_ext_id(box->storage, list_view); + ext_id = index_list_get_ext_id(box, list_view); mail_index_lookup_ext(list_view, seq, ext_id, &data, &expunged); if (expunged) return; @@ -532,9 +533,6 @@ new_rec.mtime = st.st_mtime & 0xffffffffU; if (old_rec == NULL || - memcmp(old_rec, &new_rec, sizeof(*old_rec)) != 0) { - mail_index_update_ext(trans, seq, - box->storage->list_sync_ext_id, - &new_rec, NULL); - } + memcmp(old_rec, &new_rec, sizeof(*old_rec)) != 0) + mail_index_update_ext(trans, seq, ext_id, &new_rec, NULL); } diff -r 612b8a73ada7 -r d9b0cd5b77b5 src/lib-storage/index/maildir/maildir-storage.c --- a/src/lib-storage/index/maildir/maildir-storage.c Sun Oct 02 18:30:32 2011 +0300 +++ b/src/lib-storage/index/maildir/maildir-storage.c Sun Oct 02 18:39:49 2011 +0300 @@ -52,7 +52,6 @@ storage->set = mail_storage_get_driver_settings(_storage); - storage->maildir_list_ext_id = (uint32_t)-1; storage->temp_prefix = p_strdup(_storage->pool, mailbox_list_get_temp_prefix(list)); @@ -275,6 +274,7 @@ mbox->box.storage = storage; mbox->box.list = list; mbox->box.mail_vfuncs = &maildir_mail_vfuncs; + mbox->maildir_list_index_ext_id = (uint32_t)-1; index_storage_mailbox_alloc(&mbox->box, vname, flags, MAILDIR_INDEX_PREFIX); diff -r 612b8a73ada7 -r d9b0cd5b77b5 src/lib-storage/index/maildir/maildir-storage.h --- a/src/lib-storage/index/maildir/maildir-storage.h Sun Oct 02 18:30:32 2011 +0300 +++ b/src/lib-storage/index/maildir/maildir-storage.h Sun Oct 02 18:39:49 2011 +0300 @@ -67,8 +67,6 @@ const struct maildir_settings *set; const char *temp_prefix; - - uint32_t maildir_list_ext_id; }; struct maildir_mailbox { @@ -87,6 +85,7 @@ struct maildir_index_header maildir_hdr; uint32_t maildir_ext_id; + uint32_t maildir_list_index_ext_id; unsigned int synced:1; unsigned int syncing_commit:1; diff -r 612b8a73ada7 -r d9b0cd5b77b5 src/lib-storage/index/maildir/maildir-sync-index.c --- a/src/lib-storage/index/maildir/maildir-sync-index.c Sun Oct 02 18:30:32 2011 +0300 +++ b/src/lib-storage/index/maildir/maildir-sync-index.c Sun Oct 02 18:39:49 2011 +0300 @@ -685,17 +685,18 @@ return ret < 0 ? -1 : (full_rescan ? 0 : 1); } -static unsigned int maildir_list_get_ext_id(struct maildir_storage *storage, - struct mail_index_view *view) +static unsigned int +maildir_list_get_ext_id(struct maildir_mailbox *mbox, + struct mail_index_view *view) { - if (storage->maildir_list_ext_id == (uint32_t)-1) { - storage->maildir_list_ext_id = + if (mbox->maildir_list_index_ext_id == (uint32_t)-1) { + mbox->maildir_list_index_ext_id = mail_index_ext_register(mail_index_view_get_index(view), "maildir", 0, sizeof(struct maildir_list_index_record), sizeof(uint32_t)); } - return storage->maildir_list_ext_id; + return mbox->maildir_list_index_ext_id; } int maildir_list_index_has_changed(struct mailbox *box, @@ -713,7 +714,7 @@ if (mbox->storage->set->maildir_very_dirty_syncs) return index_storage_list_index_has_changed(box, list_view, seq); - ext_id = maildir_list_get_ext_id(mbox->storage, list_view); + ext_id = maildir_list_get_ext_id(mbox, list_view); mail_index_lookup_ext(list_view, seq, ext_id, &data, &expunged); rec = data; @@ -768,7 +769,7 @@ /* get the current record */ list_view = mail_index_transaction_get_view(trans); - ext_id = maildir_list_get_ext_id(mbox->storage, list_view); + ext_id = maildir_list_get_ext_id(mbox, list_view); mail_index_lookup_ext(list_view, seq, ext_id, &data, &expunged); if (expunged) return; @@ -784,9 +785,6 @@ } if (old_rec == NULL || - memcmp(old_rec, &new_rec, sizeof(*old_rec)) != 0) { - mail_index_update_ext(trans, seq, - mbox->storage->maildir_list_ext_id, - &new_rec, NULL); - } + memcmp(old_rec, &new_rec, sizeof(*old_rec)) != 0) + mail_index_update_ext(trans, seq, ext_id, &new_rec, NULL); } diff -r 612b8a73ada7 -r d9b0cd5b77b5 src/lib-storage/mail-storage-private.h --- a/src/lib-storage/mail-storage-private.h Sun Oct 02 18:30:32 2011 +0300 +++ b/src/lib-storage/mail-storage-private.h Sun Oct 02 18:39:49 2011 +0300 @@ -87,7 +87,6 @@ struct mail_user *user; const char *temp_path_prefix; const struct mail_storage_settings *set; - uint32_t list_sync_ext_id; enum mail_storage_flags flags; From dovecot at dovecot.org Sun Oct 2 18:40:47 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 18:40:47 +0300 Subject: dovecot-2.1: mailbox list indexes: Handle name="" mailboxes. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/37c078f1745c changeset: 13593:37c078f1745c user: Timo Sirainen date: Sun Oct 02 18:49:09 2011 +0300 description: mailbox list indexes: Handle name="" mailboxes. diffstat: src/lib-storage/list/mailbox-list-index-sync.c | 5 +++-- src/lib-storage/list/mailbox-list-index.c | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diffs (41 lines): diff -r d9b0cd5b77b5 -r 37c078f1745c src/lib-storage/list/mailbox-list-index-sync.c --- a/src/lib-storage/list/mailbox-list-index-sync.c Sun Oct 02 18:39:49 2011 +0300 +++ b/src/lib-storage/list/mailbox-list-index-sync.c Sun Oct 02 18:49:09 2011 +0300 @@ -76,12 +76,13 @@ const char *name, enum mailbox_list_index_flags flags) { - const char *const *path; + const char *const *path, *empty_path[] = { "", NULL }; struct mailbox_list_index_node *node, *parent; unsigned int i; uint32_t seq = 0; - path = t_strsplit(name, ctx->sep); + path = *name == '\0' ? empty_path : + t_strsplit(name, ctx->sep); /* find the last node that exists in the path */ node = ctx->ilist->mailbox_tree; parent = NULL; for (i = 0; path[i] != NULL; i++) { diff -r d9b0cd5b77b5 -r 37c078f1745c src/lib-storage/list/mailbox-list-index.c --- a/src/lib-storage/list/mailbox-list-index.c Sun Oct 02 18:39:49 2011 +0300 +++ b/src/lib-storage/list/mailbox-list-index.c Sun Oct 02 18:49:09 2011 +0300 @@ -46,14 +46,16 @@ mailbox_list_index_lookup_real(struct mailbox_list *list, const char *name) { struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(list); - struct mailbox_list_index_node *node; + struct mailbox_list_index_node *node = ilist->mailbox_tree; const char *const *path; unsigned int i; char sep[2]; + if (*name == '\0') + return mailbox_list_index_node_find_sibling(node, ""); + sep[0] = mailbox_list_get_hierarchy_sep(list); sep[1] = '\0'; path = t_strsplit(name, sep); - node = ilist->mailbox_tree; for (i = 0;; i++) { node = mailbox_list_index_node_find_sibling(node, path[i]); if (node == NULL || path[i+1] == NULL) From dovecot at dovecot.org Sun Oct 2 18:46:34 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 18:46:34 +0300 Subject: dovecot-2.1: maildir: Maildir list index change check should alw... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/65696275eaa6 changeset: 13594:65696275eaa6 user: Timo Sirainen date: Sun Oct 02 18:54:32 2011 +0300 description: maildir: Maildir list index change check should always check index log changes. (Not only when maildir_very_dirty_syncs=no) diffstat: src/lib-storage/index/maildir/maildir-sync-index.c | 11 +++++++---- 1 files changed, 7 insertions(+), 4 deletions(-) diffs (31 lines): diff -r 37c078f1745c -r 65696275eaa6 src/lib-storage/index/maildir/maildir-sync-index.c --- a/src/lib-storage/index/maildir/maildir-sync-index.c Sun Oct 02 18:49:09 2011 +0300 +++ b/src/lib-storage/index/maildir/maildir-sync-index.c Sun Oct 02 18:54:32 2011 +0300 @@ -710,9 +710,13 @@ struct stat st; uint32_t ext_id; bool expunged; + int ret; + ret = index_storage_list_index_has_changed(box, list_view, seq); + if (ret != 0) + return ret; if (mbox->storage->set->maildir_very_dirty_syncs) - return index_storage_list_index_has_changed(box, list_view, seq); + return 0; ext_id = maildir_list_get_ext_id(mbox, list_view); mail_index_lookup_ext(list_view, seq, ext_id, &data, &expunged); @@ -762,10 +766,9 @@ uint32_t ext_id; bool expunged; - if (mbox->storage->set->maildir_very_dirty_syncs) { - index_storage_list_index_update_sync(box, trans, seq); + index_storage_list_index_update_sync(box, trans, seq); + if (mbox->storage->set->maildir_very_dirty_syncs) return; - } /* get the current record */ list_view = mail_index_transaction_get_view(trans); From dovecot at dovecot.org Sun Oct 2 20:00:51 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 20:00:51 +0300 Subject: dovecot-2.1: lib-storage: Compile fix for recent change. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/c2a173716500 changeset: 13595:c2a173716500 user: Timo Sirainen date: Sun Oct 02 20:05:23 2011 +0300 description: lib-storage: Compile fix for recent change. diffstat: src/lib-storage/mail-storage.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diffs (11 lines): diff -r 65696275eaa6 -r c2a173716500 src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Sun Oct 02 18:54:32 2011 +0300 +++ b/src/lib-storage/mail-storage.c Sun Oct 02 20:05:23 2011 +0300 @@ -368,7 +368,6 @@ storage->user = ns->user; storage->set = ns->mail_set; storage->flags = flags; - storage->list_sync_ext_id = (uint32_t)-1; p_array_init(&storage->module_contexts, storage->pool, 5); if (storage->v.create != NULL && From dovecot at dovecot.org Sun Oct 2 20:00:51 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 20:00:51 +0300 Subject: dovecot-2.1: lib-storage: mailbox_get_metadata() no longer alway... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/b7e58d26393f changeset: 13596:b7e58d26393f user: Timo Sirainen date: Sun Oct 02 20:06:58 2011 +0300 description: lib-storage: mailbox_get_metadata() no longer always opens mailbox. diffstat: src/lib-storage/index/dbox-multi/mdbox-storage.c | 4 +++- src/lib-storage/index/dbox-single/sdbox-storage.c | 4 +++- src/lib-storage/index/imapc/imapc-storage.c | 4 +++- src/lib-storage/index/index-status.c | 5 +++++ src/lib-storage/index/maildir/maildir-storage.c | 5 ++++- src/lib-storage/index/mbox/mbox-storage.c | 4 +++- src/lib-storage/mail-storage.c | 4 ---- src/plugins/virtual/virtual-storage.c | 4 +++- 8 files changed, 24 insertions(+), 10 deletions(-) diffs (141 lines): diff -r c2a173716500 -r b7e58d26393f src/lib-storage/index/dbox-multi/mdbox-storage.c --- a/src/lib-storage/index/dbox-multi/mdbox-storage.c Sun Oct 02 20:05:23 2011 +0300 +++ b/src/lib-storage/index/dbox-multi/mdbox-storage.c Sun Oct 02 20:06:58 2011 +0300 @@ -330,11 +330,13 @@ { struct mdbox_mailbox *mbox = (struct mdbox_mailbox *)box; + if (index_mailbox_get_metadata(box, items, metadata_r) < 0) + return -1; if ((items & MAILBOX_METADATA_GUID) != 0) { if (mdbox_mailbox_get_guid(mbox, metadata_r->guid) < 0) return -1; } - return index_mailbox_get_metadata(box, items, metadata_r); + return 0; } static int diff -r c2a173716500 -r b7e58d26393f src/lib-storage/index/dbox-single/sdbox-storage.c --- a/src/lib-storage/index/dbox-single/sdbox-storage.c Sun Oct 02 20:05:23 2011 +0300 +++ b/src/lib-storage/index/dbox-single/sdbox-storage.c Sun Oct 02 20:06:58 2011 +0300 @@ -271,11 +271,13 @@ { struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)box; + if (index_mailbox_get_metadata(box, items, metadata_r) < 0) + return -1; if ((items & MAILBOX_METADATA_GUID) != 0) { memcpy(metadata_r->guid, mbox->mailbox_guid, sizeof(metadata_r->guid)); } - return index_mailbox_get_metadata(box, items, metadata_r); + return 0; } static int diff -r c2a173716500 -r b7e58d26393f src/lib-storage/index/imapc/imapc-storage.c --- a/src/lib-storage/index/imapc/imapc-storage.c Sun Oct 02 20:05:23 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-storage.c Sun Oct 02 20:06:58 2011 +0300 @@ -604,12 +604,14 @@ enum mailbox_metadata_items items, struct mailbox_metadata *metadata_r) { + if (index_mailbox_get_metadata(box, items, metadata_r) < 0) + return -1; if ((items & MAILBOX_METADATA_GUID) != 0) { /* a bit ugly way to do this, but better than nothing for now. FIXME: if indexes are enabled, keep this there. */ mail_generate_guid_128_hash(box->name, metadata_r->guid); } - return index_mailbox_get_metadata(box, items, metadata_r); + return 0; } static void imapc_idle_timeout(struct imapc_mailbox *mbox) diff -r c2a173716500 -r b7e58d26393f src/lib-storage/index/index-status.c --- a/src/lib-storage/index/index-status.c Sun Oct 02 20:05:23 2011 +0300 +++ b/src/lib-storage/index/index-status.c Sun Oct 02 20:06:58 2011 +0300 @@ -263,6 +263,11 @@ enum mailbox_metadata_items items, struct mailbox_metadata *metadata_r) { + if (!box->opened) { + if (mailbox_open(box) < 0) + return -1; + } + if ((items & MAILBOX_METADATA_VIRTUAL_SIZE) != 0) { if (get_metadata_virtual_size(box, metadata_r) < 0) return -1; diff -r c2a173716500 -r b7e58d26393f src/lib-storage/index/maildir/maildir-storage.c --- a/src/lib-storage/index/maildir/maildir-storage.c Sun Oct 02 20:05:23 2011 +0300 +++ b/src/lib-storage/index/maildir/maildir-storage.c Sun Oct 02 20:06:58 2011 +0300 @@ -480,12 +480,15 @@ { struct maildir_mailbox *mbox = (struct maildir_mailbox *)box; + if (index_mailbox_get_metadata(box, items, metadata_r) < 0) + return -1; + if ((items & MAILBOX_METADATA_GUID) != 0) { if (maildir_uidlist_get_mailbox_guid(mbox->uidlist, metadata_r->guid) < 0) return -1; } - return index_mailbox_get_metadata(box, items, metadata_r); + return 0; } static void maildir_mailbox_close(struct mailbox *box) diff -r c2a173716500 -r b7e58d26393f src/lib-storage/index/mbox/mbox-storage.c --- a/src/lib-storage/index/mbox/mbox-storage.c Sun Oct 02 20:05:23 2011 +0300 +++ b/src/lib-storage/index/mbox/mbox-storage.c Sun Oct 02 20:06:58 2011 +0300 @@ -628,11 +628,13 @@ { struct mbox_mailbox *mbox = (struct mbox_mailbox *)box; + if (index_mailbox_get_metadata(box, items, metadata_r) < 0) + return -1; if ((items & MAILBOX_METADATA_GUID) != 0) { if (mbox_mailbox_get_guid(mbox, metadata_r->guid) < 0) return -1; } - return index_mailbox_get_metadata(box, items, metadata_r); + return 0; } static void mbox_notify_changes(struct mailbox *box) diff -r c2a173716500 -r b7e58d26393f src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Sun Oct 02 20:05:23 2011 +0300 +++ b/src/lib-storage/mail-storage.c Sun Oct 02 20:06:58 2011 +0300 @@ -1214,10 +1214,6 @@ { memset(metadata_r, 0, sizeof(*metadata_r)); - if (!box->opened) { - if (mailbox_open(box) < 0) - return -1; - } if (box->v.get_metadata(box, items, metadata_r) < 0) return -1; diff -r c2a173716500 -r b7e58d26393f src/plugins/virtual/virtual-storage.c --- a/src/plugins/virtual/virtual-storage.c Sun Oct 02 20:05:23 2011 +0300 +++ b/src/plugins/virtual/virtual-storage.c Sun Oct 02 20:06:58 2011 +0300 @@ -363,12 +363,14 @@ enum mailbox_metadata_items items, struct mailbox_metadata *metadata_r) { + if (index_mailbox_get_metadata(box, items, metadata_r) < 0) + return -1; if ((items & MAILBOX_METADATA_GUID) != 0) { mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE, "Virtual mailboxes have no GUIDs"); return -1; } - return index_mailbox_get_metadata(box, items, metadata_r); + return 0; } static void From dovecot at dovecot.org Sun Oct 2 20:00:51 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 20:00:51 +0300 Subject: dovecot-2.1: mailbox list indexes: Get mailbox_get_metadata(guid... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/341174c093ee changeset: 13597:341174c093ee user: Timo Sirainen date: Sun Oct 02 20:09:04 2011 +0300 description: mailbox list indexes: Get mailbox_get_metadata(guid) from index if possible. diffstat: src/lib-storage/list/mailbox-list-index-status.c | 38 ++++++++++++++++++++++++ 1 files changed, 38 insertions(+), 0 deletions(-) diffs (62 lines): diff -r b7e58d26393f -r 341174c093ee src/lib-storage/list/mailbox-list-index-status.c --- a/src/lib-storage/list/mailbox-list-index-status.c Sun Oct 02 20:06:58 2011 +0300 +++ b/src/lib-storage/list/mailbox-list-index-status.c Sun Oct 02 20:09:04 2011 +0300 @@ -151,6 +151,41 @@ } static int +index_list_get_cached_guid(struct mailbox *box, guid_128_t guid_r) +{ + struct mailbox_status status; + struct mail_index_view *view; + uint32_t seq; + int ret; + + ret = index_list_open_view(box, &view, &seq); + if (ret <= 0) + return ret; + + ret = index_list_get_view_status(box, view, seq, 0, + &status, guid_r) ? 1 : 0; + if (ret > 0 && guid_128_is_empty(guid_r)) + ret = 0; + mail_index_view_close(&view); + return ret; +} + +static int +index_list_get_metadata(struct mailbox *box, + enum mailbox_metadata_items items, + struct mailbox_metadata *metadata_r) +{ + struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box); + + if (items == MAILBOX_METADATA_GUID && !box->opened) { + if (index_list_get_cached_guid(box, metadata_r->guid) > 0) + return 0; + /* nonsynced / error, fallback to doing it the slow way */ + } + return ibox->module_ctx.super.get_metadata(box, items, metadata_r); +} + +static int index_list_update(struct mailbox *box, struct mail_index_view *view, uint32_t seq, const struct mailbox_status *status) { @@ -162,6 +197,8 @@ guid_128_t mailbox_guid; bool rec_changed, msgs_changed, hmodseq_changed; + i_assert(box->opened); + if (mailbox_get_metadata(box, MAILBOX_METADATA_GUID, &metadata) < 0) memset(&metadata, 0, sizeof(metadata)); @@ -367,6 +404,7 @@ ibox = p_new(box->pool, struct index_list_mailbox, 1); ibox->module_ctx.super = box->v; box->v.get_status = index_list_get_status; + box->v.get_metadata = index_list_get_metadata; box->v.sync_deinit = index_list_sync_deinit; box->v.transaction_commit = index_list_transaction_commit; From dovecot at dovecot.org Sun Oct 2 20:17:41 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 20:17:41 +0300 Subject: dovecot-2.1: passdb vpopmail: Always prefer to lookup plaintext ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/423cf2ccd1f1 changeset: 13598:423cf2ccd1f1 user: Timo Sirainen date: Sun Oct 02 20:26:02 2011 +0300 description: passdb vpopmail: Always prefer to lookup plaintext password if it exists. This is important when multiple auth mechanisms are used and the password is cached. diffstat: src/auth/passdb-vpopmail.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diffs (18 lines): diff -r 341174c093ee -r 423cf2ccd1f1 src/auth/passdb-vpopmail.c --- a/src/auth/passdb-vpopmail.c Sun Oct 02 20:09:04 2011 +0300 +++ b/src/auth/passdb-vpopmail.c Sun Oct 02 20:26:02 2011 +0300 @@ -75,8 +75,12 @@ password = NULL; *result_r = PASSDB_RESULT_USER_DISABLED; } else { - password = t_strdup_noconst(cleartext ? vpw->pw_clear_passwd : - vpw->pw_passwd); + if (vpw->pw_clear_passwd != NULL) + password = t_strdup_noconst(vpw->pw_clear_passwd); + else if (!cleartext) + password = t_strdup_noconst(vpw->pw_passwd); + else + password = NULL; *result_r = password != NULL ? PASSDB_RESULT_OK : PASSDB_RESULT_SCHEME_NOT_AVAILABLE; } From dovecot at dovecot.org Sun Oct 2 20:18:31 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 02 Oct 2011 20:18:31 +0300 Subject: dovecot-2.0: passdb vpopmail: Always prefer to lookup plaintext ... Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/dbd5f9ec38af changeset: 12945:dbd5f9ec38af user: Timo Sirainen date: Sun Oct 02 20:26:02 2011 +0300 description: passdb vpopmail: Always prefer to lookup plaintext password if it exists. This is important when multiple auth mechanisms are used and the password is cached. diffstat: src/auth/passdb-vpopmail.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diffs (18 lines): diff -r dd6460d046e7 -r dbd5f9ec38af src/auth/passdb-vpopmail.c --- a/src/auth/passdb-vpopmail.c Sun Oct 02 16:32:59 2011 +0300 +++ b/src/auth/passdb-vpopmail.c Sun Oct 02 20:26:02 2011 +0300 @@ -75,8 +75,12 @@ password = NULL; *result_r = PASSDB_RESULT_USER_DISABLED; } else { - password = t_strdup_noconst(cleartext ? vpw->pw_clear_passwd : - vpw->pw_passwd); + if (vpw->pw_clear_passwd != NULL) + password = t_strdup_noconst(vpw->pw_clear_passwd); + else if (!cleartext) + password = t_strdup_noconst(vpw->pw_passwd); + else + password = NULL; *result_r = password != NULL ? PASSDB_RESULT_OK : PASSDB_RESULT_SCHEME_NOT_AVAILABLE; } From dovecot at dovecot.org Mon Oct 3 19:53:01 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 03 Oct 2011 19:53:01 +0300 Subject: dovecot-2.1: script-login: Disable alarm after input has been read. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/6d1c20b1936c changeset: 13599:6d1c20b1936c user: Timo Sirainen date: Mon Oct 03 20:00:55 2011 +0300 description: script-login: Disable alarm after input has been read. diffstat: src/util/script-login.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 423cf2ccd1f1 -r 6d1c20b1936c src/util/script-login.c --- a/src/util/script-login.c Sun Oct 02 20:26:02 2011 +0300 +++ b/src/util/script-login.c Mon Oct 03 20:00:55 2011 +0300 @@ -79,6 +79,8 @@ if (fd == -1) i_fatal("client fd not received"); + alarm(0); + /* put everything to environment */ env_clean(); keys = t_str_new(256); From dovecot at dovecot.org Tue Oct 4 17:06:17 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 04 Oct 2011 17:06:17 +0300 Subject: dovecot-2.1: imapc: Mail body caching should be done at close(),... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/d3b30b82a225 changeset: 13600:d3b30b82a225 user: Timo Sirainen date: Tue Oct 04 17:14:30 2011 +0300 description: imapc: Mail body caching should be done at close(), not at free(). This cached wrong mail bodies when fetching multiple mails. diffstat: src/lib-storage/index/imapc/imapc-mail.c | 58 +++++++++++++------------------ 1 files changed, 25 insertions(+), 33 deletions(-) diffs (81 lines): diff -r 6d1c20b1936c -r d3b30b82a225 src/lib-storage/index/imapc/imapc-mail.c --- a/src/lib-storage/index/imapc/imapc-mail.c Mon Oct 03 20:00:55 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mail.c Tue Oct 04 17:14:30 2011 +0300 @@ -26,33 +26,6 @@ return &mail->imail.mail.mail; } -static void imapc_mail_free(struct mail *_mail) -{ - struct imapc_mail *mail = (struct imapc_mail *)_mail; - struct imapc_mailbox *mbox = (struct imapc_mailbox *)_mail->box; - struct imapc_mail_cache *cache = &mbox->prev_mail_cache; - - if (mail->body_fetched) { - imapc_mail_cache_free(cache); - cache->uid = _mail->uid; - if (cache->fd != -1) { - cache->fd = mail->fd; - mail->fd = -1; - } else { - cache->buf = mail->body; - mail->body = NULL; - } - } - if (mail->fd != -1) { - if (close(mail->fd) < 0) - i_error("close(imapc mail) failed: %m"); - } - if (mail->body != NULL) - buffer_free(&mail->body); - - index_mail_free(_mail); -} - static bool imapc_mail_is_expunged(struct mail *_mail) { struct imapc_mailbox *mbox = (struct imapc_mailbox *)_mail->box; @@ -243,18 +216,37 @@ static void imapc_mail_close(struct mail *_mail) { - struct imapc_mail *imail = (struct imapc_mail *)_mail; - struct imapc_storage *storage = - (struct imapc_storage *)_mail->box->storage; + struct imapc_mail *mail = (struct imapc_mail *)_mail; + struct imapc_mailbox *mbox = (struct imapc_mailbox *)_mail->box; + struct imapc_mail_cache *cache = &mbox->prev_mail_cache; - while (imail->fetch_count > 0) - imapc_storage_run(storage); + while (mail->fetch_count > 0) + imapc_storage_run(mbox->storage); + + if (mail->body_fetched) { + imapc_mail_cache_free(cache); + cache->uid = _mail->uid; + if (cache->fd != -1) { + cache->fd = mail->fd; + mail->fd = -1; + } else { + cache->buf = mail->body; + mail->body = NULL; + } + } + if (mail->fd != -1) { + if (close(mail->fd) < 0) + i_error("close(imapc mail) failed: %m"); + } + if (mail->body != NULL) + buffer_free(&mail->body); + index_mail_close(_mail); } struct mail_vfuncs imapc_mail_vfuncs = { imapc_mail_close, - imapc_mail_free, + index_mail_free, imapc_mail_set_seq, index_mail_set_uid, index_mail_set_uid_cache_updates, From dovecot at dovecot.org Tue Oct 4 17:08:52 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 04 Oct 2011 17:08:52 +0300 Subject: dovecot-2.1: lib-storage: Added mail_get_hdr_stream() and use it... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/276a39ebda4d changeset: 13601:276a39ebda4d user: Timo Sirainen date: Tue Oct 04 17:17:12 2011 +0300 description: lib-storage: Added mail_get_hdr_stream() and use it where possible. This makes it clearer for backends when it needs a message body instead of only message header. diffstat: src/doveadm/doveadm-mail-fetch.c | 2 +- src/imap/imap-fetch-body.c | 34 +++++++++++--------------- src/lib-lda/mail-send.c | 3 +- src/lib-storage/index/cydir/cydir-mail.c | 6 +++- src/lib-storage/index/dbox-common/dbox-mail.c | 3 +- src/lib-storage/index/dbox-common/dbox-mail.h | 3 +- src/lib-storage/index/imapc/imapc-mail.c | 22 +++++++++++----- src/lib-storage/index/index-mail-headers.c | 4 +- src/lib-storage/index/index-mail.c | 8 ++++- src/lib-storage/index/index-search.c | 2 +- src/lib-storage/index/maildir/maildir-mail.c | 9 +++--- src/lib-storage/index/mbox/mbox-mail.c | 2 +- src/lib-storage/index/raw/raw-mail.c | 3 +- src/lib-storage/mail-storage-private.h | 3 +- src/lib-storage/mail-storage.h | 4 +++ src/lib-storage/mail.c | 12 ++++++++- src/lib-storage/test-mail.c | 2 +- src/plugins/virtual/virtual-mail.c | 14 ++++++++-- 18 files changed, 86 insertions(+), 50 deletions(-) diffs (truncated from 386 to 300 lines): diff -r d3b30b82a225 -r 276a39ebda4d src/doveadm/doveadm-mail-fetch.c --- a/src/doveadm/doveadm-mail-fetch.c Tue Oct 04 17:14:30 2011 +0300 +++ b/src/doveadm/doveadm-mail-fetch.c Tue Oct 04 17:17:12 2011 +0300 @@ -105,7 +105,7 @@ size_t size; int ret = 0; - if (mail_get_stream(ctx->mail, &hdr_size, NULL, &input) < 0) + if (mail_get_hdr_stream(ctx->mail, &hdr_size, &input) < 0) return -1; input = i_stream_create_limit(input, hdr_size.physical_size); diff -r d3b30b82a225 -r 276a39ebda4d src/imap/imap-fetch-body.c --- a/src/imap/imap-fetch-body.c Tue Oct 04 17:14:30 2011 +0300 +++ b/src/imap/imap-fetch-body.c Tue Oct 04 17:17:12 2011 +0300 @@ -339,36 +339,28 @@ struct istream *input; struct message_size hdr_size, body_size; - if (body->section[0] == '\0') { + switch (body->section[0]) { + case '\0': + /* BODY[] - fetch everything */ if (mail_get_stream(mail, NULL, NULL, &input) < 0 || mail_get_virtual_size(mail, &body_size.virtual_size) < 0 || mail_get_physical_size(mail, &body_size.physical_size) < 0) return -1; - } else { - if (mail_get_stream(mail, &hdr_size, - body->section[0] == 'H' ? NULL : &body_size, - &input) < 0) - return -1; - } - - ctx->cur_input = input; - i_stream_ref(ctx->cur_input); - ctx->update_partial = TRUE; - - switch (body->section[0]) { - case '\0': - /* BODY[] - fetch everything */ - fetch_size = &body_size; + fetch_size = &body_size; ctx->cur_size_field = MAIL_FETCH_VIRTUAL_SIZE; break; case 'H': /* BODY[HEADER] - fetch only header */ + if (mail_get_hdr_stream(mail, &hdr_size, &input) < 0) + return -1; fetch_size = &hdr_size; ctx->cur_size_field = MAIL_FETCH_MESSAGE_PARTS; break; case 'T': /* BODY[TEXT] - skip header */ - i_stream_skip(ctx->cur_input, hdr_size.physical_size); + if (mail_get_stream(mail, &hdr_size, &body_size, &input) < 0) + return -1; + i_stream_skip(input, hdr_size.physical_size); fetch_size = &body_size; ctx->cur_size_field = MAIL_FETCH_VIRTUAL_SIZE; break; @@ -376,6 +368,10 @@ i_unreached(); } + ctx->cur_input = input; + i_stream_ref(ctx->cur_input); + ctx->update_partial = TRUE; + return fetch_data(ctx, body, fetch_size); } @@ -435,7 +431,7 @@ fetch_body_header_partial(struct imap_fetch_context *ctx, struct mail *mail, const struct imap_fetch_body_data *body) { - if (mail_get_stream(mail, NULL, NULL, &ctx->cur_input) < 0) + if (mail_get_hdr_stream(mail, NULL, &ctx->cur_input) < 0) return -1; i_stream_ref(ctx->cur_input); @@ -922,7 +918,7 @@ struct message_size hdr_size; const char *str; - if (mail_get_stream(mail, &hdr_size, NULL, &ctx->cur_input) < 0) + if (mail_get_hdr_stream(mail, &hdr_size, &ctx->cur_input) < 0) return -1; i_stream_ref(ctx->cur_input); diff -r d3b30b82a225 -r 276a39ebda4d src/lib-lda/mail-send.c --- a/src/lib-lda/mail-send.c Tue Oct 04 17:14:30 2011 +0300 +++ b/src/lib-lda/mail-send.c Tue Oct 04 17:17:12 2011 +0300 @@ -56,7 +56,6 @@ struct istream *input; struct smtp_client *smtp_client; FILE *f; - struct message_size hdr_size; const char *return_addr, *hdr; const unsigned char *data; const char *value, *msgid, *orig_msgid, *boundary; @@ -142,7 +141,7 @@ /* original message's headers */ fprintf(f, "--%s\r\nContent-Type: message/rfc822\r\n\r\n", boundary); - if (mail_get_stream(mail, &hdr_size, NULL, &input) == 0) { + if (mail_get_hdr_stream(mail, NULL, &input) == 0) { /* Note: If you add more headers, they need to be sorted. We'll drop Content-Type because we're not including the message body, and having a multipart Content-Type may confuse some diff -r d3b30b82a225 -r 276a39ebda4d src/lib-storage/index/cydir/cydir-mail.c --- a/src/lib-storage/index/cydir/cydir-mail.c Tue Oct 04 17:14:30 2011 +0300 +++ b/src/lib-storage/index/cydir/cydir-mail.c Tue Oct 04 17:17:12 2011 +0300 @@ -91,8 +91,10 @@ } static int -cydir_mail_get_stream(struct mail *_mail, struct message_size *hdr_size, - struct message_size *body_size, struct istream **stream_r) +cydir_mail_get_stream(struct mail *_mail, bool get_body ATTR_UNUSED, + struct message_size *hdr_size, + struct message_size *body_size, + struct istream **stream_r) { struct index_mail *mail = (struct index_mail *)_mail; const char *path; diff -r d3b30b82a225 -r 276a39ebda4d src/lib-storage/index/dbox-common/dbox-mail.c --- a/src/lib-storage/index/dbox-common/dbox-mail.c Tue Oct 04 17:14:30 2011 +0300 +++ b/src/lib-storage/index/dbox-common/dbox-mail.c Tue Oct 04 17:17:12 2011 +0300 @@ -234,7 +234,8 @@ return dbox_attachment_file_get_stream(file, stream_r); } -int dbox_mail_get_stream(struct mail *_mail, struct message_size *hdr_size, +int dbox_mail_get_stream(struct mail *_mail, bool get_body ATTR_UNUSED, + struct message_size *hdr_size, struct message_size *body_size, struct istream **stream_r) { diff -r d3b30b82a225 -r 276a39ebda4d src/lib-storage/index/dbox-common/dbox-mail.h --- a/src/lib-storage/index/dbox-common/dbox-mail.h Tue Oct 04 17:14:30 2011 +0300 +++ b/src/lib-storage/index/dbox-common/dbox-mail.h Tue Oct 04 17:17:12 2011 +0300 @@ -22,7 +22,8 @@ int dbox_mail_get_save_date(struct mail *_mail, time_t *date_r); int dbox_mail_get_special(struct mail *mail, enum mail_fetch_field field, const char **value_r); -int dbox_mail_get_stream(struct mail *_mail, struct message_size *hdr_size, +int dbox_mail_get_stream(struct mail *_mail, bool get_body ATTR_UNUSED, + struct message_size *hdr_size, struct message_size *body_size, struct istream **stream_r); diff -r d3b30b82a225 -r 276a39ebda4d src/lib-storage/index/imapc/imapc-mail.c --- a/src/lib-storage/index/imapc/imapc-mail.c Tue Oct 04 17:14:30 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mail.c Tue Oct 04 17:17:12 2011 +0300 @@ -134,20 +134,27 @@ } static int -imapc_mail_get_stream(struct mail *_mail, struct message_size *hdr_size, +imapc_mail_get_stream(struct mail *_mail, bool get_body, + struct message_size *hdr_size, struct message_size *body_size, struct istream **stream_r) { - struct index_mail *mail = (struct index_mail *)_mail; - struct index_mail_data *data = &mail->data; + struct imapc_mail *mail = (struct imapc_mail *)_mail; + struct index_mail_data *data = &mail->imail.data; enum mail_fetch_field fetch_field; + if (get_body && !mail->body_fetched && + mail->imail.data.stream != NULL) { + /* we've fetched the header, but we need the body now too */ + i_stream_unref(&mail->imail.data.stream); + } + if (data->stream == NULL) { - if (!mail->data.initialized) { + if (!data->initialized) { /* coming here from mail_set_seq() */ return mail_set_aborted(_mail); } - fetch_field = body_size != NULL || - (mail->wanted_fields & MAIL_FETCH_STREAM_BODY) != 0 ? + fetch_field = get_body || + (mail->imail.wanted_fields & MAIL_FETCH_STREAM_BODY) != 0 ? MAIL_FETCH_STREAM_BODY : MAIL_FETCH_STREAM_HEADER; if (imapc_mail_fetch(_mail, fetch_field) < 0) return -1; @@ -158,7 +165,8 @@ } } - return index_mail_init_stream(mail, hdr_size, body_size, stream_r); + return index_mail_init_stream(&mail->imail, hdr_size, body_size, + stream_r); } static bool diff -r d3b30b82a225 -r 276a39ebda4d src/lib-storage/index/index-mail-headers.c --- a/src/lib-storage/index/index-mail-headers.c Tue Oct 04 17:14:30 2011 +0300 +++ b/src/lib-storage/index/index-mail-headers.c Tue Oct 04 17:17:12 2011 +0300 @@ -412,7 +412,7 @@ old_offset = data->stream == NULL ? 0 : data->stream->v_offset; - if (mail_get_stream(&mail->mail.mail, NULL, NULL, &input) < 0) + if (mail_get_hdr_stream(&mail->mail.mail, NULL, &input) < 0) return -1; index_mail_parse_header_init(mail, headers); @@ -819,7 +819,7 @@ /* not in cache / error */ p_free(mail->data_pool, dest); - if (mail_get_stream(_mail, NULL, NULL, &input) < 0) + if (mail_get_hdr_stream(_mail, NULL, &input) < 0) return -1; if (mail->data.filter_stream != NULL) diff -r d3b30b82a225 -r 276a39ebda4d src/lib-storage/index/index-mail.c --- a/src/lib-storage/index/index-mail.c Tue Oct 04 17:14:30 2011 +0300 +++ b/src/lib-storage/index/index-mail.c Tue Oct 04 17:17:12 2011 +0300 @@ -1320,8 +1320,12 @@ /* open the stream only if we didn't get here from mailbox_save_init() */ hdr = mail_index_get_header(_mail->box->view); - if (!_mail->saving && _mail->uid < hdr->next_uid) - (void)mail_get_stream(_mail, NULL, NULL, &input); + if (!_mail->saving && _mail->uid < hdr->next_uid) { + if ((data->access_part & READ_BODY) != 0) + (void)mail_get_stream(_mail, NULL, NULL, &input); + else + (void)mail_get_hdr_stream(_mail, NULL, &input); + } } if ((mail->wanted_fields & MAIL_FETCH_VIRTUAL_SIZE) != 0 && diff -r d3b30b82a225 -r 276a39ebda4d src/lib-storage/index/index-search.c --- a/src/lib-storage/index/index-search.c Tue Oct 04 17:14:30 2011 +0300 +++ b/src/lib-storage/index/index-search.c Tue Oct 04 17:17:12 2011 +0300 @@ -632,7 +632,7 @@ input = NULL; } else if (have_headers) { /* we need to read the entire header */ - if (mail_get_stream(ctx->cur_mail, NULL, NULL, &input) < 0) + if (mail_get_hdr_stream(ctx->cur_mail, NULL, &input) < 0) failed = TRUE; else { hdr_ctx.parse_headers = diff -r d3b30b82a225 -r 276a39ebda4d src/lib-storage/index/maildir/maildir-mail.c --- a/src/lib-storage/index/maildir/maildir-mail.c Tue Oct 04 17:14:30 2011 +0300 +++ b/src/lib-storage/index/maildir/maildir-mail.c Tue Oct 04 17:17:12 2011 +0300 @@ -550,10 +550,11 @@ } } -static int maildir_mail_get_stream(struct mail *_mail, - struct message_size *hdr_size, - struct message_size *body_size, - struct istream **stream_r) +static int +maildir_mail_get_stream(struct mail *_mail, bool get_body ATTR_UNUSED, + struct message_size *hdr_size, + struct message_size *body_size, + struct istream **stream_r) { struct index_mail *mail = (struct index_mail *)_mail; struct maildir_mailbox *mbox = (struct maildir_mailbox *)_mail->box; diff -r d3b30b82a225 -r 276a39ebda4d src/lib-storage/index/mbox/mbox-mail.c --- a/src/lib-storage/index/mbox/mbox-mail.c Tue Oct 04 17:14:30 2011 +0300 +++ b/src/lib-storage/index/mbox/mbox-mail.c Tue Oct 04 17:17:12 2011 +0300 @@ -361,7 +361,7 @@ return 0; } -static int mbox_mail_get_stream(struct mail *_mail, +static int mbox_mail_get_stream(struct mail *_mail, bool get_body ATTR_UNUSED, struct message_size *hdr_size, struct message_size *body_size, struct istream **stream_r) diff -r d3b30b82a225 -r 276a39ebda4d src/lib-storage/index/raw/raw-mail.c --- a/src/lib-storage/index/raw/raw-mail.c Tue Oct 04 17:14:30 2011 +0300 +++ b/src/lib-storage/index/raw/raw-mail.c Tue Oct 04 17:17:12 2011 +0300 @@ -77,7 +77,8 @@ } static int -raw_mail_get_stream(struct mail *_mail, struct message_size *hdr_size, +raw_mail_get_stream(struct mail *_mail, bool get_body ATTR_UNUSED, + struct message_size *hdr_size, struct message_size *body_size, struct istream **stream_r) { struct index_mail *mail = (struct index_mail *)_mail; diff -r d3b30b82a225 -r 276a39ebda4d src/lib-storage/mail-storage-private.h --- a/src/lib-storage/mail-storage-private.h Tue Oct 04 17:14:30 2011 +0300 +++ b/src/lib-storage/mail-storage-private.h Tue Oct 04 17:17:12 2011 +0300 @@ -300,7 +300,8 @@ int (*get_header_stream)(struct mail *mail, struct mailbox_header_lookup_ctx *headers, From dovecot at dovecot.org Tue Oct 4 17:15:51 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 04 Oct 2011 17:15:51 +0300 Subject: dovecot-2.1: lib-storage: Verify that cached message size matche... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/75f044354386 changeset: 13602:75f044354386 user: Timo Sirainen date: Tue Oct 04 17:22:55 2011 +0300 description: lib-storage: Verify that cached message size matches actually read size. diffstat: src/lib-storage/index/Makefile.am | 4 +- src/lib-storage/index/imapc/imapc-mail-fetch.c | 1 + src/lib-storage/index/index-mail.c | 12 +- src/lib-storage/index/index-mail.h | 1 + src/lib-storage/index/istream-mail-stats.c | 69 ------------- src/lib-storage/index/istream-mail-stats.h | 8 - src/lib-storage/index/istream-mail.c | 129 +++++++++++++++++++++++++ src/lib-storage/index/istream-mail.h | 7 + 8 files changed, 149 insertions(+), 82 deletions(-) diffs (truncated from 308 to 300 lines): diff -r 276a39ebda4d -r 75f044354386 src/lib-storage/index/Makefile.am --- a/src/lib-storage/index/Makefile.am Tue Oct 04 17:17:12 2011 +0300 +++ b/src/lib-storage/index/Makefile.am Tue Oct 04 17:22:55 2011 +0300 @@ -13,7 +13,7 @@ libstorage_index_la_SOURCES = \ istream-attachment.c \ - istream-mail-stats.c \ + istream-mail.c \ index-attachment.c \ index-mail.c \ index-mail-headers.c \ @@ -37,7 +37,7 @@ headers = \ istream-attachment.h \ - istream-mail-stats.h \ + istream-mail.h \ index-attachment.h \ index-mail.h \ index-search-private.h \ diff -r 276a39ebda4d -r 75f044354386 src/lib-storage/index/imapc/imapc-mail-fetch.c --- a/src/lib-storage/index/imapc/imapc-mail-fetch.c Tue Oct 04 17:17:12 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mail-fetch.c Tue Oct 04 17:22:55 2011 +0300 @@ -266,6 +266,7 @@ imail->data.virtual_size = size; } + imail->data.stream_has_only_header = !have_body; if (index_mail_init_stream(imail, NULL, NULL, &input) < 0) i_stream_unref(&imail->data.stream); } diff -r 276a39ebda4d -r 75f044354386 src/lib-storage/index/index-mail.c --- a/src/lib-storage/index/index-mail.c Tue Oct 04 17:17:12 2011 +0300 +++ b/src/lib-storage/index/index-mail.c Tue Oct 04 17:22:55 2011 +0300 @@ -14,7 +14,7 @@ #include "mail-cache.h" #include "mail-index-modseq.h" #include "index-storage.h" -#include "istream-mail-stats.h" +#include "istream-mail.h" #include "index-mail.h" #include @@ -837,8 +837,8 @@ if (!data->initialized_wrapper_stream && _mail->transaction->stats_track) { - input = i_stream_create_mail_stats_counter(_mail->transaction, - data->stream); + input = i_stream_create_mail(_mail, data->stream, + !data->stream_has_only_header); i_stream_unref(&data->stream); data->stream = input; data->initialized_wrapper_stream = TRUE; @@ -1616,6 +1616,12 @@ case 0: field_name = "fields"; break; + case MAIL_FETCH_PHYSICAL_SIZE: + field_name = "physical size"; + imail->data.physical_size = (uoff_t)-1; + imail->data.virtual_size = (uoff_t)-1; + imail->data.parts = NULL; + break; case MAIL_FETCH_VIRTUAL_SIZE: field_name = "virtual size"; imail->data.physical_size = (uoff_t)-1; diff -r 276a39ebda4d -r 75f044354386 src/lib-storage/index/index-mail.h --- a/src/lib-storage/index/index-mail.h Tue Oct 04 17:17:12 2011 +0300 +++ b/src/lib-storage/index/index-mail.h Tue Oct 04 17:22:55 2011 +0300 @@ -105,6 +105,7 @@ unsigned int save_bodystructure_header:1; unsigned int save_bodystructure_body:1; unsigned int save_message_parts:1; + unsigned int stream_has_only_header:1; unsigned int parsed_bodystructure:1; unsigned int hdr_size_set:1; unsigned int body_size_set:1; diff -r 276a39ebda4d -r 75f044354386 src/lib-storage/index/istream-mail-stats.c --- a/src/lib-storage/index/istream-mail-stats.c Tue Oct 04 17:17:12 2011 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* Copyright (c) 2009-2011 Dovecot authors, see the included COPYING file */ - -#include "lib.h" -#include "mail-storage-private.h" -#include "istream-private.h" -#include "istream-mail-stats.h" - -struct mail_stats_istream { - struct istream_private istream; - - struct mailbox_transaction_context *trans; - unsigned int files_read_increased:1; -}; - -static ssize_t -i_stream_mail_stats_read_mail_stats(struct istream_private *stream) -{ - struct mail_stats_istream *mstream = - (struct mail_stats_istream *)stream; - ssize_t ret; - - i_stream_seek(stream->parent, stream->parent_start_offset + - stream->istream.v_offset); - - ret = i_stream_read_copy_from_parent(&stream->istream); - if (ret > 0) { - mstream->trans->stats.files_read_bytes += ret; - if (!mstream->files_read_increased) { - mstream->files_read_increased = TRUE; - mstream->trans->stats.files_read_count++; - } - } - return ret; -} - -static void -i_stream_mail_stats_seek(struct istream_private *stream, - uoff_t v_offset, bool mark ATTR_UNUSED) -{ - stream->istream.v_offset = v_offset; - stream->skip = stream->pos = 0; -} - -static const struct stat * -i_stream_mail_stats_stat(struct istream_private *stream, bool exact) -{ - return i_stream_stat(stream->parent, exact); -} - -struct istream * -i_stream_create_mail_stats_counter(struct mailbox_transaction_context *trans, - struct istream *input) -{ - struct mail_stats_istream *mstream; - - mstream = i_new(struct mail_stats_istream, 1); - mstream->trans = trans; - mstream->istream.max_buffer_size = input->real_stream->max_buffer_size; - - mstream->istream.parent = input; - mstream->istream.read = i_stream_mail_stats_read_mail_stats; - mstream->istream.seek = i_stream_mail_stats_seek; - mstream->istream.stat = i_stream_mail_stats_stat; - - mstream->istream.istream.blocking = input->blocking; - mstream->istream.istream.seekable = input->seekable; - return i_stream_create(&mstream->istream, input, - i_stream_get_fd(input)); -} diff -r 276a39ebda4d -r 75f044354386 src/lib-storage/index/istream-mail-stats.h --- a/src/lib-storage/index/istream-mail-stats.h Tue Oct 04 17:17:12 2011 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -#ifndef ISTREAM_MAIL_STATS_H -#define ISTREAM_MAIL_STATS_H - -struct istream * -i_stream_create_mail_stats_counter(struct mailbox_transaction_context *trans, - struct istream *input); - -#endif diff -r 276a39ebda4d -r 75f044354386 src/lib-storage/index/istream-mail.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-storage/index/istream-mail.c Tue Oct 04 17:22:55 2011 +0300 @@ -0,0 +1,129 @@ +/* Copyright (c) 2009-2011 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "mail-storage-private.h" +#include "istream-private.h" +#include "index-mail.h" +#include "istream-mail.h" + +struct mail_istream { + struct istream_private istream; + + struct mail *mail; + uoff_t expected_size; + unsigned int files_read_increased:1; + unsigned int input_has_body:1; +}; + +static bool i_stream_mail_try_get_cached_size(struct mail_istream *mstream) +{ + struct mail *mail = mstream->mail; + enum mail_lookup_abort orig_lookup_abort; + + if (mstream->expected_size != (uoff_t)-1) + return TRUE; + + orig_lookup_abort = mail->lookup_abort; + mail->lookup_abort = MAIL_LOOKUP_ABORT_NOT_IN_CACHE; + if (mail_get_physical_size(mail, &mstream->expected_size) < 0) + mstream->expected_size = (uoff_t)-1; + mail->lookup_abort = orig_lookup_abort; + return mstream->expected_size != (uoff_t)-1; +} + +static void +i_stream_mail_set_size_corrupted(struct mail_istream *mstream, size_t size) +{ + uoff_t cur_size = mstream->istream.istream.v_offset + size; + const char *str; + char chr; + + if (mstream->expected_size < cur_size) { + str = "smaller"; + chr = '<'; + } else { + str = "larger"; + chr = '>'; + } + + mail_storage_set_critical(mstream->mail->box->storage, + "Cached message size %s than expected " + "(%"PRIuUOFF_T" %c %"PRIuUOFF_T")", str, + mstream->expected_size, chr, cur_size); + index_mail_set_cache_corrupted(mstream->mail, MAIL_FETCH_PHYSICAL_SIZE); + mstream->istream.istream.stream_errno = EIO; +} + +static ssize_t +i_stream_mail_read(struct istream_private *stream) +{ + struct mail_istream *mstream = (struct mail_istream *)stream; + size_t size; + ssize_t ret; + + i_stream_seek(stream->parent, stream->parent_start_offset + + stream->istream.v_offset); + + ret = i_stream_read_copy_from_parent(&stream->istream); + (void)i_stream_get_data(&stream->istream, &size); + if (ret > 0) { + mstream->mail->transaction->stats.files_read_bytes += ret; + if (!mstream->files_read_increased) { + mstream->files_read_increased = TRUE; + mstream->mail->transaction->stats.files_read_count++; + } + if (mstream->expected_size < stream->istream.v_offset + size) { + i_stream_mail_set_size_corrupted(mstream, size); + return -1; + } + } else if (ret < 0 && stream->istream.eof) { + if (!mstream->input_has_body) { + /* trying to read past the header, but this stream + doesn't have the body */ + return -1; + } + if (i_stream_mail_try_get_cached_size(mstream) && + mstream->expected_size > stream->istream.v_offset + size) { + i_stream_mail_set_size_corrupted(mstream, size); + return -1; + } + } + return ret; +} + +static void +i_stream_mail_seek(struct istream_private *stream, + uoff_t v_offset, bool mark ATTR_UNUSED) +{ + stream->istream.v_offset = v_offset; + stream->skip = stream->pos = 0; +} + +static const struct stat * +i_stream_mail_stat(struct istream_private *stream, bool exact) +{ + return i_stream_stat(stream->parent, exact); +} + +struct istream *i_stream_create_mail(struct mail *mail, struct istream *input, + bool input_has_body) +{ + struct mail_istream *mstream; + + mstream = i_new(struct mail_istream, 1); + mstream->mail = mail; + mstream->input_has_body = input_has_body; + mstream->expected_size = (uoff_t)-1; + (void)i_stream_mail_try_get_cached_size(mstream); + mstream->istream.max_buffer_size = input->real_stream->max_buffer_size; + + mstream->istream.parent = input; + mstream->istream.read = i_stream_mail_read; + mstream->istream.seek = i_stream_mail_seek; + mstream->istream.stat = i_stream_mail_stat; + + mstream->istream.istream.blocking = input->blocking; + mstream->istream.istream.seekable = input->seekable; + return i_stream_create(&mstream->istream, input, + i_stream_get_fd(input)); +} diff -r 276a39ebda4d -r 75f044354386 src/lib-storage/index/istream-mail.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-storage/index/istream-mail.h Tue Oct 04 17:22:55 2011 +0300 From dovecot at dovecot.org Wed Oct 5 15:48:46 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 05 Oct 2011 15:48:46 +0300 Subject: dovecot-2.1: raw storage: Don't crash with mailbox_get_metadata() Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/ae1f8bae28eb changeset: 13603:ae1f8bae28eb user: Timo Sirainen date: Wed Oct 05 15:57:03 2011 +0300 description: raw storage: Don't crash with mailbox_get_metadata() diffstat: src/lib-storage/index/raw/raw-storage.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 75f044354386 -r ae1f8bae28eb src/lib-storage/index/raw/raw-storage.c --- a/src/lib-storage/index/raw/raw-storage.c Tue Oct 04 17:22:55 2011 +0300 +++ b/src/lib-storage/index/raw/raw-storage.c Wed Oct 05 15:57:03 2011 +0300 @@ -217,7 +217,7 @@ index_storage_mailbox_delete, index_storage_mailbox_rename, index_storage_get_status, - NULL, + index_mailbox_get_metadata, index_storage_list_index_has_changed, index_storage_list_index_update_sync, raw_storage_sync_init, From dovecot at dovecot.org Wed Oct 5 17:13:33 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 05 Oct 2011 17:13:33 +0300 Subject: dovecot-2.1: imapc: Fixed "Bad file descriptor" errors after mai... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/f2732fa01394 changeset: 13604:f2732fa01394 user: Timo Sirainen date: Wed Oct 05 17:21:46 2011 +0300 description: imapc: Fixed "Bad file descriptor" errors after mail was closed. diffstat: src/lib-storage/index/imapc/imapc-mail.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r ae1f8bae28eb -r f2732fa01394 src/lib-storage/index/imapc/imapc-mail.c --- a/src/lib-storage/index/imapc/imapc-mail.c Wed Oct 05 15:57:03 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mail.c Wed Oct 05 17:21:46 2011 +0300 @@ -245,6 +245,7 @@ if (mail->fd != -1) { if (close(mail->fd) < 0) i_error("close(imapc mail) failed: %m"); + mail->fd = -1; } if (mail->body != NULL) buffer_free(&mail->body); From dovecot at dovecot.org Wed Oct 5 17:44:58 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 05 Oct 2011 17:44:58 +0300 Subject: dovecot-2.1: imapc: Fixed potential assert-crash when saving a m... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/0602a0d36164 changeset: 13605:0602a0d36164 user: Timo Sirainen date: Wed Oct 05 17:34:16 2011 +0300 description: imapc: Fixed potential assert-crash when saving a mail. diffstat: src/lib-storage/index/imapc/imapc-save.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r f2732fa01394 -r 0602a0d36164 src/lib-storage/index/imapc/imapc-save.c --- a/src/lib-storage/index/imapc/imapc-save.c Wed Oct 05 17:21:46 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-save.c Wed Oct 05 17:34:16 2011 +0300 @@ -146,6 +146,7 @@ messages to remote server during our transaction */ mail_index_append(ctx->trans, uid, &seq); mail_set_seq_saving(_mail, seq); + imail->data.no_caching = TRUE; imail->data.forced_no_caching = TRUE; if (ctx->fd != -1) { From dovecot at dovecot.org Wed Oct 5 17:44:58 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 05 Oct 2011 17:44:58 +0300 Subject: dovecot-2.1: imapc: Fixed closing mail properly. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/e026ff4467a8 changeset: 13606:e026ff4467a8 user: Timo Sirainen date: Wed Oct 05 17:34:51 2011 +0300 description: imapc: Fixed closing mail properly. diffstat: src/lib-storage/index/imapc/imapc-mail.c | 6 ++-- src/lib-storage/index/index-mail.c | 34 ++++++++++++++++++------------- src/lib-storage/index/index-mail.h | 1 + 3 files changed, 24 insertions(+), 17 deletions(-) diffs (95 lines): diff -r 0602a0d36164 -r e026ff4467a8 src/lib-storage/index/imapc/imapc-mail.c --- a/src/lib-storage/index/imapc/imapc-mail.c Wed Oct 05 17:34:16 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mail.c Wed Oct 05 17:34:51 2011 +0300 @@ -145,7 +145,7 @@ if (get_body && !mail->body_fetched && mail->imail.data.stream != NULL) { /* we've fetched the header, but we need the body now too */ - i_stream_unref(&mail->imail.data.stream); + index_mail_close_streams(&mail->imail); } if (data->stream == NULL) { @@ -231,6 +231,8 @@ while (mail->fetch_count > 0) imapc_storage_run(mbox->storage); + index_mail_close(_mail); + if (mail->body_fetched) { imapc_mail_cache_free(cache); cache->uid = _mail->uid; @@ -249,8 +251,6 @@ } if (mail->body != NULL) buffer_free(&mail->body); - - index_mail_close(_mail); } struct mail_vfuncs imapc_mail_vfuncs = { diff -r 0602a0d36164 -r e026ff4467a8 src/lib-storage/index/index-mail.c --- a/src/lib-storage/index/index-mail.c Wed Oct 05 17:34:16 2011 +0300 +++ b/src/lib-storage/index/index-mail.c Wed Oct 05 17:34:51 2011 +0300 @@ -1126,10 +1126,28 @@ } } +void index_mail_close_streams(struct index_mail *mail) +{ + struct message_part *parts; + + if (mail->data.parser_ctx != NULL) { + if (message_parser_deinit(&mail->data.parser_ctx, &parts) < 0) { + mail_set_cache_corrupted(&mail->mail.mail, + MAIL_FETCH_MESSAGE_PARTS); + } + } + if (mail->data.filter_stream != NULL) + i_stream_unref(&mail->data.filter_stream); + if (mail->data.stream != NULL) { + mail->data.destroying_stream = TRUE; + i_stream_unref(&mail->data.stream); + i_assert(!mail->data.destroying_stream); + } +} + void index_mail_close(struct mail *_mail) { struct index_mail *mail = (struct index_mail *)_mail; - struct message_part *parts; /* If uid == 0 but seq != 0, we came here from saving a (non-mbox) message. If that happens, don't bother checking if anything should @@ -1141,19 +1159,7 @@ index_mail_cache_dates(mail); } - if (mail->data.parser_ctx != NULL) { - if (message_parser_deinit(&mail->data.parser_ctx, &parts) < 0) { - mail_set_cache_corrupted(_mail, - MAIL_FETCH_MESSAGE_PARTS); - } - } - if (mail->data.filter_stream != NULL) - i_stream_unref(&mail->data.filter_stream); - if (mail->data.stream != NULL) { - mail->data.destroying_stream = TRUE; - i_stream_unref(&mail->data.stream); - i_assert(!mail->data.destroying_stream); - } + index_mail_close_streams(mail); } static void index_mail_reset(struct index_mail *mail) diff -r 0602a0d36164 -r e026ff4467a8 src/lib-storage/index/index-mail.h --- a/src/lib-storage/index/index-mail.h Wed Oct 05 17:34:16 2011 +0300 +++ b/src/lib-storage/index/index-mail.h Wed Oct 05 17:34:51 2011 +0300 @@ -162,6 +162,7 @@ void index_mail_set_uid_cache_updates(struct mail *mail, bool set); bool index_mail_prefetch(struct mail *mail); void index_mail_close(struct mail *mail); +void index_mail_close_streams(struct index_mail *mail); void index_mail_free(struct mail *mail); bool index_mail_want_parse_headers(struct index_mail *mail); From dovecot at dovecot.org Wed Oct 5 17:44:58 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 05 Oct 2011 17:44:58 +0300 Subject: dovecot-2.1: imapc: Memory leak fixes. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/186910f65582 changeset: 13607:186910f65582 user: Timo Sirainen date: Wed Oct 05 17:51:01 2011 +0300 description: imapc: Memory leak fixes. diffstat: src/lib-storage/index/imapc/imapc-list.c | 2 ++ src/lib-storage/index/imapc/imapc-mail-fetch.c | 1 + 2 files changed, 3 insertions(+), 0 deletions(-) diffs (23 lines): diff -r e026ff4467a8 -r 186910f65582 src/lib-storage/index/imapc/imapc-list.c --- a/src/lib-storage/index/imapc/imapc-list.c Wed Oct 05 17:34:51 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-list.c Wed Oct 05 17:51:01 2011 +0300 @@ -40,6 +40,8 @@ { struct imapc_mailbox_list *list = (struct imapc_mailbox_list *)_list; + if (list->index_list != NULL) + mailbox_list_destroy(&list->index_list); mailbox_tree_deinit(&list->mailboxes); if (list->tmp_subscriptions != NULL) mailbox_tree_deinit(&list->tmp_subscriptions); diff -r e026ff4467a8 -r 186910f65582 src/lib-storage/index/imapc/imapc-mail-fetch.c --- a/src/lib-storage/index/imapc/imapc-mail-fetch.c Wed Oct 05 17:34:51 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mail-fetch.c Wed Oct 05 17:51:01 2011 +0300 @@ -47,6 +47,7 @@ mail_storage_set_critical(&mbox->storage->storage, "imapc: Mail prefetch failed: %s", reply->text_full); } + pool_unref(&mail->imail.mail.pool); imapc_client_stop(mbox->storage->client); } From dovecot at dovecot.org Wed Oct 5 17:44:58 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 05 Oct 2011 17:44:58 +0300 Subject: dovecot-2.1: lib-storage: Fixed reopening a mail stream. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/fab95106bcd6 changeset: 13608:fab95106bcd6 user: Timo Sirainen date: Wed Oct 05 17:51:32 2011 +0300 description: lib-storage: Fixed reopening a mail stream. diffstat: src/lib-storage/index/index-mail.c | 20 ++++++++++++-------- 1 files changed, 12 insertions(+), 8 deletions(-) diffs (36 lines): diff -r 186910f65582 -r fab95106bcd6 src/lib-storage/index/index-mail.c --- a/src/lib-storage/index/index-mail.c Wed Oct 05 17:51:01 2011 +0300 +++ b/src/lib-storage/index/index-mail.c Wed Oct 05 17:51:32 2011 +0300 @@ -1128,20 +1128,24 @@ void index_mail_close_streams(struct index_mail *mail) { + struct index_mail_data *data = &mail->data; struct message_part *parts; - if (mail->data.parser_ctx != NULL) { - if (message_parser_deinit(&mail->data.parser_ctx, &parts) < 0) { + if (data->parser_ctx != NULL) { + if (message_parser_deinit(&data->parser_ctx, &parts) < 0) { mail_set_cache_corrupted(&mail->mail.mail, MAIL_FETCH_MESSAGE_PARTS); } } - if (mail->data.filter_stream != NULL) - i_stream_unref(&mail->data.filter_stream); - if (mail->data.stream != NULL) { - mail->data.destroying_stream = TRUE; - i_stream_unref(&mail->data.stream); - i_assert(!mail->data.destroying_stream); + if (data->filter_stream != NULL) + i_stream_unref(&data->filter_stream); + if (data->stream != NULL) { + data->destroying_stream = TRUE; + i_stream_unref(&data->stream); + i_assert(!data->destroying_stream); + + data->initialized_wrapper_stream = FALSE; + data->destroy_callback_set = FALSE; } } From dovecot at dovecot.org Wed Oct 5 17:47:10 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 05 Oct 2011 17:47:10 +0300 Subject: dovecot-2.1: imapc: Fixed fetching data for a saved, but uncommi... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/09707b608d8d changeset: 13609:09707b608d8d user: Timo Sirainen date: Wed Oct 05 17:55:29 2011 +0300 description: imapc: Fixed fetching data for a saved, but uncommitted, mail. diffstat: src/lib-storage/index/imapc/imapc-mail-fetch.c | 29 ++++++++++++++----------- src/lib-storage/index/imapc/imapc-storage.c | 9 ++++--- src/lib-storage/index/imapc/imapc-storage.h | 1 + 3 files changed, 22 insertions(+), 17 deletions(-) diffs (73 lines): diff -r fab95106bcd6 -r 09707b608d8d src/lib-storage/index/imapc/imapc-mail-fetch.c --- a/src/lib-storage/index/imapc/imapc-mail-fetch.c Wed Oct 05 17:51:32 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mail-fetch.c Wed Oct 05 17:55:29 2011 +0300 @@ -68,20 +68,23 @@ if (fields == 0) return 0; - if (_mail->saving) { - mail_storage_set_critical(_mail->box->storage, - "Can't fetch data from uncommitted message"); - return -1; - } + if (!_mail->saving) { + /* if we already know that the mail is expunged, + don't try to FETCH it */ + view = mbox->delayed_sync_view != NULL ? + mbox->delayed_sync_view : mbox->box.view; + if (!mail_index_lookup_seq(view, _mail->uid, &seq) || + mail_index_is_expunged(view, seq)) { + mail_set_expunged(_mail); + return -1; + } + } else if (mbox->client_box == NULL) { + /* opened as save-only. we'll need to fetch the mail, + so actually SELECT/EXAMINE the mailbox */ + i_assert(mbox->box.opened); - /* if we already know that the mail is expunged, - don't try to FETCH it */ - view = mbox->delayed_sync_view != NULL ? - mbox->delayed_sync_view : mbox->box.view; - if (!mail_index_lookup_seq(view, _mail->uid, &seq) || - mail_index_is_expunged(view, seq)) { - mail_set_expunged(_mail); - return -1; + if (imapc_mailbox_select(mbox) < 0) + return -1; } if ((fields & MAIL_FETCH_STREAM_BODY) != 0) diff -r fab95106bcd6 -r 09707b608d8d src/lib-storage/index/imapc/imapc-storage.c --- a/src/lib-storage/index/imapc/imapc-storage.c Wed Oct 05 17:51:32 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-storage.c Wed Oct 05 17:55:29 2011 +0300 @@ -383,13 +383,14 @@ imapc_client_stop(ctx->mbox->storage->client); } -static int imapc_mailbox_select(struct imapc_mailbox *mbox) +int imapc_mailbox_select(struct imapc_mailbox *mbox) { struct imapc_open_context ctx; - bool examine; + bool examine = TRUE; - examine = (mbox->box.flags & MAILBOX_FLAG_READONLY) != 0 && - (mbox->box.flags & MAILBOX_FLAG_DROP_RECENT) == 0; + examine = (mbox->box.flags & MAILBOX_FLAG_DROP_RECENT) == 0 && + ((mbox->box.flags & MAILBOX_FLAG_READONLY) != 0 || + (mbox->box.flags & MAILBOX_FLAG_SAVEONLY) != 0); mbox->selecting = TRUE; ctx.mbox = mbox; diff -r fab95106bcd6 -r 09707b608d8d src/lib-storage/index/imapc/imapc-storage.h --- a/src/lib-storage/index/imapc/imapc-storage.h Wed Oct 05 17:51:32 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-storage.h Wed Oct 05 17:55:29 2011 +0300 @@ -105,6 +105,7 @@ void imapc_storage_run(struct imapc_storage *storage); void imapc_mail_cache_free(struct imapc_mail_cache *cache); +int imapc_mailbox_select(struct imapc_mailbox *mbox); void imapc_copy_error_from_reply(struct imapc_storage *storage, enum mail_error default_error, From pigeonhole at rename-it.nl Wed Oct 5 18:43:41 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Wed, 05 Oct 2011 17:43:41 +0200 Subject: dovecot-2.0-pigeonhole: lib-sieve: vacation extension: made disc... Message-ID: details: http://hg.rename-it.nl/dovecot-2.0-pigeonhole/rev/936f29175330 changeset: 1539:936f29175330 user: Stephan Bosch date: Wed Oct 05 17:43:37 2011 +0200 description: lib-sieve: vacation extension: made discard message for implicit deliver more verbose. diffstat: src/lib-sieve/plugins/vacation/cmd-vacation.c | 16 ++++++++++++++-- 1 files changed, 14 insertions(+), 2 deletions(-) diffs (28 lines): diff -r e10d402769fb -r 936f29175330 src/lib-sieve/plugins/vacation/cmd-vacation.c --- a/src/lib-sieve/plugins/vacation/cmd-vacation.c Wed Sep 21 11:33:00 2011 +0200 +++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c Wed Oct 05 17:43:37 2011 +0200 @@ -1184,10 +1184,22 @@ /* My address not found in the headers; we got an implicit delivery */ if ( *hdsp == NULL ) { + const char *original_recipient = ""; + /* No, bail out */ + + if ( config->use_original_recipient ) { + original_recipient = t_strdup_printf("original recipient = <%s>; ", + ( orig_recipient == NULL ? "UNAVAILABLE" : str_sanitize(orig_recipient, 128) )); + } + sieve_result_global_log(aenv, - "discarding vacation response for message implicitly delivered to <%s>", - recipient ); + "discarding vacation response for implicitly delivered message " + "(no known recipient address found in message headers: " + "recipient = <%s>; %sadditional :addresses are%s specified)", + str_sanitize(recipient, 128), original_recipient, + (ctx->addresses == NULL ? " not" : "")); + return TRUE; } } From dovecot at dovecot.org Wed Oct 5 18:39:37 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 05 Oct 2011 18:39:37 +0300 Subject: dovecot-2.1: pop3: When pop3_fast_size_lookups=yes, don't assume... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/a70f6f04f1fe changeset: 13610:a70f6f04f1fe user: Timo Sirainen date: Wed Oct 05 18:47:56 2011 +0300 description: pop3: When pop3_fast_size_lookups=yes, don't assume we need to fetch virtual size. This fixes prefetch unnecessarily opening mail files. diffstat: src/pop3/pop3-client.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 09707b608d8d -r a70f6f04f1fe src/pop3/pop3-client.c --- a/src/pop3/pop3-client.c Wed Oct 05 17:55:29 2011 +0300 +++ b/src/pop3/pop3-client.c Wed Oct 05 18:47:56 2011 +0300 @@ -151,6 +151,7 @@ search_args = mail_search_build_init(); mail_search_build_add_all(search_args); ctx = mailbox_search_init(t, search_args, pop3_sort_program, + client->set->pop3_fast_size_lookups ? 0 : MAIL_FETCH_VIRTUAL_SIZE, NULL); mail_search_args_unref(&search_args); From pigeonhole at rename-it.nl Wed Oct 5 19:45:21 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Wed, 05 Oct 2011 18:45:21 +0200 Subject: dovecot-2.0-pigeonhole: Updated documentation of sieve tools. Message-ID: details: http://hg.rename-it.nl/dovecot-2.0-pigeonhole/rev/78e92af7aa61 changeset: 1540:78e92af7aa61 user: Stephan Bosch date: Wed Oct 05 18:45:10 2011 +0200 description: Updated documentation of sieve tools. diffstat: doc/man/sieve-dump.1.in | 4 ++-- doc/man/sieve-filter.1.in | 4 ++-- doc/man/sieve-test.1.in | 30 ++++++++++++++++++++++-------- doc/man/sievec.1.in | 13 +++++++------ src/sieve-tools/sieve-dump.c | 2 +- src/sieve-tools/sieve-test.c | 3 ++- src/sieve-tools/sievec.c | 2 +- 7 files changed, 37 insertions(+), 21 deletions(-) diffs (182 lines): diff -r 936f29175330 -r 78e92af7aa61 doc/man/sieve-dump.1.in --- a/doc/man/sieve-dump.1.in Wed Oct 05 17:43:37 2011 +0200 +++ b/doc/man/sieve-dump.1.in Wed Oct 05 18:45:10 2011 +0200 @@ -1,5 +1,5 @@ .\" Copyright (c) 2010-2011 Pigeonhole authors, see the included COPYING file -.TH "SIEVE\-DUMP" 1 "2011-06-21" "Pigeonhole for Dovecot v2.0" "Pigeonhole" +.TH "SIEVE\-DUMP" 1 "2011-10-04" "Pigeonhole for Dovecot v2.0" "Pigeonhole" .\"------------------------------------------------------------------------ .SH NAME sieve\-dump \- Pigeonhole\(aqs Sieve script binary dump tool @@ -72,7 +72,7 @@ will exit with one of the following values: .TP 4 .B 0 -Dump was successful. (EX_OK, EXIT_SUCCES) +Dump was successful. (EX_OK, EXIT_SUCCESS) .TP .B 1 Operation failed. This is returned for almost all failures. diff -r 936f29175330 -r 78e92af7aa61 doc/man/sieve-filter.1.in --- a/doc/man/sieve-filter.1.in Wed Oct 05 17:43:37 2011 +0200 +++ b/doc/man/sieve-filter.1.in Wed Oct 05 18:45:10 2011 +0200 @@ -1,5 +1,5 @@ .\" Copyright (c) 2010-2011 Pigeonhole authors, see the included COPYING file -.TH "SIEVE\-FILTER" 1 "2011-02-23" "Pigeonhole for Dovecot v2.0" "Pigeonhole" +.TH "SIEVE\-FILTER" 1 "2011-10-04" "Pigeonhole for Dovecot v2.0" "Pigeonhole" .SH NAME sieve\-filter \- Pigeonhole\(aqs Sieve mailbox filter tool @@ -196,7 +196,7 @@ will exit with one of the following values: .TP 4 .B 0 -Sieve filter applied successfully. (EX_OK, EXIT_SUCCES) +Sieve filter applied successfully. (EX_OK, EXIT_SUCCESS) .TP .B 1 Operation failed. This is returned for almost all failures. diff -r 936f29175330 -r 78e92af7aa61 doc/man/sieve-test.1.in --- a/doc/man/sieve-test.1.in Wed Oct 05 17:43:37 2011 +0200 +++ b/doc/man/sieve-test.1.in Wed Oct 05 18:45:10 2011 +0200 @@ -1,5 +1,5 @@ .\" Copyright (c) 2010-2011 Pigeonhole authors, see the included COPYING file -.TH "SIEVE\-TEST" 1 "2011-06-21" "Pigeonhole for Dovecot v2.0" "Pigeonhole" +.TH "SIEVE\-TEST" 1 "2011-10-04" "Pigeonhole for Dovecot v2.0" "Pigeonhole" .SH NAME sieve\-test \- Pigeonhole\(aqs Sieve script tester .\"------------------------------------------------------------------------ @@ -32,6 +32,15 @@ .\"------------------------------------------------------------------------ .SH OPTIONS .TP +.BI \-a\ orig\-recipient\-address +The original envelope recipient address. This is what Sieve\(aqs envelope test +will compare to when the \(dqto\(dq envelope part is requested. Some tests and +actions will also use this as the script owner\(aqs e\-mail address. If this +option is omitted, the recipient address is retrieved from the +\(dqEnvelope-To:\(dq, or \(dqTo:\(dq message headers. If none of these headers +is present either, the recipient address defaults to +\fIrecipient at example.com\fP. +.TP .BI \-c\ config\-file Alternative Dovecot configuration file path. .TP @@ -58,9 +67,12 @@ SMTP recipients. Such actions only print the outgoing message to \fBstdout\fP. .TP .BI \-f\ envelope\-sender -The envelope sender or return path. This is what Sieve\(aqs envelope test will -compare to when the \(dqfrom\(dq envelope part is requested. Also, this is -where response messages are sent to. +The envelope sender address (return path). This is what Sieve\(aqs envelope test +will compare to when the \(dqfrom\(dq envelope part is requested. Also, this is +where response messages are \(aqsent\(aq to. If this option is omitted, the sender +address is retrieved from the \(dqReturn-Path:\(dq, \(dqSender:\(dq or +\(dqFrom:\(dq message headers. If none of these headers is present either, +the sender envelope address defaults to \fIsender at example.com\fP. .TP .BI \-l\ mail\-location The location of the user\(aqs mail store. The syntax of this option\(aqs @@ -75,9 +87,11 @@ by default. .TP .BI \-r\ recipient\-address -The envelope recipient address. This is what Sieve\(aqs envelope test will compare -to when the \(dqto\(dq envelope part is requested. Some tests and actions will also -use this as the owner\(aqs e\-mail address. +The final envelope recipient address. Some tests and actions will +use this as the script owner\(aqs e\-mail address. For example, this is what is +used by the vacation action to check whether a reply is appropriate. If the +\fB\-r\fP option is omitted, the orignal envelope recipient address will be used +in stead (see \fB\-a\fP option for more info). .TP .BI \-s\ script\-file Specify additional scripts to be executed before the main script. Multiple @@ -196,7 +210,7 @@ will exit with one of the following values: .TP 4 .B 0 -Execution was successful. (EX_OK, EXIT_SUCCES) +Execution was successful. (EX_OK, EXIT_SUCCESS) .TP .B 1 Operation failed. This is returned for almost all failures. diff -r 936f29175330 -r 78e92af7aa61 doc/man/sievec.1.in --- a/doc/man/sievec.1.in Wed Oct 05 17:43:37 2011 +0200 +++ b/doc/man/sievec.1.in Wed Oct 05 18:45:10 2011 +0200 @@ -1,5 +1,5 @@ .\" Copyright (c) 2010-2011 Pigeonhole authors, see the included COPYING file -.TH "SIEVEC" 1 "2011-06-21" "Pigeonhole for Dovecot v2.0" "Pigeonhole" +.TH "SIEVEC" 1 "2011-10-04" "Pigeonhole for Dovecot v2.0" "Pigeonhole" .\"------------------------------------------------------------------------ .SH NAME sievec \- Pigeonhole\(aqs Sieve script compiler @@ -32,7 +32,8 @@ extension as Sieve scripts and corresponding files with a \fB.svbin\fP extension as the associated compiled binary. This means for example that Dovecot\(aqs LDA process will first look for a binary file \(dqdovecot.svbin\(dq when it needs to -execute \(dqdovecot.sieve\(dq. It will compile a new binary when it is missing. +execute \(dqdovecot.sieve\(dq. It will compile a new binary when it is missing +or outdated. .PP The \fBsievec\fP command is also useful to verify Sieve scripts before using. Additionally, with the \fB\-d\fP option it can output a textual (and thus @@ -82,16 +83,16 @@ .TP .I out\-file Specifies where the (binary) output is to be written. This argument is optional. -If omitted a binary compiled from .sieve is saved as -.svbin. If \fB\-b\fP is specified, the binary dump is output to -\fBstdout\fP. +If this argument is omitted, a binary compiled from .sieve is saved +as .svbin. If this argument is omitted and \fB\-b\fP is specified, +the binary dump is output to \fBstdout\fP. .\"------------------------------------------------------------------------ .SH "EXIT STATUS" .B sievec will exit with one of the following values: .TP 4 .B 0 -Compile was successful. (EX_OK, EXIT_SUCCES) +Compile was successful. (EX_OK, EXIT_SUCCESS) .TP .B 1 Operation failed. This is returned for almost all failures. diff -r 936f29175330 -r 78e92af7aa61 src/sieve-tools/sieve-dump.c --- a/src/sieve-tools/sieve-dump.c Wed Oct 05 17:43:37 2011 +0200 +++ b/src/sieve-tools/sieve-dump.c Wed Oct 05 18:45:10 2011 +0200 @@ -28,7 +28,7 @@ static void print_help(void) { printf( -"Usage: sieve-dump [-h] [-P ] [-x ]\n" +"Usage: sieve-dump [-c ] [-h] [-P ] [-x ]\n" " []\n" ); } diff -r 936f29175330 -r 78e92af7aa61 src/sieve-tools/sieve-test.c --- a/src/sieve-tools/sieve-test.c Wed Oct 05 17:43:37 2011 +0200 +++ b/src/sieve-tools/sieve-test.c Wed Oct 05 18:45:10 2011 +0200 @@ -42,7 +42,8 @@ static void print_help(void) { printf( -"Usage: sieve-test [-c ] [-C] [-D] [-d ] [-e]\n" +"Usage: sieve-test [-a ]\n" +" [-C] [-D] [-d ] [-e]\n" " [-f ] [-l ]\n" " [-m ] [-P ]\n" " [-r ] [-s ]\n" diff -r 936f29175330 -r 78e92af7aa61 src/sieve-tools/sievec.c --- a/src/sieve-tools/sievec.c Wed Oct 05 17:43:37 2011 +0200 +++ b/src/sieve-tools/sievec.c Wed Oct 05 18:45:10 2011 +0200 @@ -30,7 +30,7 @@ static void print_help(void) { printf( -"Usage: sievec [-d] [-P ] [-x ] \n" +"Usage: sievec [-c ] [-d] [-P ] [-x ] \n" " []\n" ); } From pigeonhole at rename-it.nl Wed Oct 5 20:03:38 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Wed, 05 Oct 2011 19:03:38 +0200 Subject: dovecot-2.0-pigeonhole: sieve-test tool: mixed up original and f... Message-ID: details: http://hg.rename-it.nl/dovecot-2.0-pigeonhole/rev/027f450bd498 changeset: 1541:027f450bd498 user: Stephan Bosch date: Wed Oct 05 19:03:28 2011 +0200 description: sieve-test tool: mixed up original and final envelope recipient in actual implementation. diffstat: src/sieve-tools/sieve-test.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diffs (21 lines): diff -r 78e92af7aa61 -r 027f450bd498 src/sieve-tools/sieve-test.c --- a/src/sieve-tools/sieve-test.c Wed Oct 05 18:45:10 2011 +0200 +++ b/src/sieve-tools/sieve-test.c Wed Oct 05 19:03:28 2011 +0200 @@ -132,13 +132,13 @@ while ((c = sieve_tool_getopt(sieve_tool)) > 0) { switch (c) { case 'r': + /* final recipient address */ + final_recipient = optarg; + break; + case 'a': /* original recipient address */ recipient = optarg; break; - case 'a': - /* final recipient address */ - final_recipient = optarg; - break; case 'f': /* envelope sender address */ sender = optarg; From pigeonhole at rename-it.nl Wed Oct 5 20:10:53 2011 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Wed, 05 Oct 2011 19:10:53 +0200 Subject: dovecot-2.0-pigeonhole: lib-sieve: vacation extension: further t... Message-ID: details: http://hg.rename-it.nl/dovecot-2.0-pigeonhole/rev/bf72eada1f1b changeset: 1542:bf72eada1f1b user: Stephan Bosch date: Wed Oct 05 19:10:44 2011 +0200 description: lib-sieve: vacation extension: further tinkered on log message about implicitly delivered messages. diffstat: src/lib-sieve/plugins/vacation/cmd-vacation.c | 13 +++++++------ 1 files changed, 7 insertions(+), 6 deletions(-) diffs (27 lines): diff -r 027f450bd498 -r bf72eada1f1b src/lib-sieve/plugins/vacation/cmd-vacation.c --- a/src/lib-sieve/plugins/vacation/cmd-vacation.c Wed Oct 05 19:03:28 2011 +0200 +++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c Wed Oct 05 19:10:44 2011 +0200 @@ -1189,16 +1189,17 @@ /* No, bail out */ if ( config->use_original_recipient ) { - original_recipient = t_strdup_printf("original recipient = <%s>; ", - ( orig_recipient == NULL ? "UNAVAILABLE" : str_sanitize(orig_recipient, 128) )); + original_recipient = t_strdup_printf("original-recipient=<%s>, ", + ( orig_recipient == NULL ? "UNAVAILABLE" : + str_sanitize(orig_recipient, 128) )); } sieve_result_global_log(aenv, - "discarding vacation response for implicitly delivered message " - "(no known recipient address found in message headers: " - "recipient = <%s>; %sadditional :addresses are%s specified)", + "discarding vacation response for implicitly delivered message; " + "no known (envelope) recipient address found in message headers " + "(recipient=<%s>, %sand%s additional `:addresses' are specified)", str_sanitize(recipient, 128), original_recipient, - (ctx->addresses == NULL ? " not" : "")); + (ctx->addresses == NULL ? " no" : "")); return TRUE; } From dovecot at dovecot.org Fri Oct 7 18:10:02 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 07 Oct 2011 18:10:02 +0300 Subject: dovecot-2.1: auth: Improved "auth client doesn't have permission... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/99ff7bf3c490 changeset: 13611:99ff7bf3c490 user: Timo Sirainen date: Fri Oct 07 18:18:20 2011 +0300 description: auth: Improved "auth client doesn't have permissions to do .." errors. diffstat: src/auth/auth-master-connection.c | 23 ++++++++++++++++++----- src/auth/auth-master-connection.h | 4 +++- src/auth/main.c | 10 ++++++++-- 3 files changed, 29 insertions(+), 8 deletions(-) diffs (147 lines): diff -r a70f6f04f1fe -r 99ff7bf3c490 src/auth/auth-master-connection.c --- a/src/auth/auth-master-connection.c Wed Oct 05 18:47:56 2011 +0300 +++ b/src/auth/auth-master-connection.c Fri Oct 07 18:18:20 2011 +0300 @@ -329,6 +329,13 @@ auth_master_connection_unref(&conn); } +static const char *auth_restricted_reason(struct auth_master_connection *conn) +{ + return t_strdup_printf("%s mode=0666, but not owned by UID %lu", + conn->path, + (unsigned long)conn->userdb_restricted_uid); +} + static bool master_input_pass(struct auth_master_connection *conn, const char *args) { @@ -347,8 +354,8 @@ } else if (conn->userdb_restricted_uid != 0) { /* no permissions to do this lookup */ auth_request_log_error(auth_request, "passdb", - "Remote client doesn't have permissions to do " - "a PASS lookup"); + "Auth client doesn't have permissions to do " + "a PASS lookup: %s", auth_restricted_reason(conn)); pass_callback(PASSDB_RESULT_INTERNAL_FAILURE, NULL, 0, auth_request); } else { @@ -445,7 +452,8 @@ } if (conn->userdb_restricted_uid != 0) { - i_error("Remote client doesn't have permissions to list users"); + i_error("Auth client doesn't have permissions to list users: %s", + auth_restricted_reason(conn)); str = t_strdup_printf("DONE\t%u\tfail\n", id); (void)o_stream_send_str(conn->output, str); return TRUE; @@ -600,14 +608,18 @@ struct auth_master_connection * auth_master_connection_create(struct auth *auth, int fd, - const struct stat *socket_st, bool userdb_only) + const char *path, const struct stat *socket_st, + bool userdb_only) { struct auth_master_connection *conn; const char *line; + i_assert(path != NULL); + conn = i_new(struct auth_master_connection, 1); conn->refcount = 1; conn->fd = fd; + conn->path = i_strdup(path); conn->auth = auth; conn->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE); conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE); @@ -657,7 +669,7 @@ io_remove(&conn->io); if (conn->fd != -1) { if (close(conn->fd) < 0) - i_error("close(): %m"); + i_error("close(%s): %m", conn->path); conn->fd = -1; } @@ -687,6 +699,7 @@ if (conn->output != NULL) o_stream_unref(&conn->output); + i_free(conn->path); i_free(conn); } diff -r a70f6f04f1fe -r 99ff7bf3c490 src/auth/auth-master-connection.h --- a/src/auth/auth-master-connection.h Wed Oct 05 18:47:56 2011 +0300 +++ b/src/auth/auth-master-connection.h Fri Oct 07 18:18:20 2011 +0300 @@ -9,6 +9,7 @@ int refcount; int fd; + char *path; struct istream *input; struct ostream *output; struct io *io; @@ -28,7 +29,8 @@ struct auth_master_connection * auth_master_connection_create(struct auth *auth, int fd, - const struct stat *socket_st, bool userdb_only); + const char *path, const struct stat *socket_st, + bool userdb_only); void auth_master_connection_destroy(struct auth_master_connection **conn); void auth_master_connection_ref(struct auth_master_connection *conn); diff -r a70f6f04f1fe -r 99ff7bf3c490 src/auth/main.c --- a/src/auth/main.c Wed Oct 05 18:47:56 2011 +0300 +++ b/src/auth/main.c Fri Oct 07 18:18:20 2011 +0300 @@ -43,6 +43,7 @@ struct auth_socket_listener { enum auth_socket_type type; struct stat st; + char *path; }; bool worker = FALSE, shutdown_request = FALSE; @@ -141,6 +142,7 @@ l = array_idx_modifiable(&listeners, fd); l->type = auth_socket_type_get(fd, &path); + l->path = i_strdup(path); if (l->type == AUTH_SOCKET_USERDB) { if (stat(path, &l->st) < 0) i_error("stat(%s) failed: %m", path); @@ -245,6 +247,8 @@ static void main_deinit(void) { + struct auth_socket_listener *l; + if (auth_penalty != NULL) { /* cancel all pending anvil penalty lookups */ auth_penalty_deinit(&auth_penalty); @@ -278,6 +282,8 @@ sql_drivers_deinit(); random_deinit(); + array_foreach_modifiable(&listeners, l) + i_free(l->path); array_free(&listeners); pool_unref(&auth_set_pool); } @@ -303,11 +309,11 @@ switch (l->type) { case AUTH_SOCKET_MASTER: (void)auth_master_connection_create(auth, conn->fd, - NULL, FALSE); + l->path, NULL, FALSE); break; case AUTH_SOCKET_USERDB: (void)auth_master_connection_create(auth, conn->fd, - &l->st, TRUE); + l->path, &l->st, TRUE); break; case AUTH_SOCKET_LOGIN_CLIENT: (void)auth_client_connection_create(auth, conn->fd, TRUE); From dovecot at dovecot.org Fri Oct 7 19:16:42 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 07 Oct 2011 19:16:42 +0300 Subject: dovecot-2.0: auth: Don't re-add IO to master connection input. Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/f6a2c0e8bc03 changeset: 12946:f6a2c0e8bc03 user: Timo Sirainen date: Fri Oct 07 19:25:01 2011 +0300 description: auth: Don't re-add IO to master connection input. This fixes a panic crash in some situations. diffstat: src/auth/auth-master-connection.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r dbd5f9ec38af -r f6a2c0e8bc03 src/auth/auth-master-connection.c --- a/src/auth/auth-master-connection.c Sun Oct 02 20:26:02 2011 +0300 +++ b/src/auth/auth-master-connection.c Fri Oct 07 19:25:01 2011 +0300 @@ -480,7 +480,8 @@ return 1; } - if (o_stream_get_buffer_used_size(conn->output) <= MAX_OUTBUF_SIZE/2) { + if (conn->io == NULL && + o_stream_get_buffer_used_size(conn->output) <= MAX_OUTBUF_SIZE/2) { /* allow input again */ conn->io = io_add(conn->fd, IO_READ, master_input, conn); } From dovecot at dovecot.org Fri Oct 7 19:17:31 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 07 Oct 2011 19:17:31 +0300 Subject: dovecot-2.1: auth: Don't re-add IO to master connection input. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/21566f1780ef changeset: 13612:21566f1780ef user: Timo Sirainen date: Fri Oct 07 19:25:52 2011 +0300 description: auth: Don't re-add IO to master connection input. This fixes a panic crash in some situations. diffstat: src/auth/auth-master-connection.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r 99ff7bf3c490 -r 21566f1780ef src/auth/auth-master-connection.c --- a/src/auth/auth-master-connection.c Fri Oct 07 18:18:20 2011 +0300 +++ b/src/auth/auth-master-connection.c Fri Oct 07 19:25:52 2011 +0300 @@ -566,7 +566,8 @@ return 1; } - if (o_stream_get_buffer_used_size(conn->output) <= MAX_OUTBUF_SIZE/2) { + if (conn->io == NULL && + o_stream_get_buffer_used_size(conn->output) <= MAX_OUTBUF_SIZE/2) { /* allow input again */ conn->io = io_add(conn->fd, IO_READ, master_input, conn); } From dovecot at dovecot.org Fri Oct 7 20:01:54 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 07 Oct 2011 20:01:54 +0300 Subject: dovecot-2.1: imapc: Command sending API changed to be more exten... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/e0a339d677cb changeset: 13613:e0a339d677cb user: Timo Sirainen date: Fri Oct 07 20:10:11 2011 +0300 description: imapc: Command sending API changed to be more extensible. diffstat: src/lib-imap-client/imapc-client-private.h | 3 + src/lib-imap-client/imapc-client.c | 128 ++++------------------ src/lib-imap-client/imapc-client.h | 21 +- src/lib-imap-client/imapc-connection.c | 142 ++++++++++++++---------- src/lib-imap-client/imapc-connection.h | 14 +- src/lib-storage/index/imapc/imapc-list.c | 48 ++++--- src/lib-storage/index/imapc/imapc-mail-fetch.c | 7 +- src/lib-storage/index/imapc/imapc-mail.c | 6 +- src/lib-storage/index/imapc/imapc-save.c | 17 +- src/lib-storage/index/imapc/imapc-storage.c | 31 +++- src/lib-storage/index/imapc/imapc-sync.c | 17 +- 11 files changed, 200 insertions(+), 234 deletions(-) diffs (truncated from 929 to 300 lines): diff -r 21566f1780ef -r e0a339d677cb src/lib-imap-client/imapc-client-private.h --- a/src/lib-imap-client/imapc-client-private.h Fri Oct 07 19:25:52 2011 +0300 +++ b/src/lib-imap-client/imapc-client-private.h Fri Oct 07 20:10:11 2011 +0300 @@ -37,4 +37,7 @@ void imapc_client_ref(struct imapc_client *client); void imapc_client_unref(struct imapc_client **client); +void imapc_command_set_mailbox(struct imapc_command *cmd, + struct imapc_client_mailbox *box); + #endif diff -r 21566f1780ef -r e0a339d677cb src/lib-imap-client/imapc-client.c --- a/src/lib-imap-client/imapc-client.c Fri Oct 07 19:25:52 2011 +0300 +++ b/src/lib-imap-client/imapc-client.c Fri Oct 07 20:10:11 2011 +0300 @@ -12,13 +12,6 @@ #include -struct imapc_client_command_context { - struct imapc_client_mailbox *box; - - imapc_command_callback_t *callback; - void *context; -}; - const struct imapc_capability_name imapc_capability_names[] = { { "SASL-IR", IMAPC_CAPABILITY_SASL_IR }, { "LITERAL+", IMAPC_CAPABILITY_LITERALPLUS }, @@ -203,18 +196,14 @@ return (*connp)->conn; } -void imapc_client_cmdf(struct imapc_client *client, - imapc_command_callback_t *callback, void *context, - const char *cmd_fmt, ...) +struct imapc_command * +imapc_client_cmd(struct imapc_client *client, + imapc_command_callback_t *callback, void *context) { struct imapc_connection *conn; - va_list args; conn = imapc_client_find_connection(client); - - va_start(args, cmd_fmt); - imapc_connection_cmdvf(conn, FALSE, callback, context, cmd_fmt, args); - va_end(args); + return imapc_connection_cmd(conn, callback, context); } static struct imapc_client_connection * @@ -292,93 +281,15 @@ *_box = NULL; } -static void imapc_client_mailbox_cmd_cb(const struct imapc_command_reply *reply, - void *context) +struct imapc_command * +imapc_client_mailbox_cmd(struct imapc_client_mailbox *box, + imapc_command_callback_t *callback, void *context) { - struct imapc_client_command_context *ctx = context; + struct imapc_command *cmd; - ctx->box->pending_box_command_count--; - - ctx->callback(reply, ctx->context); - i_free(ctx); -} - -static struct imapc_client_command_context * -imapc_client_mailbox_cmd_common(struct imapc_client_mailbox *box, - imapc_command_callback_t *callback, - void *context) -{ - struct imapc_client_command_context *ctx; - - ctx = i_new(struct imapc_client_command_context, 1); - ctx->box = box; - ctx->callback = callback; - ctx->context = context; - - box->pending_box_command_count++; - return ctx; -} - -static bool -imapc_client_mailbox_is_selected(struct imapc_client_mailbox *box, - struct imapc_command_reply *reply_r) -{ - struct imapc_client_mailbox *selected_box; - - selected_box = box->conn == NULL ? NULL : - imapc_connection_get_mailbox(box->conn); - if (selected_box == box) - return TRUE; - - memset(reply_r, 0, sizeof(*reply_r)); - reply_r->state = IMAPC_COMMAND_STATE_DISCONNECTED; - if (selected_box == NULL) { - reply_r->text_full = "Disconnected from server"; - } else { - i_error("imapc: Selected mailbox changed unexpectedly"); - reply_r->text_full = "Internal error"; - } - reply_r->text_without_resp = reply_r->text_full; - - box->conn = NULL; - return FALSE; -} - -void imapc_client_mailbox_cmd(struct imapc_client_mailbox *box, - imapc_command_callback_t *callback, - void *context, const char *cmd) -{ - struct imapc_client_command_context *ctx; - struct imapc_command_reply reply; - - if (!imapc_client_mailbox_is_selected(box, &reply)) { - callback(&reply, context); - return; - } - - ctx = imapc_client_mailbox_cmd_common(box, callback, context); - imapc_connection_cmd(box->conn, TRUE, cmd, - imapc_client_mailbox_cmd_cb, ctx); -} - -void imapc_client_mailbox_cmdf(struct imapc_client_mailbox *box, - imapc_command_callback_t *callback, - void *context, const char *cmd_fmt, ...) -{ - struct imapc_client_command_context *ctx; - va_list args; - struct imapc_command_reply reply; - - if (!imapc_client_mailbox_is_selected(box, &reply)) { - callback(&reply, context); - return; - } - - ctx = imapc_client_mailbox_cmd_common(box, callback, context); - va_start(args, cmd_fmt); - imapc_connection_cmdvf(box->conn, TRUE, imapc_client_mailbox_cmd_cb, - ctx, cmd_fmt, args); - va_end(args); + cmd = imapc_connection_cmd(box->conn, callback, context); + imapc_command_set_mailbox(cmd, box); + return cmd; } struct imapc_msgmap * @@ -389,17 +300,24 @@ void imapc_client_mailbox_idle(struct imapc_client_mailbox *box) { - struct imapc_command_reply reply; - - if (imapc_client_mailbox_is_selected(box, &reply)) + if (imapc_client_mailbox_is_connected(box)) imapc_connection_idle(box->conn); } bool imapc_client_mailbox_is_connected(struct imapc_client_mailbox *box) { - struct imapc_command_reply reply; + struct imapc_client_mailbox *selected_box; - return imapc_client_mailbox_is_selected(box, &reply); + selected_box = box->conn == NULL ? NULL : + imapc_connection_get_mailbox(box->conn); + if (selected_box == box) + return TRUE; + + if (selected_box != NULL) + i_error("imapc: Selected mailbox changed unexpectedly"); + + box->conn = NULL; + return FALSE; } enum imapc_capability diff -r 21566f1780ef -r e0a339d677cb src/lib-imap-client/imapc-client.h --- a/src/lib-imap-client/imapc-client.h Fri Oct 07 19:25:52 2011 +0300 +++ b/src/lib-imap-client/imapc-client.h Fri Oct 07 20:10:11 2011 +0300 @@ -109,9 +109,14 @@ void imapc_client_login(struct imapc_client *client, imapc_command_callback_t *callback, void *context); -void imapc_client_cmdf(struct imapc_client *client, - imapc_command_callback_t *callback, void *context, - const char *cmd_fmt, ...) ATTR_FORMAT(4, 5); +struct imapc_command * +imapc_client_cmd(struct imapc_client *client, + imapc_command_callback_t *callback, void *context); +void imapc_command_send(struct imapc_command *cmd, const char *cmd_str); +void imapc_command_sendf(struct imapc_command *cmd, const char *cmd_fmt, ...) + ATTR_FORMAT(2, 3); +void imapc_command_sendvf(struct imapc_command *cmd, + const char *cmd_fmt, va_list args) ATTR_FORMAT(2, 0); void imapc_client_register_untagged(struct imapc_client *client, imapc_untagged_callback_t *callback, @@ -132,13 +137,9 @@ void *untagged_box_context); void imapc_client_mailbox_close(struct imapc_client_mailbox **box); void imapc_client_mailbox_disconnect(struct imapc_client_mailbox *box); -void imapc_client_mailbox_cmd(struct imapc_client_mailbox *box, - imapc_command_callback_t *callback, - void *context, const char *cmd); -void imapc_client_mailbox_cmdf(struct imapc_client_mailbox *box, - imapc_command_callback_t *callback, - void *context, const char *cmd_fmt, ...) - ATTR_FORMAT(4, 5); +struct imapc_command * +imapc_client_mailbox_cmd(struct imapc_client_mailbox *box, + imapc_command_callback_t *callback, void *context); struct imapc_msgmap * imapc_client_mailbox_get_msgmap(struct imapc_client_mailbox *box); diff -r 21566f1780ef -r e0a339d677cb src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Fri Oct 07 19:25:52 2011 +0300 +++ b/src/lib-imap-client/imapc-connection.c Fri Oct 07 20:10:11 2011 +0300 @@ -47,13 +47,19 @@ unsigned int send_pos; unsigned int tag; + struct imapc_connection *conn; + /* If non-NULL, points to the mailbox where this command should be + executed */ + struct imapc_client_mailbox *box; + ARRAY_DEFINE(streams, struct imapc_command_stream); imapc_command_callback_t *callback; void *context; + /* This is the IDLE command */ unsigned int idle:1; - unsigned int mailboxcmd:1; + /* Waiting for '+' literal reply before we can continue */ unsigned int wait_for_literal:1; }; @@ -657,7 +663,7 @@ static void imapc_connection_authenticate(struct imapc_connection *conn) { const struct imapc_client_settings *set = &conn->client->set; - const char *cmd; + struct imapc_command *cmd; if (conn->client->set.debug) { if (set->master_user == NULL) { @@ -669,23 +675,21 @@ } } + cmd = imapc_connection_cmd(conn, imapc_connection_login_cb, + conn); + if ((set->master_user == NULL && need_literal(set->username) && need_literal(set->password)) || (conn->capabilities & IMAPC_CAPABILITY_AUTH_PLAIN) == 0) { /* We can use LOGIN command */ - imapc_connection_cmdf(conn, FALSE, imapc_connection_login_cb, - conn, "LOGIN %s %s", - set->username, set->password); + imapc_command_sendf(cmd, "LOGIN %s %s", + set->username, set->password); } else if ((conn->capabilities & IMAPC_CAPABILITY_SASL_IR) != 0) { - cmd = t_strdup_printf("AUTHENTICATE PLAIN %s", + imapc_command_sendf(cmd, "AUTHENTICATE PLAIN %1s", imapc_connection_get_sasl_plain_request(conn)); - imapc_connection_cmd(conn, FALSE, cmd, - imapc_connection_login_cb, conn); } else { - cmd = t_strdup_printf("AUTHENTICATE PLAIN\r\n%s", + imapc_command_sendf(cmd, "AUTHENTICATE PLAIN\r\n%1s", imapc_connection_get_sasl_plain_request(conn)); - imapc_connection_cmd(conn, FALSE, cmd, - imapc_connection_login_cb, conn); } } @@ -709,6 +713,8 @@ static void imapc_connection_starttls(struct imapc_connection *conn) { + struct imapc_command *cmd; + if (conn->client->set.ssl_mode == IMAPC_CLIENT_SSL_MODE_STARTTLS && conn->ssl_iostream == NULL) { if ((conn->capabilities & IMAPC_CAPABILITY_STARTTLS) == 0) { @@ -718,8 +724,9 @@ imapc_connection_disconnect(conn); return; } - imapc_connection_cmd(conn, FALSE, "STARTTLS", - imapc_connection_starttls_cb, conn); + cmd = imapc_connection_cmd(conn, imapc_connection_starttls_cb, From dovecot at dovecot.org Fri Oct 7 20:23:40 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 07 Oct 2011 20:23:40 +0300 Subject: dovecot-2.1: imapc: Changed mailbox opening API to be more exten... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/c358b13e32cc changeset: 13614:c358b13e32cc user: Timo Sirainen date: Fri Oct 07 20:31:57 2011 +0300 description: imapc: Changed mailbox opening API to be more extensible. diffstat: src/lib-imap-client/imapc-client.c | 4 -- src/lib-imap-client/imapc-client.h | 9 +++- src/lib-imap-client/imapc-connection.c | 57 ++++++++++++++++------------ src/lib-imap-client/imapc-connection.h | 3 - src/lib-storage/index/imapc/imapc-storage.c | 18 +++++++-- 5 files changed, 53 insertions(+), 38 deletions(-) diffs (200 lines): diff -r e0a339d677cb -r c358b13e32cc src/lib-imap-client/imapc-client.c --- a/src/lib-imap-client/imapc-client.c Fri Oct 07 20:10:11 2011 +0300 +++ b/src/lib-imap-client/imapc-client.c Fri Oct 07 20:31:57 2011 +0300 @@ -234,8 +234,6 @@ struct imapc_client_mailbox * imapc_client_mailbox_open(struct imapc_client *client, - const char *name, bool examine, - imapc_command_callback_t *callback, void *context, void *untagged_box_context) { struct imapc_client_mailbox *box; @@ -248,8 +246,6 @@ conn->box = box; box->conn = conn->conn; box->msgmap = imapc_msgmap_init(); - - imapc_connection_select(box, name, examine, callback, context); return box; } diff -r e0a339d677cb -r c358b13e32cc src/lib-imap-client/imapc-client.h --- a/src/lib-imap-client/imapc-client.h Fri Oct 07 20:10:11 2011 +0300 +++ b/src/lib-imap-client/imapc-client.h Fri Oct 07 20:31:57 2011 +0300 @@ -25,6 +25,11 @@ }; extern const struct imapc_capability_name imapc_capability_names[]; +enum imapc_command_flags { + /* The command changes the selected mailbox (SELECT, EXAMINE) */ + IMAPC_COMMAND_FLAG_SELECT = 0x01 +}; + enum imapc_client_ssl_mode { IMAPC_CLIENT_SSL_MODE_NONE, IMAPC_CLIENT_SSL_MODE_IMMEDIATE, @@ -112,6 +117,8 @@ struct imapc_command * imapc_client_cmd(struct imapc_client *client, imapc_command_callback_t *callback, void *context); +void imapc_command_set_flags(struct imapc_command *cmd, + enum imapc_command_flags flags); void imapc_command_send(struct imapc_command *cmd, const char *cmd_str); void imapc_command_sendf(struct imapc_command *cmd, const char *cmd_fmt, ...) ATTR_FORMAT(2, 3); @@ -132,8 +139,6 @@ struct imapc_client_mailbox * imapc_client_mailbox_open(struct imapc_client *client, - const char *name, bool examine, - imapc_command_callback_t *callback, void *context, void *untagged_box_context); void imapc_client_mailbox_close(struct imapc_client_mailbox **box); void imapc_client_mailbox_disconnect(struct imapc_client_mailbox *box); diff -r e0a339d677cb -r c358b13e32cc src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Fri Oct 07 20:10:11 2011 +0300 +++ b/src/lib-imap-client/imapc-connection.c Fri Oct 07 20:31:57 2011 +0300 @@ -47,6 +47,7 @@ unsigned int send_pos; unsigned int tag; + enum imapc_command_flags flags; struct imapc_connection *conn; /* If non-NULL, points to the mailbox where this command should be executed */ @@ -1421,6 +1422,24 @@ return 1; } +static void imapc_connection_set_selecting(struct imapc_client_mailbox *box) +{ + struct imapc_connection *conn = box->conn; + + i_assert(conn->selecting_box == NULL); + + if (conn->selected_box != NULL && + (conn->capabilities & IMAPC_CAPABILITY_QRESYNC) != 0) { + /* server will send a [CLOSED] once selected mailbox is + closed */ + conn->selecting_box = box; + } else { + /* we'll have to assume that all the future untagged messages + are for the mailbox we're selecting */ + conn->selected_box = box; + } +} + static void imapc_command_send_more(struct imapc_connection *conn, struct imapc_command *cmd) { @@ -1432,7 +1451,13 @@ i_assert(!cmd->wait_for_literal); i_assert(cmd->send_pos < cmd->data->used); - if (cmd->box != NULL && !imapc_client_mailbox_is_connected(cmd->box)) { + if (cmd->box == NULL) { + /* non-mailbox command */ + } else if (cmd->send_pos == 0 && + (cmd->flags & IMAPC_COMMAND_FLAG_SELECT) != 0) { + /* SELECT/EXAMINE command */ + imapc_connection_set_selecting(cmd->box); + } else if (!imapc_client_mailbox_is_connected(cmd->box)) { /* shouldn't normally happen */ memset(&reply, 0, sizeof(reply)); reply.text_without_resp = reply.text_full = "Mailbox not open"; @@ -1569,6 +1594,12 @@ return cmd; } +void imapc_command_set_flags(struct imapc_command *cmd, + enum imapc_command_flags flags) +{ + cmd->flags = flags; +} + void imapc_command_set_mailbox(struct imapc_command *cmd, struct imapc_client_mailbox *box) { @@ -1676,30 +1707,6 @@ return conn->capabilities; } -void imapc_connection_select(struct imapc_client_mailbox *box, - const char *name, bool examine, - imapc_command_callback_t *callback, void *context) -{ - struct imapc_connection *conn = box->conn; - struct imapc_command *cmd; - - i_assert(conn->selecting_box == NULL); - - if (conn->selected_box != NULL && - (conn->capabilities & IMAPC_CAPABILITY_QRESYNC) != 0) { - /* server will send a [CLOSED] once selected mailbox is - closed */ - conn->selecting_box = box; - } else { - /* we'll have to assume that all the future untagged messages - are for the mailbox we're selecting */ - conn->selected_box = box; - } - - cmd = imapc_connection_cmd(conn, callback, context); - imapc_command_sendf(cmd, examine ? "EXAMINE %s" : "SELECT %s", name); -} - void imapc_connection_unselect(struct imapc_client_mailbox *box) { struct imapc_connection *conn = box->conn; diff -r e0a339d677cb -r c358b13e32cc src/lib-imap-client/imapc-connection.h --- a/src/lib-imap-client/imapc-connection.h Fri Oct 07 20:10:11 2011 +0300 +++ b/src/lib-imap-client/imapc-connection.h Fri Oct 07 20:31:57 2011 +0300 @@ -32,9 +32,6 @@ imapc_connection_cmd(struct imapc_connection *conn, imapc_command_callback_t *callback, void *context); -void imapc_connection_select(struct imapc_client_mailbox *box, - const char *name, bool examine, - imapc_command_callback_t *callback, void *context); void imapc_connection_unselect(struct imapc_client_mailbox *box); enum imapc_connection_state diff -r e0a339d677cb -r c358b13e32cc src/lib-storage/index/imapc/imapc-storage.c --- a/src/lib-storage/index/imapc/imapc-storage.c Fri Oct 07 20:10:11 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-storage.c Fri Oct 07 20:31:57 2011 +0300 @@ -386,20 +386,30 @@ int imapc_mailbox_select(struct imapc_mailbox *mbox) { + struct imapc_command *cmd; struct imapc_open_context ctx; bool examine = TRUE; + i_assert(mbox->client_box == NULL); + examine = (mbox->box.flags & MAILBOX_FLAG_DROP_RECENT) == 0 && ((mbox->box.flags & MAILBOX_FLAG_READONLY) != 0 || (mbox->box.flags & MAILBOX_FLAG_SAVEONLY) != 0); + mbox->client_box = + imapc_client_mailbox_open(mbox->storage->client, mbox); + mbox->selecting = TRUE; ctx.mbox = mbox; ctx.ret = -2; - mbox->client_box = - imapc_client_mailbox_open(mbox->storage->client, mbox->box.name, - examine, imapc_mailbox_open_callback, - &ctx, mbox); + cmd = imapc_client_mailbox_cmd(mbox->client_box, + imapc_mailbox_open_callback, &ctx); + imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_SELECT); + if (examine) + imapc_command_sendf(cmd, "EXAMINE %s", mbox->box.name); + else + imapc_command_sendf(cmd, "SELECT %s", mbox->box.name); + while (ctx.ret == -2) imapc_storage_run(mbox->storage); mbox->selecting = FALSE; From dovecot at dovecot.org Fri Oct 7 20:26:35 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 07 Oct 2011 20:26:35 +0300 Subject: dovecot-2.1: imapc: Removed unused "stop now" functionality. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/4f305d785bc7 changeset: 13615:4f305d785bc7 user: Timo Sirainen date: Fri Oct 07 20:34:53 2011 +0300 description: imapc: Removed unused "stop now" functionality. diffstat: src/lib-imap-client/imapc-client-private.h | 2 -- src/lib-imap-client/imapc-client.c | 11 ----------- src/lib-imap-client/imapc-client.h | 3 --- src/lib-imap-client/imapc-connection.c | 2 +- 4 files changed, 1 insertions(+), 17 deletions(-) diffs (74 lines): diff -r c358b13e32cc -r 4f305d785bc7 src/lib-imap-client/imapc-client-private.h --- a/src/lib-imap-client/imapc-client-private.h Fri Oct 07 20:31:57 2011 +0300 +++ b/src/lib-imap-client/imapc-client-private.h Fri Oct 07 20:34:53 2011 +0300 @@ -21,8 +21,6 @@ ARRAY_DEFINE(conns, struct imapc_client_connection *); struct ioloop *ioloop; - - unsigned int stop_now:1; }; struct imapc_client_mailbox { diff -r c358b13e32cc -r 4f305d785bc7 src/lib-imap-client/imapc-client.c --- a/src/lib-imap-client/imapc-client.c Fri Oct 07 20:31:57 2011 +0300 +++ b/src/lib-imap-client/imapc-client.c Fri Oct 07 20:34:53 2011 +0300 @@ -122,20 +122,15 @@ { struct imapc_client_connection *const *connp; struct ioloop *prev_ioloop = current_ioloop; - bool handle_pending = client->stop_now; i_assert(client->ioloop == NULL); - client->stop_now = FALSE; - client->ioloop = io_loop_create(); io_loop_set_running(client->ioloop); array_foreach(&client->conns, connp) { imapc_connection_ioloop_changed((*connp)->conn); imapc_connection_connect((*connp)->conn, NULL, NULL); - if (handle_pending) - imapc_connection_input_pending((*connp)->conn); } if (io_loop_is_running(client->ioloop)) @@ -167,12 +162,6 @@ return client->ioloop != NULL; } -void imapc_client_stop_now(struct imapc_client *client) -{ - client->stop_now = TRUE; - imapc_client_stop(client); -} - static struct imapc_client_connection * imapc_client_add_connection(struct imapc_client *client) { diff -r c358b13e32cc -r 4f305d785bc7 src/lib-imap-client/imapc-client.h --- a/src/lib-imap-client/imapc-client.h Fri Oct 07 20:31:57 2011 +0300 +++ b/src/lib-imap-client/imapc-client.h Fri Oct 07 20:34:53 2011 +0300 @@ -132,9 +132,6 @@ void imapc_client_run_pre(struct imapc_client *client); void imapc_client_run_post(struct imapc_client *client); void imapc_client_stop(struct imapc_client *client); -/* Stop immediately, don't finish even any already read pending replies. - They'll be finished when imapc_client_run() is again called. */ -void imapc_client_stop_now(struct imapc_client *client); bool imapc_client_is_running(struct imapc_client *client); struct imapc_client_mailbox * diff -r c358b13e32cc -r 4f305d785bc7 src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Fri Oct 07 20:31:57 2011 +0300 +++ b/src/lib-imap-client/imapc-connection.c Fri Oct 07 20:34:53 2011 +0300 @@ -1294,7 +1294,7 @@ timeout_reset(conn->to); o_stream_cork(conn->output); - while (ret > 0 && !conn->client->stop_now && conn->input != NULL) { + while (ret > 0 && conn->input != NULL) { T_BEGIN { ret = imapc_connection_input_one(conn); } T_END; From dovecot at dovecot.org Fri Oct 7 21:07:34 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 07 Oct 2011 21:07:34 +0300 Subject: dovecot-2.1: imapc: Code cleanup: avoid unnecessarily accessing ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/cd4a65125c84 changeset: 13616:cd4a65125c84 user: Timo Sirainen date: Fri Oct 07 20:49:32 2011 +0300 description: imapc: Code cleanup: avoid unnecessarily accessing imapc-client-private.h diffstat: src/lib-storage/index/imapc/imapc-mailbox.c | 4 ++++ src/lib-storage/index/imapc/imapc-storage.c | 18 ++---------------- src/lib-storage/index/imapc/imapc-storage.h | 1 + 3 files changed, 7 insertions(+), 16 deletions(-) diffs (73 lines): diff -r 4f305d785bc7 -r cd4a65125c84 src/lib-storage/index/imapc/imapc-mailbox.c --- a/src/lib-storage/index/imapc/imapc-mailbox.c Fri Oct 07 20:34:53 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mailbox.c Fri Oct 07 20:49:32 2011 +0300 @@ -135,11 +135,15 @@ static void imapc_mailbox_idle_notify(struct imapc_mailbox *mbox) { + struct ioloop *old_ioloop = current_ioloop; + if (mbox->box.notify_callback != NULL && mbox->to_idle_delay == NULL) { + io_loop_set_current(mbox->storage->root_ioloop); mbox->to_idle_delay = timeout_add(NOTIFY_DELAY_MSECS, imapc_mailbox_idle_timeout, mbox); + io_loop_set_current(old_ioloop); } } diff -r 4f305d785bc7 -r cd4a65125c84 src/lib-storage/index/imapc/imapc-storage.c --- a/src/lib-storage/index/imapc/imapc-storage.c Fri Oct 07 20:34:53 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-storage.c Fri Oct 07 20:49:32 2011 +0300 @@ -7,7 +7,7 @@ #include "imap-resp-code.h" #include "mailbox-tree.h" #include "imapc-mail.h" -#include "imapc-client-private.h" +#include "imapc-client.h" #include "imapc-connection.h" #include "imapc-list.h" #include "imapc-sync.h" @@ -78,6 +78,7 @@ storage = p_new(pool, struct imapc_storage, 1); storage->storage = imapc_storage; storage->storage.pool = pool; + storage->root_ioloop = current_ioloop; return &storage->storage; } @@ -112,22 +113,7 @@ void imapc_storage_run(struct imapc_storage *storage) { - struct imapc_client_mailbox *client_box; - struct imapc_client_connection *const *connp; - struct imapc_mailbox *mbox; - imapc_client_run_pre(storage->client); - - array_foreach(&storage->client->conns, connp) { - client_box = imapc_connection_get_mailbox((*connp)->conn); - if (client_box == NULL) - continue; - - mbox = client_box->untagged_box_context; - if (mbox->to_idle_delay != NULL) - mbox->to_idle_delay = io_loop_move_timeout(&mbox->to_idle_delay); - } - imapc_client_run_post(storage->client); } diff -r 4f305d785bc7 -r cd4a65125c84 src/lib-storage/index/imapc/imapc-storage.h --- a/src/lib-storage/index/imapc/imapc-storage.h Fri Oct 07 20:34:53 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-storage.h Fri Oct 07 20:49:32 2011 +0300 @@ -31,6 +31,7 @@ struct mail_storage storage; const struct imapc_settings *set; + struct ioloop *root_ioloop; struct imapc_mailbox_list *list; struct imapc_client *client; From dovecot at dovecot.org Fri Oct 7 21:07:34 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 07 Oct 2011 21:07:34 +0300 Subject: dovecot-2.1: imapc: Detect when message has been unexpectedly ex... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/aaa0463aa66f changeset: 13618:aaa0463aa66f user: Timo Sirainen date: Fri Oct 07 21:14:58 2011 +0300 description: imapc: Detect when message has been unexpectedly expunged from index. diffstat: src/lib-storage/index/imapc/imapc-mailbox.c | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletions(-) diffs (29 lines): diff -r 3058a10313bd -r aaa0463aa66f src/lib-storage/index/imapc/imapc-mailbox.c --- a/src/lib-storage/index/imapc/imapc-mailbox.c Fri Oct 07 20:50:02 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mailbox.c Fri Oct 07 21:14:58 2011 +0300 @@ -229,7 +229,8 @@ mbox->prev_skipped_uid = fetch_uid; } else if (fetch_uid < imapc_msgmap_uidnext(msgmap)) { imapc_mailbox_set_corrupted(mbox, - "Expunged message reappeared (uid=%u < next_uid=%u)", + "Expunged message reappeared in session " + "(uid=%u < next_uid=%u)", fetch_uid, imapc_msgmap_uidnext(msgmap)); return -1; } else { @@ -237,6 +238,15 @@ imapc_msgmap_append(msgmap, rseq, uid); if (uid < mbox->min_append_uid) { /* message is already added to index */ + if (!mbox->initial_sync_done && + !mail_index_lookup_seq(mbox->delayed_sync_view, + uid, lseq_r)) { + imapc_mailbox_set_corrupted(mbox, + "Expunged message reappeared " + "(uid=%u < next_uid=%u)", + uid, mbox->min_append_uid); + return -1; + } } else if (mbox->syncing) { mail_index_append(mbox->delayed_sync_trans, uid, lseq_r); From dovecot at dovecot.org Fri Oct 7 21:07:34 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 07 Oct 2011 21:07:34 +0300 Subject: dovecot-2.1: imapc: IDLE didn't notify immediately about new mails. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/3058a10313bd changeset: 13617:3058a10313bd user: Timo Sirainen date: Fri Oct 07 20:50:02 2011 +0300 description: imapc: IDLE didn't notify immediately about new mails. diffstat: src/lib-storage/index/imapc/imapc-mailbox.c | 43 ++++++++++++++-------------- 1 files changed, 22 insertions(+), 21 deletions(-) diffs (60 lines): diff -r cd4a65125c84 -r 3058a10313bd src/lib-storage/index/imapc/imapc-mailbox.c --- a/src/lib-storage/index/imapc/imapc-mailbox.c Fri Oct 07 20:49:32 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mailbox.c Fri Oct 07 20:50:02 2011 +0300 @@ -102,6 +102,27 @@ return ret; } +static void imapc_mailbox_idle_timeout(struct imapc_mailbox *mbox) +{ + timeout_remove(&mbox->to_idle_delay); + if (mbox->box.notify_callback != NULL) + mbox->box.notify_callback(&mbox->box, mbox->box.notify_context); +} + +static void imapc_mailbox_idle_notify(struct imapc_mailbox *mbox) +{ + struct ioloop *old_ioloop = current_ioloop; + + if (mbox->box.notify_callback != NULL && + mbox->to_idle_delay == NULL) { + io_loop_set_current(mbox->storage->root_ioloop); + mbox->to_idle_delay = + timeout_add(NOTIFY_DELAY_MSECS, + imapc_mailbox_idle_timeout, mbox); + io_loop_set_current(old_ioloop); + } +} + static void imapc_untagged_exists(const struct imapc_untagged_reply *reply, struct imapc_mailbox *mbox) @@ -124,27 +145,7 @@ mbox->sync_fetch_first_uid = hdr->next_uid; } mbox->exists_count = exists_count; -} - -static void imapc_mailbox_idle_timeout(struct imapc_mailbox *mbox) -{ - timeout_remove(&mbox->to_idle_delay); - if (mbox->box.notify_callback != NULL) - mbox->box.notify_callback(&mbox->box, mbox->box.notify_context); -} - -static void imapc_mailbox_idle_notify(struct imapc_mailbox *mbox) -{ - struct ioloop *old_ioloop = current_ioloop; - - if (mbox->box.notify_callback != NULL && - mbox->to_idle_delay == NULL) { - io_loop_set_current(mbox->storage->root_ioloop); - mbox->to_idle_delay = - timeout_add(NOTIFY_DELAY_MSECS, - imapc_mailbox_idle_timeout, mbox); - io_loop_set_current(old_ioloop); - } + imapc_mailbox_idle_notify(mbox); } static bool keywords_are_equal(struct mail_keywords *kw, From dovecot at dovecot.org Fri Oct 7 21:07:34 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Fri, 07 Oct 2011 21:07:34 +0300 Subject: dovecot-2.1: imapc: Fixed handling keywords. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/92dd30cf0d22 changeset: 13619:92dd30cf0d22 user: Timo Sirainen date: Fri Oct 07 21:15:52 2011 +0300 description: imapc: Fixed handling keywords. The status->keywords must point to mail_index's keywords. diffstat: src/lib-storage/index/imapc/imapc-mailbox.c | 13 ++++--------- src/lib-storage/index/imapc/imapc-storage.c | 3 --- src/lib-storage/index/imapc/imapc-storage.h | 1 - 3 files changed, 4 insertions(+), 13 deletions(-) diffs (70 lines): diff -r aaa0463aa66f -r 92dd30cf0d22 src/lib-storage/index/imapc/imapc-mailbox.c --- a/src/lib-storage/index/imapc/imapc-mailbox.c Fri Oct 07 21:14:58 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mailbox.c Fri Oct 07 21:15:52 2011 +0300 @@ -443,6 +443,7 @@ { const struct imap_arg *flags_args, *arg; const char *flag; + unsigned int idx; i_assert(reply->args[0].type == IMAP_ARG_ATOM); @@ -450,7 +451,6 @@ return; mbox->permanent_flags = 0; - array_clear(&mbox->permanent_keywords); mbox->box.disallow_new_keywords = TRUE; for (arg = flags_args; arg->type != IMAP_ARG_EOL; arg++) { @@ -462,16 +462,11 @@ else if (*flag == '\\') mbox->permanent_flags |= imap_parse_system_flag(flag); else { - /* this wastes some memory when called multiple times, - but that should happen quite rarely */ - flag = p_strdup(mbox->box.pool, flag); - array_append(&mbox->permanent_keywords, &flag, 1); + /* we'll simply make sure that it exists in the index */ + mail_index_keyword_lookup_or_create(mbox->box.index, + flag, &idx); } } - /* NULL-terminate it */ - (void)array_append_space(&mbox->permanent_keywords); - array_delete(&mbox->permanent_keywords, - array_count(&mbox->permanent_keywords)-1, 1); } void imapc_mailbox_register_untagged(struct imapc_mailbox *mbox, diff -r aaa0463aa66f -r 92dd30cf0d22 src/lib-storage/index/imapc/imapc-storage.c --- a/src/lib-storage/index/imapc/imapc-storage.c Fri Oct 07 21:14:58 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-storage.c Fri Oct 07 21:15:52 2011 +0300 @@ -325,7 +325,6 @@ p_array_init(&mbox->untagged_callbacks, pool, 16); p_array_init(&mbox->resp_text_callbacks, pool, 16); p_array_init(&mbox->fetch_mails, pool, 16); - p_array_init(&mbox->permanent_keywords, pool, 32); p_array_init(&mbox->delayed_expunged_uids, pool, 16); mbox->prev_mail_cache.fd = -1; imapc_mailbox_register_callbacks(mbox); @@ -539,8 +538,6 @@ struct mailbox_status *status_r) { index_storage_get_status(&mbox->box, items, status_r); - if ((items & STATUS_KEYWORDS) != 0) - status_r->keywords = &mbox->permanent_keywords; if ((items & STATUS_PERMANENT_FLAGS) != 0) status_r->permanent_flags = mbox->permanent_flags; } diff -r aaa0463aa66f -r 92dd30cf0d22 src/lib-storage/index/imapc/imapc-storage.h --- a/src/lib-storage/index/imapc/imapc-storage.h Fri Oct 07 21:14:58 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-storage.h Fri Oct 07 21:15:52 2011 +0300 @@ -64,7 +64,6 @@ ARRAY_DEFINE(resp_text_callbacks, struct imapc_mailbox_event_callback); enum mail_flags permanent_flags; - ARRAY_TYPE(keywords) permanent_keywords; ARRAY_TYPE(uint32_t) delayed_expunged_uids; uint32_t sync_uid_validity; From dovecot at dovecot.org Sat Oct 8 20:23:12 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 08 Oct 2011 20:23:12 +0300 Subject: dovecot-2.1: imapc: Fixed updating message flags from another se... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/7e0bdfa76f12 changeset: 13620:7e0bdfa76f12 user: Timo Sirainen date: Sat Oct 08 20:31:22 2011 +0300 description: imapc: Fixed updating message flags from another session. diffstat: src/lib-storage/index/imapc/imapc-mailbox.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diffs (30 lines): diff -r 92dd30cf0d22 -r 7e0bdfa76f12 src/lib-storage/index/imapc/imapc-mailbox.c --- a/src/lib-storage/index/imapc/imapc-mailbox.c Fri Oct 07 21:15:52 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mailbox.c Sat Oct 08 20:31:22 2011 +0300 @@ -212,6 +212,7 @@ fetch_uid, uid); return -1; } + *uid_r = uid; } else if (fetch_uid == 0 || rseq != msg_count+1) { /* probably a flag update for a message we haven't yet received our initial UID FETCH for. we should get @@ -322,8 +323,8 @@ /* already expunged by another session */ return; } - rec = mail_index_lookup(mbox->delayed_sync_view, lseq); } + rec = mail_index_lookup(mbox->delayed_sync_view, lseq); if (rseq == mbox->sync_next_rseq) { /* we're doing the initial full sync of mails. expunge any @@ -340,7 +341,7 @@ mbox->sync_next_lseq++; } - if (seen_flags && (rec == NULL || rec->flags != flags)) { + if (seen_flags && rec->flags != flags) { mail_index_update_flags(mbox->delayed_sync_trans, lseq, MODIFY_REPLACE, flags); } From dovecot at dovecot.org Sun Oct 9 16:32:57 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 09 Oct 2011 16:32:57 +0300 Subject: dovecot-2.1: imapc: Initial support for automatically reconnecti... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/8fdd22504aab changeset: 13621:8fdd22504aab user: Timo Sirainen date: Sun Oct 09 16:41:17 2011 +0300 description: imapc: Initial support for automatically reconnecting to remote server. diffstat: src/lib-imap-client/imapc-client-private.h | 5 + src/lib-imap-client/imapc-client.c | 76 +++++++++++++++------ src/lib-imap-client/imapc-client.h | 19 ++++- src/lib-imap-client/imapc-connection.c | 99 +++++++++++++++++----------- src/lib-imap-client/imapc-connection.h | 4 +- src/lib-imap-client/imapc-msgmap.c | 6 + src/lib-imap-client/imapc-msgmap.h | 1 + src/lib-storage/index/imapc/imapc-mail.c | 2 +- src/lib-storage/index/imapc/imapc-mailbox.c | 2 +- src/lib-storage/index/imapc/imapc-storage.c | 66 ++++++++++++++++--- src/lib-storage/index/imapc/imapc-storage.h | 1 + 11 files changed, 200 insertions(+), 81 deletions(-) diffs (truncated from 659 to 300 lines): diff -r 7e0bdfa76f12 -r 8fdd22504aab src/lib-imap-client/imapc-client-private.h --- a/src/lib-imap-client/imapc-client-private.h Sat Oct 08 20:31:22 2011 +0300 +++ b/src/lib-imap-client/imapc-client-private.h Sun Oct 09 16:41:17 2011 +0300 @@ -28,8 +28,13 @@ struct imapc_connection *conn; struct imapc_msgmap *msgmap; + void (*reopen_callback)(void *context); + void *reopen_context; + void *untagged_box_context; unsigned int pending_box_command_count; + + bool reconnect_ok; }; void imapc_client_ref(struct imapc_client *client); diff -r 7e0bdfa76f12 -r 8fdd22504aab src/lib-imap-client/imapc-client.c --- a/src/lib-imap-client/imapc-client.c Sat Oct 08 20:31:22 2011 +0300 +++ b/src/lib-imap-client/imapc-client.c Sun Oct 09 16:41:17 2011 +0300 @@ -118,7 +118,7 @@ client->untagged_context = context; } -void imapc_client_run_pre(struct imapc_client *client) +static void imapc_client_run_pre(struct imapc_client *client) { struct imapc_client_connection *const *connp; struct ioloop *prev_ioloop = current_ioloop; @@ -138,7 +138,7 @@ current_ioloop = prev_ioloop; } -void imapc_client_run_post(struct imapc_client *client) +static void imapc_client_run_post(struct imapc_client *client) { struct imapc_client_connection *const *connp; struct ioloop *ioloop = client->ioloop; @@ -151,6 +151,12 @@ io_loop_destroy(&ioloop); } +void imapc_client_run(struct imapc_client *client) +{ + imapc_client_run_pre(client); + imapc_client_run_post(client); +} + void imapc_client_stop(struct imapc_client *client) { if (client->ioloop != NULL) @@ -238,10 +244,34 @@ return box; } -void imapc_client_mailbox_disconnect(struct imapc_client_mailbox *box) +void imapc_client_mailbox_set_reopen_cb(struct imapc_client_mailbox *box, + void (*callback)(void *context), + void *context) { - if (box->conn != NULL) - imapc_connection_disconnect(box->conn); + box->reopen_callback = callback; + box->reopen_context = context; +} + +static void +imapc_client_reconnect_cb(const struct imapc_command_reply *reply, + void *context) +{ + struct imapc_client_mailbox *box = context; + + if (reply->state == IMAPC_COMMAND_STATE_OK) { + /* reopen the mailbox */ + box->reopen_callback(box->reopen_context); + } +} + +void imapc_client_mailbox_reconnect(struct imapc_client_mailbox *box) +{ + imapc_connection_disconnect(box->conn); + if (box->reopen_callback != NULL && box->reconnect_ok) { + imapc_connection_connect(box->conn, + imapc_client_reconnect_cb, box); + } + box->reconnect_ok = FALSE; } void imapc_client_mailbox_close(struct imapc_client_mailbox **_box) @@ -249,6 +279,13 @@ struct imapc_client_mailbox *box = *_box; struct imapc_client_connection *const *connp; + /* cancel any pending commands */ + imapc_connection_unselect(box); + + /* set this only after unselect, which may cancel some commands that + reference this box */ + *_box = NULL; + array_foreach(&box->client->conns, connp) { if ((*connp)->box == box) { (*connp)->box = NULL; @@ -256,14 +293,8 @@ } } - if (box->conn != NULL) - imapc_connection_unselect(box); imapc_msgmap_deinit(&box->msgmap); i_free(box); - - /* set this only after unselect, which may cancel some commands that - reference this box */ - *_box = NULL; } struct imapc_command * @@ -285,24 +316,25 @@ void imapc_client_mailbox_idle(struct imapc_client_mailbox *box) { - if (imapc_client_mailbox_is_connected(box)) + if (imapc_client_mailbox_is_opened(box)) imapc_connection_idle(box->conn); + box->reconnect_ok = TRUE; } -bool imapc_client_mailbox_is_connected(struct imapc_client_mailbox *box) +bool imapc_client_mailbox_is_opened(struct imapc_client_mailbox *box) { struct imapc_client_mailbox *selected_box; - selected_box = box->conn == NULL ? NULL : - imapc_connection_get_mailbox(box->conn); - if (selected_box == box) - return TRUE; + if (imapc_connection_get_state(box->conn) != IMAPC_CONNECTION_STATE_DONE) + return FALSE; - if (selected_box != NULL) - i_error("imapc: Selected mailbox changed unexpectedly"); - - box->conn = NULL; - return FALSE; + selected_box = imapc_connection_get_mailbox(box->conn); + if (selected_box != box) { + if (selected_box != NULL) + i_error("imapc: Selected mailbox changed unexpectedly"); + return FALSE; + } + return TRUE; } enum imapc_capability diff -r 7e0bdfa76f12 -r 8fdd22504aab src/lib-imap-client/imapc-client.h --- a/src/lib-imap-client/imapc-client.h Sat Oct 08 20:31:22 2011 +0300 +++ b/src/lib-imap-client/imapc-client.h Sun Oct 09 16:41:17 2011 +0300 @@ -27,7 +27,14 @@ enum imapc_command_flags { /* The command changes the selected mailbox (SELECT, EXAMINE) */ - IMAPC_COMMAND_FLAG_SELECT = 0x01 + IMAPC_COMMAND_FLAG_SELECT = 0x01, + /* The command is sent to server before login (or is the login + command itself). Non-prelogin commands will be queued until login + is successful. */ + IMAPC_COMMAND_FLAG_PRELOGIN = 0x02, + /* Allow command to be automatically retried if disconnected before it + finishes. */ + IMAPC_COMMAND_FLAG_RETRIABLE = 0x04 }; enum imapc_client_ssl_mode { @@ -129,16 +136,18 @@ imapc_untagged_callback_t *callback, void *context); -void imapc_client_run_pre(struct imapc_client *client); -void imapc_client_run_post(struct imapc_client *client); +void imapc_client_run(struct imapc_client *client); void imapc_client_stop(struct imapc_client *client); bool imapc_client_is_running(struct imapc_client *client); struct imapc_client_mailbox * imapc_client_mailbox_open(struct imapc_client *client, void *untagged_box_context); +void imapc_client_mailbox_set_reopen_cb(struct imapc_client_mailbox *box, + void (*callback)(void *context), + void *context); void imapc_client_mailbox_close(struct imapc_client_mailbox **box); -void imapc_client_mailbox_disconnect(struct imapc_client_mailbox *box); +void imapc_client_mailbox_reconnect(struct imapc_client_mailbox *box); struct imapc_command * imapc_client_mailbox_cmd(struct imapc_client_mailbox *box, imapc_command_callback_t *callback, void *context); @@ -146,7 +155,7 @@ imapc_client_mailbox_get_msgmap(struct imapc_client_mailbox *box); void imapc_client_mailbox_idle(struct imapc_client_mailbox *box); -bool imapc_client_mailbox_is_connected(struct imapc_client_mailbox *box); +bool imapc_client_mailbox_is_opened(struct imapc_client_mailbox *box); enum imapc_capability imapc_client_get_capabilities(struct imapc_client *client); diff -r 7e0bdfa76f12 -r 8fdd22504aab src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Sat Oct 08 20:31:22 2011 +0300 +++ b/src/lib-imap-client/imapc-connection.c Sun Oct 09 16:41:17 2011 +0300 @@ -122,8 +122,7 @@ static int imapc_connection_output(struct imapc_connection *conn); static int imapc_connection_ssl_init(struct imapc_connection *conn); static void imapc_command_free(struct imapc_command *cmd); -static void imapc_command_send_more(struct imapc_connection *conn, - struct imapc_command *cmd); +static void imapc_command_send_more(struct imapc_connection *conn); struct imapc_connection * imapc_connection_init(struct imapc_client *client) @@ -253,9 +252,12 @@ static void imapc_connection_set_state(struct imapc_connection *conn, enum imapc_connection_state state) { - if (state == IMAPC_CONNECTION_STATE_DISCONNECTED) { - struct imapc_command_reply reply; + struct imapc_command_reply reply; + conn->state = state; + + switch (state) { + case IMAPC_CONNECTION_STATE_DISCONNECTED: memset(&reply, 0, sizeof(reply)); reply.state = IMAPC_COMMAND_STATE_DISCONNECTED; reply.text_without_resp = reply.text_full = @@ -269,15 +271,13 @@ conn->selecting_box = NULL; conn->selected_box = NULL; + break; + case IMAPC_CONNECTION_STATE_DONE: + imapc_command_send_more(conn); + break; + default: + break; } - if (state == IMAPC_CONNECTION_STATE_DONE) { - if (array_count(&conn->cmd_send_queue) > 0) { - struct imapc_command *const *cmd_p = - array_idx(&conn->cmd_send_queue, 0); - imapc_command_send_more(conn, *cmd_p); - } - } - conn->state = state; } static void imapc_connection_lfiles_free(struct imapc_connection *conn) @@ -330,6 +330,14 @@ imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DISCONNECTED); } +static void imapc_connection_reconnect(struct imapc_connection *conn) +{ + if (conn->selected_box != NULL) + imapc_client_mailbox_reconnect(conn->selected_box); + else + imapc_connection_disconnect(conn); +} + static void ATTR_FORMAT(2, 3) imapc_connection_input_error(struct imapc_connection *conn, const char *fmt, ...) @@ -339,7 +347,6 @@ va_start(va, fmt); i_error("imapc(%s): Server sent invalid input: %s", conn->name, t_strdup_vprintf(fmt, va)); - sleep(3600); imapc_connection_disconnect(conn); va_end(va); } @@ -636,6 +643,8 @@ timeout_remove(&conn->to); imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DONE); imapc_login_callback(conn, reply); + + imapc_command_send_more(conn); } static const char * @@ -678,6 +687,7 @@ cmd = imapc_connection_cmd(conn, imapc_connection_login_cb, conn); + imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_PRELOGIN); if ((set->master_user == NULL && need_literal(set->username) && need_literal(set->password)) || @@ -727,6 +737,7 @@ } cmd = imapc_connection_cmd(conn, imapc_connection_starttls_cb, conn); + imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_PRELOGIN); From dovecot at dovecot.org Sun Oct 9 17:07:28 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 09 Oct 2011 17:07:28 +0300 Subject: dovecot-2.1: imapc: Fixed detecting when messages are missing fr... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/305ca9c93dd7 changeset: 13622:305ca9c93dd7 user: Timo Sirainen date: Sun Oct 09 17:15:31 2011 +0300 description: imapc: Fixed detecting when messages are missing from index. diffstat: src/lib-storage/index/imapc/imapc-mail.c | 8 +--- src/lib-storage/index/imapc/imapc-mailbox.c | 13 +------ src/lib-storage/index/imapc/imapc-storage.c | 51 +++++++++++++++------------- src/lib-storage/index/imapc/imapc-storage.h | 5 +- src/lib-storage/index/imapc/imapc-sync.c | 36 +++++++++++++++---- 5 files changed, 61 insertions(+), 52 deletions(-) diffs (210 lines): diff -r 8fdd22504aab -r 305ca9c93dd7 src/lib-storage/index/imapc/imapc-mail.c --- a/src/lib-storage/index/imapc/imapc-mail.c Sun Oct 09 16:41:17 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mail.c Sun Oct 09 17:15:31 2011 +0300 @@ -30,8 +30,6 @@ { struct imapc_mailbox *mbox = (struct imapc_mailbox *)_mail->box; struct imapc_msgmap *msgmap; - struct imapc_command *cmd; - struct imapc_simple_context sctx; uint32_t lseq, rseq; if (mbox->sync_view != NULL) { @@ -47,11 +45,7 @@ /* we may be running against a server that hasn't bothered sending us an EXPUNGE. see if NOOP sends it. */ - imapc_simple_context_init(&sctx, mbox->storage); - cmd = imapc_client_mailbox_cmd(mbox->client_box, - imapc_simple_callback, &sctx); - imapc_command_send(cmd, "NOOP"); - imapc_simple_run(&sctx); + imapc_mailbox_noop(mbox); return !imapc_msgmap_uid_to_rseq(msgmap, _mail->uid, &rseq); } diff -r 8fdd22504aab -r 305ca9c93dd7 src/lib-storage/index/imapc/imapc-mailbox.c --- a/src/lib-storage/index/imapc/imapc-mailbox.c Sun Oct 09 16:41:17 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mailbox.c Sun Oct 09 17:15:31 2011 +0300 @@ -12,8 +12,8 @@ #define NOTIFY_DELAY_MSECS 500 -static void imapc_mailbox_set_corrupted(struct imapc_mailbox *mbox, - const char *reason, ...) +void imapc_mailbox_set_corrupted(struct imapc_mailbox *mbox, + const char *reason, ...) { va_list va; @@ -239,15 +239,6 @@ imapc_msgmap_append(msgmap, rseq, uid); if (uid < mbox->min_append_uid) { /* message is already added to index */ - if (!mbox->initial_sync_done && - !mail_index_lookup_seq(mbox->delayed_sync_view, - uid, lseq_r)) { - imapc_mailbox_set_corrupted(mbox, - "Expunged message reappeared " - "(uid=%u < next_uid=%u)", - uid, mbox->min_append_uid); - return -1; - } } else if (mbox->syncing) { mail_index_append(mbox->delayed_sync_trans, uid, lseq_r); diff -r 8fdd22504aab -r 305ca9c93dd7 src/lib-storage/index/imapc/imapc-storage.c --- a/src/lib-storage/index/imapc/imapc-storage.c Sun Oct 09 16:41:17 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-storage.c Sun Oct 09 17:15:31 2011 +0300 @@ -137,31 +137,16 @@ imapc_client_stop(ctx->storage->client); } -static void imapc_noop_callback(const struct imapc_command_reply *reply, - void *context) +void imapc_mailbox_noop(struct imapc_mailbox *mbox) +{ + struct imapc_command *cmd; + struct imapc_simple_context sctx; -{ - struct imapc_storage *storage = context; - - if (reply->state == IMAPC_COMMAND_STATE_OK) - ; - else if (reply->state == IMAPC_COMMAND_STATE_NO) - imapc_copy_error_from_reply(storage, MAIL_ERROR_PARAMS, reply); - else if (reply->state == IMAPC_COMMAND_STATE_DISCONNECTED) - mail_storage_set_internal_error(&storage->storage); - else { - mail_storage_set_critical(&storage->storage, - "imapc: NOOP failed: %s", reply->text_full); - } -} - -void imapc_noop_stop_callback(const struct imapc_command_reply *reply, - void *context) -{ - struct imapc_storage *storage = context; - - imapc_noop_callback(reply, context); - imapc_client_stop(storage->client); + imapc_simple_context_init(&sctx, mbox->storage); + cmd = imapc_client_mailbox_cmd(mbox->client_box, + imapc_simple_callback, &sctx); + imapc_command_send(cmd, "NOOP"); + imapc_simple_run(&sctx); } static void imapc_storage_untagged_cb(const struct imapc_untagged_reply *reply, @@ -657,6 +642,24 @@ return 0; } +static void imapc_noop_callback(const struct imapc_command_reply *reply, + void *context) + +{ + struct imapc_storage *storage = context; + + if (reply->state == IMAPC_COMMAND_STATE_OK) + ; + else if (reply->state == IMAPC_COMMAND_STATE_NO) + imapc_copy_error_from_reply(storage, MAIL_ERROR_PARAMS, reply); + else if (reply->state == IMAPC_COMMAND_STATE_DISCONNECTED) + mail_storage_set_internal_error(&storage->storage); + else { + mail_storage_set_critical(&storage->storage, + "imapc: NOOP failed: %s", reply->text_full); + } +} + static void imapc_idle_timeout(struct imapc_mailbox *mbox) { struct imapc_command *cmd; diff -r 8fdd22504aab -r 305ca9c93dd7 src/lib-storage/index/imapc/imapc-storage.h --- a/src/lib-storage/index/imapc/imapc-storage.h Sun Oct 09 16:41:17 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-storage.h Sun Oct 09 17:15:31 2011 +0300 @@ -116,10 +116,11 @@ void imapc_simple_run(struct imapc_simple_context *sctx); void imapc_simple_callback(const struct imapc_command_reply *reply, void *context); -void imapc_noop_stop_callback(const struct imapc_command_reply *reply, - void *context); int imapc_mailbox_commit_delayed_trans(struct imapc_mailbox *mbox, bool *changes_r); +void imapc_mailbox_noop(struct imapc_mailbox *mbox); +void imapc_mailbox_set_corrupted(struct imapc_mailbox *mbox, + const char *reason, ...); void imapc_storage_register_untagged(struct imapc_storage *storage, const char *name, diff -r 8fdd22504aab -r 305ca9c93dd7 src/lib-storage/index/imapc/imapc-sync.c --- a/src/lib-storage/index/imapc/imapc-sync.c Sun Oct 09 16:41:17 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-sync.c Sun Oct 09 17:15:31 2011 +0300 @@ -230,6 +230,26 @@ } } +static void imapc_initial_sync_check(struct imapc_sync_context *ctx) +{ + unsigned int idx_count; + + idx_count = mail_index_view_get_messages_count(ctx->mbox->delayed_sync_view); + if (idx_count >= ctx->mbox->exists_count) + return; + + /* NOOP should send EXPUNGEs */ + imapc_mailbox_noop(ctx->mbox); + + idx_count = mail_index_view_get_messages_count(ctx->mbox->delayed_sync_view); + if (idx_count < ctx->mbox->exists_count) { + imapc_mailbox_set_corrupted(ctx->mbox, + "Index is missing messages (%u < %u)", + idx_count, ctx->mbox->exists_count); + ctx->failed = TRUE; + } +} + static void imapc_sync_index(struct imapc_sync_context *ctx) { struct imapc_mailbox *mbox = ctx->mbox; @@ -292,10 +312,15 @@ /* add uidnext after all appends */ imapc_sync_uid_next(ctx); - imapc_sync_expunge_eom(ctx); + if (!ctx->failed) + imapc_sync_expunge_eom(ctx); if (mbox->box.v.sync_notify != NULL) mbox->box.v.sync_notify(&mbox->box, 0, 0); - mbox->initial_sync_done = TRUE; + + if (!mbox->initial_sync_done) { + imapc_initial_sync_check(ctx); + mbox->initial_sync_done = TRUE; + } } static int @@ -390,7 +415,6 @@ imapc_mailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags) { struct imapc_mailbox *mbox = (struct imapc_mailbox *)box; - struct imapc_command *cmd; enum imapc_capability capabilities; bool changes; int ret = 0; @@ -404,11 +428,7 @@ if ((capabilities & IMAPC_CAPABILITY_IDLE) == 0) { /* IDLE not supported. do NOOP to get latest changes before starting sync. */ - cmd = imapc_client_mailbox_cmd(mbox->client_box, - imapc_noop_stop_callback, - mbox->storage); - imapc_command_send(cmd, "NOOP"); - imapc_storage_run(mbox->storage); + imapc_mailbox_noop(mbox); } if (imapc_mailbox_commit_delayed_trans(mbox, &changes) < 0) From dovecot at dovecot.org Sun Oct 9 18:56:12 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 09 Oct 2011 18:56:12 +0300 Subject: dovecot-2.1: imapc: Better implementation of checking if index i... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/2ecf19d88f8e changeset: 13624:2ecf19d88f8e user: Timo Sirainen date: Sun Oct 09 18:27:54 2011 +0300 description: imapc: Better implementation of checking if index is missing messages. diffstat: src/lib-storage/index/imapc/imapc-sync.c | 72 +++++++++++++++++++++++++------ 1 files changed, 57 insertions(+), 15 deletions(-) diffs (101 lines): diff -r 256b9b32b242 -r 2ecf19d88f8e src/lib-storage/index/imapc/imapc-sync.c --- a/src/lib-storage/index/imapc/imapc-sync.c Sun Oct 09 18:25:18 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-sync.c Sun Oct 09 18:27:54 2011 +0300 @@ -5,8 +5,9 @@ #include "str.h" #include "imap-util.h" #include "index-sync-private.h" +#include "imapc-client.h" +#include "imapc-msgmap.h" #include "imapc-storage.h" -#include "imapc-client.h" #include "imapc-sync.h" static void imapc_sync_callback(const struct imapc_command_reply *reply, @@ -230,23 +231,63 @@ } } -static void imapc_initial_sync_check(struct imapc_sync_context *ctx) +static void +imapc_initial_sync_check(struct imapc_sync_context *ctx, bool nooped) { - unsigned int idx_count; + struct imapc_msgmap *msgmap = + imapc_client_mailbox_get_msgmap(ctx->mbox->client_box); + struct mail_index_view *view = ctx->mbox->delayed_sync_view; + const struct mail_index_header *hdr = mail_index_get_header(view); + uint32_t rseq, lseq, ruid, luid, rcount, lcount; - idx_count = mail_index_view_get_messages_count(ctx->mbox->delayed_sync_view); - if (idx_count >= ctx->mbox->exists_count) - return; + rseq = lseq = 1; + rcount = imapc_msgmap_count(msgmap); + lcount = mail_index_view_get_messages_count(view); + while (rseq <= rcount || lseq <= lcount) { + if (rseq <= rcount) + ruid = imapc_msgmap_rseq_to_uid(msgmap, rseq); + else + ruid = (uint32_t)-1; + if (lseq <= lcount) + mail_index_lookup_uid(view, lseq, &luid); + else + luid = (uint32_t)-1; - /* NOOP should send EXPUNGEs */ - imapc_mailbox_noop(ctx->mbox); + if (ruid == luid) { + /* message exists in index and in remote server */ + lseq++; rseq++; + } else if (luid < ruid) { + /* message exists in index but not in remote server */ + if (luid >= ctx->mbox->sync_uid_next) { + /* the message was added to index by another + imapc session, and it's not visible yet + in this session */ + break; + } + /* it's already expunged and we should have marked it */ + i_assert(mail_index_is_expunged(view, lseq)); + lseq++; + } else { + /* message doesn't exist in index, but exists in + remote server */ + if (lseq > lcount && ruid >= hdr->next_uid) { + /* the message hasn't been yet added to index */ + break; + } - idx_count = mail_index_view_get_messages_count(ctx->mbox->delayed_sync_view); - if (idx_count < ctx->mbox->exists_count) { - imapc_mailbox_set_corrupted(ctx->mbox, - "Index is missing messages (%u < %u)", - idx_count, ctx->mbox->exists_count); - ctx->failed = TRUE; + /* another imapc session expunged it => + NOOP should send us an EXPUNGE event */ + if (!nooped) { + imapc_mailbox_noop(ctx->mbox); + imapc_initial_sync_check(ctx, TRUE); + return; + } + /* already nooped => index is corrupted */ + imapc_mailbox_set_corrupted(ctx->mbox, + "Expunged message uid=%u reappeared", ruid); + ctx->failed = TRUE; + rseq++; + } } } @@ -318,7 +359,8 @@ mbox->box.v.sync_notify(&mbox->box, 0, 0); if (!mbox->initial_sync_done) { - imapc_initial_sync_check(ctx); + if (!ctx->failed) + imapc_initial_sync_check(ctx, FALSE); mbox->initial_sync_done = TRUE; } } From dovecot at dovecot.org Sun Oct 9 18:56:12 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 09 Oct 2011 18:56:12 +0300 Subject: dovecot-2.1: imapc: Fixes to sending commands. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/256b9b32b242 changeset: 13623:256b9b32b242 user: Timo Sirainen date: Sun Oct 09 18:25:18 2011 +0300 description: imapc: Fixes to sending commands. diffstat: src/lib-imap-client/imapc-connection.c | 38 +++++++++++++++++---------------- 1 files changed, 20 insertions(+), 18 deletions(-) diffs (82 lines): diff -r 305ca9c93dd7 -r 256b9b32b242 src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Sun Oct 09 17:15:31 2011 +0300 +++ b/src/lib-imap-client/imapc-connection.c Sun Oct 09 18:25:18 2011 +0300 @@ -873,6 +873,9 @@ /* "+ idling" reply for IDLE command */ conn->idle_plus_waiting = FALSE; conn->idling = TRUE; + /* no timeouting while IDLEing */ + if (conn->to != NULL) + timeout_remove(&conn->to); } else if (cmds_count > 0 && cmds[0]->wait_for_literal) { /* reply for literal */ cmds[0]->wait_for_literal = FALSE; @@ -1372,8 +1375,8 @@ return TRUE; } -static void imapc_command_send_done(struct imapc_connection *conn, - struct imapc_command *cmd) +static void imapc_command_send_finished(struct imapc_connection *conn, + struct imapc_command *cmd) { if (cmd->idle) conn->idle_plus_waiting = TRUE; @@ -1487,6 +1490,7 @@ array_delete(&conn->cmd_send_queue, 0, 1); imapc_command_reply_free(cmd, &reply); + imapc_command_send_more(conn); return; } @@ -1524,7 +1528,7 @@ if (cmd->send_pos == cmd->data->used) { i_assert(!array_is_created(&cmd->streams) || array_count(&cmd->streams) == 0); - imapc_command_send_done(conn, cmd); + imapc_command_send_finished(conn, cmd); } else { cmd->wait_for_literal = TRUE; } @@ -1556,27 +1560,25 @@ struct imapc_connection *conn = cmd->conn; imapc_connection_send_idle_done(conn); - switch (conn->state) { - case IMAPC_CONNECTION_STATE_AUTHENTICATING: + + if ((cmd->flags & IMAPC_COMMAND_FLAG_PRELOGIN) != 0 && + conn->state == IMAPC_CONNECTION_STATE_AUTHENTICATING) { + /* pre-login commands get inserted before everything else */ array_insert(&conn->cmd_send_queue, 0, &cmd, 1); imapc_command_send_more(conn); - break; - case IMAPC_CONNECTION_STATE_DONE: - if (cmd->idle) { - if (conn->to != NULL) - timeout_remove(&conn->to); - } else if (conn->to == NULL) { + return; + } + + if (conn->state == IMAPC_CONNECTION_STATE_DONE) { + /* add timeout for commands if there's not one yet + (pre-login has its own timeout) */ + if (conn->to == NULL) { conn->to = timeout_add(IMAPC_COMMAND_TIMEOUT_MSECS, imapc_command_timeout, conn); } - - array_append(&conn->cmd_send_queue, &cmd, 1); - imapc_command_send_more(conn); - break; - default: - array_append(&conn->cmd_send_queue, &cmd, 1); - break; } + array_append(&conn->cmd_send_queue, &cmd, 1); + imapc_command_send_more(conn); } static int imapc_connection_output(struct imapc_connection *conn) From dovecot at dovecot.org Sun Oct 9 18:56:12 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 09 Oct 2011 18:56:12 +0300 Subject: dovecot-2.1: imapc: Mailbox reopening fix. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/2dbc6108f090 changeset: 13626:2dbc6108f090 user: Timo Sirainen date: Sun Oct 09 19:04:27 2011 +0300 description: imapc: Mailbox reopening fix. diffstat: src/lib-storage/index/imapc/imapc-storage.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r d8ba3f6d1b9d -r 2dbc6108f090 src/lib-storage/index/imapc/imapc-storage.c --- a/src/lib-storage/index/imapc/imapc-storage.c Sun Oct 09 19:04:15 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-storage.c Sun Oct 09 19:04:27 2011 +0300 @@ -368,6 +368,8 @@ /* we're reconnecting and need to reopen the mailbox */ mbox->initial_sync_done = FALSE; mbox->selecting = TRUE; + mbox->prev_skipped_rseq = 0; + mbox->prev_skipped_uid = 0; imapc_msgmap_reset(imapc_client_mailbox_get_msgmap(mbox->client_box)); cmd = imapc_client_mailbox_cmd(mbox->client_box, From dovecot at dovecot.org Sun Oct 9 18:56:12 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 09 Oct 2011 18:56:12 +0300 Subject: dovecot-2.1: imapc: Fixed expunging too many messages from index. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/d8ba3f6d1b9d changeset: 13625:d8ba3f6d1b9d user: Timo Sirainen date: Sun Oct 09 19:04:15 2011 +0300 description: imapc: Fixed expunging too many messages from index. diffstat: src/lib-storage/index/imapc/imapc-mailbox.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (24 lines): diff -r 2ecf19d88f8e -r d8ba3f6d1b9d src/lib-storage/index/imapc/imapc-mailbox.c --- a/src/lib-storage/index/imapc/imapc-mailbox.c Sun Oct 09 18:27:54 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mailbox.c Sun Oct 09 19:04:15 2011 +0300 @@ -312,10 +312,11 @@ if (!mail_index_lookup_seq(mbox->delayed_sync_view, uid, &lseq)) { /* already expunged by another session */ + if (rseq == mbox->sync_next_rseq) + mbox->sync_next_rseq++; return; } } - rec = mail_index_lookup(mbox->delayed_sync_view, lseq); if (rseq == mbox->sync_next_rseq) { /* we're doing the initial full sync of mails. expunge any @@ -332,6 +333,7 @@ mbox->sync_next_lseq++; } + rec = mail_index_lookup(mbox->delayed_sync_view, lseq); if (seen_flags && rec->flags != flags) { mail_index_update_flags(mbox->delayed_sync_trans, lseq, MODIFY_REPLACE, flags); From dovecot at dovecot.org Sun Oct 9 20:28:07 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 09 Oct 2011 20:28:07 +0300 Subject: dovecot-2.1: lib-imap: Added reference counting to imap parser. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/f63f2b2217c3 changeset: 13627:f63f2b2217c3 user: Timo Sirainen date: Sun Oct 09 20:36:28 2011 +0300 description: lib-imap: Added reference counting to imap parser. diffstat: src/director/director-test.c | 2 +- src/imap-login/client.c | 4 ++-- src/imap/cmd-append.c | 2 +- src/imap/imap-client.c | 6 +++--- src/lib-imap-client/imapc-connection.c | 2 +- src/lib-imap/imap-bodystructure.c | 2 +- src/lib-imap/imap-envelope.c | 2 +- src/lib-imap/imap-id.c | 2 +- src/lib-imap/imap-parser.c | 16 +++++++++++++++- src/lib-imap/imap-parser.h | 3 ++- src/lib-imap/test-imap-parser.c | 2 +- src/plugins/virtual/virtual-config.c | 2 +- 12 files changed, 30 insertions(+), 15 deletions(-) diffs (201 lines): diff -r 2dbc6108f090 -r f63f2b2217c3 src/director/director-test.c --- a/src/director/director-test.c Sun Oct 09 19:04:27 2011 +0300 +++ b/src/director/director-test.c Sun Oct 09 20:36:28 2011 +0300 @@ -275,7 +275,7 @@ } DLLIST_REMOVE(&imap_clients, client); - imap_parser_destroy(&client->parser); + imap_parser_unref(&client->parser); io_remove(&client->io); i_stream_unref(&client->input); o_stream_unref(&client->output); diff -r 2dbc6108f090 -r f63f2b2217c3 src/imap-login/client.c --- a/src/imap-login/client.c Sun Oct 09 19:04:27 2011 +0300 +++ b/src/imap-login/client.c Sun Oct 09 20:36:28 2011 +0300 @@ -365,7 +365,7 @@ struct imap_client *imap_client = (struct imap_client *)client; i_free_and_null(imap_client->proxy_backend_capability); - imap_parser_destroy(&imap_client->parser); + imap_parser_unref(&imap_client->parser); } static void imap_client_send_greeting(struct client *client) @@ -386,7 +386,7 @@ { struct imap_client *imap_client = (struct imap_client *)client; - imap_parser_destroy(&imap_client->parser); + imap_parser_unref(&imap_client->parser); imap_client->parser = imap_parser_create(imap_client->common.input, imap_client->common.output, MAX_IMAP_LINE); diff -r 2dbc6108f090 -r f63f2b2217c3 src/imap/cmd-append.c --- a/src/imap/cmd-append.c Sun Oct 09 19:04:27 2011 +0300 +++ b/src/imap/cmd-append.c Sun Oct 09 20:36:28 2011 +0300 @@ -145,7 +145,7 @@ static void cmd_append_finish(struct cmd_append_context *ctx) { - imap_parser_destroy(&ctx->save_parser); + imap_parser_unref(&ctx->save_parser); i_assert(ctx->client->input_lock == ctx->cmd); diff -r 2dbc6108f090 -r f63f2b2217c3 src/imap/imap-client.c --- a/src/imap/imap-client.c Sun Oct 09 19:04:27 2011 +0300 +++ b/src/imap/imap-client.c Sun Oct 09 20:36:28 2011 +0300 @@ -44,7 +44,7 @@ net_set_nonblock(fd_in, TRUE); net_set_nonblock(fd_out, TRUE); - pool = pool_alloconly_create("imap client", 1024); + pool = pool_alloconly_create("imap client", 2048); client = p_new(pool, struct client, 1); client->pool = pool; client->set = set; @@ -210,7 +210,7 @@ mail_user_unref(&client->user); if (client->free_parser != NULL) - imap_parser_destroy(&client->free_parser); + imap_parser_unref(&client->free_parser); if (client->io != NULL) io_remove(&client->io); if (client->to_idle_output != NULL) @@ -548,7 +548,7 @@ client->mailbox_change_lock = NULL; if (client->free_parser != NULL) - imap_parser_destroy(&cmd->parser); + imap_parser_unref(&cmd->parser); else { imap_parser_reset(cmd->parser); client->free_parser = cmd->parser; diff -r 2dbc6108f090 -r f63f2b2217c3 src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Sun Oct 09 19:04:27 2011 +0300 +++ b/src/lib-imap-client/imapc-connection.c Sun Oct 09 20:36:28 2011 +0300 @@ -318,7 +318,7 @@ timeout_remove(&conn->to); if (conn->to_output != NULL) timeout_remove(&conn->to_output); - imap_parser_destroy(&conn->parser); + imap_parser_unref(&conn->parser); io_remove(&conn->io); if (conn->ssl_iostream != NULL) ssl_iostream_unref(&conn->ssl_iostream); diff -r 2dbc6108f090 -r f63f2b2217c3 src/lib-imap/imap-bodystructure.c --- a/src/lib-imap/imap-bodystructure.c Sun Oct 09 19:04:27 2011 +0300 +++ b/src/lib-imap/imap-bodystructure.c Sun Oct 09 20:36:28 2011 +0300 @@ -715,7 +715,7 @@ if (!ret) i_error("Error parsing IMAP bodystructure: %s", bodystructure); - imap_parser_destroy(&parser); + imap_parser_unref(&parser); i_stream_destroy(&input); return ret; } diff -r 2dbc6108f090 -r f63f2b2217c3 src/lib-imap/imap-envelope.c --- a/src/lib-imap/imap-envelope.c Sun Oct 09 19:04:27 2011 +0300 +++ b/src/lib-imap/imap-envelope.c Sun Oct 09 20:36:28 2011 +0300 @@ -392,7 +392,7 @@ ret = FALSE; } - imap_parser_destroy(&parser); + imap_parser_unref(&parser); i_stream_destroy(&input); return ret; } diff -r 2dbc6108f090 -r f63f2b2217c3 src/lib-imap/imap-id.c --- a/src/lib-imap/imap-id.c Sun Oct 09 19:04:27 2011 +0300 +++ b/src/lib-imap/imap-id.c Sun Oct 09 20:36:28 2011 +0300 @@ -118,7 +118,7 @@ else ret = imap_id_reply_generate_from_imap_args(args); - imap_parser_destroy(&parser); + imap_parser_unref(&parser); i_stream_destroy(&input); return ret; } diff -r 2dbc6108f090 -r f63f2b2217c3 src/lib-imap/imap-parser.c --- a/src/lib-imap/imap-parser.c Sun Oct 09 19:04:27 2011 +0300 +++ b/src/lib-imap/imap-parser.c Sun Oct 09 20:36:28 2011 +0300 @@ -22,6 +22,7 @@ struct imap_parser { /* permanent */ + int refcount; pool_t pool; struct istream *input; struct ostream *output; @@ -56,6 +57,7 @@ struct imap_parser *parser; parser = i_new(struct imap_parser, 1); + parser->refcount = 1; parser->pool = pool_alloconly_create(MEMPOOL_GROWING"IMAP parser", 1024*10); parser->input = input; @@ -67,8 +69,20 @@ return parser; } -void imap_parser_destroy(struct imap_parser **parser) +void imap_parser_ref(struct imap_parser *parser) { + i_assert(parser->refcount > 0); + + parser->refcount++; +} + +void imap_parser_unref(struct imap_parser **parser) +{ + i_assert((*parser)->refcount > 0); + + if (--(*parser)->refcount > 0) + return; + pool_unref(&(*parser)->pool); i_free(*parser); *parser = NULL; diff -r 2dbc6108f090 -r f63f2b2217c3 src/lib-imap/imap-parser.h --- a/src/lib-imap/imap-parser.h Sun Oct 09 19:04:27 2011 +0300 +++ b/src/lib-imap/imap-parser.h Sun Oct 09 20:36:28 2011 +0300 @@ -35,7 +35,8 @@ struct imap_parser * imap_parser_create(struct istream *input, struct ostream *output, size_t max_line_size); -void imap_parser_destroy(struct imap_parser **parser); +void imap_parser_ref(struct imap_parser *parser); +void imap_parser_unref(struct imap_parser **parser); /* Reset the parser to initial state. */ void imap_parser_reset(struct imap_parser *parser); diff -r 2dbc6108f090 -r f63f2b2217c3 src/lib-imap/test-imap-parser.c --- a/src/lib-imap/test-imap-parser.c Sun Oct 09 19:04:27 2011 +0300 +++ b/src/lib-imap/test-imap-parser.c Sun Oct 09 20:36:28 2011 +0300 @@ -44,7 +44,7 @@ test_assert(imap_parser_read_args(parser, 0, 0, &args) == -1); test_assert(strcmp(imap_parser_get_error(parser, &fatal), "CR sent without LF") == 0 && !fatal); - imap_parser_destroy(&parser); + imap_parser_unref(&parser); i_stream_destroy(&input); test_end(); } diff -r 2dbc6108f090 -r f63f2b2217c3 src/plugins/virtual/virtual-config.c --- a/src/plugins/virtual/virtual-config.c Sun Oct 09 19:04:27 2011 +0300 +++ b/src/plugins/virtual/virtual-config.c Sun Oct 09 20:36:28 2011 +0300 @@ -63,7 +63,7 @@ mail_search_parser_deinit(&parser); } - imap_parser_destroy(&imap_parser); + imap_parser_unref(&imap_parser); i_stream_destroy(&input); return sargs; } From dovecot at dovecot.org Sun Oct 9 20:29:51 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 09 Oct 2011 20:29:51 +0300 Subject: dovecot-2.1: imapc: Support retrying some IMAP commands if we ge... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/c9594ff166a9 changeset: 13628:c9594ff166a9 user: Timo Sirainen date: Sun Oct 09 20:38:11 2011 +0300 description: imapc: Support retrying some IMAP commands if we get disconnected. diffstat: src/lib-imap-client/imapc-client-private.h | 1 + src/lib-imap-client/imapc-client.c | 19 ++- src/lib-imap-client/imapc-connection.c | 157 +++++++++++++++--------- src/lib-imap-client/imapc-connection.h | 1 + src/lib-storage/index/imapc/imapc-mail-fetch.c | 1 + src/lib-storage/index/imapc/imapc-storage.c | 3 + src/lib-storage/index/imapc/imapc-storage.h | 1 + src/lib-storage/index/imapc/imapc-sync.c | 17 ++ src/lib-storage/index/imapc/imapc-sync.h | 1 + 9 files changed, 142 insertions(+), 59 deletions(-) diffs (truncated from 455 to 300 lines): diff -r f63f2b2217c3 -r c9594ff166a9 src/lib-imap-client/imapc-client-private.h --- a/src/lib-imap-client/imapc-client-private.h Sun Oct 09 20:36:28 2011 +0300 +++ b/src/lib-imap-client/imapc-client-private.h Sun Oct 09 20:38:11 2011 +0300 @@ -35,6 +35,7 @@ unsigned int pending_box_command_count; bool reconnect_ok; + bool reconnecting; }; void imapc_client_ref(struct imapc_client *client); diff -r f63f2b2217c3 -r c9594ff166a9 src/lib-imap-client/imapc-client.c --- a/src/lib-imap-client/imapc-client.c Sun Oct 09 20:36:28 2011 +0300 +++ b/src/lib-imap-client/imapc-client.c Sun Oct 09 20:38:11 2011 +0300 @@ -258,16 +258,27 @@ { struct imapc_client_mailbox *box = context; + i_assert(box->reconnecting); + box->reconnecting = FALSE; + if (reply->state == IMAPC_COMMAND_STATE_OK) { /* reopen the mailbox */ box->reopen_callback(box->reopen_context); + } else { + imapc_connection_abort_commands(box->conn); } } void imapc_client_mailbox_reconnect(struct imapc_client_mailbox *box) { + bool reconnect = box->reopen_callback != NULL && box->reconnect_ok; + + if (reconnect) { + i_assert(!box->reconnecting); + box->reconnecting = TRUE; + } imapc_connection_disconnect(box->conn); - if (box->reopen_callback != NULL && box->reconnect_ok) { + if (reconnect) { imapc_connection_connect(box->conn, imapc_client_reconnect_cb, box); } @@ -282,6 +293,12 @@ /* cancel any pending commands */ imapc_connection_unselect(box); + if (box->reconnecting) { + /* need to abort the reconnection so it won't try to access + the box */ + imapc_connection_disconnect(box->conn); + } + /* set this only after unselect, which may cancel some commands that reference this box */ *_box = NULL; diff -r f63f2b2217c3 -r c9594ff166a9 src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Sun Oct 09 20:36:28 2011 +0300 +++ b/src/lib-imap-client/imapc-connection.c Sun Oct 09 20:38:11 2011 +0300 @@ -63,6 +63,7 @@ /* Waiting for '+' literal reply before we can continue */ unsigned int wait_for_literal:1; }; +ARRAY_DEFINE_TYPE(imapc_command, struct imapc_command *); struct imapc_connection_literal { char *temp_path; @@ -103,9 +104,9 @@ void *login_context; /* commands pending in queue to be sent */ - ARRAY_DEFINE(cmd_send_queue, struct imapc_command *); + ARRAY_TYPE(imapc_command) cmd_send_queue; /* commands that have been sent, waiting for their tagged reply */ - ARRAY_DEFINE(cmd_wait_list, struct imapc_command *); + ARRAY_TYPE(imapc_command) cmd_wait_list; unsigned int ips_count, prev_connect_idx; struct ip_addr *ips; @@ -209,29 +210,70 @@ } static void -imapc_connection_abort_pending_commands(struct imapc_connection *conn, - const struct imapc_command_reply *reply) +imapc_connection_abort_commands_array(ARRAY_TYPE(imapc_command) *cmd_array, + ARRAY_TYPE(imapc_command) *dest_array, + bool keep_retriable) { struct imapc_command *const *cmdp, *cmd; + unsigned int i; - while (array_count(&conn->cmd_wait_list) > 0) { - cmdp = array_idx(&conn->cmd_wait_list, 0); + for (i = 0; i < array_count(cmd_array); ) { + cmdp = array_idx(cmd_array, i); cmd = *cmdp; - array_delete(&conn->cmd_wait_list, 0, 1); - if (cmd->callback != NULL) - cmd->callback(reply, cmd->context); + if (keep_retriable && + (cmd->flags & IMAPC_COMMAND_FLAG_RETRIABLE) != 0) { + cmd->send_pos = 0; + cmd->wait_for_literal = 0; + i++; + } else { + array_delete(cmd_array, i, 1); + array_append(dest_array, &cmd, 1); + } + } +} + +static void +imapc_connection_abort_commands_full(struct imapc_connection *conn, + bool keep_retriable) +{ + struct imapc_command *const *cmdp, *cmd; + ARRAY_TYPE(imapc_command) tmp_array; + struct imapc_command_reply reply; + + t_array_init(&tmp_array, 8); + imapc_connection_abort_commands_array(&conn->cmd_wait_list, + &tmp_array, keep_retriable); + imapc_connection_abort_commands_array(&conn->cmd_send_queue, + &tmp_array, keep_retriable); + + if (array_count(&conn->cmd_wait_list) > 0) { + /* need to move all the waiting commands to send queue */ + array_append_array(&conn->cmd_wait_list, + &conn->cmd_send_queue); + array_clear(&conn->cmd_send_queue); + array_append_array(&conn->cmd_send_queue, + &conn->cmd_wait_list); + array_clear(&conn->cmd_wait_list); + } + + /* abort the commands. we'll do it here later so that if the + callback recurses us back here we don't crash */ + memset(&reply, 0, sizeof(reply)); + reply.state = IMAPC_COMMAND_STATE_DISCONNECTED; + reply.text_without_resp = reply.text_full = + "Disconnected from server"; + array_foreach(&tmp_array, cmdp) { + cmd = *cmdp; + + cmd->callback(&reply, cmd->context); imapc_command_free(cmd); } - while (array_count(&conn->cmd_send_queue) > 0) { - cmdp = array_idx(&conn->cmd_send_queue, 0); - cmd = *cmdp; - array_delete(&conn->cmd_send_queue, 0, 1); +} - if (cmd->callback != NULL) - cmd->callback(reply, cmd->context); - imapc_command_free(cmd); - } +void imapc_connection_abort_commands(struct imapc_connection *conn) +{ + imapc_connection_abort_commands_full(conn, FALSE); } static void @@ -262,7 +304,6 @@ reply.state = IMAPC_COMMAND_STATE_DISCONNECTED; reply.text_without_resp = reply.text_full = "Disconnected from server"; - imapc_connection_abort_pending_commands(conn, &reply); imapc_login_callback(conn, &reply); conn->idling = FALSE; @@ -272,9 +313,6 @@ conn->selecting_box = NULL; conn->selected_box = NULL; break; - case IMAPC_CONNECTION_STATE_DONE: - imapc_command_send_more(conn); - break; default: break; } @@ -306,6 +344,9 @@ void imapc_connection_disconnect(struct imapc_connection *conn) { + bool reconnecting = conn->selected_box != NULL && + conn->selected_box->reconnecting; + if (conn->fd == -1) return; @@ -327,6 +368,13 @@ net_disconnect(conn->fd); conn->fd = -1; + imapc_connection_abort_commands_full(conn, reconnecting); + imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DISCONNECTED); +} + +static void imapc_connection_set_disconnected(struct imapc_connection *conn) +{ + imapc_connection_abort_commands(conn); imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DISCONNECTED); } @@ -794,6 +842,7 @@ { const struct imap_arg *imap_args; const char *name, *value; + struct imap_parser *parser; struct imapc_untagged_reply reply; int ret; @@ -854,7 +903,12 @@ reply.untagged_box_context = conn->selected_box->untagged_box_context; } + + /* the callback may disconnect and destroy the parser */ + parser = conn->parser; + imap_parser_ref(parser); conn->client->untagged_callback(&reply, conn->client->untagged_context); + imap_parser_unref(&parser); imapc_connection_input_reset(conn); return 1; } @@ -893,8 +947,7 @@ imapc_command_reply_free(struct imapc_command *cmd, const struct imapc_command_reply *reply) { - if (cmd->callback != NULL) - cmd->callback(reply, cmd->context); + cmd->callback(reply, cmd->context); imapc_command_free(cmd); } @@ -904,6 +957,7 @@ unsigned int i, count; char *line, *linep; const char *p; + struct imap_parser *parser; struct imapc_command_reply reply; line = i_stream_next_line(conn->input); @@ -985,7 +1039,13 @@ } imapc_connection_input_reset(conn); + + parser = conn->parser; + imap_parser_ref(parser); imapc_command_reply_free(cmd, &reply); + imap_parser_unref(&parser); + + imapc_command_send_more(conn); return 1; } @@ -1215,8 +1275,7 @@ ip = &conn->ips[conn->prev_connect_idx]; fd = net_connect_ip(ip, conn->client->set.port, NULL); if (fd == -1) { - imapc_connection_set_state(conn, - IMAPC_CONNECTION_STATE_DISCONNECTED); + imapc_connection_set_disconnected(conn); return; } conn->fd = fd; @@ -1252,8 +1311,7 @@ if (result->ret != 0) { i_error("imapc(%s): dns_lookup(%s) failed: %s", conn->name, conn->client->set.host, result->error); - imapc_connection_set_state(conn, - IMAPC_CONNECTION_STATE_DISCONNECTED); + imapc_connection_set_disconnected(conn); return; } @@ -1483,10 +1541,14 @@ /* SELECT/EXAMINE command */ imapc_connection_set_selecting(cmd->box); } else if (!imapc_client_mailbox_is_opened(cmd->box)) { + if (cmd->box->reconnecting) { + /* wait for SELECT/EXAMINE */ + return; + } /* shouldn't normally happen */ memset(&reply, 0, sizeof(reply)); reply.text_without_resp = reply.text_full = "Mailbox not open"; - reply.state = IMAPC_COMMAND_STATE_BAD; + reply.state = IMAPC_COMMAND_STATE_DISCONNECTED; array_delete(&conn->cmd_send_queue, 0, 1); imapc_command_reply_free(cmd, &reply); @@ -1577,7 +1639,14 @@ imapc_command_timeout, conn); } } From dovecot at dovecot.org Sun Oct 9 20:38:33 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 09 Oct 2011 20:38:33 +0300 Subject: dovecot-2.1: imapc: Post-login capabilities weren't detected/used. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/8a2ec8284b61 changeset: 13629:8a2ec8284b61 user: Timo Sirainen date: Sun Oct 09 20:46:28 2011 +0300 description: imapc: Post-login capabilities weren't detected/used. diffstat: src/lib-imap-client/imapc-connection.c | 7 ++----- 1 files changed, 2 insertions(+), 5 deletions(-) diffs (24 lines): diff -r c9594ff166a9 -r 8a2ec8284b61 src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Sun Oct 09 20:38:11 2011 +0300 +++ b/src/lib-imap-client/imapc-connection.c Sun Oct 09 20:46:28 2011 +0300 @@ -618,7 +618,7 @@ *key_r = text; *value_r = NULL; } - return 0; + return imapc_connection_handle_resp_text_code(conn, *key_r, *value_r); } static int @@ -640,10 +640,7 @@ } return 0; } - if (imapc_connection_handle_resp_text(conn, text, key_r, value_r) < 0) - return -1; - - return imapc_connection_handle_resp_text_code(conn, *key_r, *value_r); + return imapc_connection_handle_resp_text(conn, text, key_r, value_r); } static bool need_literal(const char *str) From dovecot at dovecot.org Sun Oct 9 20:38:33 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 09 Oct 2011 20:38:33 +0300 Subject: dovecot-2.1: imapc: When asking for capabilities, try to ask fro... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/337f4e427bb1 changeset: 13630:337f4e427bb1 user: Timo Sirainen date: Sun Oct 09 20:46:53 2011 +0300 description: imapc: When asking for capabilities, try to ask from a logged in connection. diffstat: src/lib-imap-client/imapc-client.c | 12 ++++++++++-- 1 files changed, 10 insertions(+), 2 deletions(-) diffs (23 lines): diff -r 8a2ec8284b61 -r 337f4e427bb1 src/lib-imap-client/imapc-client.c --- a/src/lib-imap-client/imapc-client.c Sun Oct 09 20:46:28 2011 +0300 +++ b/src/lib-imap-client/imapc-client.c Sun Oct 09 20:46:53 2011 +0300 @@ -358,9 +358,17 @@ imapc_client_get_capabilities(struct imapc_client *client) { struct imapc_client_connection *const *connp; + struct imapc_connection *conn = NULL; - connp = array_idx(&client->conns, 0); - return imapc_connection_get_capabilities((*connp)->conn); + /* try to find a connection that is already logged in */ + array_foreach(&client->conns, connp) { + conn = (*connp)->conn; + if (imapc_connection_get_state(conn) == IMAPC_CONNECTION_STATE_DONE) + return imapc_connection_get_capabilities(conn); + } + + /* fallback to whatever exists (there always exists one) */ + return imapc_connection_get_capabilities(conn); } int imapc_client_create_temp_fd(struct imapc_client *client, From dovecot at dovecot.org Wed Oct 12 17:07:55 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 12 Oct 2011 17:07:55 +0300 Subject: dovecot-2.0: mdbox: Don't assert-crash on storage rebuild if a m... Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/962df5d9413a changeset: 12947:962df5d9413a user: Timo Sirainen date: Wed Oct 12 17:16:10 2011 +0300 description: mdbox: Don't assert-crash on storage rebuild if a mailbox name is invalid. diffstat: src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (15 lines): diff -r f6a2c0e8bc03 -r 962df5d9413a src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c --- a/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c Fri Oct 07 19:25:01 2011 +0300 +++ b/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c Wed Oct 12 17:16:10 2011 +0300 @@ -500,6 +500,11 @@ int ret; name = mail_namespace_get_storage_name(ns, vname); + if (!mailbox_list_is_valid_existing_name(ns->list, name)) { + i_warning("Invalid mailbox name: %s", name); + return 0; + } + box = mailbox_alloc(ns->list, name, MAILBOX_FLAG_READONLY | MAILBOX_FLAG_KEEP_RECENT | MAILBOX_FLAG_IGNORE_ACLS); From dovecot at dovecot.org Wed Oct 12 18:58:48 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 12 Oct 2011 18:58:48 +0300 Subject: dovecot-2.1: imapc: Mail body wasn't always prefetched when it s... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/d2608fc3c9e2 changeset: 13631:d2608fc3c9e2 user: Timo Sirainen date: Wed Oct 12 19:07:07 2011 +0300 description: imapc: Mail body wasn't always prefetched when it should have been. diffstat: src/lib-storage/index/imapc/imapc-mail.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 337f4e427bb1 -r d2608fc3c9e2 src/lib-storage/index/imapc/imapc-mail.c --- a/src/lib-storage/index/imapc/imapc-mail.c Sun Oct 09 20:46:53 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mail.c Wed Oct 12 19:07:07 2011 +0300 @@ -150,7 +150,7 @@ return mail_set_aborted(_mail); } fetch_field = get_body || - (mail->imail.wanted_fields & MAIL_FETCH_STREAM_BODY) != 0 ? + (data->access_part & READ_BODY) != 0 ? MAIL_FETCH_STREAM_BODY : MAIL_FETCH_STREAM_HEADER; if (imapc_mail_fetch(_mail, fetch_field) < 0) return -1; From dovecot at dovecot.org Wed Oct 12 18:59:25 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 12 Oct 2011 18:59:25 +0300 Subject: dovecot-2.1: mdbox rebuild: Log an error whenever opening a mail... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/fad85406a088 changeset: 13632:fad85406a088 user: Timo Sirainen date: Wed Oct 12 17:21:01 2011 +0300 description: mdbox rebuild: Log an error whenever opening a mailbox fails. diffstat: src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r d2608fc3c9e2 -r fad85406a088 src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c --- a/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c Wed Oct 12 19:07:07 2011 +0300 +++ b/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c Wed Oct 12 17:21:01 2011 +0300 @@ -483,6 +483,8 @@ i_assert(box->storage == &ctx->storage->storage.storage); if (mailbox_open(box) < 0) { error = mailbox_get_last_mail_error(box); + i_error("Couldn't open mailbox '%s': %s", + vname, mailbox_get_last_error(box, NULL)); mailbox_free(&box); if (error == MAIL_ERROR_TEMP) return -1; From dovecot at dovecot.org Wed Oct 12 19:00:44 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 12 Oct 2011 19:00:44 +0300 Subject: dovecot-2.1: lib-storage: Added mail_log_update_wanted_fields() Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/e77601949937 changeset: 13633:e77601949937 user: Timo Sirainen date: Wed Oct 12 19:08:31 2011 +0300 description: lib-storage: Added mail_log_update_wanted_fields() diffstat: src/lib-storage/index/cydir/cydir-mail.c | 1 + src/lib-storage/index/dbox-multi/mdbox-mail.c | 1 + src/lib-storage/index/dbox-single/sdbox-mail.c | 1 + src/lib-storage/index/imapc/imapc-mail-fetch.c | 2 +- src/lib-storage/index/imapc/imapc-mail.c | 47 +++++-- src/lib-storage/index/index-mail-headers.c | 15 +- src/lib-storage/index/index-mail.c | 146 ++++++++++++++++-------- src/lib-storage/index/index-mail.h | 8 +- src/lib-storage/index/maildir/maildir-mail.c | 5 +- src/lib-storage/index/mbox/mbox-mail.c | 1 + src/lib-storage/index/raw/raw-mail.c | 1 + src/lib-storage/mail-storage-private.h | 4 + src/lib-storage/mail-storage.h | 6 + src/lib-storage/mail.c | 9 + src/lib-storage/test-mail.c | 8 + src/plugins/virtual/virtual-mail.c | 12 ++ 16 files changed, 191 insertions(+), 76 deletions(-) diffs (truncated from 669 to 300 lines): diff -r fad85406a088 -r e77601949937 src/lib-storage/index/cydir/cydir-mail.c --- a/src/lib-storage/index/cydir/cydir-mail.c Wed Oct 12 17:21:01 2011 +0300 +++ b/src/lib-storage/index/cydir/cydir-mail.c Wed Oct 12 19:08:31 2011 +0300 @@ -133,6 +133,7 @@ index_mail_set_uid_cache_updates, index_mail_prefetch, index_mail_precache, + index_mail_add_temp_wanted_fields, index_mail_get_flags, index_mail_get_keywords, diff -r fad85406a088 -r e77601949937 src/lib-storage/index/dbox-multi/mdbox-mail.c --- a/src/lib-storage/index/dbox-multi/mdbox-mail.c Wed Oct 12 17:21:01 2011 +0300 +++ b/src/lib-storage/index/dbox-multi/mdbox-mail.c Wed Oct 12 19:08:31 2011 +0300 @@ -192,6 +192,7 @@ index_mail_set_uid_cache_updates, index_mail_prefetch, index_mail_precache, + index_mail_add_temp_wanted_fields, index_mail_get_flags, index_mail_get_keywords, diff -r fad85406a088 -r e77601949937 src/lib-storage/index/dbox-single/sdbox-mail.c --- a/src/lib-storage/index/dbox-single/sdbox-mail.c Wed Oct 12 17:21:01 2011 +0300 +++ b/src/lib-storage/index/dbox-single/sdbox-mail.c Wed Oct 12 19:08:31 2011 +0300 @@ -100,6 +100,7 @@ index_mail_set_uid_cache_updates, index_mail_prefetch, index_mail_precache, + index_mail_add_temp_wanted_fields, index_mail_get_flags, index_mail_get_keywords, diff -r fad85406a088 -r e77601949937 src/lib-storage/index/imapc/imapc-mail-fetch.c --- a/src/lib-storage/index/imapc/imapc-mail-fetch.c Wed Oct 12 17:21:01 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mail-fetch.c Wed Oct 12 19:08:31 2011 +0300 @@ -149,7 +149,7 @@ if (mbox->prev_mail_cache.uid == _mail->uid) imapc_mail_cache_get(mail, &mbox->prev_mail_cache); - if ((mail->imail.wanted_fields & MAIL_FETCH_RECEIVED_DATE) != 0 && + if ((data->wanted_fields & MAIL_FETCH_RECEIVED_DATE) != 0 && data->received_date == (time_t)-1) fields |= MAIL_FETCH_RECEIVED_DATE; diff -r fad85406a088 -r e77601949937 src/lib-storage/index/imapc/imapc-mail.c --- a/src/lib-storage/index/imapc/imapc-mail.c Wed Oct 12 17:21:01 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mail.c Wed Oct 12 19:08:31 2011 +0300 @@ -180,44 +180,62 @@ return TRUE; } -static void imapc_mail_set_seq(struct mail *_mail, uint32_t seq, bool saving) +static void index_mail_update_access_parts(struct index_mail *mail) { - struct imapc_mail *imail = (struct imapc_mail *)_mail; - struct index_mail *mail = &imail->imail; + struct mail *_mail = &mail->mail.mail; + struct index_mail_data *data = &mail->data; struct mailbox_header_lookup_ctx *header_ctx; time_t date; uoff_t size; - index_mail_set_seq(_mail, seq, saving); - - if ((mail->wanted_fields & MAIL_FETCH_RECEIVED_DATE) != 0) + if ((data->wanted_fields & MAIL_FETCH_RECEIVED_DATE) != 0) (void)index_mail_get_received_date(_mail, &date); - if ((mail->wanted_fields & MAIL_FETCH_PHYSICAL_SIZE) != 0) { + if ((data->wanted_fields & MAIL_FETCH_PHYSICAL_SIZE) != 0) { if (index_mail_get_physical_size(_mail, &size) < 0) - mail->data.access_part |= READ_HDR | READ_BODY; + data->access_part |= READ_HDR | READ_BODY; } - if (mail->data.access_part == 0 && mail->wanted_headers != NULL) { + if (data->access_part == 0 && data->wanted_headers != NULL) { /* see if all wanted headers exist in cache */ - if (!imapc_mail_has_headers_in_cache(mail, mail->wanted_headers)) - mail->data.access_part |= PARSE_HDR; + if (!imapc_mail_has_headers_in_cache(mail, data->wanted_headers)) + data->access_part |= PARSE_HDR; } - if (mail->data.access_part == 0 && - (mail->wanted_fields & MAIL_FETCH_IMAP_ENVELOPE) != 0) { + if (data->access_part == 0 && + (data->wanted_fields & MAIL_FETCH_IMAP_ENVELOPE) != 0) { /* the common code already checked this partially, but we need a guaranteed correct answer */ header_ctx = mailbox_header_lookup_init(_mail->box, imap_envelope_headers); if (!imapc_mail_has_headers_in_cache(mail, header_ctx)) - mail->data.access_part |= PARSE_HDR; + data->access_part |= PARSE_HDR; mailbox_header_lookup_unref(&header_ctx); } +} + +static void imapc_mail_set_seq(struct mail *_mail, uint32_t seq, bool saving) +{ + struct imapc_mail *imail = (struct imapc_mail *)_mail; + struct index_mail *mail = &imail->imail; + + index_mail_set_seq(_mail, seq, saving); + /* searching code handles prefetching internally, elsewhere we want to do it immediately */ if (!mail->search_mail && !_mail->saving) (void)imapc_mail_prefetch(_mail); } +static void +imapc_mail_add_temp_wanted_fields(struct mail *_mail, + enum mail_fetch_field fields, + struct mailbox_header_lookup_ctx *headers) +{ + struct index_mail *mail = (struct index_mail *)_mail; + + index_mail_add_temp_wanted_fields(_mail, fields, headers); + index_mail_update_access_parts(mail); +} + static void imapc_mail_close(struct mail *_mail) { struct imapc_mail *mail = (struct imapc_mail *)_mail; @@ -257,6 +275,7 @@ index_mail_set_uid_cache_updates, imapc_mail_prefetch, index_mail_precache, + imapc_mail_add_temp_wanted_fields, index_mail_get_flags, index_mail_get_keywords, diff -r fad85406a088 -r e77601949937 src/lib-storage/index/index-mail-headers.c --- a/src/lib-storage/index/index-mail-headers.c Wed Oct 12 17:21:01 2011 +0300 +++ b/src/lib-storage/index/index-mail-headers.c Wed Oct 12 19:08:31 2011 +0300 @@ -151,7 +151,7 @@ bool index_mail_want_parse_headers(struct index_mail *mail) { - if (mail->wanted_headers != NULL || + if (mail->data.wanted_headers != NULL || mail->data.save_bodystructure_header) return TRUE; @@ -185,10 +185,11 @@ void index_mail_parse_header_init(struct index_mail *mail, struct mailbox_header_lookup_ctx *headers) { + struct index_mail_data *data = &mail->data; const uint8_t *match; unsigned int i, field_idx, match_count; - mail->header_seq = mail->data.seq; + mail->header_seq = data->seq; if (mail->header_data == NULL) { mail->header_data = buffer_create_dynamic(default_pool, 4096); i_array_init(&mail->header_lines, 32); @@ -217,8 +218,8 @@ } } - if (mail->wanted_headers != NULL && mail->wanted_headers != headers) { - headers = mail->wanted_headers; + if (data->wanted_headers != NULL && data->wanted_headers != headers) { + headers = data->wanted_headers; for (i = 0; i < headers->count; i++) { array_idx_set(&mail->header_match, headers->idx[i], &mail->header_match_value); @@ -240,10 +241,10 @@ if (field_idx < match_count && match[field_idx] == mail->header_match_value) { /* cache Date: header */ - } else if ((mail->data.cache_fetch_fields & MAIL_FETCH_DATE) != 0 || - mail->data.save_sent_date) { + } else if ((data->cache_fetch_fields & MAIL_FETCH_DATE) != 0 || + data->save_sent_date) { /* parse Date: header, but don't cache it. */ - mail->data.dont_cache_field_idx = field_idx; + data->dont_cache_field_idx = field_idx; array_idx_set(&mail->header_match, field_idx, &mail->header_match_value); } diff -r fad85406a088 -r e77601949937 src/lib-storage/index/index-mail.c --- a/src/lib-storage/index/index-mail.c Wed Oct 12 17:21:01 2011 +0300 +++ b/src/lib-storage/index/index-mail.c Wed Oct 12 19:08:31 2011 +0300 @@ -457,8 +457,8 @@ mail->ibox->cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx; struct mail *_mail = &mail->mail.mail; - if ((mail->wanted_fields & (MAIL_FETCH_IMAP_BODY | - MAIL_FETCH_IMAP_BODYSTRUCTURE)) != 0) + if ((mail->data.wanted_fields & (MAIL_FETCH_IMAP_BODY | + MAIL_FETCH_IMAP_BODYSTRUCTURE)) != 0) return TRUE; if (mail_cache_field_want_add(_mail->transaction->cache_trans, @@ -544,7 +544,7 @@ } if (decision == MAIL_CACHE_DECISION_NO && !data->save_message_parts && - (mail->wanted_fields & MAIL_FETCH_MESSAGE_PARTS) == 0) { + (data->wanted_fields & MAIL_FETCH_MESSAGE_PARTS) == 0) { /* we didn't really care about the message parts themselves, just wanted to use something that depended on it */ return; @@ -596,7 +596,7 @@ if (plain_bodystructure) cache_bodystructure = FALSE; else if (field == MAIL_CACHE_IMAP_BODYSTRUCTURE || - (mail->wanted_fields & MAIL_FETCH_IMAP_BODYSTRUCTURE) != 0) { + (data->wanted_fields & MAIL_FETCH_IMAP_BODYSTRUCTURE) != 0) { cache_bodystructure = mail_cache_field_can_add(_mail->transaction->cache_trans, _mail->seq, cache_field_bodystructure); @@ -1113,15 +1113,13 @@ mail->mail.v = *t->box->mail_vfuncs; mail->mail.mail.box = t->box; mail->mail.mail.transaction = t; - mail->mail.wanted_fields = wanted_fields; - mail->mail.wanted_headers = wanted_headers; t->mail_ref_count++; mail->data_pool = pool_alloconly_create("index_mail", 16384); mail->ibox = INDEX_STORAGE_CONTEXT(t->box); - mail->wanted_fields = wanted_fields; + mail->mail.wanted_fields = wanted_fields; if (wanted_headers != NULL) { - mail->wanted_headers = wanted_headers; + mail->mail.wanted_headers = wanted_headers; mailbox_header_lookup_ref(wanted_headers); } } @@ -1164,6 +1162,8 @@ } index_mail_close_streams(mail); + if (mail->data.wanted_headers != NULL) + mailbox_header_lookup_unref(&mail->data.wanted_headers); } static void index_mail_reset(struct index_mail *mail) @@ -1182,6 +1182,12 @@ data->sent_date.time = (uint32_t)-1; data->dont_cache_field_idx = -1U; + data->wanted_fields = mail->mail.wanted_fields; + if (mail->mail.wanted_headers != NULL) { + data->wanted_headers = mail->mail.wanted_headers; + mailbox_header_lookup_ref(data->wanted_headers); + } + mail->mail.mail.seq = 0; mail->mail.mail.uid = 0; mail->mail.mail.expunged = FALSE; @@ -1219,35 +1225,19 @@ mail->data.save_envelope = TRUE; } -void index_mail_set_seq(struct mail *_mail, uint32_t seq, bool saving) +static void index_mail_update_access_parts(struct index_mail *mail) { - struct index_mail *mail = (struct index_mail *)_mail; + struct mail *_mail = &mail->mail.mail; struct index_mail_data *data = &mail->data; const struct mail_cache_field *cache_fields = mail->ibox->cache_fields; struct mail_cache_view *cache_view = _mail->transaction->cache_view; const struct mail_index_header *hdr; struct istream *input; - if (data->seq == seq) - return; - - index_mail_reset(mail); - - data->seq = seq; - - mail->mail.mail.seq = seq; - mail->mail.mail.saving = saving; - mail_index_lookup_uid(_mail->transaction->view, seq, - &mail->mail.mail.uid); - - if (mail_index_view_is_inconsistent(_mail->transaction->view)) { - mail_set_expunged(&mail->mail.mail); - return; - } - - if ((mail->wanted_fields & (MAIL_FETCH_NUL_STATE | + if ((data->wanted_fields & (MAIL_FETCH_NUL_STATE | MAIL_FETCH_IMAP_BODY | - MAIL_FETCH_IMAP_BODYSTRUCTURE)) != 0) { + MAIL_FETCH_IMAP_BODYSTRUCTURE)) != 0 && + !_mail->has_nuls && !_mail->has_no_nuls) { (void)index_mail_get_fixed_field(mail, MAIL_CACHE_FLAGS, &data->cache_flags, sizeof(data->cache_flags)); @@ -1262,44 +1252,48 @@ /* see if wanted_fields can tell us if we need to read/parse header/body */ From dovecot at dovecot.org Wed Oct 12 19:00:44 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 12 Oct 2011 19:00:44 +0300 Subject: dovecot-2.1: mail-log: Use mail_log_update_wanted_fields() to av... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/381555875651 changeset: 13634:381555875651 user: Timo Sirainen date: Wed Oct 12 19:09:02 2011 +0300 description: mail-log: Use mail_log_update_wanted_fields() to avoid parsing message multiple times. diffstat: src/plugins/mail-log/mail-log-plugin.c | 33 ++++++++++++++++++++++++++++++++- 1 files changed, 32 insertions(+), 1 deletions(-) diffs (52 lines): diff -r e77601949937 -r 381555875651 src/plugins/mail-log/mail-log-plugin.c --- a/src/plugins/mail-log/mail-log-plugin.c Wed Oct 12 19:08:31 2011 +0300 +++ b/src/plugins/mail-log/mail-log-plugin.c Wed Oct 12 19:09:02 2011 +0300 @@ -203,6 +203,34 @@ } static void +mail_log_update_wanted_fields(struct mail *mail, enum mail_log_field fields) +{ + enum mail_fetch_field wanted_fields = 0; + struct mailbox_header_lookup_ctx *wanted_headers = NULL; + const char *headers[4]; + unsigned int hdr_idx = 0; + + if ((fields & MAIL_LOG_FIELD_MSGID) != 0) + headers[hdr_idx++] = "Message-ID"; + if ((fields & MAIL_LOG_FIELD_FROM) != 0) + headers[hdr_idx++] = "From"; + if ((fields & MAIL_LOG_FIELD_SUBJECT) != 0) + headers[hdr_idx++] = "Subject"; + if (hdr_idx > 0) { + i_assert(hdr_idx < N_ELEMENTS(headers)); + headers[hdr_idx] = NULL; + wanted_headers = mailbox_header_lookup_init(mail->box, headers); + } + + if ((fields & MAIL_LOG_FIELD_PSIZE) != 0) + wanted_fields |= MAIL_FETCH_PHYSICAL_SIZE; + if ((fields & MAIL_LOG_FIELD_VSIZE) != 0) + wanted_fields |= MAIL_FETCH_VIRTUAL_SIZE; + + mail_add_temp_wanted_fields(mail, wanted_fields, wanted_headers); +} + +static void mail_log_append_mail_message_real(struct mail_log_mail_txn_context *ctx, struct mail *mail, enum mail_log_event event, const char *desc) @@ -212,9 +240,12 @@ struct mail_log_message *msg; string_t *text; uoff_t size; - + msg = p_new(ctx->pool, struct mail_log_message, 1); + /* avoid parsing through the message multiple times */ + mail_log_update_wanted_fields(mail, muser->fields); + text = t_str_new(128); str_append(text, desc); str_append(text, ": "); From dovecot at dovecot.org Mon Oct 17 15:27:37 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 17 Oct 2011 15:27:37 +0300 Subject: dovecot-2.1: imapc: Added imapc_ssl_verify setting. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/63ac3b1c2950 changeset: 13635:63ac3b1c2950 user: Timo Sirainen date: Mon Oct 17 15:35:54 2011 +0300 description: imapc: Added imapc_ssl_verify setting. diffstat: src/lib-imap-client/imapc-client.c | 3 ++- src/lib-imap-client/imapc-client.h | 1 + src/lib-imap-client/imapc-connection.c | 13 +++++++++---- src/lib-storage/index/imapc/imapc-settings.c | 2 ++ src/lib-storage/index/imapc/imapc-settings.h | 1 + src/lib-storage/index/imapc/imapc-storage.c | 1 + 6 files changed, 16 insertions(+), 5 deletions(-) diffs (98 lines): diff -r 381555875651 -r 63ac3b1c2950 src/lib-imap-client/imapc-client.c --- a/src/lib-imap-client/imapc-client.c Wed Oct 12 19:09:02 2011 +0300 +++ b/src/lib-imap-client/imapc-client.c Mon Oct 17 15:35:54 2011 +0300 @@ -59,10 +59,11 @@ if (set->ssl_mode != IMAPC_CLIENT_SSL_MODE_NONE) { client->set.ssl_mode = set->ssl_mode; client->set.ssl_ca_dir = p_strdup(pool, set->ssl_ca_dir); + client->set.ssl_verify = set->ssl_verify; memset(&ssl_set, 0, sizeof(ssl_set)); ssl_set.ca_dir = set->ssl_ca_dir; - ssl_set.verify_remote_cert = TRUE; + ssl_set.verify_remote_cert = set->ssl_verify; source = t_strdup_printf("%s:%u", set->host, set->port); if (ssl_iostream_context_init_client(source, &ssl_set, diff -r 381555875651 -r 63ac3b1c2950 src/lib-imap-client/imapc-client.h --- a/src/lib-imap-client/imapc-client.h Wed Oct 12 19:09:02 2011 +0300 +++ b/src/lib-imap-client/imapc-client.h Mon Oct 17 15:35:54 2011 +0300 @@ -56,6 +56,7 @@ enum imapc_client_ssl_mode ssl_mode; const char *ssl_ca_dir; + bool ssl_verify; const char *rawlog_dir; bool debug; diff -r 381555875651 -r 63ac3b1c2950 src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Wed Oct 12 19:09:02 2011 +0300 +++ b/src/lib-imap-client/imapc-connection.c Mon Oct 17 15:35:54 2011 +0300 @@ -1123,7 +1123,10 @@ { struct imapc_connection *conn = context; - if (!ssl_iostream_has_valid_client_cert(conn->ssl_iostream)) { + if (!conn->client->set.ssl_verify) { + /* skip certificate checks */ + return 0; + } else if (!ssl_iostream_has_valid_client_cert(conn->ssl_iostream)) { if (!ssl_iostream_has_broken_client_cert(conn->ssl_iostream)) { i_error("imapc(%s): SSL certificate not received", conn->name); @@ -1158,9 +1161,11 @@ } memset(&ssl_set, 0, sizeof(ssl_set)); - ssl_set.verbose_invalid_cert = TRUE; - ssl_set.verify_remote_cert = TRUE; - ssl_set.require_valid_cert = TRUE; + if (conn->client->set.ssl_verify) { + ssl_set.verbose_invalid_cert = TRUE; + ssl_set.verify_remote_cert = TRUE; + ssl_set.require_valid_cert = TRUE; + } if (conn->client->set.debug) i_debug("imapc(%s): Starting SSL handshake", conn->name); diff -r 381555875651 -r 63ac3b1c2950 src/lib-storage/index/imapc/imapc-settings.c --- a/src/lib-storage/index/imapc/imapc-settings.c Wed Oct 12 19:09:02 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-settings.c Mon Oct 17 15:35:54 2011 +0300 @@ -22,6 +22,7 @@ DEF(SET_ENUM, imapc_ssl), DEF(SET_STR, imapc_ssl_ca_dir), + DEF(SET_BOOL, imapc_ssl_verify), DEF(SET_STR, imapc_rawlog_dir), @@ -37,6 +38,7 @@ .imapc_ssl = "no:imaps:starttls", .imapc_ssl_ca_dir = "", + .imapc_ssl_verify = TRUE, .imapc_rawlog_dir = "" }; diff -r 381555875651 -r 63ac3b1c2950 src/lib-storage/index/imapc/imapc-settings.h --- a/src/lib-storage/index/imapc/imapc-settings.h Wed Oct 12 19:09:02 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-settings.h Mon Oct 17 15:35:54 2011 +0300 @@ -10,6 +10,7 @@ const char *imapc_ssl; const char *imapc_ssl_ca_dir; + bool imapc_ssl_verify; const char *imapc_rawlog_dir; }; diff -r 381555875651 -r 63ac3b1c2950 src/lib-storage/index/imapc/imapc-storage.c --- a/src/lib-storage/index/imapc/imapc-storage.c Wed Oct 12 19:09:02 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-storage.c Mon Oct 17 15:35:54 2011 +0300 @@ -239,6 +239,7 @@ set.temp_path_prefix = str_c(str); set.ssl_ca_dir = storage->set->imapc_ssl_ca_dir; + set.ssl_verify = storage->set->imapc_ssl_verify; if (strcmp(storage->set->imapc_ssl, "imaps") == 0) set.ssl_mode = IMAPC_CLIENT_SSL_MODE_IMMEDIATE; else if (strcmp(storage->set->imapc_ssl, "starttls") == 0) From dovecot at dovecot.org Tue Oct 18 16:44:49 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 18 Oct 2011 16:44:49 +0300 Subject: dovecot-2.1: istream-mail: Call mail_cache_set_corrupted() properly Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/fb22546542a5 changeset: 13636:fb22546542a5 user: Timo Sirainen date: Tue Oct 18 16:52:23 2011 +0300 description: istream-mail: Call mail_cache_set_corrupted() properly diffstat: src/lib-storage/index/istream-mail.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 63ac3b1c2950 -r fb22546542a5 src/lib-storage/index/istream-mail.c --- a/src/lib-storage/index/istream-mail.c Mon Oct 17 15:35:54 2011 +0300 +++ b/src/lib-storage/index/istream-mail.c Tue Oct 18 16:52:23 2011 +0300 @@ -50,7 +50,7 @@ "Cached message size %s than expected " "(%"PRIuUOFF_T" %c %"PRIuUOFF_T")", str, mstream->expected_size, chr, cur_size); - index_mail_set_cache_corrupted(mstream->mail, MAIL_FETCH_PHYSICAL_SIZE); + mail_set_cache_corrupted(mstream->mail, MAIL_FETCH_PHYSICAL_SIZE); mstream->istream.istream.stream_errno = EIO; } From dovecot at dovecot.org Tue Oct 18 16:44:49 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 18 Oct 2011 16:44:49 +0300 Subject: dovecot-2.1: maildir: If maildir filename has broken W/S size, r... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/e3d2262e995a changeset: 13637:e3d2262e995a user: Timo Sirainen date: Tue Oct 18 16:53:06 2011 +0300 description: maildir: If maildir filename has broken W/S size, rename the file to drop them. diffstat: src/lib-storage/index/maildir/maildir-mail.c | 92 ++++++++++++++++++++------- 1 files changed, 66 insertions(+), 26 deletions(-) diffs (112 lines): diff -r fb22546542a5 -r e3d2262e995a src/lib-storage/index/maildir/maildir-mail.c --- a/src/lib-storage/index/maildir/maildir-mail.c Tue Oct 18 16:52:23 2011 +0300 +++ b/src/lib-storage/index/maildir/maildir-mail.c Tue Oct 18 16:53:06 2011 +0300 @@ -9,6 +9,7 @@ #include "maildir-uidlist.h" #include "maildir-sync.h" +#include #include #include #include @@ -595,35 +596,74 @@ MAILDIR_UIDLIST_REC_EXT_POP3_UIDL, uidl); } +static void maildir_mail_remove_sizes_from_uidlist(struct mail *mail) +{ + struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->box; + + if (maildir_uidlist_lookup_ext(mbox->uidlist, mail->uid, + MAILDIR_UIDLIST_REC_EXT_VSIZE) != NULL) { + maildir_uidlist_set_ext(mbox->uidlist, mail->uid, + MAILDIR_UIDLIST_REC_EXT_VSIZE, NULL); + } + if (maildir_uidlist_lookup_ext(mbox->uidlist, mail->uid, + MAILDIR_UIDLIST_REC_EXT_PSIZE) != NULL) { + maildir_uidlist_set_ext(mbox->uidlist, mail->uid, + MAILDIR_UIDLIST_REC_EXT_PSIZE, NULL); + } +} + +static void +maildir_mail_remove_sizes_from_filename(struct mail *mail, + enum mail_fetch_field field) +{ + struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->box; + enum maildir_uidlist_rec_flag flags; + const char *subdir, *fname, *path, *newpath, *p; + uoff_t size; + + if (maildir_sync_lookup(mbox, mail->uid, &flags, &fname) <= 0) + return; + + p = strchr(fname, MAILDIR_EXTRA_SEP); + if (p == NULL) + return; + + subdir = (flags & MAILDIR_UIDLIST_REC_FLAG_NEW_DIR) != 0 ? + "new" : "cur"; + path = t_strdup_printf("%s/%s/%s", mailbox_get_path(&mbox->box), + subdir, fname); + + if (maildir_filename_get_size(fname, MAILDIR_EXTRA_VIRTUAL_SIZE, + &size) && + field == MAIL_FETCH_VIRTUAL_SIZE) { + mail_storage_set_critical(mail->box->storage, + "Maildir filename has wrong W value: %s", path); + } + if (maildir_filename_get_size(fname, MAILDIR_EXTRA_FILE_SIZE, + &size) && + field == MAIL_FETCH_PHYSICAL_SIZE) { + mail_storage_set_critical(mail->box->storage, + "Maildir filename has wrong S value: %s", path); + } + + newpath = t_strdup_printf("%s/%s/%s", mailbox_get_path(&mbox->box), + subdir, t_strdup_until(fname, p)); + if (rename(path, newpath) == 0) { + i_warning("Renamed broken maildir filename %s to %s", + path, newpath); + } else { + mail_storage_set_critical(mail->box->storage, + "rename(%s, %s) failed: %m", path, newpath); + } +} + static void maildir_mail_set_cache_corrupted(struct mail *_mail, enum mail_fetch_field field) { - struct maildir_mailbox *mbox = (struct maildir_mailbox *)_mail->box; - enum maildir_uidlist_rec_flag flags; - const char *fname; - uoff_t size; - int ret; - - if (field == MAIL_FETCH_VIRTUAL_SIZE) { - /* make sure it gets removed from uidlist. - if it's in file name, we can't really do more than log it. */ - ret = maildir_sync_lookup(mbox, _mail->uid, &flags, &fname); - if (ret <= 0) - return; - if (maildir_filename_get_size(fname, MAILDIR_EXTRA_VIRTUAL_SIZE, - &size)) { - const char *subdir = - (flags & MAILDIR_UIDLIST_REC_FLAG_NEW_DIR) != 0 ? - "new" : "cur"; - mail_storage_set_critical(_mail->box->storage, - "Maildir filename has wrong W value: %s/%s/%s", - mailbox_get_path(&mbox->box), subdir, fname); - } else if (maildir_uidlist_lookup_ext(mbox->uidlist, _mail->uid, - MAILDIR_UIDLIST_REC_EXT_VSIZE) != NULL) { - maildir_uidlist_set_ext(mbox->uidlist, _mail->uid, - MAILDIR_UIDLIST_REC_EXT_VSIZE, - NULL); - } + if (field == MAIL_FETCH_PHYSICAL_SIZE || + field == MAIL_FETCH_VIRTUAL_SIZE) { + maildir_mail_remove_sizes_from_uidlist(_mail); + maildir_mail_remove_sizes_from_filename(_mail, field); } index_mail_set_cache_corrupted(_mail, field); } From dovecot at dovecot.org Wed Oct 19 16:03:28 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 19 Oct 2011 16:03:28 +0300 Subject: dovecot-2.1: auth: passdb static crashed if no password was given Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/809944f5015a changeset: 13638:809944f5015a user: Timo Sirainen date: Wed Oct 19 16:11:44 2011 +0300 description: auth: passdb static crashed if no password was given diffstat: src/auth/passdb-static.c | 10 +++++++--- 1 files changed, 7 insertions(+), 3 deletions(-) diffs (20 lines): diff -r e3d2262e995a -r 809944f5015a src/auth/passdb-static.c --- a/src/auth/passdb-static.c Tue Oct 18 16:53:06 2011 +0300 +++ b/src/auth/passdb-static.c Wed Oct 19 16:11:44 2011 +0300 @@ -24,9 +24,13 @@ auth_request_log_debug(request, "static", "lookup"); passdb_template_export(module->tmpl, request); - table = auth_request_get_var_expand_table(request, NULL); - var_expand(str, module->static_password_tmpl, table); - *password_r = str_c(str); + if (module->static_password_tmpl == NULL) + *password_r = NULL; + else { + table = auth_request_get_var_expand_table(request, NULL); + var_expand(str, module->static_password_tmpl, table); + *password_r = str_c(str); + } } static void From dovecot at dovecot.org Thu Oct 20 16:46:18 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 20 Oct 2011 16:46:18 +0300 Subject: dovecot-2.1: imapc: Fixed reopening a mailbox. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/221ec0404d8e changeset: 13639:221ec0404d8e user: Timo Sirainen date: Thu Oct 20 16:54:36 2011 +0300 description: imapc: Fixed reopening a mailbox. diffstat: src/lib-imap-client/imapc-client.c | 2 +- src/lib-imap-client/imapc-connection.c | 25 +++++++++++-------------- src/lib-imap-client/imapc-connection.h | 3 ++- 3 files changed, 14 insertions(+), 16 deletions(-) diffs (95 lines): diff -r 809944f5015a -r 221ec0404d8e src/lib-imap-client/imapc-client.c --- a/src/lib-imap-client/imapc-client.c Wed Oct 19 16:11:44 2011 +0300 +++ b/src/lib-imap-client/imapc-client.c Thu Oct 20 16:54:36 2011 +0300 @@ -266,7 +266,7 @@ /* reopen the mailbox */ box->reopen_callback(box->reopen_context); } else { - imapc_connection_abort_commands(box->conn); + imapc_connection_abort_commands(box->conn, TRUE, FALSE); } } diff -r 809944f5015a -r 221ec0404d8e src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Wed Oct 19 16:11:44 2011 +0300 +++ b/src/lib-imap-client/imapc-connection.c Thu Oct 20 16:54:36 2011 +0300 @@ -233,21 +233,23 @@ } } -static void -imapc_connection_abort_commands_full(struct imapc_connection *conn, - bool keep_retriable) +void imapc_connection_abort_commands(struct imapc_connection *conn, + bool disconnected, bool keep_retriable) { struct imapc_command *const *cmdp, *cmd; ARRAY_TYPE(imapc_command) tmp_array; struct imapc_command_reply reply; t_array_init(&tmp_array, 8); - imapc_connection_abort_commands_array(&conn->cmd_wait_list, - &tmp_array, keep_retriable); + if (disconnected) { + imapc_connection_abort_commands_array(&conn->cmd_wait_list, + &tmp_array, + keep_retriable); + } imapc_connection_abort_commands_array(&conn->cmd_send_queue, &tmp_array, keep_retriable); - if (array_count(&conn->cmd_wait_list) > 0) { + if (array_count(&conn->cmd_wait_list) > 0 && disconnected) { /* need to move all the waiting commands to send queue */ array_append_array(&conn->cmd_wait_list, &conn->cmd_send_queue); @@ -271,11 +273,6 @@ } } -void imapc_connection_abort_commands(struct imapc_connection *conn) -{ - imapc_connection_abort_commands_full(conn, FALSE); -} - static void imapc_login_callback(struct imapc_connection *conn, const struct imapc_command_reply *reply) @@ -368,13 +365,13 @@ net_disconnect(conn->fd); conn->fd = -1; - imapc_connection_abort_commands_full(conn, reconnecting); + imapc_connection_abort_commands(conn, TRUE, reconnecting); imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DISCONNECTED); } static void imapc_connection_set_disconnected(struct imapc_connection *conn) { - imapc_connection_abort_commands(conn); + imapc_connection_abort_commands(conn, TRUE, FALSE); imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DISCONNECTED); } @@ -1808,7 +1805,7 @@ struct imapc_connection *conn = box->conn; imapc_connection_send_idle_done(conn); - imapc_connection_abort_commands(conn); + imapc_connection_abort_commands(conn, FALSE, FALSE); if (conn->selected_box != NULL || conn->selecting_box != NULL) { i_assert(conn->selected_box == box || diff -r 809944f5015a -r 221ec0404d8e src/lib-imap-client/imapc-connection.h --- a/src/lib-imap-client/imapc-connection.h Wed Oct 19 16:11:44 2011 +0300 +++ b/src/lib-imap-client/imapc-connection.h Thu Oct 20 16:54:36 2011 +0300 @@ -25,7 +25,8 @@ imapc_command_callback_t *login_callback, void *login_context); void imapc_connection_disconnect(struct imapc_connection *conn); -void imapc_connection_abort_commands(struct imapc_connection *conn); +void imapc_connection_abort_commands(struct imapc_connection *conn, + bool disconnected, bool keep_retriable); void imapc_connection_ioloop_changed(struct imapc_connection *conn); void imapc_connection_input_pending(struct imapc_connection *conn); From dovecot at dovecot.org Thu Oct 20 18:17:56 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 20 Oct 2011 18:17:56 +0300 Subject: dovecot-2.0: master: Reset service's listen_pending flag when it... Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/6f1442a0d1c6 changeset: 12948:6f1442a0d1c6 user: Timo Sirainen date: Thu Oct 20 18:26:15 2011 +0300 description: master: Reset service's listen_pending flag when it gets a new available process. diffstat: src/master/service-monitor.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (21 lines): diff -r 962df5d9413a -r 6f1442a0d1c6 src/master/service-monitor.c --- a/src/master/service-monitor.c Wed Oct 12 17:16:10 2011 +0300 +++ b/src/master/service-monitor.c Thu Oct 20 18:26:15 2011 +0300 @@ -216,8 +216,8 @@ reach connection limit */ service_login_notify(service, TRUE); + service_monitor_listen_stop(service); service->listen_pending = TRUE; - service_monitor_listen_stop(service); } else { /* just accept and close the connection, so it's clear that this is happening because of the limit, rather than because @@ -302,6 +302,7 @@ io_remove(&l->io); } service->listening = FALSE; + service->listen_pending = FALSE; } static int service_login_create_notify_fd(struct service *service) From dovecot at dovecot.org Thu Oct 20 18:28:51 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 20 Oct 2011 18:28:51 +0300 Subject: dovecot-2.0: master: When process_limit fills up, wait 10s befor... Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/d4e15513192a changeset: 12949:d4e15513192a user: Timo Sirainen date: Thu Oct 20 18:37:09 2011 +0300 description: master: When process_limit fills up, wait 10s before closing pending connections. It might have only been a temporary burst that gets resolved quickly enough. diffstat: src/master/service-monitor.c | 63 ++++++++++++++++++++++++++++++++++++------- src/master/service.h | 3 ++ 2 files changed, 55 insertions(+), 11 deletions(-) diffs (131 lines): diff -r 6f1442a0d1c6 -r d4e15513192a src/master/service-monitor.c --- a/src/master/service-monitor.c Thu Oct 20 18:26:15 2011 +0300 +++ b/src/master/service-monitor.c Thu Oct 20 18:37:09 2011 +0300 @@ -22,10 +22,12 @@ #define SERVICE_STARTUP_FAILURE_THROTTLE_SECS 60 #define SERVICE_DROP_WARN_INTERVAL_SECS 60 +#define SERVICE_DROP_TIMEOUT_MSECS (10*1000) static void service_monitor_start_extra_avail(struct service *service); static void service_status_more(struct service_process *process, const struct master_status *status); +static void service_monitor_listen_start_force(struct service *service); static void service_process_kill_idle(struct service_process *process) { @@ -195,6 +197,32 @@ service_throttle(service, SERVICE_STARTUP_FAILURE_THROTTLE_SECS); } +static void service_drop_timeout(struct service *service) +{ + struct service_listener *const *lp; + int fd; + + i_assert(service->process_avail == 0); + + /* drop all pending connections */ + array_foreach(&service->listeners, lp) { + while ((fd = net_accept((*lp)->fd, NULL, NULL)) > 0) + net_disconnect(fd); + } + + service_monitor_listen_start_force(service); + service->listen_pending = TRUE; +} + +static void service_monitor_listen_pending(struct service *service) +{ + service_monitor_listen_stop(service); + service->listen_pending = TRUE; + + service->to_drop = timeout_add(SERVICE_DROP_TIMEOUT_MSECS, + service_drop_timeout, service); +} + static void service_drop_connections(struct service_listener *l) { struct service *service = l->service; @@ -216,12 +244,16 @@ reach connection limit */ service_login_notify(service, TRUE); - service_monitor_listen_stop(service); - service->listen_pending = TRUE; + service_monitor_listen_pending(service); + } else if (!service->listen_pending) { + /* maybe this is a temporary peak, stop for a while and + see if it goes away */ + service_monitor_listen_pending(service); } else { - /* just accept and close the connection, so it's clear that - this is happening because of the limit, rather than because - the service processes aren't answering fast enough */ + /* this has been happening for a while now. just accept and + close the connection, so it's clear that this is happening + because of the limit, rather than because the service + processes aren't answering fast enough */ fd = net_accept(l->fd, NULL, NULL); if (fd > 0) net_disconnect(fd); @@ -271,17 +303,14 @@ } } -void service_monitor_listen_start(struct service *service) +static void service_monitor_listen_start_force(struct service *service) { struct service_listener *const *listeners; - if (service->process_avail > 0 || - (service->process_count == service->process_limit && - service->listen_pending)) - return; - service->listening = TRUE; service->listen_pending = FALSE; + if (service->to_drop != NULL) + timeout_remove(&service->to_drop); array_foreach(&service->listeners, listeners) { struct service_listener *l = *listeners; @@ -291,6 +320,16 @@ } } +void service_monitor_listen_start(struct service *service) +{ + if (service->process_avail > 0 || + (service->process_count == service->process_limit && + service->listen_pending)) + return; + + service_monitor_listen_start_force(service); +} + void service_monitor_listen_stop(struct service *service) { struct service_listener *const *listeners; @@ -303,6 +342,8 @@ } service->listening = FALSE; service->listen_pending = FALSE; + if (service->to_drop != NULL) + timeout_remove(&service->to_drop); } static int service_login_create_notify_fd(struct service *service) diff -r 6f1442a0d1c6 -r d4e15513192a src/master/service.h --- a/src/master/service.h Thu Oct 20 18:26:15 2011 +0300 +++ b/src/master/service.h Thu Oct 20 18:37:09 2011 +0300 @@ -88,6 +88,9 @@ /* if a process fails before servicing its first request, assume it's broken and start throtting new process creations */ struct timeout *to_throttle; + /* when process_limit is reached, wait for a while until we actually + start dropping pending connections */ + struct timeout *to_drop; /* Last time a "dropping client connections" warning was logged */ time_t last_drop_warning; From dovecot at dovecot.org Tue Oct 25 21:35:00 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 25 Oct 2011 21:35:00 +0300 Subject: dovecot-2.1: master: Reset service's listen_pending flag when it... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/a95bb5877f00 changeset: 13640:a95bb5877f00 user: Timo Sirainen date: Thu Oct 20 18:26:15 2011 +0300 description: master: Reset service's listen_pending flag when it gets a new available process. diffstat: src/master/service-monitor.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (21 lines): diff -r 221ec0404d8e -r a95bb5877f00 src/master/service-monitor.c --- a/src/master/service-monitor.c Thu Oct 20 16:54:36 2011 +0300 +++ b/src/master/service-monitor.c Thu Oct 20 18:26:15 2011 +0300 @@ -216,8 +216,8 @@ reach connection limit */ service_login_notify(service, TRUE); + service_monitor_listen_stop(service); service->listen_pending = TRUE; - service_monitor_listen_stop(service); } else { /* just accept and close the connection, so it's clear that this is happening because of the limit, rather than because @@ -302,6 +302,7 @@ io_remove(&l->io); } service->listening = FALSE; + service->listen_pending = FALSE; } static int service_login_create_notify_fd(struct service *service) From dovecot at dovecot.org Tue Oct 25 21:35:00 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 25 Oct 2011 21:35:00 +0300 Subject: dovecot-2.1: master: When process_limit fills up, wait 10s befor... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/fddbb26400d0 changeset: 13641:fddbb26400d0 user: Timo Sirainen date: Thu Oct 20 18:37:09 2011 +0300 description: master: When process_limit fills up, wait 10s before closing pending connections. It might have only been a temporary burst that gets resolved quickly enough. diffstat: src/master/service-monitor.c | 63 ++++++++++++++++++++++++++++++++++++------- src/master/service.h | 3 ++ 2 files changed, 55 insertions(+), 11 deletions(-) diffs (131 lines): diff -r a95bb5877f00 -r fddbb26400d0 src/master/service-monitor.c --- a/src/master/service-monitor.c Thu Oct 20 18:26:15 2011 +0300 +++ b/src/master/service-monitor.c Thu Oct 20 18:37:09 2011 +0300 @@ -22,10 +22,12 @@ #define SERVICE_STARTUP_FAILURE_THROTTLE_SECS 60 #define SERVICE_DROP_WARN_INTERVAL_SECS 60 +#define SERVICE_DROP_TIMEOUT_MSECS (10*1000) static void service_monitor_start_extra_avail(struct service *service); static void service_status_more(struct service_process *process, const struct master_status *status); +static void service_monitor_listen_start_force(struct service *service); static void service_process_kill_idle(struct service_process *process) { @@ -195,6 +197,32 @@ service_throttle(service, SERVICE_STARTUP_FAILURE_THROTTLE_SECS); } +static void service_drop_timeout(struct service *service) +{ + struct service_listener *const *lp; + int fd; + + i_assert(service->process_avail == 0); + + /* drop all pending connections */ + array_foreach(&service->listeners, lp) { + while ((fd = net_accept((*lp)->fd, NULL, NULL)) > 0) + net_disconnect(fd); + } + + service_monitor_listen_start_force(service); + service->listen_pending = TRUE; +} + +static void service_monitor_listen_pending(struct service *service) +{ + service_monitor_listen_stop(service); + service->listen_pending = TRUE; + + service->to_drop = timeout_add(SERVICE_DROP_TIMEOUT_MSECS, + service_drop_timeout, service); +} + static void service_drop_connections(struct service_listener *l) { struct service *service = l->service; @@ -216,12 +244,16 @@ reach connection limit */ service_login_notify(service, TRUE); - service_monitor_listen_stop(service); - service->listen_pending = TRUE; + service_monitor_listen_pending(service); + } else if (!service->listen_pending) { + /* maybe this is a temporary peak, stop for a while and + see if it goes away */ + service_monitor_listen_pending(service); } else { - /* just accept and close the connection, so it's clear that - this is happening because of the limit, rather than because - the service processes aren't answering fast enough */ + /* this has been happening for a while now. just accept and + close the connection, so it's clear that this is happening + because of the limit, rather than because the service + processes aren't answering fast enough */ fd = net_accept(l->fd, NULL, NULL); if (fd > 0) net_disconnect(fd); @@ -271,17 +303,14 @@ } } -void service_monitor_listen_start(struct service *service) +static void service_monitor_listen_start_force(struct service *service) { struct service_listener *const *listeners; - if (service->process_avail > 0 || - (service->process_count == service->process_limit && - service->listen_pending)) - return; - service->listening = TRUE; service->listen_pending = FALSE; + if (service->to_drop != NULL) + timeout_remove(&service->to_drop); array_foreach(&service->listeners, listeners) { struct service_listener *l = *listeners; @@ -291,6 +320,16 @@ } } +void service_monitor_listen_start(struct service *service) +{ + if (service->process_avail > 0 || + (service->process_count == service->process_limit && + service->listen_pending)) + return; + + service_monitor_listen_start_force(service); +} + void service_monitor_listen_stop(struct service *service) { struct service_listener *const *listeners; @@ -303,6 +342,8 @@ } service->listening = FALSE; service->listen_pending = FALSE; + if (service->to_drop != NULL) + timeout_remove(&service->to_drop); } static int service_login_create_notify_fd(struct service *service) diff -r a95bb5877f00 -r fddbb26400d0 src/master/service.h --- a/src/master/service.h Thu Oct 20 18:26:15 2011 +0300 +++ b/src/master/service.h Thu Oct 20 18:37:09 2011 +0300 @@ -88,6 +88,9 @@ /* if a process fails before servicing its first request, assume it's broken and start throtting new process creations */ struct timeout *to_throttle; + /* when process_limit is reached, wait for a while until we actually + start dropping pending connections */ + struct timeout *to_drop; /* Last time a "dropping client connections" warning was logged */ time_t last_drop_warning; From dovecot at dovecot.org Tue Oct 25 21:35:00 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 25 Oct 2011 21:35:00 +0300 Subject: dovecot-2.1: login: Increased client's initial memory pool size. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/402cff03919a changeset: 13642:402cff03919a user: Timo Sirainen date: Tue Oct 25 21:41:28 2011 +0300 description: login: Increased client's initial memory pool size. diffstat: src/login-common/main.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r fddbb26400d0 -r 402cff03919a src/login-common/main.c --- a/src/login-common/main.c Thu Oct 20 18:37:09 2011 +0300 +++ b/src/login-common/main.c Tue Oct 25 21:41:28 2011 +0300 @@ -111,7 +111,7 @@ local_port = 0; } - pool = pool_alloconly_create("login client", 5*1024); + pool = pool_alloconly_create("login client", 8*1024); set = login_settings_read(pool, &local_ip, &conn->remote_ip, NULL, &other_sets); From dovecot at dovecot.org Tue Oct 25 21:35:00 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 25 Oct 2011 21:35:00 +0300 Subject: dovecot-2.1: login: When renegotiating SSL handshake, don't rere... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/c9ef7a0f9b44 changeset: 13643:c9ef7a0f9b44 user: Timo Sirainen date: Tue Oct 25 21:44:38 2011 +0300 description: login: When renegotiating SSL handshake, don't reread settings when TLS SNI is used. diffstat: src/login-common/client-common.h | 1 + src/login-common/ssl-proxy-openssl.c | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diffs (31 lines): diff -r 402cff03919a -r c9ef7a0f9b44 src/login-common/client-common.h --- a/src/login-common/client-common.h Tue Oct 25 21:41:28 2011 +0300 +++ b/src/login-common/client-common.h Tue Oct 25 21:44:38 2011 +0300 @@ -118,6 +118,7 @@ unsigned int tls:1; unsigned int secured:1; unsigned int trusted:1; + unsigned int ssl_servername_settings_read:1; unsigned int authenticating:1; unsigned int auth_tried_disabled_plaintext:1; unsigned int auth_tried_unsupported_mech:1; diff -r 402cff03919a -r c9ef7a0f9b44 src/login-common/ssl-proxy-openssl.c --- a/src/login-common/ssl-proxy-openssl.c Tue Oct 25 21:41:28 2011 +0300 +++ b/src/login-common/ssl-proxy-openssl.c Tue Oct 25 21:44:38 2011 +0300 @@ -1089,9 +1089,13 @@ host = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); client = proxy->client; - client->set = login_settings_read(client->pool, - &client->local_ip, &client->ip, host, - &other_sets); + if (!client->ssl_servername_settings_read) { + client->ssl_servername_settings_read = TRUE; + client->set = login_settings_read(client->pool, + &client->local_ip, + &client->ip, host, + &other_sets); + } ctx = ssl_server_context_get(client->set); SSL_set_SSL_CTX(ssl, ctx->ctx); } From dovecot at dovecot.org Tue Oct 25 21:35:00 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 25 Oct 2011 21:35:00 +0300 Subject: dovecot-2.0: login: Increased client's initial memory pool size. Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/233565519311 changeset: 12950:233565519311 user: Timo Sirainen date: Tue Oct 25 21:41:28 2011 +0300 description: login: Increased client's initial memory pool size. diffstat: src/login-common/main.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r d4e15513192a -r 233565519311 src/login-common/main.c --- a/src/login-common/main.c Thu Oct 20 18:37:09 2011 +0300 +++ b/src/login-common/main.c Tue Oct 25 21:41:28 2011 +0300 @@ -109,7 +109,7 @@ local_port = 0; } - pool = pool_alloconly_create("login client", 5*1024); + pool = pool_alloconly_create("login client", 8*1024); set = login_settings_read(pool, &local_ip, &conn->remote_ip, NULL, &other_sets); From dovecot at dovecot.org Tue Oct 25 21:35:00 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 25 Oct 2011 21:35:00 +0300 Subject: dovecot-2.0: login: When renegotiating SSL handshake, don't rere... Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/ad2ebc237570 changeset: 12951:ad2ebc237570 user: Timo Sirainen date: Tue Oct 25 21:44:38 2011 +0300 description: login: When renegotiating SSL handshake, don't reread settings when TLS SNI is used. diffstat: src/login-common/client-common.h | 1 + src/login-common/ssl-proxy-openssl.c | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diffs (31 lines): diff -r 233565519311 -r ad2ebc237570 src/login-common/client-common.h --- a/src/login-common/client-common.h Tue Oct 25 21:41:28 2011 +0300 +++ b/src/login-common/client-common.h Tue Oct 25 21:44:38 2011 +0300 @@ -118,6 +118,7 @@ unsigned int tls:1; unsigned int secured:1; unsigned int trusted:1; + unsigned int ssl_servername_settings_read:1; unsigned int authenticating:1; unsigned int auth_tried_disabled_plaintext:1; unsigned int auth_tried_unsupported_mech:1; diff -r 233565519311 -r ad2ebc237570 src/login-common/ssl-proxy-openssl.c --- a/src/login-common/ssl-proxy-openssl.c Tue Oct 25 21:41:28 2011 +0300 +++ b/src/login-common/ssl-proxy-openssl.c Tue Oct 25 21:44:38 2011 +0300 @@ -1083,9 +1083,13 @@ host = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); client = proxy->client; - client->set = login_settings_read(client->pool, - &client->local_ip, &client->ip, host, - &other_sets); + if (!client->ssl_servername_settings_read) { + client->ssl_servername_settings_read = TRUE; + client->set = login_settings_read(client->pool, + &client->local_ip, + &client->ip, host, + &other_sets); + } ctx = ssl_server_context_get(client->set); SSL_set_SSL_CTX(ssl, ctx->ctx); } From dovecot at dovecot.org Tue Oct 25 22:48:23 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 25 Oct 2011 22:48:23 +0300 Subject: dovecot-2.0: master: Assert-crashfix when service process limit ... Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/878ddbd54f44 changeset: 12952:878ddbd54f44 user: Timo Sirainen date: Tue Oct 25 22:58:02 2011 +0300 description: master: Assert-crashfix when service process limit was reached. Introduced by commit d4e15513192a. diffstat: src/master/service-monitor.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (21 lines): diff -r ad2ebc237570 -r 878ddbd54f44 src/master/service-monitor.c --- a/src/master/service-monitor.c Tue Oct 25 21:44:38 2011 +0300 +++ b/src/master/service-monitor.c Tue Oct 25 22:58:02 2011 +0300 @@ -216,6 +216,8 @@ static void service_monitor_listen_pending(struct service *service) { + i_assert(service->process_avail == 0); + service_monitor_listen_stop(service); service->listen_pending = TRUE; @@ -297,7 +299,7 @@ break; } } - if (i > 0 && service->listening) { + if (i > 0) { /* we created some processes, they'll do the listening now */ service_monitor_listen_stop(service); } From dovecot at dovecot.org Tue Oct 25 22:48:57 2011 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 25 Oct 2011 22:48:57 +0300 Subject: dovecot-2.1: master: Assert-crashfix when service process limit ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/1dd992f75906 changeset: 13644:1dd992f75906 user: Timo Sirainen date: Tue Oct 25 22:58:48 2011 +0300 description: master: Assert-crashfix when service process limit was reached. Introduced by commit fddbb26400d0. diffstat: src/master/service-monitor.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (21 lines): diff -r c9ef7a0f9b44 -r 1dd992f75906 src/master/service-monitor.c --- a/src/master/service-monitor.c Tue Oct 25 21:44:38 2011 +0300 +++ b/src/master/service-monitor.c Tue Oct 25 22:58:48 2011 +0300 @@ -216,6 +216,8 @@ static void service_monitor_listen_pending(struct service *service) { + i_assert(service->process_avail == 0); + service_monitor_listen_stop(service); service->listen_pending = TRUE; @@ -297,7 +299,7 @@ break; } } - if (i > 0 && service->listening) { + if (i > 0) { /* we created some processes, they'll do the listening now */ service_monitor_listen_stop(service); }