goto bail;
if (irc == IMAP_CMD_RESPOND) {
- if (sasl_decode64(idata->cmd.buf + 2, m_strlen(idata->cmd.buf + 2), buf,
- LONG_STRING - 1, &len) != SASL_OK) {
+ if (sasl_decode64(idata->cmd.buf.data + 2, idata->cmd.buf.len - 2, buf,
+ LONG_STRING - 1, &len) != SASL_OK)
+ {
goto bail;
}
}
if (rc != SASL_OK)
goto bail;
- if (imap_code (idata->cmd.buf)) {
+ if (imap_code(idata->cmd.buf.data)) {
mutt_sasl_setup_conn (idata->conn, saslconn);
return IMAP_AUTH_SUCCESS;
}
mbox[n] = '\0';
}
}
- } while (m_strncmp(idata->cmd.buf, idata->cmd.seq, SEQLEN));
+ } while (m_strncmp(idata->cmd.buf.data, idata->cmd.seq, SEQLEN));
}
/* if we're descending a folder, mark it as current in browser_state */
}
if (imap_rename_mailbox (idata, &mx, newname) < 0) {
- mutt_error (_("Rename failed: %s"), imap_get_qualifier (idata->cmd.buf));
+ mutt_error (_("Rename failed: %s"),
+ imap_get_qualifier(idata->cmd.buf.data));
mutt_sleep (1);
goto fail;
}
imap_add_folder (idata->delim, name, noselect, noinferiors, state,
isparent);
}
- } while ((m_strncmp(idata->cmd.buf, idata->cmd.seq, SEQLEN) != 0));
+ } while ((m_strncmp(idata->cmd.buf.data, idata->cmd.seq, SEQLEN) != 0));
p_delete(&mx.mbox);
return 0;
if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE)
break;
- s = imap_next_word (idata->cmd.buf);
+ s = imap_next_word (idata->cmd.buf.data);
if (ascii_strncasecmp ("NAMESPACE", s, 9) == 0) {
/* There are three sections to the response, User, Other, Shared,
* and maybe more by extension */
&nsi->noinferiors, &delim) != 0)
return -1;
nsi->listable |= (name != NULL);
- } while ((m_strncmp(idata->cmd.buf, idata->cmd.seq, SEQLEN) != 0));
+ } while ((m_strncmp(idata->cmd.buf.data, idata->cmd.seq, SEQLEN) != 0));
}
return 0;
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_BAD;
}
- /* read into buffer, expanding buffer as necessary until we have a full
- * line */
- do {
- if (len == cmd->blen) {
- p_realloc(&cmd->buf, cmd->blen + IMAP_CMD_BUFSIZE);
- cmd->blen = cmd->blen + IMAP_CMD_BUFSIZE;
- }
-
- if (len)
- len--;
-
- c = mutt_socket_readln (cmd->buf + len, cmd->blen - len, idata->conn);
- if (c <= 0) {
- /* cmd_handle_fatal (idata); */
- return IMAP_CMD_BAD;
- }
-
- len += c;
- }
- /* 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 == cmd->blen);
-
- /* don't let one large string make cmd->buf hog memory forever */
- if ((cmd->blen > IMAP_CMD_BUFSIZE) && (len <= IMAP_CMD_BUFSIZE)) {
- p_realloc(&cmd->buf, IMAP_CMD_BUFSIZE);
- cmd->blen = IMAP_CMD_BUFSIZE;
+ buffer_reset(&cmd->buf);
+ if (mutt_socket_readln2(&cmd->buf, idata->conn) < 0) {
+ /* cmd_handle_fatal (idata); */
+ return IMAP_CMD_BAD;
}
- idata->lastread = time (NULL);
+ idata->lastread = time(NULL);
/* handle untagged messages. The caller still gets its shot afterwards. */
- if (!m_strncmp(cmd->buf, "* ", 2) && cmd_handle_untagged (idata))
+ if (!m_strncmp(cmd->buf.data, "* ", 2) && cmd_handle_untagged (idata))
return IMAP_CMD_BAD;
/* server demands a continuation response from us */
- if (cmd->buf[0] == '+')
+ if (cmd->buf.data[0] == '+')
return IMAP_CMD_RESPOND;
/* tagged completion code */
- if (!m_strncmp(cmd->buf, cmd->seq, SEQLEN)) {
+ if (!m_strncmp(cmd->buf.data, cmd->seq, SEQLEN)) {
imap_cmd_finish (idata);
- return imap_code (cmd->buf) ? IMAP_CMD_OK : IMAP_CMD_NO;
+ return imap_code(cmd->buf.data) ? IMAP_CMD_OK : IMAP_CMD_NO;
}
return IMAP_CMD_CONTINUE;
char *pn;
int count;
- s = imap_next_word (idata->cmd.buf);
+ s = imap_next_word (idata->cmd.buf.data);
if ((idata->state == IMAP_SELECTED) && isdigit ((unsigned char) *s)) {
pn = s;
if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE)
break;
- s = imap_next_word (idata->cmd.buf);
+ s = imap_next_word (idata->cmd.buf.data);
if (ascii_strncasecmp ("LIST", s, 4) == 0) {
s = imap_next_word (s);
s = imap_next_word (s);
static int imap_check_capabilities (IMAP_DATA * idata)
{
if (imap_exec (idata, "CAPABILITY", 0) != 0) {
- imap_error ("imap_check_capabilities", idata->cmd.buf);
+ imap_error ("imap_check_capabilities", idata->cmd.buf.data);
return -1;
}
if (!idata) {
/* The current connection is a new connection */
- if (!(idata = imap_new_idata ())) {
- mutt_socket_free (conn);
- return NULL;
- }
-
- conn->data = idata;
+ idata = imap_new_idata();
+ conn->data = idata;
idata->conn = conn;
new = 1;
}
return -1;
}
- if (ascii_strncasecmp ("* OK", idata->cmd.buf, 4) == 0) {
+ if (ascii_strncasecmp ("* OK", idata->cmd.buf.data, 4) == 0) {
/* TODO: Parse new tagged CAPABILITY data (* OK [CAPABILITY...]) */
if (imap_check_capabilities (idata))
goto bail;
goto err_close_conn;
}
}
- else if (ascii_strncasecmp ("* PREAUTH", idata->cmd.buf, 9) == 0) {
+ else if (ascii_strncasecmp ("* PREAUTH", idata->cmd.buf.data, 9) == 0) {
idata->state = IMAP_AUTHENTICATED;
if (imap_check_capabilities (idata) != 0)
goto bail;
if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE)
break;
- pc = idata->cmd.buf + 2;
+ pc = idata->cmd.buf.data + 2;
/* Obtain list of available flags here, may be overridden by a
* PERMANENTFLAGS tag in the OK response */
if (rc == IMAP_CMD_NO) {
char *s;
- s = imap_next_word (idata->cmd.buf); /* skip seq */
+ s = imap_next_word (idata->cmd.buf.data); /* skip seq */
s = imap_next_word (s); /* Skip response */
mutt_error ("%s", s);
mutt_sleep (2);
/* check for READ-ONLY notification */
if (!ascii_strncasecmp
- (imap_get_qualifier (idata->cmd.buf), "[READ-ONLY]", 11)
+ (imap_get_qualifier (idata->cmd.buf.data), "[READ-ONLY]", 11)
&& !mutt_bit_isset (idata->capabilities, ACL)) {
ctx->readonly = 1;
}
idata->status = IMAP_BYE;
imap_cmd_start (idata, "LOGOUT");
while (imap_cmd_step (idata) == IMAP_CMD_CONTINUE);
- p_delete(&idata->cmd.buf);
- p_delete(&idata);
-}
-
-/*
-int imap_close_connection (CONTEXT *ctx)
-{
- if (CTX_DATA->status != IMAP_BYE)
- {
- mutt_message _("Closing connection to IMAP server...");
- imap_logout (CTX_DATA);
- mutt_clear_error ();
- }
- mutt_socket_close (CTX_DATA->conn);
- CTX_DATA->state = IMAP_DISCONNECTED;
- CTX_DATA->conn->data = NULL;
- return 0;
+ imap_free_idata(&idata);
}
-*/
/* imap_set_flag: append str to flags if we currently have permission
* according to aclbit */
err_continue && (*err_continue != M_YES))
{
*err_continue = imap_continue ("imap_sync_message: STORE failed",
- idata->cmd.buf);
+ idata->cmd.buf.data);
if (*err_continue != M_YES)
return -1;
}
/* Set expunge bit so we don't get spurious reopened messages */
idata->reopen |= IMAP_EXPUNGE_EXPECTED;
if (imap_exec (idata, "EXPUNGE", 0) != 0) {
- imap_error (_("imap_sync_mailbox: EXPUNGE failed"), idata->cmd.buf);
+ imap_error (_("imap_sync_mailbox: EXPUNGE failed"), idata->cmd.buf.data);
rc = imap_reconnect (ctx);
goto out;
}
if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE)
break;
- s = imap_next_word (idata->cmd.buf);
+ s = imap_next_word (idata->cmd.buf.data);
if (ascii_strncasecmp ("STATUS", s, 6) == 0) {
s = imap_next_word (s);
/* The mailbox name may or may not be quoted here. We could try to
if (rc != IMAP_CMD_CONTINUE)
return -1;
- s = imap_next_word (idata->cmd.buf);
+ s = imap_next_word (idata->cmd.buf.data);
if ((ascii_strncasecmp ("LIST", s, 4) == 0) ||
(ascii_strncasecmp ("LSUB", s, 4) == 0)) {
*noselect = 0;
}
s = imap_next_word (s); /* name */
if (s && *s == '{') { /* Literal */
- if (imap_get_literal_count (idata->cmd.buf, &bytes) < 0)
+ if (imap_get_literal_count (idata->cmd.buf.data, &bytes) < 0)
return -1;
if (imap_cmd_step (idata) != IMAP_CMD_CONTINUE)
return -1;
- *name = idata->cmd.buf;
+ *name = idata->cmd.buf.data;
}
else
*name = s;
completions++;
}
}
- while (m_strncmp(idata->cmd.seq, idata->cmd.buf, SEQLEN));
+ while (m_strncmp(idata->cmd.seq, idata->cmd.buf.data, SEQLEN));
if (completions) {
/* reformat output */
/* IMAP command structure */
typedef struct {
- char seq[SEQLEN + 1];
- char *buf;
- unsigned int blen;
int state;
+ char seq[SEQLEN + 1];
+ buffer_t buf;
} IMAP_COMMAND;
typedef struct {
unsigned int seqno;
time_t lastread; /* last time we read a command for the server */
/* who knows, one day we may run multiple commands in parallel */
+
IMAP_COMMAND cmd;
/* The following data is all specific to the currently SELECTED mbox */
break;
if ((mfhrc =
- msg_fetch_header_fetch (idata->ctx, &h, idata->cmd.buf, fp)) == -1)
+ msg_fetch_header_fetch (idata->ctx, &h, idata->cmd.buf.data, fp)) == -1)
continue;
else if (mfhrc < 0)
break;
break;
if ((mfhrc =
- msg_fetch_header (idata->ctx, &h, idata->cmd.buf, fp)) == -1)
+ msg_fetch_header (idata->ctx, &h, idata->cmd.buf.data, fp)) == -1)
continue;
else if (mfhrc < 0)
break;
if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE)
break;
- pc = idata->cmd.buf;
+ pc = idata->cmd.buf.data;
pc = imap_next_word (pc);
pc = imap_next_word (pc);
/* pick up trailing line */
if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE)
goto bail;
- pc = idata->cmd.buf;
+ pc = idata->cmd.buf.data;
fetched = 1;
}
if (rc != IMAP_CMD_OK)
goto bail;
- if (!fetched || !imap_code (idata->cmd.buf))
+ if (!fetched || !imap_code (idata->cmd.buf.data))
goto bail;
/* Update the header information. Previously, we only downloaded a
if (rc != IMAP_CMD_RESPOND) {
char *pc;
- pc = vskipspaces(idata->cmd.buf + SEQLEN);
+ pc = vskipspaces(idata->cmd.buf.data + SEQLEN);
pc = imap_next_word (pc);
mutt_error ("%s", pc);
mutt_sleep (1);
rc = imap_cmd_step (idata);
while (rc == IMAP_CMD_CONTINUE);
- if (!imap_code (idata->cmd.buf)) {
+ if (!imap_code (idata->cmd.buf.data)) {
char *pc;
- pc = vskipspaces(idata->cmd.buf + SEQLEN);
+ pc = vskipspaces(idata->cmd.buf.data + SEQLEN);
pc = imap_next_word (pc);
mutt_error ("%s", pc);
mutt_sleep (1);
if (rc == -2) {
/* bail out if command failed for reasons other than nonexistent target */
if (ascii_strncasecmp
- (imap_get_qualifier (idata->cmd.buf), "[TRYCREATE]", 11)) {
- imap_error ("imap_copy_messages", idata->cmd.buf);
+ (imap_get_qualifier (idata->cmd.buf.data), "[TRYCREATE]", 11)) {
+ imap_error ("imap_copy_messages", idata->cmd.buf.data);
goto fail;
}
snprintf (mmbox, sizeof (mmbox), _("Create %s?"), mbox);
rc = imap_exec (idata, cmd.data, 0);
}
if (rc != 0) {
- imap_error ("imap_copy_messages", idata->cmd.buf);
+ imap_error ("imap_copy_messages", idata->cmd.buf.data);
goto fail;
}
}
}
- if (cmd.data)
- p_delete(&cmd.data);
- if (sync_cmd.data)
- p_delete(&sync_cmd.data);
+ p_delete(&cmd.data);
+ p_delete(&sync_cmd.data);
p_delete(&mx.mbox);
return 0;
fail:
- if (cmd.data)
- p_delete(&cmd.data);
- if (sync_cmd.data)
- p_delete(&sync_cmd.data);
+ p_delete(&cmd.data);
+ p_delete(&sync_cmd.data);
p_delete(&mx.mbox);
return -1;
}
if (imap_cmd_step (idata) != IMAP_CMD_CONTINUE)
return rc;
- if (msg_parse_fetch (h, idata->cmd.buf) == -1)
+ if (msg_parse_fetch (h, idata->cmd.buf.data) == -1)
return rc;
}
* Returns NULL on failure (no mem) */
IMAP_DATA *imap_new_idata (void)
{
- return p_new(IMAP_DATA, 1);
+ IMAP_DATA *res = p_new(IMAP_DATA, 1);
+ buffer_init(&res->cmd.buf);
+ return res;
}
/* imap_free_idata: Release and clear storage in an IMAP_DATA structure. */
void imap_free_idata (IMAP_DATA ** idata)
{
- if (!idata)
- return;
-
- p_delete(&(*idata)->capstr);
- string_list_wipe(&(*idata)->flags);
- p_delete(&((*idata)->cmd.buf));
- p_delete(idata);
+ if (*idata) {
+ p_delete(&(*idata)->capstr);
+ string_list_wipe(&(*idata)->flags);
+ buffer_wipe(&((*idata)->cmd.buf));
+ p_delete(idata);
+ }
}
/*