imap-fetch.c revision baf1148108b7d9739626b47cc57298c36929586a
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (C) 2002-2004 Timo Sirainen */
1faa520084b901b15d83d3d68baaee2535051defStephan Boschconst struct imap_fetch_handler default_handlers[7];
10962368c30afde135743fd9796122e88a708e87Stephan Boschstatic int imap_fetch_handler_cmp(const void *p1, const void *p2)
10962368c30afde135743fd9796122e88a708e87Stephan Bosch const struct imap_fetch_handler *h1 = p1, *h2 = p2;
10962368c30afde135743fd9796122e88a708e87Stephan Boschvoid imap_fetch_handlers_register(const struct imap_fetch_handler *handlers,
7ebcb054e0d3cc4be54038cbf763ec4189d9725bStephan Bosch fetch_handlers = buffer_create_dynamic(default_pool,
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch buffer_append(fetch_handlers, handlers, sizeof(*handlers) * count);
10962368c30afde135743fd9796122e88a708e87Stephan Bosch data = buffer_get_modifyable_data(fetch_handlers, &size);
10962368c30afde135743fd9796122e88a708e87Stephan Bosch qsort(data, size / sizeof(*handlers), sizeof(*handlers),
10962368c30afde135743fd9796122e88a708e87Stephan Boschstatic int imap_fetch_handler_bsearch(const void *name_p, const void *handler_p)
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch const struct imap_fetch_handler *h = handler_p;
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch return name[i] < 'A' || name[i] >= 'Z' ? 0 : -1;
10962368c30afde135743fd9796122e88a708e87Stephan Boschint imap_fetch_init_handler(struct imap_fetch_context *ctx, const char *arg)
10962368c30afde135743fd9796122e88a708e87Stephan Boschstruct imap_fetch_context *imap_fetch_init(struct client *client)
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch imap_fetch_handlers_register(default_handlers,
10962368c30afde135743fd9796122e88a708e87Stephan Bosch ctx = p_new(client->cmd_pool, struct imap_fetch_context, 1);
10962368c30afde135743fd9796122e88a708e87Stephan Bosch buffer_create_dynamic(client->cmd_pool, 128, (size_t)-1);
10962368c30afde135743fd9796122e88a708e87Stephan Bosch buffer_create_dynamic(client->cmd_pool, 128, (size_t)-1);
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Boschvoid imap_fetch_add_handler(struct imap_fetch_context *ctx,
10962368c30afde135743fd9796122e88a708e87Stephan Bosch const struct imap_fetch_context_handler *handlers;
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch /* don't allow duplicate handlers */
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch handlers = buffer_get_data(ctx->handlers, &size);
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch for (i = 0; i < size; i++) {
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch memset(&h, 0, sizeof(h));
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Boschvoid imap_fetch_begin(struct imap_fetch_context *ctx,
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch if (buffer_get_used_size(ctx->all_headers_buf) != 0 &&
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch ((ctx->fetch_data & (MAIL_FETCH_STREAM_HEADER |
d577bb9027e4ceb19ada88d6884265efa5e16b15Stephan Bosch buffer_append(ctx->all_headers_buf, &null, sizeof(null));
d577bb9027e4ceb19ada88d6884265efa5e16b15Stephan Bosch data = buffer_get_data(ctx->all_headers_buf, NULL);
d577bb9027e4ceb19ada88d6884265efa5e16b15Stephan Bosch ctx->trans = mailbox_transaction_begin(ctx->box, TRUE);
d577bb9027e4ceb19ada88d6884265efa5e16b15Stephan Bosch ctx->select_counter = ctx->client->select_counter;
d577bb9027e4ceb19ada88d6884265efa5e16b15Stephan Bosch mailbox_search_init(ctx->trans, NULL, search_arg, NULL,
6e62aa36a3190ef7193bd86158a4245da49132f0Stephan Bosch const struct imap_fetch_context_handler *handlers;
10962368c30afde135743fd9796122e88a708e87Stephan Bosch handlers = buffer_get_data(ctx->handlers, &size);
10962368c30afde135743fd9796122e88a708e87Stephan Bosch if (o_stream_get_buffer_used_size(ctx->client->output) >=
10962368c30afde135743fd9796122e88a708e87Stephan Bosch ctx->cur_mail = mailbox_search_next(ctx->search_ctx);
10962368c30afde135743fd9796122e88a708e87Stephan Bosch for (; ctx->cur_handler < size; ctx->cur_handler++) {
10962368c30afde135743fd9796122e88a708e87Stephan Bosch if (o_stream_send(ctx->client->output, ")\r\n", 3) < 0) {
1faa520084b901b15d83d3d68baaee2535051defStephan Boschint imap_fetch_deinit(struct imap_fetch_context *ctx)
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch if (mailbox_search_deinit(ctx->search_ctx) < 0)
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch mailbox_header_lookup_deinit(ctx->all_headers_ctx);
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch if (mailbox_transaction_commit(ctx->trans) < 0)
1faa520084b901b15d83d3d68baaee2535051defStephan Boschstatic int fetch_body(struct imap_fetch_context *ctx, struct mail *mail,
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch body = mail->get_special(mail, MAIL_FETCH_IMAP_BODY);
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch if (o_stream_send(ctx->client->output, " ", 1) < 0)
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch if (o_stream_send(ctx->client->output, "BODY (", 6) < 0 ||
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch o_stream_send_str(ctx->client->output, body) < 0 ||
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch o_stream_send(ctx->client->output, ")", 1) < 0)
10962368c30afde135743fd9796122e88a708e87Stephan Boschstatic int fetch_body_init(struct imap_fetch_context *ctx, const char *arg)
10962368c30afde135743fd9796122e88a708e87Stephan Bosch imap_fetch_add_handler(ctx, fetch_body, NULL);
10962368c30afde135743fd9796122e88a708e87Stephan Boschstatic int fetch_bodystructure(struct imap_fetch_context *ctx,
10962368c30afde135743fd9796122e88a708e87Stephan Bosch struct mail *mail, void *context __attr_unused__)
10962368c30afde135743fd9796122e88a708e87Stephan Bosch bodystructure = mail->get_special(mail, MAIL_FETCH_IMAP_BODYSTRUCTURE);
7ebcb054e0d3cc4be54038cbf763ec4189d9725bStephan Bosch if (o_stream_send(ctx->client->output, " ", 1) < 0)
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch if (o_stream_send(ctx->client->output, "BODYSTRUCTURE (", 15) < 0 ||
ba592dc74a004ad47dfe58edcfc1ca7297551e39Phil Carmody o_stream_send_str(ctx->client->output, bodystructure) < 0 ||
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch o_stream_send(ctx->client->output, ")", 1) < 0)
1faa520084b901b15d83d3d68baaee2535051defStephan Boschstatic int fetch_bodystructure_init(struct imap_fetch_context *ctx,
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch ctx->fetch_data |= MAIL_FETCH_IMAP_BODYSTRUCTURE;
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch imap_fetch_add_handler(ctx, fetch_bodystructure, NULL);
1faa520084b901b15d83d3d68baaee2535051defStephan Boschstatic int fetch_envelope(struct imap_fetch_context *ctx, struct mail *mail,
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch envelope = mail->get_special(mail, MAIL_FETCH_IMAP_ENVELOPE);
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch if (o_stream_send(ctx->client->output, " ", 1) < 0)
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch if (o_stream_send(ctx->client->output, "ENVELOPE (", 10) < 0 ||
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch o_stream_send_str(ctx->client->output, envelope) < 0 ||
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch o_stream_send(ctx->client->output, ")", 1) < 0)
1faa520084b901b15d83d3d68baaee2535051defStephan Boschstatic int fetch_envelope_init(struct imap_fetch_context *ctx,
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch imap_fetch_add_handler(ctx, fetch_envelope, NULL);
1faa520084b901b15d83d3d68baaee2535051defStephan Boschstatic int fetch_flags(struct imap_fetch_context *ctx, struct mail *mail,
d577bb9027e4ceb19ada88d6884265efa5e16b15Stephan Bosch if (ctx->flags_update_seen && (flags->flags & MAIL_SEEN) == 0) {
d577bb9027e4ceb19ada88d6884265efa5e16b15Stephan Bosch /* Add \Seen flag */
6e62aa36a3190ef7193bd86158a4245da49132f0Stephan Bosch if (mail->update_flags(mail, &ctx->seen_flag, MODIFY_ADD) < 0)
6e62aa36a3190ef7193bd86158a4245da49132f0Stephan Bosch } else if (ctx->flags_show_only_seen_changes) {
10962368c30afde135743fd9796122e88a708e87Stephan Boschstatic int fetch_flags_init(struct imap_fetch_context *ctx,
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch imap_fetch_add_handler(ctx, fetch_flags, NULL);
1faa520084b901b15d83d3d68baaee2535051defStephan Boschstatic int fetch_internaldate(struct imap_fetch_context *ctx, struct mail *mail,
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch str_printfa(ctx->cur_str, "INTERNALDATE \"%s\" ",
1faa520084b901b15d83d3d68baaee2535051defStephan Boschstatic int fetch_internaldate_init(struct imap_fetch_context *ctx,
1faa520084b901b15d83d3d68baaee2535051defStephan Bosch imap_fetch_add_handler(ctx, fetch_internaldate, NULL);
1faa520084b901b15d83d3d68baaee2535051defStephan Boschstatic int fetch_uid(struct imap_fetch_context *ctx, struct mail *mail,
10962368c30afde135743fd9796122e88a708e87Stephan Bosch str_printfa(ctx->cur_str, "UID %u ", mail->uid);
10962368c30afde135743fd9796122e88a708e87Stephan Boschstatic int fetch_uid_init(struct imap_fetch_context *ctx __attr_unused__,
5968fa8151eecd191b1973b44dd8bec9b75810a6Phil Carmodyconst struct imap_fetch_handler default_handlers[7] = {
10962368c30afde135743fd9796122e88a708e87Stephan Bosch { "BODYSTRUCTURE", fetch_bodystructure_init },