You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1009 lines
32 KiB
1009 lines
32 KiB
# --- SDE-COPYRIGHT-NOTE-BEGIN --- |
|
# This copyright note is auto-generated by ./scripts/Create-CopyPatch. |
|
# |
|
# Filename: package/.../dovecot/dovecot-2.2.3-0000-upstream-fixes.patch |
|
# Copyright (C) 2013 The OpenSDE Project |
|
# |
|
# More information can be found in the files COPYING and README. |
|
# |
|
# This patch file is dual-licensed. It is available under the license the |
|
# patched project is licensed under, as long as it is an OpenSource license |
|
# as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms |
|
# of the GNU General Public License as published by the Free Software |
|
# Foundation; either version 2 of the License, or (at your option) any later |
|
# version. |
|
# --- SDE-COPYRIGHT-NOTE-END --- |
|
|
|
From 14f13e05bf6599e138f86f465554e063e6a5a560 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Mon, 17 Jun 2013 00:03:16 +0300 |
|
Subject: [PATCH] Make static analyzer happier. |
|
|
|
|
|
diff --git a/src/doveadm/dsync/doveadm-dsync.c b/src/doveadm/dsync/doveadm-dsync.c |
|
index b8196e0..605438b 100644 |
|
--- a/src/doveadm/dsync/doveadm-dsync.c |
|
+++ b/src/doveadm/dsync/doveadm-dsync.c |
|
@@ -299,6 +299,9 @@ static bool paths_are_equal(struct mail_user *user1, struct mail_user *user2, |
|
{ |
|
const char *path1, *path2; |
|
|
|
+ i_assert(user1->namespaces != NULL); |
|
+ i_assert(user2->namespaces != NULL); |
|
+ |
|
return mailbox_list_get_root_path(user1->namespaces->list, type, &path1) && |
|
mailbox_list_get_root_path(user2->namespaces->list, type, &path2) && |
|
strcmp(path1, path2) == 0; |
|
diff --git a/src/doveadm/dsync/test-dsync-mailbox-tree-sync.c b/src/doveadm/dsync/test-dsync-mailbox-tree-sync.c |
|
index 3d8b909..e0fc7bf 100644 |
|
--- a/src/doveadm/dsync/test-dsync-mailbox-tree-sync.c |
|
+++ b/src/doveadm/dsync/test-dsync-mailbox-tree-sync.c |
|
@@ -624,7 +624,8 @@ static void test_dsync_mailbox_tree_sync_renames20(void) |
|
node_create(tree2, 3, "1/0/2", 0); |
|
|
|
test_trees_nofree(tree1, &tree2); |
|
- test_assert(tree1->root.first_child->next == NULL); |
|
+ test_assert(tree1->root.first_child != NULL && |
|
+ tree1->root.first_child->next == NULL); |
|
dsync_mailbox_tree_deinit(&tree1); |
|
test_end(); |
|
} |
|
diff --git a/src/imap-login/imap-proxy.c b/src/imap-login/imap-proxy.c |
|
index e283d48..e7faebc 100644 |
|
--- a/src/imap-login/imap-proxy.c |
|
+++ b/src/imap-login/imap-proxy.c |
|
@@ -234,6 +234,7 @@ int imap_proxy_parse_line(struct client *client, const char *line) |
|
client_proxy_failed(client, TRUE); |
|
return -1; |
|
} |
|
+ i_assert(ret == 0); |
|
|
|
str_truncate(str, 0); |
|
base64_encode(data, data_len, str); |
|
diff --git a/src/pop3-login/pop3-proxy.c b/src/pop3-login/pop3-proxy.c |
|
index dd5c7dc..b2daa47 100644 |
|
--- a/src/pop3-login/pop3-proxy.c |
|
+++ b/src/pop3-login/pop3-proxy.c |
|
@@ -110,6 +110,7 @@ pop3_proxy_continue_sasl_auth(struct client *client, struct ostream *output, |
|
error)); |
|
return -1; |
|
} |
|
+ i_assert(ret == 0); |
|
|
|
str_truncate(str, 0); |
|
base64_encode(data, data_len, str); |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From c5f34506908996ec4bdbbdd090c440270553e8a1 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Mon, 17 Jun 2013 14:39:59 +0300 |
|
Subject: [PATCH] dsync: Minor fixes to checking if namespace is wanted to be |
|
synced. |
|
|
|
|
|
diff --git a/src/doveadm/dsync/dsync-brain-mailbox-tree.c b/src/doveadm/dsync/dsync-brain-mailbox-tree.c |
|
index fc9b79e..a3fb159 100644 |
|
--- a/src/doveadm/dsync/dsync-brain-mailbox-tree.c |
|
+++ b/src/doveadm/dsync/dsync-brain-mailbox-tree.c |
|
@@ -14,8 +14,8 @@ |
|
static bool dsync_brain_want_namespace(struct dsync_brain *brain, |
|
struct mail_namespace *ns) |
|
{ |
|
- if (brain->sync_ns == ns) |
|
- return TRUE; |
|
+ if (brain->sync_ns != NULL) |
|
+ return brain->sync_ns == ns; |
|
if (ns->alias_for != NULL) { |
|
/* always skip aliases */ |
|
return FALSE; |
|
@@ -26,11 +26,11 @@ static bool dsync_brain_want_namespace(struct dsync_brain *brain, |
|
if ((ns->flags & (NAMESPACE_FLAG_LIST_PREFIX | |
|
NAMESPACE_FLAG_LIST_CHILDREN)) != 0) |
|
return TRUE; |
|
+ return FALSE; |
|
+ } else { |
|
+ return strcmp(ns->unexpanded_set->location, |
|
+ SETTING_STRVAR_UNEXPANDED) == 0; |
|
} |
|
- |
|
- return brain->sync_ns == NULL && |
|
- strcmp(ns->unexpanded_set->location, |
|
- SETTING_STRVAR_UNEXPANDED) == 0; |
|
} |
|
|
|
static void dsync_brain_check_namespaces(struct dsync_brain *brain) |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From ca2ce521c15888f678bafd48adafb895f594f9e8 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Mon, 17 Jun 2013 16:37:46 +0300 |
|
Subject: [PATCH] pop3: Fixed crash at deinit |
|
|
|
|
|
diff --git a/src/pop3/pop3-client.c b/src/pop3/pop3-client.c |
|
index 6de571c..688ccab 100644 |
|
--- a/src/pop3/pop3-client.c |
|
+++ b/src/pop3/pop3-client.c |
|
@@ -593,7 +593,8 @@ static void client_default_destroy(struct client *client, const char *reason) |
|
message sizes. */ |
|
(void)mailbox_transaction_commit(&client->trans); |
|
} |
|
- array_free(&client->all_seqs); |
|
+ if (array_is_created(&client->all_seqs)) |
|
+ array_free(&client->all_seqs); |
|
if (client->deleted_kw != NULL) |
|
mailbox_keywords_unref(&client->deleted_kw); |
|
if (client->mailbox != NULL) |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From c1e0a95f98da1099d38caeca9a77413a0b7704a2 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 18 Jun 2013 11:59:21 +0300 |
|
Subject: [PATCH] imap/pop3 proxy: Master user logins were broken by lib-sasl |
|
change. |
|
|
|
|
|
diff --git a/src/imap-login/imap-proxy.c b/src/imap-login/imap-proxy.c |
|
index e7faebc..ba254de 100644 |
|
--- a/src/imap-login/imap-proxy.c |
|
+++ b/src/imap-login/imap-proxy.c |
|
@@ -79,8 +79,9 @@ static int proxy_write_login(struct imap_client *client, string_t *str) |
|
|
|
i_assert(client->common.proxy_sasl_client == NULL); |
|
memset(&sasl_set, 0, sizeof(sasl_set)); |
|
- sasl_set.authid = client->common.proxy_user; |
|
- sasl_set.authzid = client->common.proxy_master_user; |
|
+ sasl_set.authid = client->common.proxy_master_user != NULL ? |
|
+ client->common.proxy_master_user : client->common.proxy_user; |
|
+ sasl_set.authzid = client->common.proxy_user; |
|
sasl_set.password = client->common.proxy_password; |
|
client->common.proxy_sasl_client = |
|
sasl_client_new(client->common.proxy_mech, &sasl_set); |
|
diff --git a/src/pop3-login/pop3-proxy.c b/src/pop3-login/pop3-proxy.c |
|
index b2daa47..beb8f2e 100644 |
|
--- a/src/pop3-login/pop3-proxy.c |
|
+++ b/src/pop3-login/pop3-proxy.c |
|
@@ -55,8 +55,9 @@ static int proxy_send_login(struct pop3_client *client, struct ostream *output) |
|
|
|
i_assert(client->common.proxy_sasl_client == NULL); |
|
memset(&sasl_set, 0, sizeof(sasl_set)); |
|
- sasl_set.authid = client->common.proxy_user; |
|
- sasl_set.authzid = client->common.proxy_master_user; |
|
+ sasl_set.authid = client->common.proxy_master_user != NULL ? |
|
+ client->common.proxy_master_user : client->common.proxy_user; |
|
+ sasl_set.authzid = client->common.proxy_user; |
|
sasl_set.password = client->common.proxy_password; |
|
client->common.proxy_sasl_client = |
|
sasl_client_new(client->common.proxy_mech, &sasl_set); |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From ea9231b00f7f0ae0bdbca0b7f7d9443ee5387539 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 18 Jun 2013 12:15:50 +0300 |
|
Subject: [PATCH] lib-sasl: API usage comment update |
|
|
|
|
|
diff --git a/src/lib-sasl/sasl-client.h b/src/lib-sasl/sasl-client.h |
|
index dc969ef..53f04e4 100644 |
|
--- a/src/lib-sasl/sasl-client.h |
|
+++ b/src/lib-sasl/sasl-client.h |
|
@@ -4,7 +4,8 @@ |
|
struct sasl_client_settings { |
|
/* authentication ID - must be set with most mechanisms */ |
|
const char *authid; |
|
- /* authorization ID ("master user") */ |
|
+ /* authorization ID (who to log in as, if authentication ID is a |
|
+ master user) */ |
|
const char *authzid; |
|
/* password - must be set with most mechanisms */ |
|
const char *password; |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 9683a96c657a9f3b4b42e475eec42ab60aa81f15 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 18 Jun 2013 12:56:27 +0300 |
|
Subject: [PATCH] lib-index: If error is found from transaction log, update |
|
dovecot.index so it won't be read again. |
|
|
|
|
|
diff --git a/src/lib-index/mail-index-sync.c b/src/lib-index/mail-index-sync.c |
|
index 65ef817..bc17e77 100644 |
|
--- a/src/lib-index/mail-index-sync.c |
|
+++ b/src/lib-index/mail-index-sync.c |
|
@@ -895,6 +895,9 @@ void mail_index_sync_set_corrupted(struct mail_index_sync_map_ctx *ctx, |
|
uoff_t offset; |
|
|
|
ctx->errors = TRUE; |
|
+ /* make sure we don't get to this same error again by updating the |
|
+ dovecot.index */ |
|
+ ctx->view->index->need_recreate = TRUE; |
|
|
|
mail_transaction_log_view_get_prev_pos(ctx->view->log_view, |
|
&seq, &offset); |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From f464fa4fe9f876e76aad1bc5efdf23068746cfe4 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 18 Jun 2013 12:59:17 +0300 |
|
Subject: [PATCH] lib-index: Don't bother tracking if header/records were |
|
changed. They aren't really needed. When mail_index_write() |
|
is called, we already know we want to update the index. |
|
|
|
|
|
diff --git a/src/lib-index/mail-index-fsck.c b/src/lib-index/mail-index-fsck.c |
|
index 91c62cf..923a098 100644 |
|
--- a/src/lib-index/mail-index-fsck.c |
|
+++ b/src/lib-index/mail-index-fsck.c |
|
@@ -454,7 +454,6 @@ int mail_index_fsck(struct mail_index *index) |
|
mail_index_fsck_map(index, map); |
|
} T_END; |
|
|
|
- map->header_changed = TRUE; |
|
mail_index_write(index, FALSE); |
|
|
|
if (!orig_locked) |
|
diff --git a/src/lib-index/mail-index-map.c b/src/lib-index/mail-index-map.c |
|
index a735c3c..c489e51 100644 |
|
--- a/src/lib-index/mail-index-map.c |
|
+++ b/src/lib-index/mail-index-map.c |
|
@@ -332,8 +332,6 @@ static void mail_index_map_copy_records(struct mail_index_record_map *dest, |
|
|
|
dest->records = buffer_get_modifiable_data(dest->buffer, NULL); |
|
dest->records_count = src->records_count; |
|
- |
|
- dest->records_changed = src->records_changed; |
|
} |
|
|
|
static void mail_index_map_copy_header(struct mail_index_map *dest, |
|
@@ -396,8 +394,6 @@ struct mail_index_map *mail_index_map_clone(const struct mail_index_map *map) |
|
|
|
mail_index_map_copy_header(mem_map, map); |
|
|
|
- mem_map->header_changed = map->header_changed; |
|
- |
|
/* copy extensions */ |
|
if (array_is_created(&map->ext_id_map)) { |
|
count = array_count(&map->ext_id_map); |
|
diff --git a/src/lib-index/mail-index-modseq.c b/src/lib-index/mail-index-modseq.c |
|
index 75aecf3..8fe42a8 100644 |
|
--- a/src/lib-index/mail-index-modseq.c |
|
+++ b/src/lib-index/mail-index-modseq.c |
|
@@ -470,7 +470,6 @@ static void mail_index_modseq_sync_init(struct mail_index_modseq_sync *ctx) |
|
} T_END; |
|
} |
|
} |
|
- map->rec_map->records_changed = TRUE; |
|
mail_transaction_log_view_close(&ctx->log_view); |
|
} |
|
|
|
@@ -521,7 +520,6 @@ static void mail_index_modseq_update_header(struct mail_index_view *view, |
|
buffer_write(map->hdr_copy_buf, ext->hdr_offset, |
|
&new_modseq_hdr, sizeof(new_modseq_hdr)); |
|
map->hdr_base = map->hdr_copy_buf->data; |
|
- map->header_changed = TRUE; |
|
} |
|
} |
|
|
|
diff --git a/src/lib-index/mail-index-private.h b/src/lib-index/mail-index-private.h |
|
index 1473b28..0e3122c 100644 |
|
--- a/src/lib-index/mail-index-private.h |
|
+++ b/src/lib-index/mail-index-private.h |
|
@@ -127,9 +127,6 @@ struct mail_index_record_map { |
|
|
|
struct mail_index_map_modseq *modseq; |
|
uint32_t last_appended_uid; |
|
- |
|
- /* The records have changed since it was read */ |
|
- bool records_changed; |
|
}; |
|
|
|
struct mail_index_map { |
|
@@ -147,8 +144,6 @@ struct mail_index_map { |
|
ARRAY(unsigned int) keyword_idx_map; /* file -> index */ |
|
|
|
struct mail_index_record_map *rec_map; |
|
- |
|
- unsigned int header_changed:1; |
|
}; |
|
|
|
struct mail_index_module_register { |
|
diff --git a/src/lib-index/mail-index-sync-ext.c b/src/lib-index/mail-index-sync-ext.c |
|
index 68c2a2d..c9423a7 100644 |
|
--- a/src/lib-index/mail-index-sync-ext.c |
|
+++ b/src/lib-index/mail-index-sync-ext.c |
|
@@ -317,7 +317,6 @@ sync_ext_resize(const struct mail_transaction_ext_intro *u, |
|
i_assert((map->hdr_copy_buf->used % sizeof(uint64_t)) == 0); |
|
map->hdr_base = map->hdr_copy_buf->data; |
|
map->hdr.header_size = map->hdr_copy_buf->used; |
|
- map->header_changed = TRUE; |
|
|
|
ext_hdr = get_ext_header(map, ext); |
|
ext_hdr->reset_id = ext->reset_id; |
|
@@ -577,7 +576,6 @@ static void mail_index_sync_ext_clear(struct mail_index_view *view, |
|
memset(PTR_OFFSET(rec, ext->record_offset), 0, |
|
ext->record_size); |
|
} |
|
- map->rec_map->records_changed = TRUE; |
|
} |
|
|
|
int mail_index_sync_ext_reset(struct mail_index_sync_map_ctx *ctx, |
|
@@ -630,9 +628,14 @@ int mail_index_sync_ext_hdr_update(struct mail_index_sync_map_ctx *ctx, |
|
|
|
ext = array_idx(&map->extensions, ctx->cur_ext_map_idx); |
|
if (offset + size > ext->hdr_size) { |
|
+#if 1 |
|
mail_index_sync_set_corrupted(ctx, |
|
"Extension header update points outside header size"); |
|
return -1; |
|
+#else |
|
+ size = offset > ext->hdr_size ? 0 : |
|
+ ext->hdr_size - offset; |
|
+#endif |
|
} |
|
|
|
buffer_write(map->hdr_copy_buf, ext->hdr_offset + offset, data, size); |
|
@@ -640,8 +643,6 @@ int mail_index_sync_ext_hdr_update(struct mail_index_sync_map_ctx *ctx, |
|
|
|
if (ext->index_idx == ctx->view->index->modseq_ext_id) |
|
mail_index_modseq_hdr_update(ctx->modseq_ctx); |
|
- |
|
- map->header_changed = TRUE; |
|
return 1; |
|
} |
|
|
|
@@ -690,8 +691,6 @@ mail_index_sync_ext_rec_update(struct mail_index_sync_map_ctx *ctx, |
|
return ret; |
|
} |
|
|
|
- view->map->rec_map->records_changed = TRUE; |
|
- |
|
/* @UNSAFE */ |
|
memcpy(old_data, u + 1, ext->record_size); |
|
return 1; |
|
@@ -791,7 +790,5 @@ mail_index_sync_ext_atomic_inc(struct mail_index_sync_map_ctx *ctx, |
|
u->uid, u->diff, (unsigned long long)orig_num); |
|
return -1; |
|
} |
|
- |
|
- view->map->rec_map->records_changed = TRUE; |
|
return 1; |
|
} |
|
diff --git a/src/lib-index/mail-index-sync-keywords.c b/src/lib-index/mail-index-sync-keywords.c |
|
index 36ab1d0..eff6385 100644 |
|
--- a/src/lib-index/mail-index-sync-keywords.c |
|
+++ b/src/lib-index/mail-index-sync-keywords.c |
|
@@ -215,7 +215,6 @@ keywords_update_records(struct mail_index_sync_map_ctx *ctx, |
|
if (!mail_index_lookup_seq_range(view, uid1, uid2, &seq1, &seq2)) |
|
return 1; |
|
|
|
- view->map->rec_map->records_changed = TRUE; |
|
mail_index_modseq_update_keyword(ctx->modseq_ctx, keyword_idx, |
|
seq1, seq2); |
|
|
|
@@ -337,7 +336,6 @@ mail_index_sync_keywords_reset(struct mail_index_sync_map_ctx *ctx, |
|
&seq1, &seq2)) |
|
continue; |
|
|
|
- map->rec_map->records_changed = TRUE; |
|
mail_index_modseq_reset_keywords(ctx->modseq_ctx, seq1, seq2); |
|
for (seq1--; seq1 < seq2; seq1++) { |
|
rec = MAIL_INDEX_MAP_IDX(map, seq1); |
|
diff --git a/src/lib-index/mail-index-sync-update.c b/src/lib-index/mail-index-sync-update.c |
|
index 986d3a1..508209c 100644 |
|
--- a/src/lib-index/mail-index-sync-update.c |
|
+++ b/src/lib-index/mail-index-sync-update.c |
|
@@ -380,7 +380,6 @@ static int sync_append(const struct mail_index_record *rec, |
|
map->rec_map->last_appended_uid = rec->uid; |
|
new_flags = rec->flags; |
|
|
|
- map->rec_map->records_changed = TRUE; |
|
mail_index_modseq_append(ctx->modseq_ctx, |
|
map->rec_map->records_count); |
|
} |
|
@@ -408,7 +407,6 @@ static int sync_flag_update(const struct mail_transaction_flag_update *u, |
|
if (!mail_index_lookup_seq_range(view, u->uid1, u->uid2, &seq1, &seq2)) |
|
return 1; |
|
|
|
- view->map->rec_map->records_changed = TRUE; |
|
if (!MAIL_TRANSACTION_FLAG_UPDATE_IS_INTERNAL(u)) { |
|
mail_index_modseq_update_flags(ctx->modseq_ctx, |
|
u->add_flags | u->remove_flags, |
|
@@ -464,7 +462,6 @@ static int sync_header_update(const struct mail_transaction_header_update *u, |
|
|
|
buffer_write(map->hdr_copy_buf, u->offset, u + 1, u->size); |
|
map->hdr_base = map->hdr_copy_buf->data; |
|
- map->header_changed = TRUE; |
|
|
|
/* @UNSAFE */ |
|
if ((uint32_t)(u->offset + u->size) <= sizeof(map->hdr)) { |
|
@@ -945,10 +942,8 @@ int mail_index_sync_map(struct mail_index_map **_map, |
|
map->refcount--; |
|
|
|
had_dirty = (map->hdr.flags & MAIL_INDEX_HDR_FLAG_HAVE_DIRTY) != 0; |
|
- if (had_dirty) { |
|
+ if (had_dirty) |
|
map->hdr.flags &= ~MAIL_INDEX_HDR_FLAG_HAVE_DIRTY; |
|
- map->header_changed = TRUE; |
|
- } |
|
|
|
if (map->hdr_base != map->hdr_copy_buf->data) { |
|
/* if syncing updates the header, it updates hdr_copy_buf |
|
diff --git a/src/lib-index/mail-index-write.c b/src/lib-index/mail-index-write.c |
|
index 3c05f58..958a98b 100644 |
|
--- a/src/lib-index/mail-index-write.c |
|
+++ b/src/lib-index/mail-index-write.c |
|
@@ -119,9 +119,6 @@ static int mail_index_recreate(struct mail_index *index) |
|
return ret; |
|
} |
|
|
|
-#define mail_index_map_has_changed(map) \ |
|
- ((map)->header_changed || (map)->rec_map->records_changed) |
|
- |
|
void mail_index_write(struct mail_index *index, bool want_rotate) |
|
{ |
|
struct mail_index_map *map = index->map; |
|
@@ -129,7 +126,7 @@ void mail_index_write(struct mail_index *index, bool want_rotate) |
|
|
|
i_assert(index->log_sync_locked); |
|
|
|
- if (!mail_index_map_has_changed(map) || index->readonly) |
|
+ if (index->readonly) |
|
return; |
|
|
|
if (!MAIL_INDEX_IS_IN_MEMORY(index)) { |
|
@@ -143,9 +140,6 @@ void mail_index_write(struct mail_index *index, bool want_rotate) |
|
index->last_read_log_file_head_offset = hdr->log_file_head_offset; |
|
index->last_read_log_file_tail_offset = hdr->log_file_tail_offset; |
|
|
|
- map->rec_map->records_changed = FALSE; |
|
- map->header_changed = FALSE; |
|
- |
|
if (want_rotate && |
|
hdr->log_file_seq == index->log->head->hdr.file_seq && |
|
hdr->log_file_tail_offset == hdr->log_file_head_offset) |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From ec67583d343124457f383a72a1ea16359d9e21af Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 18 Jun 2013 13:00:23 +0300 |
|
Subject: [PATCH] mdbox: If mdbox header is corrupted, resize it to make sure |
|
its size is correct. |
|
|
|
|
|
diff --git a/src/lib-storage/index/dbox-multi/mdbox-storage.c b/src/lib-storage/index/dbox-multi/mdbox-storage.c |
|
index 0c353cc..c938bf6 100644 |
|
--- a/src/lib-storage/index/dbox-multi/mdbox-storage.c |
|
+++ b/src/lib-storage/index/dbox-multi/mdbox-storage.c |
|
@@ -229,7 +229,7 @@ void mdbox_update_header(struct mdbox_mailbox *mbox, |
|
|
|
if (mdbox_read_header(mbox, &hdr, &need_resize) < 0) { |
|
memset(&hdr, 0, sizeof(hdr)); |
|
- need_resize = FALSE; |
|
+ need_resize = TRUE; |
|
} |
|
|
|
new_hdr = hdr; |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 25f9eabd31f34ccc021a719c07299c6a9dd2bd8c Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 18 Jun 2013 15:14:42 +0300 |
|
Subject: [PATCH] doveadm: Added "flags" command to modify messages' flags. |
|
|
|
|
|
diff --git a/src/doveadm/Makefile.am b/src/doveadm/Makefile.am |
|
index bf8824a..30f48d4 100644 |
|
--- a/src/doveadm/Makefile.am |
|
+++ b/src/doveadm/Makefile.am |
|
@@ -64,6 +64,7 @@ common = \ |
|
doveadm-mail-batch.c \ |
|
doveadm-mail-expunge.c \ |
|
doveadm-mail-fetch.c \ |
|
+ doveadm-mail-flags.c \ |
|
doveadm-mail-import.c \ |
|
doveadm-mail-index.c \ |
|
doveadm-mail-iter.c \ |
|
diff --git a/src/doveadm/doveadm-mail-flags.c b/src/doveadm/doveadm-mail-flags.c |
|
new file mode 100644 |
|
index 0000000..e37d049 |
|
--- /dev/null |
|
+++ b/src/doveadm/doveadm-mail-flags.c |
|
@@ -0,0 +1,143 @@ |
|
+/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */ |
|
+ |
|
+#include "lib.h" |
|
+#include "imap-util.h" |
|
+#include "mail-storage.h" |
|
+#include "doveadm-mailbox-list-iter.h" |
|
+#include "doveadm-mail-iter.h" |
|
+#include "doveadm-mail.h" |
|
+ |
|
+#include <stdio.h> |
|
+ |
|
+struct flags_cmd_context { |
|
+ struct doveadm_mail_cmd_context ctx; |
|
+ enum modify_type modify_type; |
|
+ enum mail_flags flags; |
|
+ const char *const *keywords; |
|
+}; |
|
+ |
|
+static int |
|
+cmd_flags_run_box(struct flags_cmd_context *ctx, |
|
+ const struct mailbox_info *info) |
|
+{ |
|
+ struct doveadm_mail_iter *iter; |
|
+ struct mailbox *box; |
|
+ struct mail *mail; |
|
+ struct mail_keywords *kw = NULL; |
|
+ |
|
+ if (doveadm_mail_iter_init(&ctx->ctx, info, ctx->ctx.search_args, |
|
+ 0, NULL, &iter) < 0) |
|
+ return -1; |
|
+ box = doveadm_mail_iter_get_mailbox(iter); |
|
+ |
|
+ if (ctx->keywords != NULL) { |
|
+ if (mailbox_keywords_create(box, ctx->keywords, &kw) < 0) { |
|
+ i_error("Invalid keywords: %s", |
|
+ mailbox_get_last_error(box, NULL)); |
|
+ (void)doveadm_mail_iter_deinit(&iter); |
|
+ ctx->ctx.exit_code = DOVEADM_EX_NOTPOSSIBLE; |
|
+ return -1; |
|
+ } |
|
+ } |
|
+ |
|
+ while (doveadm_mail_iter_next(iter, &mail)) { |
|
+ mail_update_flags(mail, ctx->modify_type, ctx->flags); |
|
+ if (kw != NULL) |
|
+ mail_update_keywords(mail, ctx->modify_type, kw); |
|
+ } |
|
+ if (kw != NULL) |
|
+ mailbox_keywords_unref(&kw); |
|
+ return doveadm_mail_iter_deinit(&iter); |
|
+} |
|
+ |
|
+static int |
|
+cmd_flags_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user) |
|
+{ |
|
+ struct flags_cmd_context *ctx = (struct flags_cmd_context *)_ctx; |
|
+ const enum mailbox_list_iter_flags iter_flags = |
|
+ MAILBOX_LIST_ITER_NO_AUTO_BOXES | |
|
+ MAILBOX_LIST_ITER_RETURN_NO_FLAGS; |
|
+ struct doveadm_mailbox_list_iter *iter; |
|
+ const struct mailbox_info *info; |
|
+ int ret = 0; |
|
+ |
|
+ iter = doveadm_mailbox_list_iter_init(_ctx, user, _ctx->search_args, |
|
+ iter_flags); |
|
+ while ((info = doveadm_mailbox_list_iter_next(iter)) != NULL) T_BEGIN { |
|
+ if (cmd_flags_run_box(ctx, info) < 0) |
|
+ ret = -1; |
|
+ } T_END; |
|
+ if (doveadm_mailbox_list_iter_deinit(&iter) < 0) |
|
+ ret = -1; |
|
+ return ret; |
|
+} |
|
+ |
|
+static void cmd_flags_init(struct doveadm_mail_cmd_context *_ctx, |
|
+ const char *const args[]) |
|
+{ |
|
+ struct flags_cmd_context *ctx = (struct flags_cmd_context *)_ctx; |
|
+ const char *const *tmp; |
|
+ enum mail_flags flag; |
|
+ ARRAY_TYPE(const_string) keywords; |
|
+ |
|
+ if (args[0] == NULL || args[1] == NULL) |
|
+ doveadm_mail_help_name("flags"); |
|
+ |
|
+ p_array_init(&keywords, _ctx->pool, 8); |
|
+ for (tmp = t_strsplit(args[0], " "); *tmp != NULL; tmp++) { |
|
+ const char *str = *tmp; |
|
+ |
|
+ if (str[0] == '\\') { |
|
+ flag = imap_parse_system_flag(str); |
|
+ if (flag == 0) |
|
+ i_fatal("Invalid system flag: %s", str); |
|
+ ctx->flags |= flag; |
|
+ } else { |
|
+ str = p_strdup(_ctx->pool, str); |
|
+ array_append(&keywords, &str, 1); |
|
+ } |
|
+ } |
|
+ if (array_count(&keywords) > 0 || ctx->modify_type == MODIFY_REPLACE) { |
|
+ array_append_zero(&keywords); |
|
+ ctx->keywords = array_idx(&keywords, 0); |
|
+ } |
|
+ |
|
+ _ctx->search_args = doveadm_mail_build_search_args(args+1); |
|
+} |
|
+ |
|
+static struct doveadm_mail_cmd_context * |
|
+cmd_flag_alloc(enum modify_type modify_type) |
|
+{ |
|
+ struct flags_cmd_context *ctx; |
|
+ |
|
+ ctx = doveadm_mail_cmd_alloc(struct flags_cmd_context); |
|
+ ctx->modify_type = modify_type; |
|
+ ctx->ctx.v.init = cmd_flags_init; |
|
+ ctx->ctx.v.run = cmd_flags_run; |
|
+ return &ctx->ctx; |
|
+} |
|
+ |
|
+static struct doveadm_mail_cmd_context *cmd_flags_add_alloc(void) |
|
+{ |
|
+ return cmd_flag_alloc(MODIFY_ADD); |
|
+} |
|
+ |
|
+static struct doveadm_mail_cmd_context *cmd_flags_remove_alloc(void) |
|
+{ |
|
+ return cmd_flag_alloc(MODIFY_REMOVE); |
|
+} |
|
+ |
|
+static struct doveadm_mail_cmd_context *cmd_flags_replace_alloc(void) |
|
+{ |
|
+ return cmd_flag_alloc(MODIFY_REPLACE); |
|
+} |
|
+ |
|
+struct doveadm_mail_cmd cmd_flags_add = { |
|
+ cmd_flags_add_alloc, "flags add", "<flags> <search query>" |
|
+}; |
|
+struct doveadm_mail_cmd cmd_flags_remove = { |
|
+ cmd_flags_remove_alloc, "flags remove", "<flags> <search query>" |
|
+}; |
|
+struct doveadm_mail_cmd cmd_flags_replace = { |
|
+ cmd_flags_replace_alloc, "flags replace", "<flags> <search query>" |
|
+}; |
|
diff --git a/src/doveadm/doveadm-mail.c b/src/doveadm/doveadm-mail.c |
|
index d035893..5f5fc2e 100644 |
|
--- a/src/doveadm/doveadm-mail.c |
|
+++ b/src/doveadm/doveadm-mail.c |
|
@@ -692,6 +692,9 @@ static struct doveadm_mail_cmd *mail_commands[] = { |
|
&cmd_expunge, |
|
&cmd_search, |
|
&cmd_fetch, |
|
+ &cmd_flags_add, |
|
+ &cmd_flags_remove, |
|
+ &cmd_flags_replace, |
|
&cmd_import, |
|
&cmd_index, |
|
&cmd_altmove, |
|
diff --git a/src/doveadm/doveadm-mail.h b/src/doveadm/doveadm-mail.h |
|
index 5d0364d..415a614 100644 |
|
--- a/src/doveadm/doveadm-mail.h |
|
+++ b/src/doveadm/doveadm-mail.h |
|
@@ -138,6 +138,9 @@ void doveadm_mail_failed_mailbox(struct doveadm_mail_cmd_context *ctx, |
|
extern struct doveadm_mail_cmd cmd_expunge; |
|
extern struct doveadm_mail_cmd cmd_search; |
|
extern struct doveadm_mail_cmd cmd_fetch; |
|
+extern struct doveadm_mail_cmd cmd_flags_add; |
|
+extern struct doveadm_mail_cmd cmd_flags_remove; |
|
+extern struct doveadm_mail_cmd cmd_flags_replace; |
|
extern struct doveadm_mail_cmd cmd_import; |
|
extern struct doveadm_mail_cmd cmd_index; |
|
extern struct doveadm_mail_cmd cmd_altmove; |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 67945386cc61f3e4755ec2c46f301f4448877825 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 18 Jun 2013 17:05:20 +0300 |
|
Subject: [PATCH] doveadm: Added deduplicate command. By default it |
|
deduplicates only by GUIDs. With -m parameter it |
|
deduplicates by Message-Id: header. |
|
|
|
|
|
diff --git a/src/doveadm/Makefile.am b/src/doveadm/Makefile.am |
|
index 30f48d4..99e297b 100644 |
|
--- a/src/doveadm/Makefile.am |
|
+++ b/src/doveadm/Makefile.am |
|
@@ -62,6 +62,7 @@ common = \ |
|
doveadm-mail.c \ |
|
doveadm-mail-altmove.c \ |
|
doveadm-mail-batch.c \ |
|
+ doveadm-mail-deduplicate.c \ |
|
doveadm-mail-expunge.c \ |
|
doveadm-mail-fetch.c \ |
|
doveadm-mail-flags.c \ |
|
diff --git a/src/doveadm/doveadm-mail-deduplicate.c b/src/doveadm/doveadm-mail-deduplicate.c |
|
new file mode 100644 |
|
index 0000000..daa76d1 |
|
--- /dev/null |
|
+++ b/src/doveadm/doveadm-mail-deduplicate.c |
|
@@ -0,0 +1,203 @@ |
|
+/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */ |
|
+ |
|
+#include "lib.h" |
|
+#include "hash.h" |
|
+#include "mail-storage.h" |
|
+#include "mail-search-build.h" |
|
+#include "doveadm-mailbox-list-iter.h" |
|
+#include "doveadm-mail-iter.h" |
|
+#include "doveadm-mail.h" |
|
+ |
|
+struct uidlist { |
|
+ struct uidlist *next; |
|
+ uint32_t uid; |
|
+}; |
|
+ |
|
+struct deduplicate_cmd_context { |
|
+ struct doveadm_mail_cmd_context ctx; |
|
+ bool by_msgid; |
|
+}; |
|
+ |
|
+static int cmd_deduplicate_uidlist(struct mailbox *box, struct uidlist *uidlist) |
|
+{ |
|
+ struct mailbox_transaction_context *trans; |
|
+ struct mail_search_context *search_ctx; |
|
+ struct mail_search_args *search_args; |
|
+ struct mail_search_arg *arg; |
|
+ struct mail *mail; |
|
+ ARRAY_TYPE(seq_range) uids; |
|
+ int ret = 0; |
|
+ |
|
+ /* the uidlist is reversed with oldest mails at the end. |
|
+ we'll delete everything but the oldest mail. */ |
|
+ if (uidlist->next == NULL) |
|
+ return 0; |
|
+ |
|
+ t_array_init(&uids, 8); |
|
+ for (; uidlist->next != NULL; uidlist = uidlist->next) |
|
+ seq_range_array_add(&uids, uidlist->uid); |
|
+ |
|
+ search_args = mail_search_build_init(); |
|
+ arg = mail_search_build_add(search_args, SEARCH_UIDSET); |
|
+ arg->value.seqset = uids; |
|
+ |
|
+ trans = mailbox_transaction_begin(box, 0); |
|
+ search_ctx = mailbox_search_init(trans, search_args, NULL, 0, NULL); |
|
+ mail_search_args_unref(&search_args); |
|
+ |
|
+ while (mailbox_search_next(search_ctx, &mail)) |
|
+ mail_expunge(mail); |
|
+ if (mailbox_search_deinit(&search_ctx) < 0) |
|
+ ret = -1; |
|
+ if (mailbox_transaction_commit(&trans) < 0) |
|
+ ret = -1; |
|
+ return ret; |
|
+} |
|
+ |
|
+static int |
|
+cmd_deduplicate_box(struct doveadm_mail_cmd_context *_ctx, |
|
+ const struct mailbox_info *info, |
|
+ struct mail_search_args *search_args) |
|
+{ |
|
+ struct deduplicate_cmd_context *ctx = |
|
+ (struct deduplicate_cmd_context *)_ctx; |
|
+ struct doveadm_mail_iter *iter; |
|
+ struct mailbox *box; |
|
+ struct mail *mail; |
|
+ enum mail_error error; |
|
+ pool_t pool; |
|
+ HASH_TABLE(const char *, struct uidlist *) hash; |
|
+ const char *key, *errstr; |
|
+ struct uidlist *value; |
|
+ int ret = 0; |
|
+ |
|
+ if (doveadm_mail_iter_init(_ctx, info, search_args, 0, NULL, |
|
+ &iter) < 0) |
|
+ return -1; |
|
+ |
|
+ pool = pool_alloconly_create("deduplicate", 10240); |
|
+ hash_table_create(&hash, pool, 0, str_hash, strcmp); |
|
+ while (doveadm_mail_iter_next(iter, &mail)) { |
|
+ if (ctx->by_msgid) { |
|
+ if (mail_get_first_header(mail, "Message-ID", &key) < 0) { |
|
+ errstr = mailbox_get_last_error(box, &error); |
|
+ if (error == MAIL_ERROR_NOTFOUND) |
|
+ continue; |
|
+ i_error("Couldn't lookup Message-ID: for UID=%u: %s", |
|
+ mail->uid, errstr); |
|
+ ret = -1; |
|
+ break; |
|
+ } |
|
+ } else { |
|
+ if (mail_get_special(mail, MAIL_FETCH_GUID, &key) < 0) { |
|
+ errstr = mailbox_get_last_error(box, &error); |
|
+ if (error == MAIL_ERROR_NOTFOUND) |
|
+ continue; |
|
+ i_error("Couldn't lookup GUID: for UID=%u: %s", |
|
+ mail->uid, errstr); |
|
+ ret = -1; |
|
+ break; |
|
+ } |
|
+ } |
|
+ if (key != NULL && *key != '\0') { |
|
+ value = p_new(pool, struct uidlist, 1); |
|
+ value->uid = mail->uid; |
|
+ value->next = hash_table_lookup(hash, key); |
|
+ |
|
+ if (value->next == NULL) { |
|
+ key = p_strdup(pool, key); |
|
+ hash_table_insert(hash, key, value); |
|
+ } else { |
|
+ hash_table_update(hash, key, value); |
|
+ } |
|
+ } |
|
+ } |
|
+ |
|
+ if (doveadm_mail_iter_deinit_keep_box(&iter, &box) < 0) |
|
+ ret = -1; |
|
+ |
|
+ if (ret == 0) { |
|
+ struct hash_iterate_context *iter; |
|
+ |
|
+ iter = hash_table_iterate_init(hash); |
|
+ while (hash_table_iterate(iter, hash, &key, &value)) { |
|
+ T_BEGIN { |
|
+ if (cmd_deduplicate_uidlist(box, value) < 0) |
|
+ ret = -1; |
|
+ } T_END; |
|
+ } |
|
+ hash_table_iterate_deinit(&iter); |
|
+ } |
|
+ |
|
+ hash_table_destroy(&hash); |
|
+ pool_unref(&pool); |
|
+ |
|
+ if (mailbox_sync(box, 0) < 0) { |
|
+ doveadm_mail_failed_mailbox(_ctx, box); |
|
+ ret = -1; |
|
+ } |
|
+ mailbox_free(&box); |
|
+ return ret; |
|
+} |
|
+ |
|
+static int |
|
+cmd_deduplicate_run(struct doveadm_mail_cmd_context *ctx, struct mail_user *user) |
|
+{ |
|
+ const enum mailbox_list_iter_flags iter_flags = |
|
+ MAILBOX_LIST_ITER_NO_AUTO_BOXES | |
|
+ MAILBOX_LIST_ITER_RETURN_NO_FLAGS; |
|
+ struct doveadm_mailbox_list_iter *iter; |
|
+ const struct mailbox_info *info; |
|
+ int ret = 0; |
|
+ |
|
+ iter = doveadm_mailbox_list_iter_init(ctx, user, ctx->search_args, |
|
+ iter_flags); |
|
+ while ((info = doveadm_mailbox_list_iter_next(iter)) != NULL) T_BEGIN { |
|
+ if (cmd_deduplicate_box(ctx, info, ctx->search_args) < 0) |
|
+ ret = -1; |
|
+ } T_END; |
|
+ if (doveadm_mailbox_list_iter_deinit(&iter) < 0) |
|
+ ret = -1; |
|
+ return ret; |
|
+} |
|
+ |
|
+static void cmd_deduplicate_init(struct doveadm_mail_cmd_context *ctx, |
|
+ const char *const args[]) |
|
+{ |
|
+ if (args[0] == NULL) |
|
+ doveadm_mail_help_name("deduplicate"); |
|
+ |
|
+ ctx->search_args = doveadm_mail_build_search_args(args); |
|
+} |
|
+ |
|
+static bool |
|
+cmd_deduplicate_parse_arg(struct doveadm_mail_cmd_context *_ctx, int c) |
|
+{ |
|
+ struct deduplicate_cmd_context *ctx = |
|
+ (struct deduplicate_cmd_context *)_ctx; |
|
+ |
|
+ switch (c) { |
|
+ case 'm': |
|
+ ctx->by_msgid = TRUE; |
|
+ break; |
|
+ default: |
|
+ return FALSE; |
|
+ } |
|
+ return TRUE; |
|
+} |
|
+ |
|
+static struct doveadm_mail_cmd_context *cmd_deduplicate_alloc(void) |
|
+{ |
|
+ struct deduplicate_cmd_context *ctx; |
|
+ |
|
+ ctx = doveadm_mail_cmd_alloc(struct deduplicate_cmd_context); |
|
+ ctx->ctx.getopt_args = "m"; |
|
+ ctx->ctx.v.parse_arg = cmd_deduplicate_parse_arg; |
|
+ ctx->ctx.v.init = cmd_deduplicate_init; |
|
+ ctx->ctx.v.run = cmd_deduplicate_run; |
|
+ return &ctx->ctx; |
|
+} |
|
+ |
|
+struct doveadm_mail_cmd cmd_deduplicate = { |
|
+ cmd_deduplicate_alloc, "deduplicate", "[-m] <search query>" |
|
+}; |
|
diff --git a/src/doveadm/doveadm-mail.c b/src/doveadm/doveadm-mail.c |
|
index 5f5fc2e..c955eaa 100644 |
|
--- a/src/doveadm/doveadm-mail.c |
|
+++ b/src/doveadm/doveadm-mail.c |
|
@@ -699,6 +699,7 @@ static struct doveadm_mail_cmd *mail_commands[] = { |
|
&cmd_index, |
|
&cmd_altmove, |
|
&cmd_copy, |
|
+ &cmd_deduplicate, |
|
&cmd_move, |
|
&cmd_mailbox_list, |
|
&cmd_mailbox_create, |
|
diff --git a/src/doveadm/doveadm-mail.h b/src/doveadm/doveadm-mail.h |
|
index 415a614..ce07bdf 100644 |
|
--- a/src/doveadm/doveadm-mail.h |
|
+++ b/src/doveadm/doveadm-mail.h |
|
@@ -145,6 +145,7 @@ extern struct doveadm_mail_cmd cmd_import; |
|
extern struct doveadm_mail_cmd cmd_index; |
|
extern struct doveadm_mail_cmd cmd_altmove; |
|
extern struct doveadm_mail_cmd cmd_copy; |
|
+extern struct doveadm_mail_cmd cmd_deduplicate; |
|
extern struct doveadm_mail_cmd cmd_move; |
|
extern struct doveadm_mail_cmd cmd_mailbox_list; |
|
extern struct doveadm_mail_cmd cmd_mailbox_create; |
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From 703b95b5136b4f0b2600b039f2fc4488dfe3968e Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 18 Jun 2013 18:54:20 +0300 |
|
Subject: [PATCH] sdbox: If sdbox header is corrupted, resize it to make sure |
|
its size is correct. |
|
|
|
|
|
diff --git a/src/lib-storage/index/dbox-single/sdbox-storage.c b/src/lib-storage/index/dbox-single/sdbox-storage.c |
|
index 9ee0daa..63376c6 100644 |
|
--- a/src/lib-storage/index/dbox-single/sdbox-storage.c |
|
+++ b/src/lib-storage/index/dbox-single/sdbox-storage.c |
|
@@ -185,8 +185,10 @@ static void sdbox_update_header(struct sdbox_mailbox *mbox, |
|
struct sdbox_index_header hdr, new_hdr; |
|
bool need_resize; |
|
|
|
- if (sdbox_read_header(mbox, &hdr, TRUE, &need_resize) < 0) |
|
+ if (sdbox_read_header(mbox, &hdr, TRUE, &need_resize) < 0) { |
|
memset(&hdr, 0, sizeof(hdr)); |
|
+ need_resize = TRUE; |
|
+ } |
|
|
|
new_hdr = hdr; |
|
|
|
-- |
|
1.7.10.2 |
|
|
|
|
|
From ae04e6813463fdd62572c94840623149ba2bae10 Mon Sep 17 00:00:00 2001 |
|
From: Timo Sirainen <tss@iki.fi> |
|
Date: Tue, 18 Jun 2013 18:56:15 +0300 |
|
Subject: [PATCH] lib-storage: Fixed crash with some autocreated (e.g. shared) |
|
namespaces. |
|
|
|
|
|
diff --git a/src/lib-storage/mailbox-list.c b/src/lib-storage/mailbox-list.c |
|
index 03e5fec..70f4d00 100644 |
|
--- a/src/lib-storage/mailbox-list.c |
|
+++ b/src/lib-storage/mailbox-list.c |
|
@@ -808,7 +808,7 @@ int mailbox_list_get_storage(struct mailbox_list **list, const char *vname, |
|
return (*list)->v.get_storage(list, vname, storage_r); |
|
|
|
set = mailbox_settings_find((*list)->ns->user, vname); |
|
- if (set != NULL && set->driver[0] != '\0') { |
|
+ if (set != NULL && set->driver != NULL && set->driver[0] != '\0') { |
|
return mailbox_list_get_storage_driver(*list, set->driver, |
|
storage_r); |
|
} |
|
-- |
|
1.7.10.2 |
|
|
|
|