imap-fetch.c revision 88ea893b45d3ed8d68000921db9156c03cbe1b00
5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen/* Copyright (C) 2002-2004 Timo Sirainen */
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainenconst struct imap_fetch_handler default_handlers[7];
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainenstatic int imap_fetch_handler_cmp(const void *p1, const void *p2)
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen const struct imap_fetch_handler *h1 = p1, *h2 = p2;
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainenvoid imap_fetch_handlers_register(const struct imap_fetch_handler *handlers,
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen fetch_handlers = buffer_create_dynamic(default_pool, 128);
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen buffer_append(fetch_handlers, handlers, sizeof(*handlers) * count);
5a0ac2e5ef482016e00575a7dce83f52c1704732Timo Sirainen data = buffer_get_modifyable_data(fetch_handlers, &size);
5a0ac2e5ef482016e00575a7dce83f52c1704732Timo Sirainen qsort(data, size / sizeof(*handlers), sizeof(*handlers),
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainenstatic int imap_fetch_handler_bsearch(const void *name_p, const void *handler_p)
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen const struct imap_fetch_handler *h = handler_p;
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen return name[i] < 'A' || name[i] >= 'Z' ? 0 : -1;
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainenint imap_fetch_init_handler(struct imap_fetch_context *ctx, const char *name,
64055bc6d2ed9e25b3b1db3b5b90d0bdb77cd715Timo Sirainenstruct imap_fetch_context *imap_fetch_init(struct client_command_context *cmd)
beffc30d933c5e134c45cc871852a8427eba7e70Timo Sirainen imap_fetch_handlers_register(default_handlers,
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen ctx = p_new(cmd->pool, struct imap_fetch_context, 1);
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen ctx->all_headers_buf = buffer_create_dynamic(cmd->pool, 128);
beffc30d933c5e134c45cc871852a8427eba7e70Timo Sirainenvoid imap_fetch_add_handler(struct imap_fetch_context *ctx, int buffered,
beffc30d933c5e134c45cc871852a8427eba7e70Timo Sirainen /* partially because of broken clients, but also partially because
beffc30d933c5e134c45cc871852a8427eba7e70Timo Sirainen it potentially can make client implementations faster, we have a
beffc30d933c5e134c45cc871852a8427eba7e70Timo Sirainen buffered parameter which basically means that the handler promises
beffc30d933c5e134c45cc871852a8427eba7e70Timo Sirainen to write the output in ctx->cur_str. The cur_str is then sent to
beffc30d933c5e134c45cc871852a8427eba7e70Timo Sirainen client before calling any non-buffered handlers.
beffc30d933c5e134c45cc871852a8427eba7e70Timo Sirainen We try to keep the handler registration order the same as the
beffc30d933c5e134c45cc871852a8427eba7e70Timo Sirainen client requested them. This is especially useful to get UID
beffc30d933c5e134c45cc871852a8427eba7e70Timo Sirainen returned first, which some clients rely on..
beffc30d933c5e134c45cc871852a8427eba7e70Timo Sirainen const struct imap_fetch_context_handler *handlers;
beffc30d933c5e134c45cc871852a8427eba7e70Timo Sirainen unsigned int i, size;
4afd5082f38342fd688acb5796912329f57dd02cTimo Sirainen /* don't allow duplicate handlers */
a91f2c465f026ca4ebb9e6c8e92800175c0dece6Timo Sirainen for (i = 0; i < size; i++) {
a91f2c465f026ca4ebb9e6c8e92800175c0dece6Timo Sirainen memset(&h, 0, sizeof(h));
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen array_insert(&ctx->handlers, ctx->buffered_handlers_count,
beffc30d933c5e134c45cc871852a8427eba7e70Timo Sirainenvoid imap_fetch_begin(struct imap_fetch_context *ctx,
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen (void)imap_fetch_init_handler(ctx, "FLAGS", NULL);
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen if (buffer_get_used_size(ctx->all_headers_buf) != 0 &&
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen ((ctx->fetch_data & (MAIL_FETCH_STREAM_HEADER |
a91f2c465f026ca4ebb9e6c8e92800175c0dece6Timo Sirainen buffer_append(ctx->all_headers_buf, &null, sizeof(null));
a91f2c465f026ca4ebb9e6c8e92800175c0dece6Timo Sirainen data = buffer_get_data(ctx->all_headers_buf, NULL);
a91f2c465f026ca4ebb9e6c8e92800175c0dece6Timo Sirainen ctx->trans = mailbox_transaction_begin(ctx->box,
a91f2c465f026ca4ebb9e6c8e92800175c0dece6Timo Sirainen ctx->select_counter = ctx->client->select_counter;
a91f2c465f026ca4ebb9e6c8e92800175c0dece6Timo Sirainen ctx->mail = mail_alloc(ctx->trans, ctx->fetch_data,
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen mailbox_search_init(ctx->trans, NULL, search_arg, NULL);
4ce6338bf945cccfff9e4ce7cc6aa2246851b84aTimo Sirainenstatic int imap_fetch_flush_buffer(struct imap_fetch_context *ctx)
a91f2c465f026ca4ebb9e6c8e92800175c0dece6Timo Sirainen const unsigned char *data;
a91f2c465f026ca4ebb9e6c8e92800175c0dece6Timo Sirainen /* there's an extra space at the end if we added any fetch items
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen if (o_stream_send(ctx->client->output, data, len) < 0)
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen const struct imap_fetch_context_handler *handlers;
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen unsigned int size;
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen /* not an error, just lost it. */
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen if (o_stream_get_buffer_used_size(ctx->client->output) >=
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen for (; ctx->cur_handler < size; ctx->cur_handler++) {
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen /* first non-buffered handler.
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen flush the buffer. */
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen /* not an error, just lost it. */
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen /* no non-buffered handlers */
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen if (o_stream_send(ctx->client->output, ")\r\n", 3) < 0)
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainenint imap_fetch_deinit(struct imap_fetch_context *ctx)
f89cb43088c8b46d12d66ac924724b53ab14ce66Timo Sirainen if (o_stream_send(ctx->client->output, ")\r\n", 3) < 0)
const char *body;
return TRUE;
const char *bodystructure;
return TRUE;
const char *envelope;
return TRUE;
const char *const *keywords;
return TRUE;
return TRUE;
return TRUE;