Mercurial > dovecot > core-2.2
view src/imap/cmd-store.c @ 2322:aae574ed7f4c HEAD
Broke mailbox_sync() into iterator.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 12 Jul 2004 14:35:50 +0300 |
parents | 4dec6a3d79fd |
children | ab170ee24eb2 |
line wrap: on
line source
/* Copyright (C) 2002 Timo Sirainen */ #include "common.h" #include "str.h" #include "commands.h" #include "imap-search.h" #include "imap-util.h" static int get_modify_type(struct client *client, const char *item, enum modify_type *modify_type, int *silent) { if (*item == '+') { *modify_type = MODIFY_ADD; item++; } else if (*item == '-') { *modify_type = MODIFY_REMOVE; item++; } else { *modify_type = MODIFY_REPLACE; } if (strncasecmp(item, "FLAGS", 5) != 0) { client_send_tagline(client, t_strconcat( "NO Invalid item ", item, NULL)); return FALSE; } *silent = strcasecmp(item+5, ".SILENT") == 0; if (!*silent && item[5] != '\0') { client_send_tagline(client, t_strconcat( "NO Invalid item ", item, NULL)); return FALSE; } return TRUE; } static int mail_send_flags(struct client *client, struct mail *mail) { const struct mail_full_flags *flags; string_t *str; flags = mail->get_flags(mail); if (flags == NULL) return FALSE; t_push(); str = t_str_new(128); str_printfa(str, "* %u FETCH (FLAGS (", mail->seq); imap_write_flags(str, flags); if (client->cmd_uid) str_printfa(str, ") UID %u)", mail->uid); else str_append(str, "))"); client_send_line(client, str_c(str)); t_pop(); return TRUE; } int cmd_store(struct client *client) { struct imap_arg *args; struct mail_full_flags flags; enum modify_type modify_type; struct mailbox *box; struct mail_search_arg *search_arg; struct mail_search_context *search_ctx; struct mailbox_transaction_context *t; struct mail *mail; const char *messageset, *item; int silent, modify, failed = FALSE; if (!client_read_args(client, 0, 0, &args)) return FALSE; if (!client_verify_open_mailbox(client)) return TRUE; /* validate arguments */ messageset = imap_arg_string(&args[0]); item = imap_arg_string(&args[1]); if (messageset == NULL || item == NULL) { client_send_command_error(client, "Invalid arguments."); return TRUE; } if (!get_modify_type(client, item, &modify_type, &silent)) return TRUE; if (args[2].type == IMAP_ARG_LIST) { if (!client_parse_mail_flags(client, IMAP_ARG_LIST(&args[2])->args, &client->keywords, &flags)) return TRUE; } else { if (!client_parse_mail_flags(client, args+2, &client->keywords, &flags)) return TRUE; } box = client->mailbox; search_arg = imap_search_get_arg(client, messageset, client->cmd_uid); if (search_arg == NULL) return TRUE; t = mailbox_transaction_begin(box, silent); if (!mailbox_is_readonly(box)) modify = TRUE; else { /* flag changes will fail, notify client about them */ modify = FALSE; } search_ctx = failed ? NULL : mailbox_search_init(t, NULL, search_arg, NULL, MAIL_FETCH_FLAGS, NULL); if (search_ctx == NULL) failed = TRUE; else { failed = FALSE; while ((mail = mailbox_search_next(search_ctx)) != NULL) { if (modify) { if (mail->update_flags(mail, &flags, modify_type) < 0) { failed = TRUE; break; } } else { if (!mail_send_flags(client, mail)) { failed = TRUE; break; } } } } if (mailbox_search_deinit(search_ctx) < 0) failed = TRUE; if (failed) mailbox_transaction_rollback(t); else { if (mailbox_transaction_commit(t) < 0) failed = TRUE; } if (!failed) { if (client->cmd_uid) client_sync_full_fast(client); else client_sync_without_expunges(client); client_send_tagline(client, "OK Store completed."); } else { client_send_storage_error(client, mailbox_get_storage(box)); } return TRUE; }