diff options
Diffstat (limited to 'imap/command.c')
-rw-r--r-- | imap/command.c | 93 |
1 files changed, 51 insertions, 42 deletions
diff --git a/imap/command.c b/imap/command.c index f26af035..b3c3029a 100644 --- a/imap/command.c +++ b/imap/command.c @@ -1,7 +1,7 @@ /* * Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu> * Copyright (C) 1996-9 Brandon Long <blong@fiction.net> - * Copyright (C) 1999-2000 Brendan Cully <brendan@kublai.com> + * Copyright (C) 1999-2001 Brendan Cully <brendan@kublai.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,7 +35,7 @@ static void cmd_finish (IMAP_DATA* idata); static void cmd_handle_fatal (IMAP_DATA* idata); static int cmd_handle_untagged (IMAP_DATA* idata); -static void cmd_make_sequence (char* buf, size_t buflen); +static void cmd_make_sequence (IMAP_DATA* idata); static void cmd_parse_capabilities (IMAP_DATA* idata, char* s); static void cmd_parse_expunge (IMAP_DATA* idata, char* s); static void cmd_parse_myrights (IMAP_DATA* idata, char* s); @@ -62,25 +62,25 @@ int imap_cmd_start (IMAP_DATA* idata, const char* cmd) { char* out; int outlen; - int rc = 0; + int rc; if (idata->status == IMAP_FATAL) { cmd_handle_fatal (idata); - return IMAP_CMD_FAIL; + return IMAP_CMD_BAD; } - cmd_make_sequence (idata->seq, sizeof (idata->seq)); + cmd_make_sequence (idata); /* seq, space, cmd, \r\n\0 */ - outlen = strlen (idata->seq) + strlen (cmd) + 4; + outlen = strlen (idata->cmd.seq) + strlen (cmd) + 4; out = (char*) safe_malloc (outlen); - snprintf (out, outlen, "%s %s\r\n", idata->seq, cmd); + snprintf (out, outlen, "%s %s\r\n", idata->cmd.seq, cmd); rc = mutt_socket_write (idata->conn, out); FREE (&out); - return (rc < 0) ? IMAP_CMD_FAIL : 0; + return (rc < 0) ? IMAP_CMD_BAD : 0; } /* imap_cmd_step: Reads server responses from an IMAP command, detects @@ -89,33 +89,35 @@ int imap_cmd_start (IMAP_DATA* idata, const char* cmd) * large!). */ int imap_cmd_step (IMAP_DATA* idata) { + IMAP_COMMAND* cmd = &idata->cmd; unsigned int len = 0; int c; if (idata->status == IMAP_FATAL) { cmd_handle_fatal (idata); - return IMAP_CMD_FAIL; + return IMAP_CMD_BAD; } /* read into buffer, expanding buffer as necessary until we have a full * line */ do { - if (len == idata->blen) + if (len == cmd->blen) { - safe_realloc ((void**) &idata->buf, idata->blen + IMAP_CMD_BUFSIZE); - idata->blen = idata->blen + IMAP_CMD_BUFSIZE; - dprint (3, (debugfile, "imap_cmd_step: grew buffer to %u bytes\n", idata->blen)); + safe_realloc ((void**) &cmd->buf, cmd->blen + IMAP_CMD_BUFSIZE); + cmd->blen = cmd->blen + IMAP_CMD_BUFSIZE; + dprint (3, (debugfile, "imap_cmd_step: grew buffer to %u bytes\n", + cmd->blen)); } - if ((c = mutt_socket_readln (idata->buf + len, idata->blen - len, + if ((c = mutt_socket_readln (cmd->buf + len, cmd->blen - len, idata->conn)) < 0) { dprint (1, (debugfile, "imap_cmd_step: Error while reading server response, closing connection.\n")); mutt_socket_close (idata->conn); idata->status = IMAP_FATAL; - return IMAP_CMD_FAIL; + return IMAP_CMD_BAD; } len += c; @@ -123,30 +125,32 @@ int imap_cmd_step (IMAP_DATA* idata) /* if we've read all the way to the end of the buffer, we haven't read a * full line (mutt_socket_readln strips the \r, so we always have at least * one character free when we've read a full line) */ - while (len == idata->blen); + while (len == cmd->blen); - /* don't let one large string make idata->buf hog memory forever */ - if ((idata->blen > IMAP_CMD_BUFSIZE) && (len <= IMAP_CMD_BUFSIZE)) + /* don't let one large string make cmd->buf hog memory forever */ + if ((cmd->blen > IMAP_CMD_BUFSIZE) && (len <= IMAP_CMD_BUFSIZE)) { - safe_realloc ((void**) &idata->buf, IMAP_CMD_BUFSIZE); - idata->blen = IMAP_CMD_BUFSIZE; - dprint (3, (debugfile, "imap_cmd_step: shrank buffer to %u bytes\n", idata->blen)); + safe_realloc ((void**) &cmd->buf, IMAP_CMD_BUFSIZE); + cmd->blen = IMAP_CMD_BUFSIZE; + dprint (3, (debugfile, "imap_cmd_step: shrank buffer to %u bytes\n", cmd->blen)); } /* handle untagged messages. The caller still gets its shot afterwards. */ - if (!strncmp (idata->buf, "* ", 2) && + if (!strncmp (cmd->buf, "* ", 2) && cmd_handle_untagged (idata)) - return IMAP_CMD_FAIL; + return IMAP_CMD_BAD; /* server demands a continuation response from us */ - if (!strncmp (idata->buf, "+ ", 2)) + if (!strncmp (cmd->buf, "+ ", 2)) + { return IMAP_CMD_RESPOND; + } /* tagged completion code */ - if (!mutt_strncmp (idata->buf, idata->seq, SEQLEN)) + if (!mutt_strncmp (cmd->buf, cmd->seq, SEQLEN)) { cmd_finish (idata); - return imap_code (idata->buf) ? IMAP_CMD_DONE : IMAP_CMD_NO; + return imap_code (cmd->buf) ? IMAP_CMD_OK : IMAP_CMD_NO; } return IMAP_CMD_CONTINUE; @@ -181,11 +185,11 @@ int imap_exec (IMAP_DATA* idata, const char* cmd, int flags) } /* create sequence for command */ - cmd_make_sequence (idata->seq, sizeof (idata->seq)); + cmd_make_sequence (idata); /* seq, space, cmd, \r\n\0 */ - outlen = strlen (idata->seq) + strlen (cmd) + 4; + outlen = strlen (idata->cmd.seq) + strlen (cmd) + 4; out = (char*) safe_malloc (outlen); - snprintf (out, outlen, "%s %s\r\n", idata->seq, cmd); + snprintf (out, outlen, "%s %s\r\n", idata->cmd.seq, cmd); rc = mutt_socket_write_d (idata->conn, out, flags & IMAP_CMD_PASS ? IMAP_LOG_PASS : IMAP_LOG_CMD); @@ -201,15 +205,15 @@ int imap_exec (IMAP_DATA* idata, const char* cmd, int flags) if (rc == IMAP_CMD_NO && (flags & IMAP_CMD_FAIL_OK)) return -2; - if (rc != IMAP_CMD_DONE) + if (rc != IMAP_CMD_OK) { char *pc; if (flags & IMAP_CMD_FAIL_OK) return -2; - dprint (1, (debugfile, "imap_exec: command failed: %s\n", idata->buf)); - pc = idata->buf; + dprint (1, (debugfile, "imap_exec: command failed: %s\n", idata->cmd.buf)); + pc = idata->cmd.buf; pc = imap_next_word (pc); mutt_error ("%s", pc); sleep (2); @@ -220,16 +224,23 @@ int imap_exec (IMAP_DATA* idata, const char* cmd, int flags) return 0; } +/* imap_cmd_running: Returns whether an IMAP command is in progress. */ +int imap_cmd_running (IMAP_DATA* idata) +{ + if (idata->cmd.state == IMAP_CMD_CONTINUE || + idata->cmd.state == IMAP_CMD_RESPOND) + return 1; + + return 0; +} + /* cmd_finish: When the caller has finished reading command responses, * it must call this routine to perform cleanup (eg fetch new mail if * detected, do expunge). Called automatically by imap_cmd_step */ static void cmd_finish (IMAP_DATA* idata) { if (!(idata->state == IMAP_SELECTED) || idata->ctx->closing) - { - mutt_clear_error (); return; - } if ((idata->reopen & IMAP_REOPEN_ALLOW) && (idata->reopen & (IMAP_EXPUNGE_PENDING|IMAP_NEWMAIL_PENDING))) @@ -275,7 +286,7 @@ static int cmd_handle_untagged (IMAP_DATA* idata) char* pn; int count; - s = imap_next_word (idata->buf); + s = imap_next_word (idata->cmd.buf); if ((idata->state == IMAP_SELECTED) && isdigit (*s)) { @@ -360,14 +371,12 @@ static int cmd_handle_untagged (IMAP_DATA* idata) } /* cmd_make_sequence: make a tag suitable for starting an IMAP command */ -static void cmd_make_sequence (char* buf, size_t buflen) +static void cmd_make_sequence (IMAP_DATA* idata) { - static int sequence = 0; - - snprintf (buf, buflen, "a%04d", sequence++); + snprintf (idata->cmd.seq, sizeof (idata->cmd.seq), "a%04d", idata->seqno++); - if (sequence > 9999) - sequence = 0; + if (idata->seqno > 9999) + idata->seqno = 0; } /* cmd_parse_capabilities: set capability bits according to CAPABILITY |