diff options
Diffstat (limited to 'imap4d/copy.c')
-rw-r--r-- | imap4d/copy.c | 54 |
1 files changed, 39 insertions, 15 deletions
diff --git a/imap4d/copy.c b/imap4d/copy.c index 2c688921d..56e9fc90a 100644 --- a/imap4d/copy.c +++ b/imap4d/copy.c @@ -21,34 +21,57 @@ * copy messages in argv[2] to mailbox in argv[3] */ -/* FIXME if the mailbox is the one selecte we should send notif. */ int imap4d_copy (struct imap4d_command *command, char *arg) { + int rc; + char buffer[64]; + + if (! (command->states & state)) + return util_finish (command, RESP_BAD, "Wrong state"); + + rc = imap4d_copy0 (arg, 0, buffer, sizeof buffer); + if (rc == RESP_NONE) + { + /* Reset the state ourself. */ + int new_state = (rc == RESP_OK) ? command->success : command->failure; + if (new_state != STATE_NONE) + state = new_state; + return util_send ("%s %s\r\n", command->tag, buffer); + } + return util_finish (command, rc, buffer); +} + +int +imap4d_copy0 (char *arg, int isuid, char *resp, size_t resplen) +{ int status; char *msgset; char *name; char *mailbox_name; const char *delim = "/"; char *sp = NULL; - int *set = NULL; + size_t *set = NULL; size_t n = 0; mailbox_t cmbox = NULL; - if (! (command->states & state)) - return util_finish (command, RESP_BAD, "Wrong state"); - msgset = util_getword (arg, &sp); name = util_getword (NULL, &sp); util_unquote (&name); if (!msgset || !name || *name == '\0') - return util_finish (command, RESP_BAD, "Too few args"); + { + snprintf (resp, resplen, "Too few args"); + return RESP_BAD; + } /* Get the message numbers in set[]. */ - status = util_msgset (msgset, &set, &n, 0); + status = util_msgset (msgset, &set, &n, isuid); if (status != 0) - return util_finish (command, RESP_BAD, "Bogus number set"); + { + snprintf (resp, resplen, "Bogus number set"); + return RESP_BAD; + } if (strcasecmp (name, "INBOX") == 0) { @@ -71,7 +94,8 @@ imap4d_copy (struct imap4d_command *command, char *arg) for (i = 0; i < n; i++) { message_t msg = NULL; - mailbox_get_message (mbox, set[i], &msg); + size_t msgno = (isuid) ? uid_to_msgno (set[i]) : set[i]; + mailbox_get_message (mbox, msgno, &msg); mailbox_append_message (cmbox, msg); } mailbox_close (cmbox); @@ -82,16 +106,16 @@ imap4d_copy (struct imap4d_command *command, char *arg) free (mailbox_name); if (status == 0) - return util_finish (command, RESP_OK, "Completed"); - - /* Since we do not call util_finish, reset the state ourself. */ - if (command->failure != STATE_NONE) - state = command->failure; + { + snprintf (resp, resplen, "Completed"); + return RESP_OK; + } /* Unless it is certain that the destination mailbix can not be created, the server MUST send the response code "[TRYCREATE]" as the prefix of the text of the tagged NO response. This gives a hint to the client that it can attempt a CREATE command and retry the copy if the CREATE is successful. */ - return util_send ("%s NO [TRYCREATE] failed\r\n", command->tag); + snprintf (resp, resplen, "NO [TRYCREATE] failed"); + return RESP_NONE; } |