Mercurial > dovecot > original-hg > dovecot-1.2
changeset 3209:923ff19873d4 HEAD
Major mail-storage API changes. It's now a bit cleaner and much more plugin
friendly. Removed proxy_mailbox* stuff, they were difficult to use and
there's now much easier way to replace them.
line wrap: on
line diff
--- a/src/deliver/deliver.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/deliver/deliver.c Tue Mar 15 21:01:50 2005 +0200 @@ -93,7 +93,7 @@ return FALSE; } - t = mailbox_transaction_begin(box, FALSE); + t = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_EXTERNAL); memset(&ctx, 0, sizeof(ctx)); ctx.ret = -1;
--- a/src/imap/cmd-append.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/imap/cmd-append.c Tue Mar 15 21:01:50 2005 +0200 @@ -396,7 +396,8 @@ status.keywords_count); } ctx->t = ctx->box == NULL ? NULL : - mailbox_transaction_begin(ctx->box, FALSE); + mailbox_transaction_begin(ctx->box, + MAILBOX_TRANSACTION_FLAG_EXTERNAL); } io_remove(client->io);
--- a/src/imap/cmd-copy.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/imap/cmd-copy.c Tue Mar 15 21:01:50 2005 +0200 @@ -12,22 +12,15 @@ struct mail_search_context *search_ctx; struct mailbox_transaction_context *src_trans; struct mail *mail; - string_t *dest_str; int ret; - src_trans = mailbox_transaction_begin(srcbox, FALSE); - search_ctx = mailbox_search_init(src_trans, NULL, search_args, NULL, - MAIL_FETCH_STREAM_HEADER | - MAIL_FETCH_STREAM_BODY, NULL); - if (search_ctx == NULL) { - mailbox_transaction_rollback(src_trans); - return -1; - } + src_trans = mailbox_transaction_begin(srcbox, 0); + search_ctx = mailbox_search_init(src_trans, NULL, search_args, NULL); - dest_str = t_str_new(128); - + mail = mail_alloc(src_trans, MAIL_FETCH_STREAM_HEADER | + MAIL_FETCH_STREAM_BODY, NULL); ret = 1; - while ((mail = mailbox_search_next(search_ctx)) != NULL) { + while (mailbox_search_next(search_ctx, mail) > 0) { if (mail->expunged) { ret = 0; break; @@ -36,8 +29,8 @@ ret = -1; break; } - } + mail_free(mail); if (mailbox_search_deinit(search_ctx) < 0) ret = -1; @@ -89,7 +82,8 @@ } } - t = mailbox_transaction_begin(destbox, FALSE); + t = mailbox_transaction_begin(destbox, + MAILBOX_TRANSACTION_FLAG_EXTERNAL); ret = fetch_and_copy(t, client->mailbox, search_arg); if (ret <= 0)
--- a/src/imap/cmd-search.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/imap/cmd-search.c Tue Mar 15 21:01:50 2005 +0200 @@ -14,23 +14,23 @@ struct client *client = cmd->client; struct mail_search_context *ctx; struct mailbox_transaction_context *trans; - const struct mail *mail; + struct mail *mail; string_t *str; int ret, uid, first = TRUE; str = t_str_new(STRBUF_SIZE); uid = cmd->uid; - trans = mailbox_transaction_begin(client->mailbox, FALSE); - ctx = mailbox_search_init(trans, charset, sargs, - NULL, 0, NULL); + trans = mailbox_transaction_begin(client->mailbox, 0); + ctx = mailbox_search_init(trans, charset, sargs, NULL); if (ctx == NULL) { mailbox_transaction_rollback(trans); return FALSE; } str_append(str, "* SEARCH"); - while ((mail = mailbox_search_next(ctx)) != NULL) { + mail = mail_alloc(trans, 0, NULL); + while ((ret = mailbox_search_next(ctx, mail)) > 0) { if (str_len(str) >= STRBUF_SIZE-MAX_INT_STRLEN) { /* flush */ o_stream_send(client->output, @@ -41,6 +41,7 @@ str_printfa(str, " %u", uid ? mail->uid : mail->seq); } + mail_free(mail); ret = mailbox_search_deinit(ctx);
--- a/src/imap/cmd-store.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/imap/cmd-store.c Tue Mar 15 21:01:50 2005 +0200 @@ -85,28 +85,30 @@ if (search_arg == NULL) return TRUE; - t = mailbox_transaction_begin(box, silent); + t = mailbox_transaction_begin(box, !silent ? 0 : + MAILBOX_TRANSACTION_FLAG_HIDE); keywords = keywords_list != NULL || modify_type == MODIFY_REPLACE ? mailbox_keywords_create(t, keywords_list) : NULL; - search_ctx = mailbox_search_init(t, NULL, search_arg, NULL, - MAIL_FETCH_FLAGS, NULL); + search_ctx = mailbox_search_init(t, NULL, search_arg, NULL); failed = FALSE; - while ((mail = mailbox_search_next(search_ctx)) != NULL) { + mail = mail_alloc(t, MAIL_FETCH_FLAGS, NULL); + while (mailbox_search_next(search_ctx, mail) > 0) { if (modify_type == MODIFY_REPLACE || flags != 0) { - if (mail->update_flags(mail, modify_type, flags) < 0) { + if (mail_update_flags(mail, modify_type, flags) < 0) { failed = TRUE; break; } } if (modify_type == MODIFY_REPLACE || keywords != NULL) { - if (mail->update_keywords(mail, modify_type, - keywords) < 0) { + if (mail_update_keywords(mail, modify_type, + keywords) < 0) { failed = TRUE; break; } } } + mail_free(mail); if (keywords != NULL) mailbox_keywords_free(t, keywords);
--- a/src/imap/common.h Tue Mar 15 20:58:18 2005 +0200 +++ b/src/imap/common.h Tue Mar 15 21:01:50 2005 +0200 @@ -37,7 +37,7 @@ extern string_t *capability_string; -extern void (*hook_mail_storage_created)(struct mail_storage **storage); +extern void (*hook_mail_storage_created)(struct mail_storage *storage); extern void (*hook_client_created)(struct client **client); #endif
--- a/src/imap/imap-expunge.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/imap/imap-expunge.c Tue Mar 15 21:01:50 2005 +0200 @@ -18,17 +18,19 @@ search_arg.type = SEARCH_DELETED; search_arg.next = next_search_arg; - t = mailbox_transaction_begin(box, FALSE); - ctx = mailbox_search_init(t, NULL, &search_arg, NULL, 0, NULL); + t = mailbox_transaction_begin(box, 0); + ctx = mailbox_search_init(t, NULL, &search_arg, NULL); if (ctx == NULL) failed = TRUE; else { - while ((mail = mailbox_search_next(ctx)) != NULL) { - if (mail->expunge(mail) < 0) { + mail = mail_alloc(t, 0, NULL); + while (mailbox_search_next(ctx, mail) > 0) { + if (mail_expunge(mail) < 0) { failed = TRUE; break; } } + mail_free(mail); } if (mailbox_search_deinit(ctx) < 0)
--- a/src/imap/imap-fetch-body.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/imap/imap-fetch-body.c Tue Mar 15 21:01:50 2005 +0200 @@ -304,8 +304,8 @@ struct message_size hdr_size, body_size; ctx->cur_input = - mail->get_stream(mail, &hdr_size, - body->section[0] == 'H' ? NULL : &body_size); + mail_get_stream(mail, &hdr_size, + body->section[0] == 'H' ? NULL : &body_size); if (ctx->cur_input == NULL) return -1; @@ -419,7 +419,7 @@ { const struct imap_fetch_body_data *body = context; - ctx->cur_input = mail->get_stream(mail, NULL, NULL); + ctx->cur_input = mail_get_stream(mail, NULL, NULL); if (ctx->cur_input == NULL) return -1; @@ -436,7 +436,7 @@ struct message_size size; uoff_t old_offset; - ctx->cur_input = mail->get_headers(mail, body->header_ctx); + ctx->cur_input = mail_get_headers(mail, body->header_ctx); if (ctx->cur_input == NULL) return -1; @@ -463,7 +463,7 @@ const char *path; unsigned int num; - part = mail->get_parts(mail); + part = mail_get_parts(mail); if (part == NULL) return -1; @@ -526,7 +526,7 @@ return 1; } - ctx->cur_input = mail->get_stream(mail, NULL, NULL); + ctx->cur_input = mail_get_stream(mail, NULL, NULL); if (ctx->cur_input == NULL) return -1; @@ -831,7 +831,7 @@ { uoff_t size; - size = mail->get_virtual_size(mail); + size = mail_get_virtual_size(mail); if (size == (uoff_t)-1) return -1; @@ -845,7 +845,7 @@ struct message_size hdr_size, body_size; const char *str; - ctx->cur_input = mail->get_stream(mail, &hdr_size, &body_size); + ctx->cur_input = mail_get_stream(mail, &hdr_size, &body_size); if (ctx->cur_input == NULL) return -1; @@ -874,7 +874,7 @@ struct message_size hdr_size; const char *str; - ctx->cur_input = mail->get_stream(mail, &hdr_size, NULL); + ctx->cur_input = mail_get_stream(mail, &hdr_size, NULL); if (ctx->cur_input == NULL) return -1; @@ -899,7 +899,7 @@ struct message_size hdr_size, body_size; const char *str; - ctx->cur_input = mail->get_stream(mail, &hdr_size, &body_size); + ctx->cur_input = mail_get_stream(mail, &hdr_size, &body_size); if (ctx->cur_input == NULL) return -1;
--- a/src/imap/imap-fetch.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/imap/imap-fetch.c Tue Mar 15 21:01:50 2005 +0200 @@ -149,11 +149,13 @@ mailbox_header_lookup_init(ctx->box, data); } - ctx->trans = mailbox_transaction_begin(ctx->box, TRUE); + ctx->trans = mailbox_transaction_begin(ctx->box, + MAILBOX_TRANSACTION_FLAG_HIDE); ctx->select_counter = ctx->client->select_counter; + ctx->mail = mail_alloc(ctx->trans, ctx->fetch_data, + ctx->all_headers_ctx); ctx->search_ctx = - mailbox_search_init(ctx->trans, NULL, search_arg, NULL, - ctx->fetch_data, ctx->all_headers_ctx); + mailbox_search_init(ctx->trans, NULL, search_arg, NULL); } int imap_fetch(struct imap_fetch_context *ctx) @@ -199,9 +201,10 @@ ctx->cur_input = NULL; } - ctx->cur_mail = mailbox_search_next(ctx->search_ctx); - if (ctx->cur_mail == NULL) + if (mailbox_search_next(ctx->search_ctx, + ctx->mail) <= 0) break; + ctx->cur_mail = ctx->mail; str_printfa(ctx->cur_str, "* %u FETCH (", ctx->cur_mail->seq); @@ -275,6 +278,9 @@ ctx->cur_input = NULL; } + if (ctx->mail != NULL) + mail_free(ctx->mail); + if (ctx->search_ctx != NULL) { if (mailbox_search_deinit(ctx->search_ctx) < 0) ctx->failed = TRUE; @@ -298,7 +304,7 @@ { const char *body; - body = mail->get_special(mail, MAIL_FETCH_IMAP_BODY); + body = mail_get_special(mail, MAIL_FETCH_IMAP_BODY); if (body == NULL) return -1; @@ -332,7 +338,7 @@ { const char *bodystructure; - bodystructure = mail->get_special(mail, MAIL_FETCH_IMAP_BODYSTRUCTURE); + bodystructure = mail_get_special(mail, MAIL_FETCH_IMAP_BODYSTRUCTURE); if (bodystructure == NULL) return -1; @@ -365,7 +371,7 @@ { const char *envelope; - envelope = mail->get_special(mail, MAIL_FETCH_IMAP_ENVELOPE); + envelope = mail_get_special(mail, MAIL_FETCH_IMAP_ENVELOPE); if (envelope == NULL) return -1; @@ -398,13 +404,13 @@ enum mail_flags flags; const char *const *keywords; - flags = mail->get_flags(mail); - keywords = mail->get_keywords(mail); + flags = mail_get_flags(mail); + keywords = mail_get_keywords(mail); if (ctx->flags_update_seen && (flags & MAIL_SEEN) == 0) { /* Add \Seen flag */ flags |= MAIL_SEEN; - if (mail->update_flags(mail, MODIFY_ADD, MAIL_SEEN) < 0) + if (mail_update_flags(mail, MODIFY_ADD, MAIL_SEEN) < 0) return -1; } else if (ctx->flags_show_only_seen_changes) { return 1; @@ -431,7 +437,7 @@ { time_t time; - time = mail->get_received_date(mail); + time = mail_get_received_date(mail); if (time == (time_t)-1) return -1;
--- a/src/imap/imap-fetch.h Tue Mar 15 20:58:18 2005 +0200 +++ b/src/imap/imap-fetch.h Tue Mar 15 21:01:50 2005 +0200 @@ -28,6 +28,7 @@ struct mailbox_transaction_context *trans; struct mail_search_context *search_ctx; + struct mail *mail; enum mail_fetch_field fetch_data; buffer_t *all_headers_buf;
--- a/src/imap/imap-sort.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/imap/imap-sort.c Tue Mar 15 21:01:50 2005 +0200 @@ -30,6 +30,7 @@ struct sort_context { struct mail_search_context *search_ctx; struct mailbox_transaction_context *t; + struct mail *other_mail; enum mail_sort_type sort_program[MAX_SORT_PROGRAM_SIZE]; enum mail_sort_type common_mask, cache_mask; @@ -228,15 +229,9 @@ wanted_headers); /* initialize searching */ - ctx->t = mailbox_transaction_begin(client->mailbox, FALSE); - ctx->search_ctx = - mailbox_search_init(ctx->t, charset, args, norm_prog, - wanted_fields, headers_ctx); - if (ctx->search_ctx == NULL) { - mailbox_transaction_rollback(ctx->t); - mailbox_header_lookup_deinit(headers_ctx); - return -1; - } + ctx->t = mailbox_transaction_begin(client->mailbox, 0); + ctx->search_ctx = mailbox_search_init(ctx->t, charset, args, norm_prog); + ctx->other_mail = mail_alloc(ctx->t, wanted_fields, headers_ctx); ctx->box = client->mailbox; ctx->output = client->output; @@ -248,9 +243,13 @@ ctx->id_is_uid = cmd->uid; - while ((mail = mailbox_search_next(ctx->search_ctx)) != NULL) + mail = mail_alloc(ctx->t, wanted_fields, headers_ctx); + while (mailbox_search_next(ctx->search_ctx, mail) > 0) mail_sort_input(ctx, mail); + mail_free(mail); + mail_free(ctx->other_mail); + mail_sort_flush(ctx); ret = mailbox_search_deinit(ctx->search_ctx); @@ -291,7 +290,7 @@ struct message_address *addr; const char *str; - str = mail->get_header(mail, field); + str = mail_get_header(mail, field); if (str == NULL) return NULL; @@ -309,7 +308,7 @@ int changed = FALSE; if (ctx->common_mask & MAIL_SORT_ARRIVAL) { - t = mail->get_received_date(mail); + t = mail_get_received_date(mail); if (t != ctx->last_arrival) { ctx->last_arrival = t; changed = TRUE; @@ -329,7 +328,7 @@ } if (ctx->common_mask & MAIL_SORT_DATE) { - t = mail->get_date(mail, NULL); + t = mail_get_date(mail, NULL); if (t != ctx->last_date) { ctx->last_date = t; changed = TRUE; @@ -349,7 +348,7 @@ } if (ctx->common_mask & MAIL_SORT_SIZE) { - size = mail->get_virtual_size(mail); + size = mail_get_virtual_size(mail); if (size != ctx->last_size) { ctx->last_size = size; changed = TRUE; @@ -357,7 +356,7 @@ } if (ctx->common_mask & MAIL_SORT_SUBJECT) { - str = mail->get_header(mail, "subject"); + str = mail_get_header(mail, "subject"); if (str != NULL) { str = imap_get_base_subject_cased( pool_datastack_create(), str, NULL); @@ -409,7 +408,7 @@ if (ctx->common_mask & MAIL_SORT_ARRIVAL) t = ctx->last_arrival; else - t = mail->get_received_date(mail); + t = mail_get_received_date(mail); memcpy(buf + pos, &t, sizeof(t)); pos += sizeof(t); } @@ -417,7 +416,7 @@ if (ctx->common_mask & MAIL_SORT_DATE) t = ctx->last_date; else - t = mail->get_date(mail, NULL); + t = mail_get_date(mail, NULL); memcpy(buf + pos, &t, sizeof(t)); pos += sizeof(t); } @@ -425,7 +424,7 @@ if (ctx->common_mask & MAIL_SORT_SIZE) size = ctx->last_size; else - size = mail->get_virtual_size(mail); + size = mail_get_virtual_size(mail); memcpy(buf + pos, &size, sizeof(size)); pos += sizeof(size); } @@ -476,7 +475,7 @@ if (ctx->common_mask & MAIL_SORT_SUBJECT) str = ctx->last_subject; else { - str = mail->get_header(mail, "subject"); + str = mail_get_header(mail, "subject"); if (str != NULL) { str = imap_get_base_subject_cased( @@ -507,7 +506,10 @@ if (mailbox_get_uids(ctx->box, id, id, &seq, &seq) < 0) return NULL; } - return mailbox_fetch(ctx->t, seq, 0); + + if (mail_set_seq(ctx->other_mail, seq) < 0) + return NULL; + return ctx->other_mail; } @@ -524,9 +526,9 @@ switch (type) { case MAIL_SORT_ARRIVAL: - return mail->get_received_date(mail); + return mail_get_received_date(mail); case MAIL_SORT_DATE: - t = mail->get_date(mail, NULL); + t = mail_get_date(mail, NULL); if (t == (time_t)-1) t = 0; return t; @@ -554,7 +556,7 @@ i_assert(type == MAIL_SORT_SIZE); - return mail->get_virtual_size(mail); + return mail_get_virtual_size(mail); } /* use memcpy() to avoid any alignment problems */ @@ -578,7 +580,7 @@ switch (type) { case MAIL_SORT_SUBJECT: - str = mail->get_header(mail, "subject"); + str = mail_get_header(mail, "subject"); if (str == NULL) return NULL;
--- a/src/imap/imap-sync.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/imap/imap-sync.c Tue Mar 15 21:01:50 2005 +0200 @@ -18,6 +18,7 @@ struct mailbox_transaction_context *t; struct mailbox_sync_context *sync_ctx; + struct mail *mail; struct mailbox_sync_rec sync_rec; uint32_t seq; @@ -40,7 +41,8 @@ ctx->box = box; ctx->sync_ctx = mailbox_sync_init(box, flags); - ctx->t = mailbox_transaction_begin(box, FALSE); + ctx->t = mailbox_transaction_begin(box, 0); + ctx->mail = mail_alloc(ctx->t, MAIL_FETCH_FLAGS, 0); ctx->messages_count = client->messages_count; return ctx; } @@ -49,6 +51,8 @@ { struct mailbox_status status; + mail_free(ctx->mail); + if (mailbox_sync_deinit(ctx->sync_ctx, &status) < 0 || ctx->failed) { mailbox_transaction_rollback(ctx->t); i_free(ctx); @@ -80,7 +84,6 @@ int imap_sync_more(struct imap_sync_context *ctx) { - struct mail *mail; enum mail_flags flags; const char *const *keywords; string_t *str; @@ -110,11 +113,13 @@ ctx->seq = ctx->sync_rec.seq1; for (; ctx->seq <= ctx->sync_rec.seq2; ctx->seq++) { - mail = mailbox_fetch(ctx->t, ctx->seq, - MAIL_FETCH_FLAGS); + if (mail_set_seq(ctx->mail, ctx->seq) < 0) { + t_pop(); + return -1; + } - flags = mail->get_flags(mail); - keywords = mail->get_keywords(mail); + flags = mail_get_flags(ctx->mail); + keywords = mail_get_keywords(ctx->mail); str_truncate(str, 0); str_printfa(str, "* %u FETCH (FLAGS (",
--- a/src/imap/imap-thread.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/imap/imap-thread.c Tue Mar 15 21:01:50 2005 +0200 @@ -73,6 +73,7 @@ struct mailbox_transaction_context *t; struct mailbox *box; struct ostream *output; + struct mail *mail; pool_t pool; pool_t temp_pool; @@ -117,19 +118,10 @@ i_fatal("Only REFERENCES threading supported"); ctx = t_new(struct thread_context, 1); - headers_ctx = mailbox_header_lookup_init(client->mailbox, - wanted_headers); /* initialize searching */ - ctx->t = mailbox_transaction_begin(client->mailbox, FALSE); - ctx->search_ctx = - mailbox_search_init(ctx->t, charset, args, NULL, - MAIL_FETCH_DATE, headers_ctx); - if (ctx->search_ctx == NULL) { - mailbox_transaction_rollback(ctx->t); - mailbox_header_lookup_deinit(headers_ctx); - return -1; - } + ctx->t = mailbox_transaction_begin(client->mailbox, 0); + ctx->search_ctx = mailbox_search_init(ctx->t, charset, args, NULL); ctx->box = client->mailbox; ctx->output = client->output; @@ -142,11 +134,16 @@ ctx->msgid_hash = hash_create(default_pool, ctx->temp_pool, APPROX_MSG_COUNT*2, str_hash, (hash_cmp_callback_t *)strcmp); + ctx->id_is_uid = cmd->uid; - ctx->id_is_uid = cmd->uid; - while ((mail = mailbox_search_next(ctx->search_ctx)) != NULL) + headers_ctx = mailbox_header_lookup_init(client->mailbox, + wanted_headers); + mail = mail_alloc(ctx->t, MAIL_FETCH_DATE, headers_ctx); + while (mailbox_search_next(ctx->search_ctx, mail) > 0) mail_thread_input(ctx, mail); + mail_free(mail); + o_stream_send_str(client->output, "* THREAD"); mail_thread_finish(ctx); o_stream_send_str(client->output, "\r\n"); @@ -447,18 +444,18 @@ t_push(); - sent_date = mail->get_date(mail, NULL); + sent_date = mail_get_date(mail, NULL); if (sent_date == (time_t)-1) sent_date = 0; - message_id = mail->get_header(mail, "message-id"); + message_id = mail_get_header(mail, "message-id"); node = update_message(ctx, get_msgid(&message_id), sent_date, ctx->id_is_uid ? mail->uid : mail->seq); /* link references */ - references = mail->get_header(mail, "references"); + references = mail_get_header(mail, "references"); if (!link_references(ctx, node, references)) { - in_reply_to = mail->get_header(mail, "in-reply-to"); + in_reply_to = mail_get_header(mail, "in-reply-to"); refid = in_reply_to == NULL ? NULL : get_msgid(&in_reply_to); if (refid != NULL) @@ -661,8 +658,10 @@ static void gather_base_subjects(struct thread_context *ctx) { - struct mail *mail; + static const char *wanted_headers[] = { "subject", NULL }; + struct mailbox_header_lookup_ctx *headers_ctx; struct node *node; + const char *subject; unsigned int id; uint32_t seq; @@ -670,6 +669,9 @@ hash_create(default_pool, ctx->temp_pool, ctx->root_count * 2, str_hash, (hash_cmp_callback_t *)strcmp); + headers_ctx = mailbox_header_lookup_init(ctx->box, wanted_headers); + ctx->mail = mail_alloc(ctx->t, 0, headers_ctx); + node = ctx->root_node.first_child; for (; node != NULL; node = node->next) { if (!NODE_IS_DUMMY(node)) @@ -689,15 +691,16 @@ seq = 0; } - mail = seq == 0 ? NULL : mailbox_fetch(ctx->t, seq, 0); - - if (mail != NULL) { + if (seq != 0 && mail_set_seq(ctx->mail, seq) == 0) { t_push(); - add_base_subject(ctx, mail->get_header(mail, "subject"), - node); + subject = mail_get_header(ctx->mail, "subject"); + add_base_subject(ctx, subject, node); t_pop(); } } + + mail_free(ctx->mail); + mailbox_header_lookup_deinit(headers_ctx); } static void reset_children_parent(struct node *parent)
--- a/src/imap/main.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/imap/main.c Tue Mar 15 21:01:50 2005 +0200 @@ -45,7 +45,7 @@ static char log_prefix[128]; /* syslog() needs this to be permanent */ static pool_t namespace_pool; -void (*hook_mail_storage_created)(struct mail_storage **storage) = NULL; +void (*hook_mail_storage_created)(struct mail_storage *storage) = NULL; void (*hook_client_created)(struct client **client) = NULL; string_t *capability_string;
--- a/src/imap/namespace.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/imap/namespace.c Tue Mar 15 21:01:50 2005 +0200 @@ -22,7 +22,7 @@ } if (hook_mail_storage_created != NULL) - hook_mail_storage_created(&ns->storage); + hook_mail_storage_created(ns->storage); } static struct namespace *
--- a/src/lib-storage/Makefile.am Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/Makefile.am Tue Mar 15 21:01:50 2005 +0200 @@ -8,20 +8,15 @@ -I$(top_srcdir)/src/lib-imap libstorage_a_SOURCES = \ + mail.c \ mail-copy.c \ mail-search.c \ mail-storage.c \ - mailbox-tree.c \ - proxy-mail.c \ - proxy-mail-storage.c \ - proxy-mailbox.c + mailbox-tree.c noinst_HEADERS = \ mail-copy.h \ mail-search.h \ mail-storage.h \ mail-storage-private.h \ - mailbox-tree.h \ - proxy-mail.h \ - proxy-mail-storage.h \ - proxy-mailbox.h + mailbox-tree.h
--- a/src/lib-storage/index/index-fetch.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/index/index-fetch.c Tue Mar 15 21:01:50 2005 +0200 @@ -4,22 +4,6 @@ #include "index-storage.h" #include "index-mail.h" -struct mail * -index_storage_fetch(struct mailbox_transaction_context *_t, uint32_t seq, - enum mail_fetch_field wanted_fields) -{ - struct index_transaction_context *t = - (struct index_transaction_context *)_t; - - if (t->fetch_mail.pool != NULL) - index_mail_deinit(&t->fetch_mail); - - index_mail_init(t, &t->fetch_mail, wanted_fields, NULL); - if (index_mail_next(&t->fetch_mail, seq) < 0) - return NULL; - return &t->fetch_mail.mail; -} - int index_storage_get_uids(struct mailbox *box, uint32_t uid1, uint32_t uid2, uint32_t *seq1_r, uint32_t *seq2_r)
--- a/src/lib-storage/index/index-mail-headers.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/index/index-mail-headers.c Tue Mar 15 21:01:50 2005 +0200 @@ -163,7 +163,7 @@ { string_t *str; - str = str_new(mail->pool, 256); + str = str_new(mail->data_pool, 256); imap_envelope_write_part_data(mail->data.envelope_data, str); mail->data.envelope = str_c(str); @@ -187,11 +187,11 @@ if (data->save_bodystructure_header) { i_assert(part != NULL); - imap_bodystructure_parse_header(mail->pool, part, hdr); + imap_bodystructure_parse_header(mail->data_pool, part, hdr); } if (data->save_envelope) { - imap_envelope_parse_header(mail->pool, + imap_envelope_parse_header(mail->data_pool, &data->envelope_data, hdr); if (hdr == NULL) @@ -313,7 +313,7 @@ { struct index_mail_data *data = &mail->data; - if (mail->mail.get_stream(&mail->mail, NULL, NULL) == NULL) + if (mail_get_stream(&mail->mail.mail, NULL, NULL) == NULL) return -1; index_mail_parse_header_init(mail, headers); @@ -322,7 +322,7 @@ /* initialize bodystructure parsing in case we read the whole message. */ data->parser_ctx = - message_parser_init(mail->pool, data->stream); + message_parser_init(mail->data_pool, data->stream); message_parser_parse_header(data->parser_ctx, &data->hdr_size, index_mail_parse_header_cb, mail); } else { @@ -342,7 +342,8 @@ { struct index_mail *mail = context; - imap_envelope_parse_header(mail->pool, &mail->data.envelope_data, hdr); + imap_envelope_parse_header(mail->data_pool, + &mail->data.envelope_data, hdr); if (hdr == NULL) index_mail_parse_finish_imap_envelope(mail); @@ -356,7 +357,7 @@ mail->data.save_envelope = TRUE; header_ctx = mailbox_header_lookup_init(&mail->ibox->box, imap_envelope_headers); - stream = mail->mail.get_headers(&mail->mail, header_ctx); + stream = mail_get_headers(&mail->mail.mail, header_ctx); if (mail->data.envelope == NULL && stream != NULL) { /* we got the headers from cache - parse them to get the envelope */ @@ -437,7 +438,7 @@ data = buffer_get_data(mail->header_data, &size); size = get_header_size(mail->header_data, offsets[field_idx]); - return p_strndup(mail->pool, data + offsets[field_idx], size); + return p_strndup(mail->data_pool, data + offsets[field_idx], size); } const char *index_mail_get_header(struct mail *_mail, const char *field) @@ -453,11 +454,11 @@ field_idx = get_header_field_idx(mail->ibox, field); - dest = str_new(mail->pool, 128); + dest = str_new(mail->data_pool, 128); if (mail_cache_lookup_headers(mail->trans->cache_view, dest, mail->data.seq, &field_idx, 1) <= 0) { /* not in cache / error - first see if it's already parsed */ - p_free(mail->pool, dest); + p_free(mail->data_pool, dest); if (mail->header_seq == mail->data.seq) { ret = index_mail_header_is_parsed(mail, field_idx); if (ret != -1) { @@ -529,17 +530,17 @@ return NULL; } - dest = str_new(mail->pool, 256); + dest = str_new(mail->data_pool, 256); if (mail_cache_lookup_headers(mail->trans->cache_view, dest, mail->data.seq, headers->idx, headers->count) > 0) { - return i_stream_create_from_data(mail->pool, + return i_stream_create_from_data(mail->data_pool, str_data(dest), str_len(dest)); } /* not in cache / error */ - p_free(mail->pool, dest); + p_free(mail->data_pool, dest); - if (mail->mail.get_stream(&mail->mail, NULL, NULL) == NULL) + if (mail_get_stream(&mail->mail.mail, NULL, NULL) == NULL) return NULL; if (mail->data.filter_stream != NULL)
--- a/src/lib-storage/index/index-mail.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/index/index-mail.c Tue Mar 15 21:01:50 2005 +0200 @@ -48,7 +48,7 @@ return NULL; } - part = message_part_deserialize(mail->pool, + part = message_part_deserialize(mail->data_pool, buffer_get_data(part_buf, NULL), buffer_get_used_size(part_buf), &error); @@ -62,11 +62,11 @@ /* we know the NULs now, update them */ if ((part->flags & MESSAGE_PART_FLAG_HAS_NULS) != 0) { - mail->mail.has_nuls = TRUE; - mail->mail.has_no_nuls = FALSE; + mail->mail.mail.has_nuls = TRUE; + mail->mail.mail.has_no_nuls = FALSE; } else { - mail->mail.has_nuls = FALSE; - mail->mail.has_no_nuls = TRUE; + mail->mail.mail.has_nuls = FALSE; + mail->mail.mail.has_no_nuls = TRUE; } return part; @@ -77,11 +77,11 @@ { string_t *str; - str = str_new(mail->pool, 32); + str = str_new(mail->data_pool, 32); if (mail_cache_lookup_field(mail->trans->cache_view, str, mail->data.seq, mail->ibox->cache_fields[field].idx) <= 0) { - p_free(mail->pool, str); + p_free(mail->data_pool, str); return NULL; } @@ -172,8 +172,10 @@ struct index_mail_data *data = &mail->data; const char *const *keywords; - if (data->keywords_buf == NULL) - data->keywords_buf = buffer_create_dynamic(mail->pool, 128); + if (data->keywords_buf == NULL) { + data->keywords_buf = + buffer_create_dynamic(mail->data_pool, 128); + } if (mail_index_lookup_keywords(mail->ibox->view, mail->data.seq, data->keywords_buf, &keywords) < 0) { @@ -238,7 +240,7 @@ if (data->sent_date.time == (time_t)-1) { data->save_sent_date = TRUE; - str = _mail->get_header(_mail, "Date"); + str = mail_get_header(_mail, "Date"); if (data->sent_date.time == (time_t)-1) { if (!message_date_parse((const unsigned char *)str, (size_t)-1, @@ -298,7 +300,7 @@ if (get_cached_msgpart_sizes(mail)) return data->virtual_size; - if (_mail->get_stream(_mail, &hdr_size, &body_size) == NULL) + if (mail_get_stream(_mail, &hdr_size, &body_size) == NULL) return (uoff_t)-1; mail_cache_add(mail->trans->cache_trans, mail->data.seq, @@ -355,7 +357,7 @@ i_assert(!data->save_bodystructure_header); message_parser_parse_body(data->parser_ctx, parse_bodystructure_part_header, - NULL, mail->pool); + NULL, mail->data_pool); data->save_bodystructure_body = FALSE; data->parsed_bodystructure = TRUE; } else { @@ -368,17 +370,17 @@ data->body_size_set = TRUE; cache_flags = 0; - if (!mail->mail.has_nuls && !mail->mail.has_no_nuls) { + if (!mail->mail.mail.has_nuls && !mail->mail.mail.has_no_nuls) { /* we know the NULs now, update them */ if ((data->parts->flags & MESSAGE_PART_FLAG_HAS_NULS) != 0) { - mail->mail.has_nuls = TRUE; - mail->mail.has_no_nuls = FALSE; + mail->mail.mail.has_nuls = TRUE; + mail->mail.mail.has_no_nuls = FALSE; } else { - mail->mail.has_nuls = FALSE; - mail->mail.has_no_nuls = TRUE; + mail->mail.mail.has_nuls = FALSE; + mail->mail.mail.has_no_nuls = TRUE; } - if (mail->mail.has_nuls) + if (mail->mail.mail.has_nuls) cache_flags |= MAIL_CACHE_FLAG_HAS_NULS; else cache_flags |= MAIL_CACHE_FLAG_HAS_NO_NULS; @@ -480,7 +482,7 @@ message_parse_from_parts(data->parts->children, data->stream, parse_bodystructure_part_header, - mail->pool); + mail->data_pool); data->parsed_bodystructure = TRUE; } else { index_mail_parse_body(mail, FALSE); @@ -493,7 +495,7 @@ ((dec & ~MAIL_CACHE_DECISION_FORCED) != MAIL_CACHE_DECISION_NO && mail_cache_field_exists(mail->trans->cache_view, data->seq, cache_fields[MAIL_CACHE_BODYSTRUCTURE].idx) == 0)) { - str = str_new(mail->pool, 128); + str = str_new(mail->data_pool, 128); imap_bodystructure_write(data->parts, str, TRUE); data->bodystructure = str_c(str); @@ -512,7 +514,7 @@ ((dec & ~MAIL_CACHE_DECISION_FORCED) != MAIL_CACHE_DECISION_NO && mail_cache_field_exists(mail->trans->cache_view, data->seq, cache_fields[MAIL_CACHE_BODY].idx) == 0)) { - str = str_new(mail->pool, 128); + str = str_new(mail->data_pool, 128); imap_bodystructure_write(data->parts, str, FALSE); data->body = str_c(str); @@ -544,7 +546,7 @@ 3) parse body structure, and save BODY/BODYSTRUCTURE depending on what we want cached */ - str = str_new(mail->pool, 128); + str = str_new(mail->data_pool, 128); if (mail_cache_lookup_field(mail->trans->cache_view, str, mail->data.seq, cache_fields[MAIL_CACHE_BODY].idx) > 0) { @@ -554,7 +556,8 @@ if (mail_cache_lookup_field(mail->trans->cache_view, str, mail->data.seq, cache_fields[MAIL_CACHE_BODYSTRUCTURE].idx) > 0) { - data->bodystructure = p_strdup(mail->pool, str_c(str)); + data->bodystructure = + p_strdup(mail->data_pool, str_c(str)); str_truncate(str, 0); if (imap_body_parse_from_bodystructure( @@ -566,10 +569,10 @@ /* broken, continue.. */ mail_cache_set_corrupted(mail->ibox->cache, "Corrupted BODYSTRUCTURE for mail %u", - mail->mail.uid); + mail->mail.mail.uid); data->bodystructure = NULL; } - p_free(mail->pool, str); + p_free(mail->data_pool, str); index_mail_parse_bodystructure(mail, MAIL_CACHE_BODY); return data->body; @@ -577,14 +580,14 @@ if (data->bodystructure != NULL) return data->bodystructure; - str = str_new(mail->pool, 128); + str = str_new(mail->data_pool, 128); if (mail_cache_lookup_field(mail->trans->cache_view, str, mail->data.seq, cache_fields[MAIL_CACHE_BODYSTRUCTURE].idx) > 0) { data->bodystructure = str_c(str); return data->bodystructure; } - p_free(mail->pool, str); + p_free(mail->data_pool, str); index_mail_parse_bodystructure(mail, MAIL_CACHE_BODYSTRUCTURE); return data->bodystructure; @@ -611,28 +614,39 @@ } } -void index_mail_init(struct index_transaction_context *t, - struct index_mail *mail, - enum mail_fetch_field wanted_fields, - struct mailbox_header_lookup_ctx *_wanted_headers) +struct mail * +index_mail_alloc(struct mailbox_transaction_context *_t, + enum mail_fetch_field wanted_fields, + struct mailbox_header_lookup_ctx *_wanted_headers) { + struct index_transaction_context *t = + (struct index_transaction_context *)_t; struct index_header_lookup_ctx *wanted_headers = (struct index_header_lookup_ctx *)_wanted_headers; + struct index_mail *mail; const struct mail_index_header *hdr; + pool_t pool; - mail->mail = *t->ibox->mail_interface; - mail->mail.box = &t->ibox->box; - mail->mail.transaction = &t->mailbox_ctx; + pool = pool_alloconly_create("mail", 256); + mail = p_new(pool, struct index_mail, 1); + mail->mail.pool = pool; + ARRAY_CREATE(&mail->mail.module_contexts, pool, void *, 5); + + mail->mail.v = *t->ibox->mail_vfuncs; + mail->mail.mail.box = &t->ibox->box; + mail->mail.mail.transaction = &t->mailbox_ctx; /* only reason we couldn't get header is if view is invalidated */ hdr = mail_index_get_header(t->ibox->view); mail->uid_validity = hdr->uid_validity; - mail->pool = pool_alloconly_create("index_mail", 16384); + mail->data_pool = pool_alloconly_create("index_mail", 16384); mail->ibox = t->ibox; mail->trans = t; mail->wanted_fields = wanted_fields; mail->wanted_headers = wanted_headers; + + return &mail->mail.mail; } static void index_mail_close(struct index_mail *mail) @@ -643,8 +657,9 @@ i_stream_unref(mail->data.filter_stream); } -int index_mail_next(struct index_mail *mail, uint32_t seq) +int index_mail_set_seq(struct mail *_mail, uint32_t seq) { + struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; const struct mail_index_record *rec; @@ -656,7 +671,7 @@ index_mail_close(mail); memset(data, 0, sizeof(*data)); - p_clear(mail->pool); + p_clear(mail->data_pool); data->rec = rec; data->seq = seq; @@ -669,11 +684,11 @@ sizeof(data->cache_flags))) data->cache_flags = 0; - mail->mail.seq = seq; - mail->mail.uid = rec->uid; - mail->mail.has_nuls = + mail->mail.mail.seq = seq; + mail->mail.mail.uid = rec->uid; + mail->mail.mail.has_nuls = (data->cache_flags & MAIL_CACHE_FLAG_HAS_NULS) != 0; - mail->mail.has_no_nuls = + mail->mail.mail.has_no_nuls = (data->cache_flags & MAIL_CACHE_FLAG_HAS_NO_NULS) != 0; t_push(); @@ -722,7 +737,7 @@ MAIL_FETCH_STREAM_BODY)) { data->open_mail = TRUE; /* open stream to set expunged flag */ - (void)mail->mail.get_stream(&mail->mail, NULL, NULL); + (void)mail_get_stream(_mail, NULL, NULL); } if ((mail->wanted_fields & MAIL_FETCH_DATE) && @@ -736,8 +751,10 @@ return 0; } -void index_mail_deinit(struct index_mail *mail) +void index_mail_free(struct mail *_mail) { + struct index_mail *mail = (struct index_mail *)_mail; + index_mail_close(mail); if (mail->header_data != NULL) @@ -749,8 +766,8 @@ if (mail->header_offsets != NULL) buffer_free(mail->header_offsets); - pool_unref(mail->pool); - memset(mail, 0, sizeof(*mail)); + pool_unref(mail->data_pool); + pool_unref(mail->mail.pool); } int index_mail_update_flags(struct mail *mail, enum modify_type modify_type,
--- a/src/lib-storage/index/index-mail.h Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/index/index-mail.h Tue Mar 15 21:01:50 2005 +0200 @@ -87,10 +87,10 @@ }; struct index_mail { - struct mail mail; + struct mail_private mail; struct index_mail_data data; - pool_t pool; + pool_t data_pool; struct index_mailbox *ibox; struct index_transaction_context *trans; uint32_t uid_validity; @@ -107,12 +107,12 @@ uint8_t header_match_value; }; -void index_mail_init(struct index_transaction_context *t, - struct index_mail *mail, - enum mail_fetch_field wanted_fields, - struct mailbox_header_lookup_ctx *wanted_headers); -int index_mail_next(struct index_mail *mail, uint32_t seq); -void index_mail_deinit(struct index_mail *mail); +struct mail * +index_mail_alloc(struct mailbox_transaction_context *t, + enum mail_fetch_field wanted_fields, + struct mailbox_header_lookup_ctx *wanted_headers); +int index_mail_set_seq(struct mail *mail, uint32_t seq); +void index_mail_free(struct mail *mail); void index_mail_parse_header_init(struct index_mail *mail, struct mailbox_header_lookup_ctx *headers);
--- a/src/lib-storage/index/index-search.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/index/index-search.c Tue Mar 15 21:01:50 2005 +0200 @@ -27,8 +27,8 @@ struct mail_search_arg *args; uint32_t seq1, seq2; - struct index_mail imail; struct mail *mail; + struct index_mail *imail; pool_t hdr_pool; const char *error; @@ -103,9 +103,9 @@ case SEARCH_SEEN: return rec->flags & MAIL_SEEN; case SEARCH_RECENT: - return imail->mail.get_flags(&imail->mail) & MAIL_RECENT; + return mail_get_flags(&imail->mail.mail) & MAIL_RECENT; case SEARCH_KEYWORD: - keywords = imail->mail.get_keywords(&imail->mail); + keywords = mail_get_keywords(&imail->mail.mail); if (keywords != NULL) { while (*keywords != NULL) { if (strcasecmp(*keywords, value) == 0) @@ -131,13 +131,13 @@ return; } - if (ctx->imail.data.rec == NULL) { + if (ctx->imail->data.rec == NULL) { /* expunged message */ ARG_SET_RESULT(arg, 0); return; } - switch (search_arg_match_index(&ctx->imail, arg->type, + switch (search_arg_match_index(ctx->imail, arg->type, arg->value.str)) { case -1: /* unknown */ @@ -165,7 +165,7 @@ case SEARCH_BEFORE: case SEARCH_ON: case SEARCH_SINCE: - date = ctx->mail->get_received_date(ctx->mail); + date = mail_get_received_date(ctx->mail); if (date == (time_t)-1) return -1; @@ -191,7 +191,7 @@ case SEARCH_SENTSINCE: /* NOTE: RFC-3501 specifies that timezone is ignored in searches. date is returned as UTC, so change it. */ - date = ctx->mail->get_date(ctx->mail, &timezone_offset); + date = mail_get_date(ctx->mail, &timezone_offset); if (date == (time_t)-1) return -1; date += timezone_offset * 60; @@ -215,7 +215,7 @@ /* sizes */ case SEARCH_SMALLER: case SEARCH_LARGER: - virtual_size = ctx->mail->get_virtual_size(ctx->mail); + virtual_size = mail_get_virtual_size(ctx->mail); if (virtual_size == (uoff_t)-1) return -1; @@ -423,7 +423,7 @@ if (hdr->eoh) return; - index_mail_parse_header(NULL, hdr, &ctx->index_context->imail); + index_mail_parse_header(NULL, hdr, ctx->index_context->imail); if (ctx->custom_header || strcasecmp(hdr->name, "Date") == 0) { ctx->hdr = hdr; @@ -478,7 +478,7 @@ if (headers == NULL) { headers_ctx = NULL; - input = ctx->mail->get_stream(ctx->mail, NULL, NULL); + input = mail_get_stream(ctx->mail, NULL, NULL); if (input == NULL) return FALSE; } else { @@ -486,7 +486,7 @@ headers_ctx = mailbox_header_lookup_init(&ctx->ibox->box, headers); - input = ctx->mail->get_headers(ctx->mail, headers_ctx); + input = mail_get_headers(ctx->mail, headers_ctx); if (input == NULL) { mailbox_header_lookup_deinit(headers_ctx); return FALSE; @@ -498,7 +498,7 @@ hdr_ctx.custom_header = TRUE; hdr_ctx.args = args; - index_mail_parse_header_init(&ctx->imail, headers_ctx); + index_mail_parse_header_init(ctx->imail, headers_ctx); message_parse_header(NULL, input, NULL, search_header, &hdr_ctx); if (headers_ctx != NULL) @@ -506,7 +506,7 @@ } else { struct message_size hdr_size; - input = ctx->mail->get_stream(ctx->mail, &hdr_size, NULL); + input = mail_get_stream(ctx->mail, &hdr_size, NULL); if (input == NULL) return FALSE; @@ -519,7 +519,7 @@ memset(&body_ctx, 0, sizeof(body_ctx)); body_ctx.index_ctx = ctx; body_ctx.input = input; - body_ctx.part = ctx->mail->get_parts(ctx->mail); + body_ctx.part = mail_get_parts(ctx->mail); mail_search_args_foreach(args, search_body, &body_ctx); } @@ -710,9 +710,7 @@ struct mail_search_context * index_storage_search_init(struct mailbox_transaction_context *_t, const char *charset, struct mail_search_arg *args, - const enum mail_sort_type *sort_program, - enum mail_fetch_field wanted_fields, - struct mailbox_header_lookup_ctx *wanted_headers) + const enum mail_sort_type *sort_program) { struct index_transaction_context *t = (struct index_transaction_context *)_t; @@ -724,15 +722,12 @@ } ctx = i_new(struct index_search_context, 1); - ctx->mail_ctx.box = &t->ibox->box; + ctx->mail_ctx.transaction = _t; ctx->ibox = t->ibox; ctx->view = t->trans_view; ctx->charset = i_strdup(charset); ctx->args = args; - ctx->mail = &ctx->imail.mail; - index_mail_init(t, &ctx->imail, wanted_fields, wanted_headers); - mail_search_args_reset(ctx->args, TRUE); if (search_get_seqset(ctx, args) < 0) { @@ -750,9 +745,6 @@ ret = ctx->failed || ctx->error != NULL ? -1 : 0; - if (ctx->imail.pool != NULL) - index_mail_deinit(&ctx->imail); - if (ctx->error != NULL) { mail_storage_set_error(ctx->ibox->box.storage, "%s", ctx->error); @@ -777,7 +769,7 @@ if (ret >= 0) return ret > 0; - if (ctx->imail.data.rec == NULL) { + if (ctx->imail->data.rec == NULL) { /* expunged message, no way to check if the rest would have matched */ return FALSE; @@ -800,16 +792,20 @@ return TRUE; } -struct mail *index_storage_search_next(struct mail_search_context *_ctx) +int index_storage_search_next(struct mail_search_context *_ctx, + struct mail *mail) { struct index_search_context *ctx = (struct index_search_context *)_ctx; int ret; + ctx->mail = mail; + ctx->imail = (struct index_mail *)mail; + ret = 0; while (ctx->seq1 <= ctx->seq2) { - if (index_mail_next(&ctx->imail, ctx->seq1++) < 0) { + if (mail_set_seq(mail, ctx->seq1++) < 0) { ctx->failed = TRUE; - return NULL; + break; } t_push(); @@ -821,11 +817,8 @@ if (ret != 0) break; } + ctx->mail = NULL; + ctx->imail = NULL; - if (ret <= 0) { - /* error or last record */ - return NULL; - } - - return ctx->mail; + return ret; }
--- a/src/lib-storage/index/index-storage.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/index/index-storage.c Tue Mar 15 21:01:50 2005 +0200 @@ -5,6 +5,7 @@ #include "ioloop.h" #include "mail-index.h" #include "index-storage.h" +#include "index-mail.h" #include <stdlib.h> #include <time.h> @@ -42,6 +43,8 @@ enum mail_storage_flags flags) { storage->storage.flags = flags; + ARRAY_CREATE(&storage->storage.module_contexts, + storage->storage.pool, void *, 5); index_storage_refcount++; } @@ -279,12 +282,10 @@ ibox->last_notify_type = MAILBOX_LOCK_NOTIFY_NONE; } -struct index_mailbox * -index_storage_mailbox_init(struct index_storage *storage, struct mailbox *box, - struct mail_index *index, const char *name, - enum mailbox_open_flags flags) +int index_storage_mailbox_init(struct index_mailbox *ibox, + struct mail_index *index, const char *name, + enum mailbox_open_flags flags) { - struct index_mailbox *ibox; enum mail_index_open_flags index_flags; enum mail_index_lock_method lock_method = 0; const char *str; @@ -312,15 +313,13 @@ i_fatal("Unknown lock_method: %s", str); do { - ibox = i_new(struct index_mailbox, 1); - ibox->box = *box; - ibox->storage = storage; + ibox->box.storage = &ibox->storage->storage; + ibox->box.name = p_strdup(ibox->box.pool, name); + ARRAY_CREATE(&ibox->box.module_contexts, + ibox->box.pool, void *, 5); - ibox->box.storage = &storage->storage; - ibox->box.name = i_strdup(name); ibox->readonly = (flags & MAILBOX_OPEN_READONLY) != 0; ibox->keep_recent = (flags & MAILBOX_OPEN_KEEP_RECENT) != 0; - ibox->index = index; ibox->next_lock_notify = time(NULL) + LOCK_NOTIFY_INTERVAL; @@ -333,12 +332,12 @@ ibox->cache = mail_index_get_cache(index); index_cache_register_defaults(ibox); ibox->view = mail_index_view_open(index); - return ibox; + return 0; } while (0); mail_storage_set_index_error(ibox); index_storage_mailbox_free(&ibox->box); - return NULL; + return -1; } void index_storage_mailbox_free(struct mailbox *box) @@ -352,11 +351,7 @@ if (ibox->index != NULL) index_storage_unref(ibox->index); i_free(ibox->cache_fields); - i_free(ibox->path); - i_free(ibox->control_dir); - - i_free(box->name); - i_free(box); + pool_unref(box->pool); } int index_storage_is_readonly(struct mailbox *box)
--- a/src/lib-storage/index/index-storage.h Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/index/index-storage.h Tue Mar 15 21:01:50 2005 +0200 @@ -4,7 +4,6 @@ #include "file-dotlock.h" #include "mail-storage-private.h" #include "mail-index.h" -#include "index-mail.h" /* Max. mmap()ed size for a message */ #define MAIL_MMAP_BLOCK_SIZE (1024*256) @@ -25,13 +24,13 @@ struct index_storage { struct mail_storage storage; - char *dir; /* root directory */ - char *index_dir; - char *control_dir; - char *inbox_path; /* INBOX location */ - char *temp_prefix; /* prefix for temporary files */ + const char *dir; /* root directory */ + const char *index_dir; + const char *control_dir; + const char *inbox_path; /* INBOX location */ + const char *temp_prefix; /* prefix for temporary files */ - char *user; /* name of user accessing the storage */ + const char *user; /* name of user accessing the storage */ struct mail_storage_callbacks *callbacks; void *callback_context; @@ -40,12 +39,12 @@ struct index_mailbox { struct mailbox box; struct index_storage *storage; - char *path, *control_dir; + const char *path, *control_dir; struct mail_index *index; struct mail_index_view *view; struct mail_cache *cache; - struct mail *mail_interface; + struct mail_vfuncs *mail_vfuncs; int (*is_recent)(struct index_mailbox *ibox, uint32_t uid); @@ -110,13 +109,13 @@ struct index_transaction_context { struct mailbox_transaction_context mailbox_ctx; struct index_mailbox *ibox; + enum mailbox_transaction_flags flags; struct mail_index_transaction *trans; struct mail_index_view *trans_view; struct mail_cache_view *cache_view; struct mail_cache_transaction_ctx *cache_trans; - struct index_mail fetch_mail; /* for index_storage_fetch() */ unsigned int cache_trans_failed:1; }; @@ -137,10 +136,9 @@ enum mail_storage_flags flags); void index_storage_deinit(struct index_storage *storage); -struct index_mailbox * -index_storage_mailbox_init(struct index_storage *storage, struct mailbox *box, - struct mail_index *index, const char *name, - enum mailbox_open_flags flags); +int index_storage_mailbox_init(struct index_mailbox *ibox, + struct mail_index *index, const char *name, + enum mailbox_open_flags flags); void index_storage_mailbox_free(struct mailbox *box); int index_storage_is_readonly(struct mailbox *box); @@ -184,9 +182,6 @@ enum mailbox_status_items items, struct mailbox_status *status_r); -struct mail * -index_storage_fetch(struct mailbox_transaction_context *t, uint32_t seq, - enum mail_fetch_field wanted_fields); int index_storage_get_uids(struct mailbox *box, uint32_t uid1, uint32_t uid2, uint32_t *seq1_r, uint32_t *seq2_r); @@ -199,14 +194,14 @@ struct mail_search_context * index_storage_search_init(struct mailbox_transaction_context *t, const char *charset, struct mail_search_arg *args, - const enum mail_sort_type *sort_program, - enum mail_fetch_field wanted_fields, - struct mailbox_header_lookup_ctx *wanted_headers); + const enum mail_sort_type *sort_program); int index_storage_search_deinit(struct mail_search_context *ctx); -struct mail *index_storage_search_next(struct mail_search_context *ctx); +int index_storage_search_next(struct mail_search_context *ctx, + struct mail *mail); void index_transaction_init(struct index_transaction_context *t, - struct index_mailbox *ibox, int hide); + struct index_mailbox *ibox, + enum mailbox_transaction_flags flags); int index_transaction_commit(struct mailbox_transaction_context *t); void index_transaction_rollback(struct mailbox_transaction_context *t);
--- a/src/lib-storage/index/index-transaction.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/index/index-transaction.c Tue Mar 15 21:01:50 2005 +0200 @@ -2,13 +2,19 @@ #include "lib.h" #include "index-storage.h" +#include "index-mail.h" void index_transaction_init(struct index_transaction_context *t, - struct index_mailbox *ibox, int hide) + struct index_mailbox *ibox, + enum mailbox_transaction_flags flags) { t->mailbox_ctx.box = &ibox->box; t->ibox = ibox; - t->trans = mail_index_transaction_begin(ibox->view, hide, FALSE); + t->flags = flags; + + t->trans = mail_index_transaction_begin(ibox->view, + (flags & MAILBOX_TRANSACTION_FLAG_HIDE) != 0, + (flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0); t->trans_view = mail_index_transaction_open_updated_view(t->trans); t->cache_view = mail_cache_view_open(ibox->cache, t->trans_view); t->cache_trans = mail_cache_get_transaction(t->cache_view, t->trans); @@ -30,9 +36,6 @@ uoff_t offset; int ret; - if (t->fetch_mail.pool != NULL) - index_mail_deinit(&t->fetch_mail); - ret = mail_index_transaction_commit(t->trans, &seq, &offset); if (ret < 0) mail_storage_set_index_error(t->ibox); @@ -52,9 +55,6 @@ struct index_transaction_context *t = (struct index_transaction_context *)_t; - if (t->fetch_mail.pool != NULL) - index_mail_deinit(&t->fetch_mail); - mail_index_transaction_rollback(t->trans); index_transaction_free(t); }
--- a/src/lib-storage/index/maildir/maildir-copy.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/index/maildir/maildir-copy.c Tue Mar 15 21:01:50 2005 +0200 @@ -3,6 +3,7 @@ #include "lib.h" #include "ioloop.h" #include "maildir-storage.h" +#include "index-mail.h" #include "mail-copy.h" #include <stdlib.h> @@ -63,8 +64,8 @@ const char *const *keywords; const char *dest_fname; - flags = mail->get_flags(mail); - keywords = mail->get_keywords(mail); + flags = mail_get_flags(mail); + keywords = mail_get_keywords(mail); dest_fname = maildir_generate_tmp_filename(&ioloop_timeval); dest_fname = maildir_filename_set_flags(dest_fname, flags, keywords); @@ -72,7 +73,7 @@ do_ctx.dest_path = t_strconcat(ctx->ibox->path, "/new/", dest_fname, NULL); - if (maildir_file_do(imail->ibox, imail->mail.uid, + if (maildir_file_do(imail->ibox, imail->mail.mail.uid, do_hardlink, &do_ctx) < 0) return -1; @@ -123,7 +124,7 @@ } int maildir_copy(struct mailbox_transaction_context *_t, struct mail *mail, - struct mail **dest_mail_r) + struct mail *dest_mail) { struct maildir_transaction_context *t = (struct maildir_transaction_context *)_t; @@ -135,7 +136,7 @@ ctx = t->copy_ctx; if (ctx->hardlink && mail->box->storage == ctx->ibox->box.storage) { - // FIXME: handle dest_mail_r + // FIXME: handle dest_mail t_push(); ret = maildir_copy_hardlink(mail, ctx); t_pop(); @@ -148,5 +149,5 @@ /* non-fatal hardlinking failure, try the slow way */ } - return mail_storage_copy(_t, mail, dest_mail_r); + return mail_storage_copy(_t, mail, dest_mail); }
--- a/src/lib-storage/index/maildir/maildir-mail.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/index/maildir/maildir-mail.c Tue Mar 15 21:01:50 2005 +0200 @@ -77,7 +77,7 @@ if (data->open_mail && data->stream == NULL) { /* we're going to open the mail anyway */ - (void)_mail->get_stream(_mail, NULL, NULL); + (void)mail_get_stream(_mail, NULL, NULL); } if (data->stream != NULL) { @@ -90,7 +90,7 @@ return (time_t)-1; } } else { - if (maildir_file_do(mail->ibox, mail->mail.uid, + if (maildir_file_do(mail->ibox, mail->mail.mail.uid, do_stat, &st) <= 0) return (time_t)-1; } @@ -120,7 +120,7 @@ } fname = maildir_uidlist_lookup(mail->ibox->uidlist, - mail->mail.uid, &flags); + mail->mail.mail.uid, &flags); if (fname == NULL) return (uoff_t)-1; @@ -154,7 +154,7 @@ if (field == MAIL_FETCH_UIDL_FILE_NAME) { fname = maildir_uidlist_lookup(mail->ibox->uidlist, - mail->mail.uid, &flags); + mail->mail.mail.uid, &flags); end = strchr(fname, ':'); return end == NULL ? fname : t_strdup_until(fname, end); } @@ -176,7 +176,7 @@ return size; fname = maildir_uidlist_lookup(mail->ibox->uidlist, - mail->mail.uid, &flags); + mail->mail.mail.uid, &flags); if (fname == NULL) return (uoff_t)-1; @@ -195,7 +195,7 @@ } if (size == (uoff_t)-1) { - if (maildir_file_do(mail->ibox, mail->mail.uid, + if (maildir_file_do(mail->ibox, mail->mail.mail.uid, do_stat, &st) <= 0) return (uoff_t)-1; size = st.st_size; @@ -217,8 +217,8 @@ int deleted; if (data->stream == NULL) { - data->stream = maildir_open_mail(mail->ibox, mail->mail.uid, - &deleted); + data->stream = maildir_open_mail(mail->ibox, + mail->mail.mail.uid, &deleted); if (data->stream == NULL) { _mail->expunged = deleted; return NULL; @@ -228,8 +228,9 @@ return index_mail_init_stream(mail, hdr_size, body_size); } -struct mail maildir_mail = { - 0, 0, 0, 0, 0, 0, 0, +struct mail_vfuncs maildir_mail_vfuncs = { + index_mail_free, + index_mail_set_seq, index_mail_get_flags, index_mail_get_keywords,
--- a/src/lib-storage/index/maildir/maildir-save.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/index/maildir/maildir-save.c Tue Mar 15 21:01:50 2005 +0200 @@ -27,7 +27,6 @@ struct index_mailbox *ibox; struct mail_index_transaction *trans; struct maildir_uidlist_sync_ctx *sync_ctx; - struct index_mail mail; const char *tmpdir, *newdir, *curdir; struct maildir_filename *files; @@ -81,7 +80,7 @@ } static struct maildir_save_context * -maildir_transaction_save_init(struct maildir_transaction_context *t) +maildir_save_transaction_init(struct maildir_transaction_context *t) { struct index_mailbox *ibox = t->ictx.ibox; struct maildir_save_context *ctx; @@ -89,12 +88,10 @@ pool = pool_alloconly_create("maildir_save_context", 4096); ctx = p_new(pool, struct maildir_save_context, 1); - ctx->ctx.box = &ibox->box; + ctx->ctx.transaction = &t->ictx.mailbox_ctx; ctx->pool = pool; ctx->ibox = ibox; - ctx->trans = mail_index_transaction_begin(ibox->view, FALSE, TRUE); - - index_mail_init(&t->ictx, &ctx->mail, 0, NULL); + ctx->trans = t->ictx.trans; ctx->tmpdir = p_strconcat(pool, ibox->path, "/tmp", NULL); ctx->newdir = p_strconcat(pool, ibox->path, "/new", NULL); @@ -119,10 +116,12 @@ struct ostream *output; const char *fname, *dest_fname, *path; + i_assert((t->ictx.flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0); + t_push(); if (t->save_ctx == NULL) - t->save_ctx = maildir_transaction_save_init(t); + t->save_ctx = maildir_save_transaction_init(t); ctx = t->save_ctx; /* create a new file in tmp/ directory */ @@ -191,7 +190,7 @@ return 0; } -int maildir_save_finish(struct mail_save_context *_ctx, struct mail **mail_r) +int maildir_save_finish(struct mail_save_context *_ctx, struct mail *dest_mail) { struct maildir_save_context *ctx = (struct maildir_save_context *)_ctx; struct utimbuf buf; @@ -257,12 +256,11 @@ return -1; } - if (mail_r != NULL) { + if (dest_mail != NULL) { i_assert(ctx->seq != 0); - if (index_mail_next(&ctx->mail, ctx->seq) < 0) + if (mail_set_seq(dest_mail, ctx->seq) < 0) return -1; - *mail_r = &ctx->mail.mail; } t_pop(); @@ -308,9 +306,7 @@ uint32_t first_uid, last_uid; enum maildir_uidlist_rec_flag flags; const char *fname; - uint32_t seq; - uoff_t offset; - int ret = 0; + int ret; i_assert(ctx->output == NULL); @@ -352,10 +348,7 @@ } } - if (mail_index_transaction_commit(ctx->trans, &seq, &offset) < 0) - ret = -1; - return ret; - + return 0; } void maildir_transaction_save_commit_post(struct maildir_save_context *ctx) @@ -363,7 +356,6 @@ /* can't do anything anymore if we fail */ (void)maildir_uidlist_sync_deinit(ctx->sync_ctx); - index_mail_deinit(&ctx->mail); pool_unref(ctx->pool); } @@ -385,7 +377,5 @@ } t_pop(); - mail_index_transaction_rollback(ctx->trans); - index_mail_deinit(&ctx->mail); pool_unref(ctx->pool); }
--- a/src/lib-storage/index/maildir/maildir-storage.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/index/maildir/maildir-storage.c Tue Mar 15 21:01:50 2005 +0200 @@ -8,6 +8,7 @@ #include "subscription-file/subscription-file.h" #include "maildir-storage.h" #include "maildir-uidlist.h" +#include "index-mail.h" #include <stdio.h> #include <stdlib.h> @@ -38,6 +39,7 @@ const char *root_dir, *inbox_dir, *index_dir, *control_dir; const char *home, *path, *p; size_t len; + pool_t pool; inbox_dir = root_dir = index_dir = control_dir = NULL; @@ -114,19 +116,21 @@ inbox_dir == NULL ? "" : inbox_dir); } - storage = i_new(struct index_storage, 1); + pool = pool_alloconly_create("storage", 256); + storage = p_new(pool, struct index_storage, 1); storage->storage = maildir_storage; + storage->storage.pool = pool; /* the default ".temp.xxx" prefix would be treated as directory */ storage->temp_prefix = - i_strconcat("temp.", my_hostname, ".", my_pid, ".", NULL); + p_strconcat(pool, "temp.", my_hostname, ".", my_pid, ".", NULL); - storage->dir = i_strdup(home_expand(root_dir)); - storage->inbox_path = i_strdup(home_expand(inbox_dir)); - storage->index_dir = i_strdup(home_expand(index_dir)); - storage->control_dir = i_strdup(home_expand(control_dir)); - storage->user = i_strdup(user); - storage->callbacks = i_new(struct mail_storage_callbacks, 1); + storage->dir = p_strdup(pool, home_expand(root_dir)); + storage->inbox_path = p_strdup(pool, home_expand(inbox_dir)); + storage->index_dir = p_strdup(pool, home_expand(index_dir)); + storage->control_dir = p_strdup(pool, home_expand(control_dir)); + storage->user = p_strdup(pool, user); + storage->callbacks = p_new(pool, struct mail_storage_callbacks, 1); index_storage_init(storage, flags); (void)verify_inbox(storage); @@ -138,15 +142,7 @@ struct index_storage *storage = (struct index_storage *) _storage; index_storage_deinit(storage); - - i_free(storage->temp_prefix); - i_free(storage->dir); - i_free(storage->inbox_path); - i_free(storage->index_dir); - i_free(storage->control_dir); - i_free(storage->user); - i_free(storage->callbacks); - i_free(storage); + pool_unref(storage->storage.pool); } static int maildir_autodetect(const char *data, enum mail_storage_flags flags) @@ -406,6 +402,7 @@ const char *path, *index_dir, *control_dir; struct stat st; int shared; + pool_t pool; path = maildir_get_path(storage, name); index_dir = maildir_get_index_path(storage, name); @@ -419,15 +416,21 @@ if (shared) mail_index_set_permissions(index, st.st_mode & 0666, st.st_gid); - ibox = index_storage_mailbox_init(storage, &maildir_mailbox, - index, name, flags); - if (ibox == NULL) - return NULL; + pool = pool_alloconly_create("mailbox", 256); + ibox = p_new(pool, struct index_mailbox, 1); + ibox->box = maildir_mailbox; + ibox->box.pool = pool; + ibox->storage = storage; - ibox->path = i_strdup(path); - ibox->control_dir = i_strdup(control_dir); + if (index_storage_mailbox_init(ibox, index, name, flags) < 0) { + /* the memory was already freed */ + return NULL; + } - ibox->mail_interface = &maildir_mail; + ibox->path = p_strdup(pool, path); + ibox->control_dir = p_strdup(pool, control_dir); + + ibox->mail_vfuncs = &maildir_mail_vfuncs; ibox->uidlist = maildir_uidlist_init(ibox); ibox->is_recent = maildir_is_recent; @@ -836,59 +839,67 @@ } struct mail_storage maildir_storage = { - "maildir", /* name */ - - '.', /* hierarchy separator */ + MEMBER(name) "maildir", + MEMBER(hierarchy_sep) '.', - maildir_create, - maildir_free, - maildir_autodetect, - index_storage_set_callbacks, - maildir_mailbox_open, - maildir_mailbox_create, - maildir_mailbox_delete, - maildir_mailbox_rename, - maildir_mailbox_list_init, - maildir_mailbox_list_next, - maildir_mailbox_list_deinit, - maildir_set_subscribed, - maildir_get_mailbox_name_status, - index_storage_get_last_error, + { + maildir_create, + maildir_free, + maildir_autodetect, + index_storage_set_callbacks, + maildir_mailbox_open, + maildir_mailbox_create, + maildir_mailbox_delete, + maildir_mailbox_rename, + maildir_mailbox_list_init, + maildir_mailbox_list_next, + maildir_mailbox_list_deinit, + maildir_set_subscribed, + maildir_get_mailbox_name_status, + index_storage_get_last_error + }, - NULL, - 0, - 0 + MEMBER(pool) NULL, + MEMBER(error) NULL, + MEMBER(flags) 0, + MEMBER(module_contexts) ARRAY_INIT, + MEMBER(syntax_error) 0 }; struct mailbox maildir_mailbox = { - NULL, /* name */ - NULL, /* storage */ + MEMBER(name) NULL, + MEMBER(storage) NULL, - index_storage_is_readonly, - index_storage_allow_new_keywords, - maildir_storage_close, - index_storage_get_status, - maildir_storage_sync_init, - index_mailbox_sync_next, - index_mailbox_sync_deinit, - maildir_notify_changes, - maildir_transaction_begin, - maildir_transaction_commit, - maildir_transaction_rollback, - index_keywords_create, - index_keywords_free, - index_storage_fetch, - index_storage_get_uids, - index_header_lookup_init, - index_header_lookup_deinit, - index_storage_search_get_sorting, - index_storage_search_init, - index_storage_search_deinit, - index_storage_search_next, - maildir_save_init, - maildir_save_continue, - maildir_save_finish, - maildir_save_cancel, - maildir_copy, - index_storage_is_inconsistent + { + index_storage_is_readonly, + index_storage_allow_new_keywords, + maildir_storage_close, + index_storage_get_status, + maildir_storage_sync_init, + index_mailbox_sync_next, + index_mailbox_sync_deinit, + maildir_notify_changes, + maildir_transaction_begin, + maildir_transaction_commit, + maildir_transaction_rollback, + index_keywords_create, + index_keywords_free, + index_storage_get_uids, + index_mail_alloc, + index_header_lookup_init, + index_header_lookup_deinit, + index_storage_search_get_sorting, + index_storage_search_init, + index_storage_search_deinit, + index_storage_search_next, + maildir_save_init, + maildir_save_continue, + maildir_save_finish, + maildir_save_cancel, + maildir_copy, + index_storage_is_inconsistent + }, + + MEMBER(pool) NULL, + MEMBER(module_contexts) ARRAY_INIT };
--- a/src/lib-storage/index/maildir/maildir-storage.h Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/index/maildir/maildir-storage.h Tue Mar 15 21:01:50 2005 +0200 @@ -20,7 +20,7 @@ struct maildir_copy_context *copy_ctx; }; -extern struct mail maildir_mail; +extern struct mail_vfuncs maildir_mail_vfuncs; /* Return -1 = error, 0 = file not found, 1 = ok */ typedef int maildir_file_do_func(struct index_mailbox *ibox, @@ -51,7 +51,8 @@ int partial); struct mailbox_transaction_context * -maildir_transaction_begin(struct mailbox *box, int hide); +maildir_transaction_begin(struct mailbox *box, + enum mailbox_transaction_flags flags); int maildir_transaction_commit(struct mailbox_transaction_context *t, enum mailbox_sync_flags flags); void maildir_transaction_rollback(struct mailbox_transaction_context *t); @@ -63,7 +64,7 @@ const char *from_envelope, struct istream *input, int want_mail); int maildir_save_continue(struct mail_save_context *ctx); -int maildir_save_finish(struct mail_save_context *ctx, struct mail **mail_r); +int maildir_save_finish(struct mail_save_context *ctx, struct mail *dest_mail); void maildir_save_cancel(struct mail_save_context *ctx); int maildir_transaction_save_commit_pre(struct maildir_save_context *ctx); @@ -71,7 +72,7 @@ void maildir_transaction_save_rollback(struct maildir_save_context *ctx); int maildir_copy(struct mailbox_transaction_context *t, struct mail *mail, - struct mail **dest_mail_r); + struct mail *dest_mail); int maildir_transaction_copy_commit(struct maildir_copy_context *ctx); void maildir_transaction_copy_rollback(struct maildir_copy_context *ctx);
--- a/src/lib-storage/index/maildir/maildir-transaction.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/index/maildir/maildir-transaction.c Tue Mar 15 21:01:50 2005 +0200 @@ -4,13 +4,14 @@ #include "maildir-storage.h" struct mailbox_transaction_context * -maildir_transaction_begin(struct mailbox *box, int hide) +maildir_transaction_begin(struct mailbox *box, + enum mailbox_transaction_flags flags) { struct index_mailbox *ibox = (struct index_mailbox *)box; struct maildir_transaction_context *t; t = i_new(struct maildir_transaction_context, 1); - index_transaction_init(&t->ictx, ibox, hide); + index_transaction_init(&t->ictx, ibox, flags); return &t->ictx.mailbox_ctx; }
--- a/src/lib-storage/index/mbox/mbox-mail.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/index/mbox/mbox-mail.c Tue Mar 15 21:01:50 2005 +0200 @@ -22,7 +22,7 @@ enum mbox_sync_flags sync_flags = 0; int ret, deleted; - if (mail->mail.expunged) + if (mail->mail.mail.expunged) return 0; __again: @@ -45,11 +45,11 @@ if (mbox_file_open_stream(ibox) < 0) return -1; - ret = mbox_file_seek(ibox, mail->trans->trans_view, mail->mail.seq, - &deleted); + ret = mbox_file_seek(ibox, mail->trans->trans_view, + mail->mail.mail.seq, &deleted); if (ret < 0) { if (deleted) { - mail->mail.expunged = TRUE; + mail->mail.mail.expunged = TRUE; return 0; } return -1; @@ -160,8 +160,9 @@ return index_mail_init_stream(mail, hdr_size, body_size); } -struct mail mbox_mail = { - 0, 0, 0, 0, 0, 0, 0, +struct mail_vfuncs mbox_mail_vfuncs = { + index_mail_free, + index_mail_set_seq, index_mail_get_flags, index_mail_get_keywords,
--- a/src/lib-storage/index/mbox/mbox-save.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/index/mbox/mbox-save.c Tue Mar 15 21:01:50 2005 +0200 @@ -40,7 +40,6 @@ uoff_t extra_hdr_offset, eoh_offset, eoh_input_offset; char last_char; - struct index_mail mail; struct mbox_md5_context *mbox_md5_ctx; unsigned int synced:1; @@ -191,8 +190,6 @@ ctx->next_uid = hdr->next_uid; ctx->synced = TRUE; t->mbox_modified = TRUE; - - index_mail_init(&t->ictx, &ctx->mail, 0, NULL); } static void status_flags_append(string_t *str, enum mail_flags flags, @@ -312,16 +309,17 @@ enum mail_flags save_flags; uint64_t offset; + i_assert((t->ictx.flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0); + /* FIXME: we could write timezone_offset to From-line.. */ if (received_date == (time_t)-1) received_date = ioloop_time; if (ctx == NULL) { ctx = t->save_ctx = i_new(struct mbox_save_context, 1); - ctx->ctx.box = &ibox->box; + ctx->ctx.transaction = &t->ictx.mailbox_ctx; ctx->ibox = ibox; - ctx->trans = mail_index_transaction_begin(ibox->view, - FALSE, TRUE); + ctx->trans = t->ictx.trans; ctx->append_offset = (uoff_t)-1; ctx->headers = str_new(default_pool, 512); ctx->save_crlf = getenv("MAIL_SAVE_CRLF") != NULL; @@ -463,7 +461,7 @@ return ctx->input->eof && size == 0 ? 0 : mbox_save_continue(_ctx); } -int mbox_save_finish(struct mail_save_context *_ctx, struct mail **mail_r) +int mbox_save_finish(struct mail_save_context *_ctx, struct mail *dest_mail) { struct mbox_save_context *ctx = (struct mbox_save_context *)_ctx; @@ -501,12 +499,11 @@ return -1; } - if (mail_r != NULL) { + if (dest_mail != NULL) { i_assert(ctx->seq != 0); - if (index_mail_next(&ctx->mail, ctx->seq) < 0) + if (mail_set_seq(dest_mail, ctx->seq) < 0) return -1; - *mail_r = &ctx->mail.mail; } return 0; @@ -524,9 +521,6 @@ { i_assert(ctx->body_output == NULL); - if (ctx->mail.pool != NULL) - index_mail_deinit(&ctx->mail); - if (ctx->output != NULL) o_stream_unref(ctx->output); str_free(ctx->headers); @@ -535,8 +529,6 @@ int mbox_transaction_save_commit(struct mbox_save_context *ctx) { - uint32_t seq; - uoff_t offset; int ret = 0; if (ctx->synced) { @@ -553,9 +545,6 @@ } } - if (mail_index_transaction_commit(ctx->trans, &seq, &offset) < 0) - ret = -1; - mbox_transaction_save_deinit(ctx); return ret; } @@ -576,6 +565,5 @@ mbox_set_syscall_error(ibox, "ftruncate()"); } - mail_index_transaction_rollback(ctx->trans); mbox_transaction_save_deinit(ctx); }
--- a/src/lib-storage/index/mbox/mbox-storage.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/index/mbox/mbox-storage.c Tue Mar 15 21:01:50 2005 +0200 @@ -11,6 +11,7 @@ #include "mbox-file.h" #include "mbox-sync-private.h" #include "mail-copy.h" +#include "index-mail.h" #include <stdio.h> #include <stdlib.h> @@ -248,6 +249,7 @@ const char *root_dir, *inbox_file, *index_dir, *p; struct stat st; int autodetect; + pool_t pool; root_dir = inbox_file = index_dir = NULL; @@ -325,14 +327,16 @@ inbox_file == NULL ? "" : inbox_file); } - storage = i_new(struct index_storage, 1); + pool = pool_alloconly_create("storage", 256); + storage = p_new(pool, struct index_storage, 1); storage->storage = mbox_storage; + storage->storage.pool = pool; - storage->dir = i_strdup(home_expand(root_dir)); - storage->inbox_path = i_strdup(home_expand(inbox_file)); - storage->index_dir = i_strdup(home_expand(index_dir)); - storage->user = i_strdup(user); - storage->callbacks = i_new(struct mail_storage_callbacks, 1); + storage->dir = p_strdup(pool, home_expand(root_dir)); + storage->inbox_path = p_strdup(pool, home_expand(inbox_file)); + storage->index_dir = p_strdup(pool, home_expand(index_dir)); + storage->user = p_strdup(pool, user); + storage->callbacks = p_new(pool, struct mail_storage_callbacks, 1); index_storage_init(storage, flags); return &storage->storage; } @@ -342,13 +346,7 @@ struct index_storage *storage = (struct index_storage *)_storage; index_storage_deinit(storage); - - i_free(storage->dir); - i_free(storage->inbox_path); - i_free(storage->index_dir); - i_free(storage->user); - i_free(storage->callbacks); - i_free(storage); + pool_unref(storage->storage.pool); } int mbox_is_valid_mask(struct mail_storage *storage, const char *mask) @@ -488,6 +486,7 @@ struct mail_index *index; const char *path, *index_dir; uint32_t mbox_ext_idx; + pool_t pool; if (strcmp(name, "INBOX") == 0) { /* name = "INBOX" @@ -507,18 +506,25 @@ mbox_ext_idx = mail_index_ext_register(index, "mbox", 0, sizeof(uint64_t), sizeof(uint64_t)); - ibox = index_storage_mailbox_init(storage, &mbox_mailbox, - index, name, flags); - if (ibox == NULL) + + pool = pool_alloconly_create("mailbox", 256); + ibox = p_new(pool, struct index_mailbox, 1); + ibox->box = mbox_mailbox; + ibox->box.pool = pool; + ibox->storage = storage; + + if (index_storage_mailbox_init(ibox, index, name, flags) < 0) { + /* the memory was already freed */ return NULL; + } - ibox->path = i_strdup(path); + ibox->path = p_strdup(pool, path); ibox->mbox_fd = -1; ibox->mbox_lock_type = F_UNLCK; ibox->mbox_ext_idx = mbox_ext_idx; ibox->is_recent = mbox_mail_is_recent; - ibox->mail_interface = &mbox_mail; + ibox->mail_vfuncs = &mbox_mail_vfuncs; ibox->mbox_very_dirty_syncs = getenv("MBOX_VERY_DIRTY_SYNCS") != NULL; ibox->mbox_do_dirty_syncs = ibox->mbox_very_dirty_syncs || getenv("MBOX_DIRTY_SYNCS") != NULL; @@ -931,59 +937,67 @@ } struct mail_storage mbox_storage = { - "mbox", /* name */ - - '/', /* hierarchy separator */ + MEMBER(name) "mbox", + MEMBER(hierarchy_sep) '/', - mbox_create, - mbox_free, - mbox_autodetect, - index_storage_set_callbacks, - mbox_mailbox_open, - mbox_mailbox_create, - mbox_mailbox_delete, - mbox_mailbox_rename, - mbox_mailbox_list_init, - mbox_mailbox_list_next, - mbox_mailbox_list_deinit, - mbox_set_subscribed, - mbox_get_mailbox_name_status, - index_storage_get_last_error, + { + mbox_create, + mbox_free, + mbox_autodetect, + index_storage_set_callbacks, + mbox_mailbox_open, + mbox_mailbox_create, + mbox_mailbox_delete, + mbox_mailbox_rename, + mbox_mailbox_list_init, + mbox_mailbox_list_next, + mbox_mailbox_list_deinit, + mbox_set_subscribed, + mbox_get_mailbox_name_status, + index_storage_get_last_error + }, - NULL, - 0, - 0 + MEMBER(pool) NULL, + MEMBER(error) NULL, + MEMBER(flags) 0, + MEMBER(module_contexts) ARRAY_INIT, + MEMBER(syntax_error) 0 }; struct mailbox mbox_mailbox = { - NULL, /* name */ - NULL, /* storage */ + MEMBER(name) NULL, + MEMBER(storage) NULL, - index_storage_is_readonly, - index_storage_allow_new_keywords, - mbox_storage_close, - index_storage_get_status, - mbox_storage_sync_init, - index_mailbox_sync_next, - index_mailbox_sync_deinit, - mbox_notify_changes, - mbox_transaction_begin, - mbox_transaction_commit, - mbox_transaction_rollback, - index_keywords_create, - index_keywords_free, - index_storage_fetch, - index_storage_get_uids, - index_header_lookup_init, - index_header_lookup_deinit, - index_storage_search_get_sorting, - index_storage_search_init, - index_storage_search_deinit, - index_storage_search_next, - mbox_save_init, - mbox_save_continue, - mbox_save_finish, - mbox_save_cancel, - mail_storage_copy, - index_storage_is_inconsistent + { + index_storage_is_readonly, + index_storage_allow_new_keywords, + mbox_storage_close, + index_storage_get_status, + mbox_storage_sync_init, + index_mailbox_sync_next, + index_mailbox_sync_deinit, + mbox_notify_changes, + mbox_transaction_begin, + mbox_transaction_commit, + mbox_transaction_rollback, + index_keywords_create, + index_keywords_free, + index_storage_get_uids, + index_mail_alloc, + index_header_lookup_init, + index_header_lookup_deinit, + index_storage_search_get_sorting, + index_storage_search_init, + index_storage_search_deinit, + index_storage_search_next, + mbox_save_init, + mbox_save_continue, + mbox_save_finish, + mbox_save_cancel, + mail_storage_copy, + index_storage_is_inconsistent + }, + + MEMBER(pool) NULL, + MEMBER(module_contexts) ARRAY_INIT };
--- a/src/lib-storage/index/mbox/mbox-storage.h Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/index/mbox/mbox-storage.h Tue Mar 15 21:01:50 2005 +0200 @@ -19,7 +19,7 @@ unsigned int mbox_modified:1; }; -extern struct mail mbox_mail; +extern struct mail_vfuncs mbox_mail_vfuncs; extern const char *mbox_hide_headers[]; extern size_t mbox_hide_headers_count; @@ -33,7 +33,8 @@ struct mailbox_list *mbox_mailbox_list_next(struct mailbox_list_context *ctx); struct mailbox_transaction_context * -mbox_transaction_begin(struct mailbox *box, int hide); +mbox_transaction_begin(struct mailbox *box, + enum mailbox_transaction_flags flags); int mbox_transaction_commit(struct mailbox_transaction_context *t, enum mailbox_sync_flags flags); void mbox_transaction_rollback(struct mailbox_transaction_context *t); @@ -47,7 +48,7 @@ time_t received_date, int timezone_offset, const char *from_envelope, struct istream *input, int want_mail); int mbox_save_continue(struct mail_save_context *ctx); -int mbox_save_finish(struct mail_save_context *ctx, struct mail **mail_r); +int mbox_save_finish(struct mail_save_context *ctx, struct mail *dest_mail); void mbox_save_cancel(struct mail_save_context *ctx); int mbox_transaction_save_commit(struct mbox_save_context *ctx);
--- a/src/lib-storage/index/mbox/mbox-transaction.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/index/mbox/mbox-transaction.c Tue Mar 15 21:01:50 2005 +0200 @@ -6,13 +6,14 @@ #include "mbox-sync-private.h" struct mailbox_transaction_context * -mbox_transaction_begin(struct mailbox *box, int hide) +mbox_transaction_begin(struct mailbox *box, + enum mailbox_transaction_flags flags) { struct index_mailbox *ibox = (struct index_mailbox *)box; struct mbox_transaction_context *t; t = i_new(struct mbox_transaction_context, 1); - index_transaction_init(&t->ictx, ibox, hide); + index_transaction_init(&t->ictx, ibox, flags); return &t->ictx.mailbox_ctx; }
--- a/src/lib-storage/mail-copy.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/mail-copy.c Tue Mar 15 21:01:50 2005 +0200 @@ -6,25 +6,25 @@ #include "mail-copy.h" int mail_storage_copy(struct mailbox_transaction_context *t, struct mail *mail, - struct mail **dest_mail_r) + struct mail *dest_mail) { struct mail_save_context *ctx; struct istream *input; struct mail_keywords *keywords; const char *from_envelope, *const *keywords_list; - input = mail->get_stream(mail, NULL, NULL); + input = mail_get_stream(mail, NULL, NULL); if (input == NULL) return -1; - from_envelope = mail->get_special(mail, MAIL_FETCH_FROM_ENVELOPE); + from_envelope = mail_get_special(mail, MAIL_FETCH_FROM_ENVELOPE); - keywords_list = mail->get_keywords(mail); + keywords_list = mail_get_keywords(mail); keywords = keywords_list == NULL ? NULL : mailbox_keywords_create(t, keywords_list); - ctx = mailbox_save_init(t, mail->get_flags(mail), keywords, - mail->get_received_date(mail), - 0, from_envelope, input, dest_mail_r != NULL); + ctx = mailbox_save_init(t, mail_get_flags(mail), keywords, + mail_get_received_date(mail), + 0, from_envelope, input, dest_mail != NULL); if (keywords != NULL) mailbox_keywords_free(t, keywords); @@ -38,5 +38,5 @@ return -1; } - return mailbox_save_finish(ctx, dest_mail_r); + return mailbox_save_finish(ctx, dest_mail); }
--- a/src/lib-storage/mail-copy.h Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/mail-copy.h Tue Mar 15 21:01:50 2005 +0200 @@ -2,6 +2,6 @@ #define __MAIL_COPY_H int mail_storage_copy(struct mailbox_transaction_context *t, struct mail *mail, - struct mail **dest_mail_r); + struct mail *dest_mail); #endif
--- a/src/lib-storage/mail-storage-private.h Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/mail-storage-private.h Tue Mar 15 21:01:50 2005 +0200 @@ -3,10 +3,11 @@ #include "mail-storage.h" -struct mail_storage { - char *name; - char hierarchy_sep; +/* Modules should use do "my_id = mail_storage_module_id++" and + use objects' module_contexts[id] for their own purposes. */ +extern unsigned int mail_storage_module_id; +struct mail_storage_vfuncs { struct mail_storage *(*create)(const char *data, const char *user, enum mail_storage_flags flags); void (*destroy)(struct mail_storage *storage); @@ -44,19 +45,27 @@ const char *(*get_last_error)(struct mail_storage *storage, int *syntax_error_r); +}; + +struct mail_storage { + char *name; + char hierarchy_sep; + + struct mail_storage_vfuncs v; /* private: */ + pool_t pool; + char *error; enum mail_storage_flags flags; + /* Module-specific contexts. See mail_storage_module_id. */ + array_t ARRAY_DEFINE(module_contexts, void); + unsigned int syntax_error:1; /* Give a BAD reply instead of NO */ }; -struct mailbox { - char *name; - - struct mail_storage *storage; - +struct mailbox_vfuncs { int (*is_readonly)(struct mailbox *box); int (*allow_new_keywords)(struct mailbox *box); @@ -78,7 +87,8 @@ void *context); struct mailbox_transaction_context * - (*transaction_begin)(struct mailbox *box, int hide); + (*transaction_begin)(struct mailbox *box, + enum mailbox_transaction_flags flags); int (*transaction_commit)(struct mailbox_transaction_context *t, enum mailbox_sync_flags flags); void (*transaction_rollback)(struct mailbox_transaction_context *t); @@ -89,12 +99,14 @@ void (*keywords_free)(struct mailbox_transaction_context *t, struct mail_keywords *keywords); - struct mail *(*fetch)(struct mailbox_transaction_context *t, - uint32_t seq, - enum mail_fetch_field wanted_fields); int (*get_uids)(struct mailbox *box, uint32_t uid1, uint32_t uid2, uint32_t *seq1_r, uint32_t *seq2_r); + struct mail * + (*mail_alloc)(struct mailbox_transaction_context *t, + enum mail_fetch_field wanted_fields, + struct mailbox_header_lookup_ctx *wanted_headers); + struct mailbox_header_lookup_ctx * (*header_lookup_init)(struct mailbox *box, const char *const headers[]); @@ -105,11 +117,9 @@ struct mail_search_context * (*search_init)(struct mailbox_transaction_context *t, const char *charset, struct mail_search_arg *args, - const enum mail_sort_type *sort_program, - enum mail_fetch_field wanted_fields, - struct mailbox_header_lookup_ctx *wanted_headers); + const enum mail_sort_type *sort_program); int (*search_deinit)(struct mail_search_context *ctx); - struct mail *(*search_next)(struct mail_search_context *ctx); + int (*search_next)(struct mail_search_context *ctx, struct mail *mail); struct mail_save_context * (*save_init)(struct mailbox_transaction_context *t, @@ -119,15 +129,68 @@ const char *from_envelope, struct istream *input, int want_mail); int (*save_continue)(struct mail_save_context *ctx); - int (*save_finish)(struct mail_save_context *ctx, struct mail **mail_r); + int (*save_finish)(struct mail_save_context *ctx, + struct mail *dest_mail); void (*save_cancel)(struct mail_save_context *ctx); int (*copy)(struct mailbox_transaction_context *t, struct mail *mail, - struct mail **dest_mail_r); + struct mail *dest_mail); int (*is_inconsistent)(struct mailbox *box); }; +struct mailbox { + char *name; + struct mail_storage *storage; + + struct mailbox_vfuncs v; +/* private: */ + pool_t pool; + + /* Module-specific contexts. See mail_storage_module_id. */ + array_t ARRAY_DEFINE(module_contexts, void); +}; + +struct mail_vfuncs { + void (*free)(struct mail *mail); + int (*set_seq)(struct mail *mail, uint32_t seq); + + enum mail_flags (*get_flags)(struct mail *mail); + const char *const *(*get_keywords)(struct mail *mail); + const struct message_part *(*get_parts)(struct mail *mail); + + time_t (*get_received_date)(struct mail *mail); + time_t (*get_date)(struct mail *mail, int *timezone); + uoff_t (*get_virtual_size)(struct mail *mail); + uoff_t (*get_physical_size)(struct mail *mail); + + const char *(*get_header)(struct mail *mail, const char *field); + struct istream * + (*get_headers)(struct mail *mail, + struct mailbox_header_lookup_ctx *headers); + struct istream *(*get_stream)(struct mail *mail, + struct message_size *hdr_size, + struct message_size *body_size); + + const char *(*get_special)(struct mail *mail, + enum mail_fetch_field field); + + int (*update_flags)(struct mail *mail, enum modify_type modify_type, + enum mail_flags flags); + int (*update_keywords)(struct mail *mail, enum modify_type modify_type, + struct mail_keywords *keywords); + + int (*expunge)(struct mail *mail); +}; + +struct mail_private { + struct mail mail; + struct mail_vfuncs v; + + pool_t pool; + array_t ARRAY_DEFINE(module_contexts, void); +}; + struct mailbox_list_context { struct mail_storage *storage; }; @@ -137,11 +200,11 @@ }; struct mail_search_context { - struct mailbox *box; + struct mailbox_transaction_context *transaction; }; struct mail_save_context { - struct mailbox *box; + struct mailbox_transaction_context *transaction; }; struct mailbox_sync_context {
--- a/src/lib-storage/mail-storage.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/mail-storage.c Tue Mar 15 21:01:50 2005 +0200 @@ -18,6 +18,8 @@ struct mail_storage *storage; }; +unsigned int mail_storage_module_id = 0; + static struct mail_storage_list *storages = NULL; void mail_storage_init(void) @@ -76,7 +78,7 @@ for (list = storages; list != NULL; list = list->next) { if (strcasecmp(list->storage->name, name) == 0) - return list->storage->create(data, user, flags); + return list->storage->v.create(data, user, flags); } return NULL; @@ -89,7 +91,7 @@ struct mail_storage *storage; for (list = storages; list != NULL; list = list->next) { - storage = list->storage->create(NULL, user, flags); + storage = list->storage->v.create(NULL, user, flags); if (storage != NULL) return storage; } @@ -103,7 +105,7 @@ struct mail_storage_list *list; for (list = storages; list != NULL; list = list->next) { - if (list->storage->autodetect(data, flags)) + if (list->storage->v.autodetect(data, flags)) return list->storage; } @@ -131,7 +133,7 @@ } else { storage = mail_storage_autodetect(data, flags); if (storage != NULL) - storage = storage->create(data, user, flags); + storage = storage->v.create(data, user, flags); } return storage; @@ -141,7 +143,7 @@ { i_assert(storage != NULL); - storage->destroy(storage); + storage->v.destroy(storage); } void mail_storage_clear_error(struct mail_storage *storage) @@ -228,24 +230,24 @@ struct mail_storage_callbacks *callbacks, void *context) { - storage->set_callbacks(storage, callbacks, context); + storage->v.set_callbacks(storage, callbacks, context); } int mail_storage_mailbox_create(struct mail_storage *storage, const char *name, int directory) { - return storage->mailbox_create(storage, name, directory); + return storage->v.mailbox_create(storage, name, directory); } int mail_storage_mailbox_delete(struct mail_storage *storage, const char *name) { - return storage->mailbox_delete(storage, name); + return storage->v.mailbox_delete(storage, name); } int mail_storage_mailbox_rename(struct mail_storage *storage, const char *oldname, const char *newname) { - return storage->mailbox_rename(storage, oldname, newname); + return storage->v.mailbox_rename(storage, oldname, newname); } struct mailbox_list_context * @@ -253,48 +255,48 @@ const char *ref, const char *mask, enum mailbox_list_flags flags) { - return storage->mailbox_list_init(storage, ref, mask, flags); + return storage->v.mailbox_list_init(storage, ref, mask, flags); } struct mailbox_list * mail_storage_mailbox_list_next(struct mailbox_list_context *ctx) { - return ctx->storage->mailbox_list_next(ctx); + return ctx->storage->v.mailbox_list_next(ctx); } int mail_storage_mailbox_list_deinit(struct mailbox_list_context *ctx) { - return ctx->storage->mailbox_list_deinit(ctx); + return ctx->storage->v.mailbox_list_deinit(ctx); } int mail_storage_set_subscribed(struct mail_storage *storage, const char *name, int set) { - return storage->set_subscribed(storage, name, set); + return storage->v.set_subscribed(storage, name, set); } int mail_storage_get_mailbox_name_status(struct mail_storage *storage, const char *name, enum mailbox_name_status *status) { - return storage->get_mailbox_name_status(storage, name, status); + return storage->v.get_mailbox_name_status(storage, name, status); } const char *mail_storage_get_last_error(struct mail_storage *storage, int *syntax_error_r) { - return storage->get_last_error(storage, syntax_error_r); + return storage->v.get_last_error(storage, syntax_error_r); } struct mailbox *mailbox_open(struct mail_storage *storage, const char *name, enum mailbox_open_flags flags) { - return storage->mailbox_open(storage, name, flags); + return storage->v.mailbox_open(storage, name, flags); } int mailbox_close(struct mailbox *box) { - return box->close(box); + return box->v.close(box); } struct mail_storage *mailbox_get_storage(struct mailbox *box) @@ -309,123 +311,115 @@ int mailbox_is_readonly(struct mailbox *box) { - return box->is_readonly(box); + return box->v.is_readonly(box); } int mailbox_allow_new_keywords(struct mailbox *box) { - return box->allow_new_keywords(box); + return box->v.allow_new_keywords(box); } int mailbox_get_status(struct mailbox *box, enum mailbox_status_items items, struct mailbox_status *status) { - return box->get_status(box, items, status); + return box->v.get_status(box, items, status); } struct mailbox_sync_context * mailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags) { - return box->sync_init(box, flags); + return box->v.sync_init(box, flags); } int mailbox_sync_next(struct mailbox_sync_context *ctx, struct mailbox_sync_rec *sync_rec_r) { - return ctx->box->sync_next(ctx, sync_rec_r); + return ctx->box->v.sync_next(ctx, sync_rec_r); } int mailbox_sync_deinit(struct mailbox_sync_context *ctx, struct mailbox_status *status_r) { - return ctx->box->sync_deinit(ctx, status_r); + return ctx->box->v.sync_deinit(ctx, status_r); } void mailbox_notify_changes(struct mailbox *box, unsigned int min_interval, mailbox_notify_callback_t *callback, void *context) { - box->notify_changes(box, min_interval, callback, context); + box->v.notify_changes(box, min_interval, callback, context); } struct mail_keywords * mailbox_keywords_create(struct mailbox_transaction_context *t, const char *const keywords[]) { - return t->box->keywords_create(t, keywords); + return t->box->v.keywords_create(t, keywords); } void mailbox_keywords_free(struct mailbox_transaction_context *t, struct mail_keywords *keywords) { - t->box->keywords_free(t, keywords); -} - -struct mail *mailbox_fetch(struct mailbox_transaction_context *t, uint32_t seq, - enum mail_fetch_field wanted_fields) -{ - return t->box->fetch(t, seq, wanted_fields); + t->box->v.keywords_free(t, keywords); } int mailbox_get_uids(struct mailbox *box, uint32_t uid1, uint32_t uid2, uint32_t *seq1_r, uint32_t *seq2_r) { - return box->get_uids(box, uid1, uid2, seq1_r, seq2_r); + return box->v.get_uids(box, uid1, uid2, seq1_r, seq2_r); } struct mailbox_header_lookup_ctx * mailbox_header_lookup_init(struct mailbox *box, const char *const headers[]) { - return box->header_lookup_init(box, headers); + return box->v.header_lookup_init(box, headers); } void mailbox_header_lookup_deinit(struct mailbox_header_lookup_ctx *ctx) { - ctx->box->header_lookup_deinit(ctx); + ctx->box->v.header_lookup_deinit(ctx); } int mailbox_search_get_sorting(struct mailbox *box, enum mail_sort_type *sort_program) { - return box->search_get_sorting(box, sort_program); + return box->v.search_get_sorting(box, sort_program); } struct mail_search_context * mailbox_search_init(struct mailbox_transaction_context *t, const char *charset, struct mail_search_arg *args, - const enum mail_sort_type *sort_program, - enum mail_fetch_field wanted_fields, - struct mailbox_header_lookup_ctx *wanted_headers) + const enum mail_sort_type *sort_program) { - return t->box->search_init(t, charset, args, sort_program, - wanted_fields, wanted_headers); + return t->box->v.search_init(t, charset, args, sort_program); } int mailbox_search_deinit(struct mail_search_context *ctx) { - return ctx->box->search_deinit(ctx); + return ctx->transaction->box->v.search_deinit(ctx); } -struct mail *mailbox_search_next(struct mail_search_context *ctx) +int mailbox_search_next(struct mail_search_context *ctx, struct mail *mail) { - return ctx->box->search_next(ctx); + return ctx->transaction->box->v.search_next(ctx, mail); } struct mailbox_transaction_context * -mailbox_transaction_begin(struct mailbox *box, int hide) +mailbox_transaction_begin(struct mailbox *box, + enum mailbox_transaction_flags flags) { - return box->transaction_begin(box, hide); + return box->v.transaction_begin(box, flags); } int mailbox_transaction_commit(struct mailbox_transaction_context *t, enum mailbox_sync_flags flags) { - return t->box->transaction_commit(t, flags); + return t->box->v.transaction_commit(t, flags); } void mailbox_transaction_rollback(struct mailbox_transaction_context *t) { - t->box->transaction_rollback(t); + t->box->v.transaction_rollback(t); } struct mail_save_context * @@ -435,33 +429,33 @@ const char *from_envelope, struct istream *input, int want_mail) { - return t->box->save_init(t, flags, keywords, - received_date, timezone_offset, - from_envelope, input, want_mail); + return t->box->v.save_init(t, flags, keywords, + received_date, timezone_offset, + from_envelope, input, want_mail); } int mailbox_save_continue(struct mail_save_context *ctx) { - return ctx->box->save_continue(ctx); + return ctx->transaction->box->v.save_continue(ctx); } -int mailbox_save_finish(struct mail_save_context *ctx, struct mail **mail_r) +int mailbox_save_finish(struct mail_save_context *ctx, struct mail *dest_mail) { - return ctx->box->save_finish(ctx, mail_r); + return ctx->transaction->box->v.save_finish(ctx, dest_mail); } void mailbox_save_cancel(struct mail_save_context *ctx) { - ctx->box->save_cancel(ctx); + ctx->transaction->box->v.save_cancel(ctx); } int mailbox_copy(struct mailbox_transaction_context *t, struct mail *mail, - struct mail **dest_mail_r) + struct mail *dest_mail) { - return t->box->copy(t, mail, dest_mail_r); + return t->box->v.copy(t, mail, dest_mail); } int mailbox_is_inconsistent(struct mailbox *box) { - return box->is_inconsistent(box); + return box->v.is_inconsistent(box); }
--- a/src/lib-storage/mail-storage.h Tue Mar 15 20:58:18 2005 +0200 +++ b/src/lib-storage/mail-storage.h Tue Mar 15 21:01:50 2005 +0200 @@ -94,6 +94,14 @@ MAIL_FETCH_UIDL_FILE_NAME = 0x00020000 }; +enum mailbox_transaction_flags { + /* Hide changes done in this transaction from next view sync */ + MAILBOX_TRANSACTION_FLAG_HIDE = 0x01, + /* External transaction. Should be used for copying and appends, + but nothing else. */ + MAILBOX_TRANSACTION_FLAG_EXTERNAL = 0x02 +}; + enum mailbox_sync_flags { /* Make sure we sync all external changes done to mailbox */ MAILBOX_SYNC_FLAG_FULL_READ = 0x01, @@ -119,7 +127,6 @@ struct mail_storage; struct mail_search_arg; struct mail_keywords; -struct mail; struct mailbox; struct mailbox_list_context; struct mailbox_transaction_context; @@ -151,6 +158,17 @@ enum mailbox_sync_type type; }; +struct mail { + /* always set */ + struct mailbox *box; + struct mailbox_transaction_context *transaction; + uint32_t seq, uid; + + unsigned int expunged:1; + unsigned int has_nuls:1; /* message data is known to contain NULs */ + unsigned int has_no_nuls:1; /* -''- known to not contain NULs */ +}; + struct mail_storage_callbacks { /* Alert: Not enough disk space */ void (*alert_no_diskspace)(struct mailbox *mailbox, void *context); @@ -291,7 +309,8 @@ mailbox_notify_callback_t *callback, void *context); struct mailbox_transaction_context * -mailbox_transaction_begin(struct mailbox *box, int hide); +mailbox_transaction_begin(struct mailbox *box, + enum mailbox_transaction_flags flags); int mailbox_transaction_commit(struct mailbox_transaction_context *t, enum mailbox_sync_flags flags); void mailbox_transaction_rollback(struct mailbox_transaction_context *t); @@ -303,10 +322,6 @@ void mailbox_keywords_free(struct mailbox_transaction_context *t, struct mail_keywords *keywords); -/* Simplified fetching for a single sequence. */ -struct mail *mailbox_fetch(struct mailbox_transaction_context *t, uint32_t seq, - enum mail_fetch_field wanted_fields); - /* Convert uid range to sequence range. */ int mailbox_get_uids(struct mailbox *box, uint32_t uid1, uint32_t uid2, uint32_t *seq1_r, uint32_t *seq2_r); @@ -326,21 +341,15 @@ If sort_program is non-NULL, it requests that the returned messages are sorted by the given criteria. sort_program must have gone - through search_get_sorting(). - - wanted_fields and wanted_headers aren't required, but they can be - used for optimizations. */ + through search_get_sorting(). */ struct mail_search_context * mailbox_search_init(struct mailbox_transaction_context *t, const char *charset, struct mail_search_arg *args, - const enum mail_sort_type *sort_program, - enum mail_fetch_field wanted_fields, - struct mailbox_header_lookup_ctx *wanted_headers); + const enum mail_sort_type *sort_program); /* Deinitialize search request. */ int mailbox_search_deinit(struct mail_search_context *ctx); -/* Search the next message. Returned mail object can be used until - the next call to search_next() or search_deinit(). */ -struct mail *mailbox_search_next(struct mail_search_context *ctx); +/* Search the next message. Returns 1 if found, 0 if not, -1 if failure. */ +int mailbox_search_next(struct mail_search_context *ctx, struct mail *mail); /* Save a mail into mailbox. timezone_offset specifies the timezone in minutes in which received_date was originally given with. To use @@ -356,14 +365,14 @@ const char *from_envelope, struct istream *input, int want_mail); int mailbox_save_continue(struct mail_save_context *ctx); -int mailbox_save_finish(struct mail_save_context *ctx, struct mail **mail_r); +int mailbox_save_finish(struct mail_save_context *ctx, struct mail *dest_mail); void mailbox_save_cancel(struct mail_save_context *ctx); -/* Copy given message. If dest_mail_r is non-NULL, the copied message can be +/* Copy given message. If dest_mail is non-NULL, the copied message can be accessed using it. Note that setting it non-NULL may require mailbox syncing, so don't give give it unless you need it. */ int mailbox_copy(struct mailbox_transaction_context *t, struct mail *mail, - struct mail **dest_mail_r); + struct mail *dest_mail); /* Returns TRUE if mailbox is now in inconsistent state, meaning that the message IDs etc. may have changed - only way to recover this @@ -372,60 +381,56 @@ do forced CLOSE. */ int mailbox_is_inconsistent(struct mailbox *box); -struct mail { - /* always set */ - struct mailbox *box; - struct mailbox_transaction_context *transaction; - uint32_t seq, uid; - - unsigned int expunged:1; - unsigned int has_nuls:1; /* message data is known to contain NULs */ - unsigned int has_no_nuls:1; /* -''- known to not contain NULs */ - - enum mail_flags (*get_flags)(struct mail *mail); - const char *const *(*get_keywords)(struct mail *mail); - const struct message_part *(*get_parts)(struct mail *mail); +/* Returns message's flags */ +enum mail_flags mail_get_flags(struct mail *mail); +/* Returns message's keywords */ +const char *const *mail_get_keywords(struct mail *mail); +/* Returns message's MIME parts */ +const struct message_part *mail_get_parts(struct mail *mail); - /* Get the time message was received (IMAP INTERNALDATE). - Returns (time_t)-1 if error occured. */ - time_t (*get_received_date)(struct mail *mail); - /* Get the Date-header in mail. Timezone is in minutes. - Returns (time_t)-1 if error occured, 0 if field wasn't found or - couldn't be parsed. */ - time_t (*get_date)(struct mail *mail, int *timezone); - /* Get the full virtual size of mail (IMAP RFC822.SIZE). - Returns (uoff_t)-1 if error occured */ - uoff_t (*get_virtual_size)(struct mail *mail); - /* Get the full physical size of mail. - Returns (uoff_t)-1 if error occured */ - uoff_t (*get_physical_size)(struct mail *mail); +struct mail *mail_alloc(struct mailbox_transaction_context *t, + enum mail_fetch_field wanted_fields, + struct mailbox_header_lookup_ctx *wanted_headers); +void mail_free(struct mail *mail); +int mail_set_seq(struct mail *mail, uint32_t seq); + +/* Get the time message was received (IMAP INTERNALDATE). + Returns (time_t)-1 if error occured. */ +time_t mail_get_received_date(struct mail *mail); +/* Get the Date-header in mail. Timezone is in minutes. + Returns (time_t)-1 if error occured, 0 if field wasn't found or + couldn't be parsed. */ +time_t mail_get_date(struct mail *mail, int *timezone); - /* Get value for single header field */ - const char *(*get_header)(struct mail *mail, const char *field); - /* Returns stream containing specified headers. */ - struct istream * - (*get_headers)(struct mail *mail, - struct mailbox_header_lookup_ctx *headers); - - /* Returns input stream pointing to beginning of message header. - hdr_size and body_size are updated unless they're NULL. */ - struct istream *(*get_stream)(struct mail *mail, - struct message_size *hdr_size, - struct message_size *body_size); +/* Get the full virtual size of mail (IMAP RFC822.SIZE). + Returns (uoff_t)-1 if error occured */ +uoff_t mail_get_virtual_size(struct mail *mail); +/* Get the full physical size of mail. + Returns (uoff_t)-1 if error occured */ +uoff_t mail_get_physical_size(struct mail *mail); - /* Get any of the "special" fields. */ - const char *(*get_special)(struct mail *mail, - enum mail_fetch_field field); +/* Get value for single header field */ +const char *mail_get_header(struct mail *mail, const char *field); +/* Returns stream containing specified headers. */ +struct istream *mail_get_headers(struct mail *mail, + struct mailbox_header_lookup_ctx *headers); +/* Returns input stream pointing to beginning of message header. + hdr_size and body_size are updated unless they're NULL. */ +struct istream *mail_get_stream(struct mail *mail, + struct message_size *hdr_size, + struct message_size *body_size); - /* Update message flags. */ - int (*update_flags)(struct mail *mail, enum modify_type modify_type, - enum mail_flags flags); - /* Update message keywords. */ - int (*update_keywords)(struct mail *mail, enum modify_type modify_type, - struct mail_keywords *keywords); +/* Get any of the "special" fields. */ +const char *mail_get_special(struct mail *mail, enum mail_fetch_field field); - /* Expunge this message. Sequence numbers don't change until commit. */ - int (*expunge)(struct mail *mail); -}; +/* Update message flags. */ +int mail_update_flags(struct mail *mail, enum modify_type modify_type, + enum mail_flags flags); +/* Update message keywords. */ +int mail_update_keywords(struct mail *mail, enum modify_type modify_type, + struct mail_keywords *keywords); + +/* Expunge this message. Sequence numbers don't change until commit. */ +int mail_expunge(struct mail *mail); #endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-storage/mail.c Tue Mar 15 21:01:50 2005 +0200 @@ -0,0 +1,133 @@ +/* Copyright (C) 2002-2003 Timo Sirainen */ + +#include "lib.h" +#include "ioloop.h" +#include "mail-storage-private.h" + +struct mail *mail_alloc(struct mailbox_transaction_context *t, + enum mail_fetch_field wanted_fields, + struct mailbox_header_lookup_ctx *wanted_headers) +{ + return t->box->v.mail_alloc(t, wanted_fields, wanted_headers); +} + +void mail_free(struct mail *mail) +{ + struct mail_private *p = (struct mail_private *)mail; + + return p->v.free(mail); +} + +int mail_set_seq(struct mail *mail, uint32_t seq) +{ + struct mail_private *p = (struct mail_private *)mail; + + return p->v.set_seq(mail, seq); +} + +enum mail_flags mail_get_flags(struct mail *mail) +{ + struct mail_private *p = (struct mail_private *)mail; + + return p->v.get_flags(mail); +} + +const char *const *mail_get_keywords(struct mail *mail) +{ + struct mail_private *p = (struct mail_private *)mail; + + return p->v.get_keywords(mail); +} + +const struct message_part *mail_get_parts(struct mail *mail) +{ + struct mail_private *p = (struct mail_private *)mail; + + return p->v.get_parts(mail); +} + +time_t mail_get_received_date(struct mail *mail) +{ + struct mail_private *p = (struct mail_private *)mail; + + return p->v.get_received_date(mail); +} + +time_t mail_get_date(struct mail *mail, int *timezone) +{ + struct mail_private *p = (struct mail_private *)mail; + + return p->v.get_date(mail, timezone); +} + +uoff_t mail_get_virtual_size(struct mail *mail) +{ + struct mail_private *p = (struct mail_private *)mail; + + return p->v.get_virtual_size(mail); +} + +uoff_t mail_get_physical_size(struct mail *mail) +{ + struct mail_private *p = (struct mail_private *)mail; + + return p->v.get_physical_size(mail); +} + +const char *mail_get_header(struct mail *mail, const char *field) +{ +{ + struct mail_private *p = (struct mail_private *)mail; + + return p->v.get_header(mail, field); +} +} + +struct istream *mail_get_headers(struct mail *mail, + struct mailbox_header_lookup_ctx *headers) +{ +{ + struct mail_private *p = (struct mail_private *)mail; + + return p->v.get_headers(mail, headers); +} +} + +struct istream *mail_get_stream(struct mail *mail, + struct message_size *hdr_size, + struct message_size *body_size) +{ + struct mail_private *p = (struct mail_private *)mail; + + return p->v.get_stream(mail, hdr_size, body_size); +} + +const char *mail_get_special(struct mail *mail, enum mail_fetch_field field) +{ + struct mail_private *p = (struct mail_private *)mail; + + return p->v.get_special(mail, field); +} + +int mail_update_flags(struct mail *mail, enum modify_type modify_type, + enum mail_flags flags) +{ + struct mail_private *p = (struct mail_private *)mail; + + return p->v.update_flags(mail, modify_type, flags); +} + +int mail_update_keywords(struct mail *mail, enum modify_type modify_type, + struct mail_keywords *keywords) +{ + struct mail_private *p = (struct mail_private *)mail; + + return p->v.update_keywords(mail, modify_type, keywords); +} + +int mail_expunge(struct mail *mail) +{ + struct mail_private *p = (struct mail_private *)mail; + + return p->v.expunge(mail); +}
--- a/src/lib-storage/proxy-mail-storage.c Tue Mar 15 20:58:18 2005 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,114 +0,0 @@ -/* Copyright (C) 2003 Timo Sirainen */ - -#include "lib.h" -#include "proxy-mail-storage.h" - -static void _destroy(struct mail_storage *storage) -{ - struct proxy_mail_storage *s = (struct proxy_mail_storage *) storage; - - s->storage->destroy(s->storage); -} - -static void _set_callbacks(struct mail_storage *storage, - struct mail_storage_callbacks *callbacks, - void *context) -{ - struct proxy_mail_storage *s = (struct proxy_mail_storage *) storage; - - s->storage->set_callbacks(s->storage, callbacks, context); -} - -static struct mailbox *_mailbox_open(struct mail_storage *storage, - const char *name, - enum mailbox_open_flags flags) -{ - struct proxy_mail_storage *s = (struct proxy_mail_storage *) storage; - - return s->storage->mailbox_open(s->storage, name, flags); -} - -static int _mailbox_create(struct mail_storage *storage, const char *name, - int only_hierarchy) -{ - struct proxy_mail_storage *s = (struct proxy_mail_storage *) storage; - - return s->storage->mailbox_create(s->storage, name, only_hierarchy); -} - -static int _mailbox_delete(struct mail_storage *storage, const char *name) -{ - struct proxy_mail_storage *s = (struct proxy_mail_storage *) storage; - - return s->storage->mailbox_delete(s->storage, name); -} - -static int _mailbox_rename(struct mail_storage *storage, const char *oldname, - const char *newname) -{ - struct proxy_mail_storage *s = (struct proxy_mail_storage *) storage; - - return s->storage->mailbox_rename(s->storage, oldname, newname); -} - -static struct mailbox_list_context * -_mailbox_list_init(struct mail_storage *storage, - const char *ref, const char *mask, - enum mailbox_list_flags flags) -{ - struct proxy_mail_storage *s = (struct proxy_mail_storage *) storage; - - return s->storage->mailbox_list_init(s->storage, ref, mask, flags); -} - -static int _set_subscribed(struct mail_storage *storage, - const char *name, int set) -{ - struct proxy_mail_storage *s = (struct proxy_mail_storage *) storage; - - return s->storage->set_subscribed(s->storage, name, set); -} - -static int _get_mailbox_name_status(struct mail_storage *storage, - const char *name, - enum mailbox_name_status *status) -{ - struct proxy_mail_storage *s = (struct proxy_mail_storage *) storage; - - return s->storage->get_mailbox_name_status(s->storage, name, status); -} - -static const char *_get_last_error(struct mail_storage *storage, - int *syntax_error) -{ - struct proxy_mail_storage *s = (struct proxy_mail_storage *) storage; - - return s->storage->get_last_error(s->storage, syntax_error); -} - -void proxy_mail_storage_init(struct proxy_mail_storage *proxy, - struct mail_storage *storage) -{ - struct mail_storage *ps = &proxy->proxy_storage; - - proxy->storage = storage; - - ps->name = storage->name; - ps->hierarchy_sep = storage->hierarchy_sep; - - ps->create = storage->create; - ps->autodetect = storage->autodetect; - ps->mailbox_list_deinit = storage->mailbox_list_deinit; - ps->mailbox_list_next = storage->mailbox_list_next; - - ps->destroy = _destroy; - ps->set_callbacks = _set_callbacks; - ps->mailbox_open = _mailbox_open; - ps->mailbox_create = _mailbox_create; - ps->mailbox_delete = _mailbox_delete; - ps->mailbox_rename = _mailbox_rename; - ps->mailbox_list_init = _mailbox_list_init; - ps->set_subscribed = _set_subscribed; - ps->get_mailbox_name_status = _get_mailbox_name_status; - ps->get_last_error = _get_last_error; -}
--- a/src/lib-storage/proxy-mail-storage.h Tue Mar 15 20:58:18 2005 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -#ifndef __PROXY_MAIL_STORAGE_H -#define __PROXY_MAIL_STORAGE_H - -#include "mail-storage-private.h" - -struct proxy_mail_storage { - struct mail_storage proxy_storage; - struct mail_storage *storage; -}; - -void proxy_mail_storage_init(struct proxy_mail_storage *proxy, - struct mail_storage *storage); - -#endif
--- a/src/lib-storage/proxy-mail.c Tue Mar 15 20:58:18 2005 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +0,0 @@ -/* Copyright (C) 2003 Timo Sirainen */ - -#include "lib.h" -#include "proxy-mail.h" - -static enum mail_flags _get_flags(struct mail *mail) -{ - struct proxy_mail *p = (struct proxy_mail *) mail; - - return p->mail->get_flags(p->mail); -} - -static const char *const *_get_keywords(struct mail *mail) -{ - struct proxy_mail *p = (struct proxy_mail *) mail; - - return p->mail->get_keywords(p->mail); -} - -static const struct message_part *_get_parts(struct mail *mail) -{ - struct proxy_mail *p = (struct proxy_mail *) mail; - - return p->mail->get_parts(p->mail); -} - -static time_t _get_received_date(struct mail *mail) -{ - struct proxy_mail *p = (struct proxy_mail *) mail; - - return p->mail->get_received_date(p->mail); -} - -static time_t _get_date(struct mail *mail, int *timezone) -{ - struct proxy_mail *p = (struct proxy_mail *) mail; - - return p->mail->get_date(p->mail, timezone); -} - -static uoff_t _get_virtual_size(struct mail *mail) -{ - struct proxy_mail *p = (struct proxy_mail *) mail; - - return p->mail->get_virtual_size(p->mail); -} - -static uoff_t _get_physical_size(struct mail *mail) -{ - struct proxy_mail *p = (struct proxy_mail *) mail; - - return p->mail->get_physical_size(p->mail); -} - -static const char *_get_header(struct mail *mail, const char *field) -{ - struct proxy_mail *p = (struct proxy_mail *) mail; - - return p->mail->get_header(p->mail, field); -} - -static struct istream * -_get_headers(struct mail *mail, struct mailbox_header_lookup_ctx *headers) -{ - struct proxy_mail *p = (struct proxy_mail *) mail; - - return p->mail->get_headers(p->mail, headers); -} - -static struct istream *_get_stream(struct mail *mail, - struct message_size *hdr_size, - struct message_size *body_size) -{ - struct proxy_mail *p = (struct proxy_mail *) mail; - - return p->mail->get_stream(p->mail, hdr_size, body_size); -} - -static const char *_get_special(struct mail *mail, enum mail_fetch_field field) -{ - struct proxy_mail *p = (struct proxy_mail *) mail; - - return p->mail->get_special(p->mail, field); -} - -static int _update_flags(struct mail *mail, enum modify_type modify_type, - enum mail_flags flags) -{ - struct proxy_mail *p = (struct proxy_mail *) mail; - - return p->mail->update_flags(p->mail, modify_type, flags); -} - -static int _update_keywords(struct mail *mail, enum modify_type modify_type, - struct mail_keywords *keywords) -{ - struct proxy_mail *p = (struct proxy_mail *) mail; - - return p->mail->update_keywords(p->mail, modify_type, keywords); -} - -static int _expunge(struct mail *mail) -{ - struct proxy_mail *p = (struct proxy_mail *) mail; - - return p->mail->expunge(p->mail); -} - -void proxy_mail_init(struct proxy_mail *proxy, struct mail *mail) -{ - struct mail *pm = &proxy->proxy_mail; - - proxy->mail = mail; - - pm->box = mail->box; - - pm->get_flags = _get_flags; - pm->get_keywords = _get_keywords; - pm->get_parts = _get_parts; - pm->get_received_date = _get_received_date; - pm->get_date = _get_date; - pm->get_virtual_size = _get_virtual_size; - pm->get_physical_size = _get_physical_size; - pm->get_header = _get_header; - pm->get_headers = _get_headers; - pm->get_stream = _get_stream; - pm->get_special = _get_special; - pm->update_flags = _update_flags; - pm->update_keywords = _update_keywords; - pm->expunge = _expunge; -} - -void proxy_mail_next(struct proxy_mail *proxy) -{ - proxy->proxy_mail.seq = proxy->mail->seq; - proxy->proxy_mail.uid = proxy->mail->uid; - - proxy->proxy_mail.has_nuls = proxy->mail->has_nuls; - proxy->proxy_mail.has_no_nuls = proxy->mail->has_no_nuls; -}
--- a/src/lib-storage/proxy-mail.h Tue Mar 15 20:58:18 2005 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -#ifndef __PROXY_MAIL_H -#define __PROXY_MAIL_H - -#include "mail-storage.h" - -struct proxy_mail { - struct mail proxy_mail; - struct mail *mail; -}; - -void proxy_mail_init(struct proxy_mail *proxy, struct mail *mail); -void proxy_mail_next(struct proxy_mail *proxy); - -#endif
--- a/src/lib-storage/proxy-mailbox.c Tue Mar 15 20:58:18 2005 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,220 +0,0 @@ -/* Copyright (C) 2003 Timo Sirainen */ - -#include "lib.h" -#include "proxy-mailbox.h" - -static int _is_readonly(struct mailbox *box) -{ - struct proxy_mailbox *p = (struct proxy_mailbox *) box; - - return p->box->is_readonly(p->box); -} - -static int _allow_new_keywords(struct mailbox *box) -{ - struct proxy_mailbox *p = (struct proxy_mailbox *) box; - - return p->box->allow_new_keywords(p->box); -} - -static int _close(struct mailbox *box) -{ - struct proxy_mailbox *p = (struct proxy_mailbox *) box; - - return p->box->close(p->box); -} - -static int _get_status(struct mailbox *box, enum mailbox_status_items items, - struct mailbox_status *status) -{ - struct proxy_mailbox *p = (struct proxy_mailbox *) box; - - return p->box->get_status(p->box, items, status); -} - -static struct mailbox_sync_context * -_sync_init(struct mailbox *box, enum mailbox_sync_flags flags) -{ - struct proxy_mailbox *p = (struct proxy_mailbox *) box; - - return p->box->sync_init(p->box, flags); -} - -static void _notify_changes(struct mailbox *box, unsigned int min_interval, - mailbox_notify_callback_t *callback, void *context) -{ - struct proxy_mailbox *p = (struct proxy_mailbox *) box; - - p->box->notify_changes(box, min_interval, callback, context); -} - -static struct mail *_fetch(struct mailbox_transaction_context *t, uint32_t seq, - enum mail_fetch_field wanted_fields) -{ - struct proxy_mailbox_transaction_context *pt = - (struct proxy_mailbox_transaction_context *)t; - struct proxy_mailbox *pbox = (struct proxy_mailbox *)t->box; - - return pbox->box->fetch(pt->ctx, seq, wanted_fields); -} - -static int _get_uids(struct mailbox *box, uint32_t uid1, uint32_t uid2, - uint32_t *seq1_r, uint32_t *seq2_r) -{ - struct proxy_mailbox *p = (struct proxy_mailbox *) box; - - return p->box->get_uids(p->box, uid1, uid2, seq1_r, seq2_r); -} - -static struct mailbox_header_lookup_ctx * -_header_lookup_init(struct mailbox *box, const char *const headers[]) -{ - struct proxy_mailbox *p = (struct proxy_mailbox *) box; - - return p->box->header_lookup_init(p->box, headers); -} - -static int _search_get_sorting(struct mailbox *box, - enum mail_sort_type *sort_program) -{ - struct proxy_mailbox *p = (struct proxy_mailbox *) box; - - return p->box->search_get_sorting(p->box, sort_program); -} - -static struct mail_search_context * -_search_init(struct mailbox_transaction_context *t, - const char *charset, struct mail_search_arg *args, - const enum mail_sort_type *sort_program, - enum mail_fetch_field wanted_fields, - struct mailbox_header_lookup_ctx *wanted_headers) -{ - struct proxy_mailbox_transaction_context *pt = - (struct proxy_mailbox_transaction_context *)t; - struct proxy_mailbox *pbox = (struct proxy_mailbox *)t->box; - - return pbox->box->search_init(pt->ctx, charset, args, sort_program, - wanted_fields, wanted_headers); -} - -static int _transaction_commit(struct mailbox_transaction_context *t, - enum mailbox_sync_flags flags) -{ - struct proxy_mailbox_transaction_context *pt = - (struct proxy_mailbox_transaction_context *)t; - struct proxy_mailbox *pbox = (struct proxy_mailbox *)t->box; - - return pbox->box->transaction_commit(pt->ctx, flags); -} - -static void _transaction_rollback(struct mailbox_transaction_context *t) -{ - struct proxy_mailbox_transaction_context *pt = - (struct proxy_mailbox_transaction_context *)t; - struct proxy_mailbox *pbox = (struct proxy_mailbox *)t->box; - - pbox->box->transaction_rollback(pt->ctx); -} - -static struct mail_keywords * -_keywords_create(struct mailbox_transaction_context *t, - const char *const keywords[]) -{ - struct proxy_mailbox_transaction_context *pt = - (struct proxy_mailbox_transaction_context *)t; - struct proxy_mailbox *pbox = (struct proxy_mailbox *)t->box; - - return pbox->box->keywords_create(pt->ctx, keywords); -} - -static void _keywords_free(struct mailbox_transaction_context *t, - struct mail_keywords *keywords) -{ - struct proxy_mailbox_transaction_context *pt = - (struct proxy_mailbox_transaction_context *)t; - struct proxy_mailbox *pbox = (struct proxy_mailbox *)t->box; - - pbox->box->keywords_free(pt->ctx, keywords); -} - -static struct mail_save_context * -_save_init(struct mailbox_transaction_context *t, - enum mail_flags flags, struct mail_keywords *keywords, - time_t received_date, int timezone_offset, - const char *from_envelope, struct istream *input, int want_mail) -{ - struct proxy_mailbox_transaction_context *pt = - (struct proxy_mailbox_transaction_context *)t; - struct proxy_mailbox *pbox = (struct proxy_mailbox *)t->box; - - return pbox->box->save_init(pt->ctx, flags, keywords, received_date, - timezone_offset, from_envelope, input, - want_mail); -} - -static int _copy(struct mailbox_transaction_context *t, struct mail *mail, - struct mail **dest_mail_r) -{ - struct proxy_mailbox_transaction_context *pt = - (struct proxy_mailbox_transaction_context *)t; - struct proxy_mailbox *pbox = (struct proxy_mailbox *)t->box; - - return pbox->box->copy(pt->ctx, mail, dest_mail_r); -} - -static int _is_inconsistent(struct mailbox *box) -{ - struct proxy_mailbox *p = (struct proxy_mailbox *) box; - - return p->box->is_inconsistent(p->box); -} - -void proxy_mailbox_init(struct proxy_mailbox *proxy, struct mailbox *box) -{ - struct mailbox *pb = &proxy->proxy_box; - - proxy->box = box; - - pb->name = box->name; - pb->storage = box->storage; - - pb->is_readonly = _is_readonly; - pb->allow_new_keywords = _allow_new_keywords; - pb->close = _close; - pb->get_status = _get_status; - pb->sync_init = _sync_init; - pb->sync_next = box->sync_next; - pb->sync_deinit = box->sync_deinit; - pb->notify_changes = _notify_changes; - pb->fetch = _fetch; - pb->get_uids = _get_uids; - pb->header_lookup_init = _header_lookup_init; - - pb->search_get_sorting = _search_get_sorting; - pb->search_init = _search_init; - pb->search_next = box->search_next; - pb->search_deinit = box->search_deinit; - - pb->transaction_begin = NULL; /* must be implemented */ - pb->transaction_commit = _transaction_commit; - pb->transaction_rollback = _transaction_rollback; - - pb->keywords_create = _keywords_create; - pb->keywords_free = _keywords_free; - - pb->save_init = _save_init; - pb->save_continue = box->save_continue; - pb->save_finish = box->save_finish; - pb->save_cancel = box->save_cancel; - pb->copy = _copy; - - pb->is_inconsistent = _is_inconsistent; -} - -void proxy_transaction_init(struct proxy_mailbox *proxy_box, - struct proxy_mailbox_transaction_context *proxy_ctx, - struct mailbox_transaction_context *ctx) -{ - proxy_ctx->proxy_ctx.box = &proxy_box->proxy_box; - proxy_ctx->ctx = ctx; -}
--- a/src/lib-storage/proxy-mailbox.h Tue Mar 15 20:58:18 2005 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -#ifndef __PROXY_MAILBOX_H -#define __PROXY_MAILBOX_H - -#include "mail-storage-private.h" - -struct proxy_mailbox { - struct mailbox proxy_box; - struct mailbox *box; -}; - -struct proxy_mailbox_transaction_context { - struct mailbox_transaction_context proxy_ctx; - struct mailbox_transaction_context *ctx; -}; - -void proxy_mailbox_init(struct proxy_mailbox *proxy_box, struct mailbox *box); -void proxy_transaction_init(struct proxy_mailbox *proxy_box, - struct proxy_mailbox_transaction_context *proxy_ctx, - struct mailbox_transaction_context *ctx); - -#endif
--- a/src/pop3/client.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/pop3/client.c Tue Mar 15 21:01:50 2005 +0200 @@ -70,9 +70,8 @@ } client->uid_validity = status.uidvalidity; - t = mailbox_transaction_begin(client->mailbox, FALSE); - ctx = mailbox_search_init(t, NULL, &search_arg, NULL, - MAIL_FETCH_VIRTUAL_SIZE, NULL); + t = mailbox_transaction_begin(client->mailbox, 0); + ctx = mailbox_search_init(t, NULL, &search_arg, NULL); if (ctx == NULL) { client_send_storage_error(client); mailbox_transaction_rollback(t); @@ -84,15 +83,16 @@ buffer_set_used_size(message_sizes_buf, 0); failed = FALSE; - while ((mail = mailbox_search_next(ctx)) != NULL) { - uoff_t size = mail->get_virtual_size(mail); + mail = mail_alloc(t, MAIL_FETCH_VIRTUAL_SIZE, NULL); + while (mailbox_search_next(ctx, mail) > 0) { + uoff_t size = mail_get_virtual_size(mail); if (size == (uoff_t)-1) { failed = TRUE; break; } - if ((mail->get_flags(mail) & MAIL_SEEN) != 0) + if ((mail_get_flags(mail) & MAIL_SEEN) != 0) client->last_seen = mail->seq; client->total_size += size; @@ -101,6 +101,7 @@ client->messages_count = message_sizes_buf->used / sizeof(uoff_t); + mail_free(mail); if (mailbox_search_deinit(ctx) < 0) { client_send_storage_error(client); mailbox_transaction_rollback(t);
--- a/src/pop3/commands.c Tue Mar 15 20:58:18 2005 +0200 +++ b/src/pop3/commands.c Tue Mar 15 21:01:50 2005 +0200 @@ -185,6 +185,7 @@ struct mail_search_context *ctx; struct mail *mail; uint32_t idx; + int ret = TRUE; if (client->deleted_bitmask == NULL) return TRUE; @@ -192,18 +193,23 @@ memset(&search_arg, 0, sizeof(search_arg)); search_arg.type = SEARCH_ALL; - ctx = mailbox_search_init(client->trans, NULL, &search_arg, - NULL, 0, NULL); - while ((mail = mailbox_search_next(ctx)) != NULL) { + ctx = mailbox_search_init(client->trans, NULL, &search_arg, NULL); + mail = mail_alloc(client->trans, 0, NULL); + while (mailbox_search_next(ctx, mail) > 0) { idx = mail->seq - 1; if ((client->deleted_bitmask[idx / CHAR_BIT] & 1 << (idx % CHAR_BIT)) != 0) { - if (mail->expunge(mail) < 0) - return FALSE; + if (mail_expunge(mail) < 0) { + ret = FALSE; + break; + } } } + mail_free(mail); - return mailbox_search_deinit(ctx) == 0; + if (mailbox_search_deinit(ctx) < 0) + ret = FALSE; + return ret; } static int cmd_quit(struct client *client, const char *args __attr_unused__) @@ -230,6 +236,7 @@ struct fetch_context { struct mail_search_context *search_ctx; + struct mail *mail; struct istream *stream; uoff_t body_lines; @@ -243,6 +250,7 @@ static void fetch_deinit(struct fetch_context *ctx) { (void)mailbox_search_deinit(ctx->search_ctx); + mail_free(ctx->mail); i_free(ctx); } @@ -342,7 +350,6 @@ static void fetch(struct client *client, unsigned int msgnum, uoff_t body_lines) { struct fetch_context *ctx; - struct mail *mail; ctx = i_new(struct fetch_context, 1); @@ -351,11 +358,15 @@ ctx->search_arg.value.seqset = &ctx->seqset; ctx->search_ctx = mailbox_search_init(client->trans, NULL, - &ctx->search_arg, - NULL, MAIL_FETCH_STREAM_HEADER | - MAIL_FETCH_STREAM_BODY, NULL); - mail = mailbox_search_next(ctx->search_ctx); - ctx->stream = mail == NULL ? NULL : mail->get_stream(mail, NULL, NULL); + &ctx->search_arg, NULL); + ctx->mail = mail_alloc(client->trans, MAIL_FETCH_STREAM_HEADER | + MAIL_FETCH_STREAM_BODY, NULL); + + if (mailbox_search_next(ctx->search_ctx, ctx->mail) <= 0) + ctx->stream = NULL; + else + ctx->stream = mail_get_stream(ctx->mail, NULL, NULL); + if (ctx->stream == NULL) { client_send_line(client, "-ERR Message not found."); fetch_deinit(ctx); @@ -363,9 +374,10 @@ } if (body_lines == (uoff_t)-1 && !no_flag_updates) { - if ((mail->get_flags(mail) & MAIL_SEEN) == 0) { + if ((mail_get_flags(ctx->mail) & MAIL_SEEN) == 0) { /* mark the message seen with RETR command */ - (void)mail->update_flags(mail, MODIFY_ADD, MAIL_SEEN); + (void)mail_update_flags(ctx->mail, + MODIFY_ADD, MAIL_SEEN); } } @@ -414,7 +426,7 @@ /* forget all our seen flag updates as well.. */ mailbox_transaction_rollback(client->trans); - client->trans = mailbox_transaction_begin(client->mailbox, FALSE); + client->trans = mailbox_transaction_begin(client->mailbox, 0); if (enable_last_command) { /* remove all \Seen flags */ @@ -422,12 +434,14 @@ search_arg.type = SEARCH_ALL; search_ctx = mailbox_search_init(client->trans, NULL, - &search_arg, NULL, 0, NULL); - while ((mail = mailbox_search_next(search_ctx)) != NULL) { - if (mail->update_flags(mail, MAIL_SEEN, - MODIFY_REMOVE) < 0) + &search_arg, NULL); + mail = mail_alloc(client->trans, 0, NULL); + while (mailbox_search_next(search_ctx, mail) > 0) { + if (mail_update_flags(mail, MAIL_SEEN, + MODIFY_REMOVE) < 0) break; } + mail_free(mail); (void)mailbox_search_deinit(search_ctx); } @@ -460,6 +474,7 @@ struct cmd_uidl_context { struct mail_search_context *search_ctx; + struct mail *mail; unsigned int message; struct mail_search_arg search_arg; @@ -476,7 +491,6 @@ { '\0', NULL } }; struct var_expand_table *tab; - struct mail *mail; string_t *str; int ret, found = FALSE; @@ -485,10 +499,9 @@ tab[0].value = t_strdup_printf("%u", client->uid_validity); str = str_new(default_pool, 128); - - while ((mail = mailbox_search_next(ctx->search_ctx)) != NULL) { + while (mailbox_search_next(ctx->search_ctx, ctx->mail) > 0) { if (client->deleted) { - uint32_t idx = mail->seq - 1; + uint32_t idx = ctx->mail->seq - 1; if (client->deleted_bitmask[idx / CHAR_BIT] & (1 << (idx % CHAR_BIT))) continue; @@ -497,20 +510,20 @@ t_push(); if ((uidl_keymask & UIDL_UID) != 0) - tab[1].value = dec2str(mail->uid); + tab[1].value = dec2str(ctx->mail->uid); if ((uidl_keymask & UIDL_MD5) != 0) { - tab[2].value = - mail->get_special(mail, MAIL_FETCH_HEADER_MD5); + tab[2].value = mail_get_special(ctx->mail, + MAIL_FETCH_HEADER_MD5); } if ((uidl_keymask & UIDL_FILE_NAME) != 0) { tab[3].value = - mail->get_special(mail, - MAIL_FETCH_UIDL_FILE_NAME); + mail_get_special(ctx->mail, + MAIL_FETCH_UIDL_FILE_NAME); } str_truncate(str, 0); str_printfa(str, ctx->message == 0 ? "%u " : "+OK %u ", - mail->seq); + ctx->mail->seq); var_expand(str, uidl_format, tab); ret = client_send_line(client, "%s", str_c(str)); @@ -528,6 +541,7 @@ str_free(str); /* finished */ + mail_free(ctx->mail); (void)mailbox_search_deinit(ctx->search_ctx); client->cmd = NULL; @@ -567,8 +581,8 @@ wanted_fields |= MAIL_FETCH_HEADER_MD5; ctx->search_ctx = mailbox_search_init(client->trans, NULL, - &ctx->search_arg, NULL, - wanted_fields, NULL); + &ctx->search_arg, NULL); + ctx->mail = mail_alloc(client->trans, wanted_fields, NULL); if (message == 0) { client->cmd = cmd_uidl_callback; client->cmd_context = ctx;