summaryrefslogtreecommitdiffstats
path: root/imap
diff options
context:
space:
mode:
authorThomas Roessler <roessler@does-not-exist.org>2000-08-21 15:42:19 +0000
committerThomas Roessler <roessler@does-not-exist.org>2000-08-21 15:42:19 +0000
commitcbcf88a4a7872274f8c2d979097978313ce02b73 (patch)
tree5b6f33da796c18573728d9c2d1e6e7ab72030ba8 /imap
parent2526f63a480644c2b70494cbbbc3c9ce19f682f7 (diff)
patch-bac.createplus-1
Diffstat (limited to 'imap')
-rw-r--r--imap/browse.c78
-rw-r--r--imap/command.c2
-rw-r--r--imap/imap.c128
-rw-r--r--imap/imap.h2
-rw-r--r--imap/imap_private.h3
-rw-r--r--imap/message.c62
-rw-r--r--imap/util.c13
7 files changed, 192 insertions, 96 deletions
diff --git a/imap/browse.c b/imap/browse.c
index cd3b0470..95ef83d6 100644
--- a/imap/browse.c
+++ b/imap/browse.c
@@ -67,22 +67,22 @@ int imap_browse (char* path, struct browser_state* state)
strfcpy (list_cmd, option (OPTIMAPLSUB) ? "LSUB" : "LIST", sizeof (list_cmd));
if (!(idata = imap_conn_find (&(mx.account), 0)))
- return -1;
+ goto fail;
- if (mx.mbox[0] == '\0')
+ if (!mx.mbox)
{
home_namespace = 1;
mbox[0] = '\0'; /* Do not replace "" with "INBOX" here */
- mx.mbox = ImapHomeNamespace;
+ mx.mbox = safe_strdup(ImapHomeNamespace);
nns = 0;
if (mutt_bit_isset(idata->capabilities,NAMESPACE))
{
mutt_message _("Getting namespaces...");
if (browse_get_namespace (idata, nsbuf, sizeof (nsbuf),
nsi, sizeof (nsi), &nns) != 0)
- return -1;
+ goto fail;
if (browse_verify_namespace (idata, nsi, nns) != 0)
- return -1;
+ goto fail;
}
}
@@ -110,7 +110,7 @@ int imap_browse (char* path, struct browser_state* state)
{
if (imap_parse_list_response (idata, &cur_folder, &noselect,
&noinferiors, &idata->delim) != 0)
- return -1;
+ goto fail;
if (cur_folder)
{
@@ -200,14 +200,14 @@ int imap_browse (char* path, struct browser_state* state)
* server to see if it has descendants. */
dprint (4, (debugfile, "imap_init_browse: adding INBOX\n"));
if (browse_add_list_result (idata, "LIST \"\" \"INBOX\"", state, 0))
- return -1;
+ goto fail;
}
nsup = state->entrylen;
snprintf (buf, sizeof (buf), "%s \"\" \"%s%%\"", list_cmd, mbox);
if (browse_add_list_result (idata, buf, state, 0))
- return -1;
+ goto fail;
qsort(&(state->entry[nsup]),state->entrylen-nsup,sizeof(state->entry[0]),
(int (*)(const void*,const void*)) compare_names);
@@ -223,7 +223,60 @@ int imap_browse (char* path, struct browser_state* state)
}
mutt_clear_error ();
+ FREE (&mx.mbox);
+ return 0;
+
+ fail:
+ FREE (&mx.mbox);
+ return -1;
+}
+
+/* imap_mailbox_create: Prompt for a new mailbox name, and try to create it */
+int imap_mailbox_create (const char* folder)
+{
+ IMAP_DATA* idata;
+ IMAP_MBOX mx;
+ char buf[LONG_STRING];
+ short n;
+
+ if (imap_parse_path (folder, &mx) < 0)
+ {
+ dprint (1, (debugfile, "imap_mailbox_create: Bad starting path %s\n",
+ folder));
+ return -1;
+ }
+
+ if (!(idata = imap_conn_find (&mx.account, M_IMAP_CONN_NONEW)))
+ {
+ dprint (1, (debugfile, "imap_mailbox_create: Couldn't find open connection to %s", mx.account.host));
+ goto fail;
+ }
+
+ strfcpy (buf, NONULL (mx.mbox), sizeof (buf));
+
+ /* append a delimiter if necessary */
+ n = mutt_strlen (buf);
+ if (n && (n < sizeof (buf) - 1) && (buf[n-1] != idata->delim))
+ {
+ buf[n++] = idata->delim;
+ buf[n] = '\0';
+ }
+
+ if (mutt_get_field (_("Create mailbox: "), buf, sizeof (buf), M_FILE) < 0)
+ goto fail;
+
+ if (imap_create_mailbox (idata, buf) < 0)
+ goto fail;
+
+ mutt_message _("Mailbox created.");
+ sleep (1);
+
+ FREE (&mx.mbox);
return 0;
+
+ fail:
+ FREE (&mx.mbox);
+ return -1;
}
static int browse_add_list_result (IMAP_DATA* idata, const char* cmd,
@@ -247,7 +300,10 @@ static int browse_add_list_result (IMAP_DATA* idata, const char* cmd,
{
if (imap_parse_list_response(idata, &name, &noselect, &noinferiors,
&idata->delim) != 0)
+ {
+ FREE (&mx.mbox);
return -1;
+ }
if (name)
{
@@ -262,6 +318,7 @@ static int browse_add_list_result (IMAP_DATA* idata, const char* cmd,
}
while ((mutt_strncmp (idata->buf, idata->seq, SEQLEN) != 0));
+ FREE (&mx.mbox);
return 0;
}
@@ -300,7 +357,10 @@ static void imap_add_folder (char delim, char *folder, int noselect,
* than at scan, since it's so expensive to scan. But that's big changes
* to browser.c */
if (!((regexec (Mask.rx, relpath, 0, NULL, 0) == 0) ^ Mask.not))
+ {
+ FREE (&mx.mbox);
return;
+ }
imap_qualify_path (tmp, sizeof (tmp), &mx, folder, NULL);
(state->entry)[state->entrylen].name = safe_strdup (tmp);
@@ -322,6 +382,8 @@ static void imap_add_folder (char delim, char *folder, int noselect,
(state->entry)[state->entrylen].selectable = !noselect;
(state->entry)[state->entrylen].inferiors = !noinferiors;
(state->entrylen)++;
+
+ FREE (&mx.mbox);
}
static int compare_names(struct folder_file *a, struct folder_file *b)
diff --git a/imap/command.c b/imap/command.c
index a406c942..babde98e 100644
--- a/imap/command.c
+++ b/imap/command.c
@@ -242,11 +242,11 @@ static void cmd_finish (IMAP_DATA* idata)
{
/* read new mail messages */
dprint (2, (debugfile, "cmd_finish: Fetching new mail\n"));
- count = imap_read_headers (idata, idata->ctx->msgcount, count-1)+1;
/* check_status: curs_main uses imap_check_mailbox to detect
* whether the index needs updating */
idata->check_status = IMAP_NEWMAIL_PENDING;
idata->reopen &= ~IMAP_NEWMAIL_PENDING;
+ count = imap_read_headers (idata, idata->ctx->msgcount, count-1)+1;
}
else
{
diff --git a/imap/imap.c b/imap/imap.c
index c122df69..e66878ca 100644
--- a/imap/imap.c
+++ b/imap/imap.c
@@ -45,18 +45,15 @@ static int imap_check_capabilities (IMAP_DATA* idata);
static void imap_set_flag (IMAP_DATA* idata, int aclbit, int flag,
const char* str, char* flags);
-int imap_create_mailbox (CONTEXT* ctx, char* mailbox)
+int imap_create_mailbox (IMAP_DATA* idata, char* mailbox)
{
char buf[LONG_STRING], mbox[LONG_STRING];
imap_munge_mbox_name (mbox, sizeof (mbox), mailbox);
snprintf (buf, sizeof (buf), "CREATE %s", mbox);
- if (imap_exec ((IMAP_DATA*) ctx->data, buf, 0) != 0)
- {
- imap_error ("imap_create_mailbox", CTX_DATA->buf);
+ if (imap_exec (idata, buf, 0) != 0)
return -1;
- }
return 0;
}
@@ -65,14 +62,11 @@ int imap_delete_mailbox (CONTEXT* ctx, char* mailbox)
{
char buf[LONG_STRING], mbox[LONG_STRING];
- imap_quote_string (mbox, sizeof (mbox), mailbox);
+ imap_munge_mbox_name (mbox, sizeof (mbox), mailbox);
snprintf (buf, sizeof (buf), "DELETE %s", mbox);
if (imap_exec ((IMAP_DATA*) ctx->data, buf, 0) != 0)
- {
- imap_error ("imap_delete_mailbox", CTX_DATA->buf);
return -1;
- }
return 0;
}
@@ -475,14 +469,14 @@ int imap_open_mailbox (CONTEXT* ctx)
/* we require a connection which isn't currently in IMAP_SELECTED state */
if (!(idata = imap_conn_find (&(mx.account), M_IMAP_CONN_NOSELECT)))
- return -1;
+ goto fail;
conn = idata->conn;
/* once again the context is new */
ctx->data = idata;
if (idata->status == IMAP_FATAL)
- return -1;
+ goto fail;
/* Clean up path and replace the one in the ctx */
imap_fix_path (idata, mx.mbox, buf, sizeof (buf));
@@ -537,7 +531,7 @@ int imap_open_mailbox (CONTEXT* ctx)
{
dprint (2, (debugfile, "Getting mailbox FLAGS\n"));
if ((pc = imap_get_flags (&(idata->flags), pc)) == NULL)
- return -1;
+ goto fail;
}
}
/* PERMANENTFLAGS are massaged to look like FLAGS, then override FLAGS */
@@ -549,13 +543,13 @@ int imap_open_mailbox (CONTEXT* ctx)
/* skip "OK [PERMANENT" so syntax is the same as FLAGS */
pc += 13;
if ((pc = imap_get_flags (&(idata->flags), pc)) == NULL)
- return -1;
+ goto fail;
}
}
while (rc == IMAP_CMD_CONTINUE);
if (rc != IMAP_CMD_DONE)
- return -1;
+ goto fail;
/* check for READ-ONLY notification */
if (!strncmp (imap_get_qualifier (idata->buf), "[READ-ONLY]", 11))
@@ -595,13 +589,13 @@ int imap_open_mailbox (CONTEXT* ctx)
mutt_error ("%s", s);
idata->state = IMAP_AUTHENTICATED;
sleep (1);
- return -1;
+ goto fail;
}
if (mutt_bit_isset (idata->capabilities, ACL))
{
if (imap_check_acl (idata))
- return -1;
+ goto fail;
}
/* assume we have all rights if ACL is unavailable */
else
@@ -623,7 +617,12 @@ int imap_open_mailbox (CONTEXT* ctx)
count = imap_read_headers (idata, 0, count - 1) + 1;
dprint (1, (debugfile, "imap_open_mailbox(): msgcount is %d\n", ctx->msgcount));
+ FREE (&mx.mbox);
return 0;
+
+ fail:
+ FREE (&mx.mbox);
+ return -1;
}
int imap_open_mailbox_append (CONTEXT *ctx)
@@ -642,7 +641,7 @@ int imap_open_mailbox_append (CONTEXT *ctx)
* ctx is brand new and mostly empty */
if (!(idata = imap_conn_find (&(mx.account), 0)))
- return -1;
+ goto fail;
conn = idata->conn;
ctx->magic = M_IMAP;
@@ -665,7 +664,7 @@ int imap_open_mailbox_append (CONTEXT *ctx)
/* STATUS not supported */
mutt_message _("Unable to append to IMAP mailboxes at this server");
- return -1;
+ goto fail;
}
r = imap_exec (idata, buf, IMAP_CMD_FAIL_OK);
@@ -674,16 +673,21 @@ int imap_open_mailbox_append (CONTEXT *ctx)
/* command failed cause folder doesn't exist */
snprintf (buf, sizeof (buf), _("Create %s?"), mailbox);
if (option (OPTCONFIRMCREATE) && mutt_yesorno (buf, 1) < 1)
- return -1;
+ goto fail;
- if (imap_create_mailbox (ctx, mailbox) < 0)
- return -1;
+ if (imap_create_mailbox (idata, mailbox) < 0)
+ goto fail;
}
else if (r == -1)
/* Hmm, some other failure */
- return -1;
+ goto fail;
+ FREE (&mx.mbox);
return 0;
+
+ fail:
+ FREE (&mx.mbox);
+ return -1;
}
/* imap_logout: Gracefully log out of server. */
@@ -915,12 +919,12 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int* index_hint)
mutt_remove_trailing_ws (flags);
- snprintf (buf, sizeof (buf), "STORE %d -FLAGS.SILENT (%s)",
- ctx->hdrs[n]->index + 1, flags);
+ snprintf (buf, sizeof (buf), "UID STORE %d -FLAGS.SILENT (%s)",
+ HEADER_DATA (ctx->hdrs[n])->uid, flags);
}
else
- snprintf (buf, sizeof (buf), "STORE %d FLAGS.SILENT (%s)",
- ctx->hdrs[n]->index + 1, flags);
+ snprintf (buf, sizeof (buf), "UID STORE %d FLAGS.SILENT (%s)",
+ HEADER_DATA (ctx->hdrs[n])->uid, flags);
/* after all this it's still possible to have no flags, if you
* have no ACL rights */
@@ -964,15 +968,14 @@ void imap_close_mailbox (CONTEXT* ctx)
if (!idata)
return;
- idata->reopen &= IMAP_REOPEN_ALLOW;
-
if ((idata->status != IMAP_FATAL) &&
(idata->state == IMAP_SELECTED) &&
(ctx == idata->ctx))
{
if (!(idata->noclose) && imap_exec (idata, "CLOSE", 0))
imap_error ("CLOSE failed", idata->buf);
-
+
+ idata->reopen &= IMAP_REOPEN_ALLOW;
idata->state = IMAP_AUTHENTICATED;
FREE (&(idata->mailbox));
}
@@ -1001,45 +1004,33 @@ void imap_close_mailbox (CONTEXT* ctx)
*/
int imap_check_mailbox (CONTEXT *ctx, int *index_hint)
{
- static time_t checktime=0;
+ /* overload keyboard timeout to avoid many mailbox checks in a row.
+ * Most users don't like having to wait exactly when they press a key. */
+ static time_t LastCheck = 0;
IMAP_DATA* idata;
- time_t t = 0;
+ time_t now;
idata = (IMAP_DATA*) ctx->data;
- /*
- * gcc thinks it has to warn about uninitialized use
- * of t. This is wrong.
- */
-
- if (ImapCheckTimeout)
- {
- t = time(NULL);
- t -= checktime;
- }
-
- /* TODO: wtf?! */
- if ((ImapCheckTimeout && t >= ImapCheckTimeout)
- || ((idata->reopen & IMAP_REOPEN_ALLOW) && (idata->reopen & ~IMAP_REOPEN_ALLOW)))
- {
- if (ImapCheckTimeout) checktime += t;
+ now = time(NULL);
+ if (now > LastCheck + Timeout) {
+ LastCheck = now;
if (imap_exec (idata, "NOOP", 0) != 0)
{
imap_error ("imap_check_mailbox", idata->buf);
return -1;
}
+ }
- if (idata->check_status & IMAP_NEWMAIL_PENDING)
- {
- idata->check_status &= ~IMAP_NEWMAIL_PENDING;
- return M_NEW_MAIL;
- }
-
- /* TODO: we should be able to detect external changes and return
- * M_REOPENED here. */
+ if (idata->check_status & IMAP_NEWMAIL_PENDING)
+ {
+ idata->check_status &= ~IMAP_NEWMAIL_PENDING;
+ return M_NEW_MAIL;
}
+ /* TODO: we should be able to detect external changes and return
+ * M_REOPENED here. */
return 0;
}
@@ -1071,7 +1062,7 @@ int imap_mailbox_check (char* path, int new)
connflags = M_IMAP_CONN_NONEW;
if (!(idata = imap_conn_find (&(mx.account), connflags)))
- return -1;
+ goto fail;
conn = idata->conn;
imap_fix_path (idata, mx.mbox, buf, sizeof (buf));
@@ -1099,11 +1090,9 @@ int imap_mailbox_check (char* path, int new)
new ? "RECENT" : "MESSAGES");
}
else
- {
/* Server does not support STATUS, and this is not the current mailbox.
* There is no lightweight way to check recent arrivals */
- return -1;
- }
+ goto fail;
imap_cmd_start (idata, buf);
@@ -1128,8 +1117,8 @@ int imap_mailbox_check (char* path, int new)
{
if (*s != '0')
{
- dprint (1, (debugfile, "Mail in %s\n", path));
msgcount = atoi(s);
+ dprint (2, (debugfile, "%d new messages in %s\n", msgcount, path));
}
}
}
@@ -1139,7 +1128,12 @@ int imap_mailbox_check (char* path, int new)
}
while (rc == IMAP_CMD_CONTINUE);
+ FREE (&mx.mbox);
return msgcount;
+
+ fail:
+ FREE (&mx.mbox);
+ return -1;
}
/* all this listing/browsing is a mess. I don't like that name is a pointer
@@ -1227,7 +1221,7 @@ int imap_subscribe (char *path, int subscribe)
return -1;
if (!(idata = imap_conn_find (&(mx.account), 0)))
- return -1;
+ goto fail;
conn = idata->conn;
@@ -1242,9 +1236,14 @@ int imap_subscribe (char *path, int subscribe)
"UNSUBSCRIBE", mbox);
if (imap_exec (idata, buf, 0) < 0)
- return -1;
+ goto fail;
+ FREE (&mx.mbox);
return 0;
+
+ fail:
+ FREE (&mx.mbox);
+ return -1;
}
/* imap_complete: given a partial IMAP folder path, return a string which
@@ -1272,7 +1271,7 @@ int imap_complete(char* dest, size_t dlen, char* path) {
/* don't open a new socket just for completion */
if (!(idata = imap_conn_find (&(mx.account), M_IMAP_CONN_NONEW)))
- return -1;
+ goto fail;
conn = idata->conn;
/* reformat path for IMAP list, and append wildcard */
@@ -1336,8 +1335,11 @@ int imap_complete(char* dest, size_t dlen, char* path) {
imap_qualify_path (dest, dlen, &mx, completion, NULL);
mutt_pretty_mailbox (dest);
+ FREE (&mx.mbox);
return 0;
}
+ fail:
+ FREE (&mx.mbox);
return -1;
}
diff --git a/imap/imap.h b/imap/imap.h
index 99eaacaa..1e26941e 100644
--- a/imap/imap.h
+++ b/imap/imap.h
@@ -32,7 +32,6 @@ typedef struct
/* imap.c */
int imap_check_mailbox (CONTEXT *ctx, int *index_hint);
-int imap_create_mailbox (CONTEXT* idata, char* mailbox);
int imap_close_connection (CONTEXT *ctx);
int imap_delete_mailbox (CONTEXT* idata, char* mailbox);
int imap_open_mailbox (CONTEXT *ctx);
@@ -49,6 +48,7 @@ void imap_disallow_reopen (CONTEXT *ctx);
/* browse.c */
int imap_browse (char* path, struct browser_state* state);
+int imap_mailbox_create (const char* folder);
/* message.c */
int imap_append_message (CONTEXT* ctx, MESSAGE* msg);
diff --git a/imap/imap_private.h b/imap/imap_private.h
index b574ee81..9611890e 100644
--- a/imap/imap_private.h
+++ b/imap/imap_private.h
@@ -44,7 +44,7 @@
#define SEQLEN 5
#define IMAP_REOPEN_ALLOW (1<<0)
-#define IMAP_EXPUNGE_PENDING (1<<1)
+#define IMAP_EXPUNGE_PENDING (1<<1)
#define IMAP_NEWMAIL_PENDING (1<<2)
/* imap_exec flags (see imap_exec) */
@@ -172,6 +172,7 @@ typedef struct
/* -- private IMAP functions -- */
/* imap.c */
+int imap_create_mailbox (IMAP_DATA* idata, char* mailbox);
int imap_make_msg_set (IMAP_DATA* idata, char* buf, size_t buflen, int flag,
int changed);
int imap_open_connection (IMAP_DATA* idata);
diff --git a/imap/message.c b/imap/message.c
index ad25e918..9db78bb1 100644
--- a/imap/message.c
+++ b/imap/message.c
@@ -192,6 +192,7 @@ int imap_read_headers (IMAP_DATA* idata, int msgbegin, int msgend)
int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
{
IMAP_DATA* idata;
+ HEADER* h;
char buf[LONG_STRING];
char path[_POSIX_PATH_MAX];
char *pc;
@@ -293,9 +294,10 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
!ctx->hdrs[msgno]->changed)
{
IMAP_HEADER newh;
- HEADER* h = ctx->hdrs[msgno];
unsigned char readonly;
+ h = ctx->hdrs[msgno];
+
memset (&newh, 0, sizeof (newh));
newh.data = safe_calloc (1, sizeof (IMAP_HEADER_DATA));
@@ -348,23 +350,37 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
/* Update the header information. Previously, we only downloaded a
* portion of the headers, those required for the main display.
*/
+ h = ctx->hdrs[msgno];
rewind (msg->fp);
- mutt_free_envelope (&ctx->hdrs[msgno]->env);
- ctx->hdrs[msgno]->env = mutt_read_rfc822_header (msg->fp, ctx->hdrs[msgno],0, 0);
- ctx->hdrs[msgno]->lines = 0;
+ /* I hate do this here, since it's so low-level, but I'm not sure where
+ * I can abstract it. Problem: the id and subj hashes lose their keys when
+ * mutt_free_envelope gets called, but keep their spots in the hash. This
+ * confuses threading. Alternatively we could try to merge the new
+ * envelope into the old one. Also messy and lowlevel. */
+ if (h->env->message_id)
+ hash_delete (ctx->id_hash, h->env->message_id, h, NULL);
+ if (h->env->real_subj)
+ hash_delete (ctx->subj_hash, h->env->real_subj, h, NULL);
+ mutt_free_envelope (&h->env);
+ h->env = mutt_read_rfc822_header (msg->fp, h, 0, 0);
+ if (h->env->message_id)
+ hash_insert (ctx->id_hash, h->env->message_id, h, 0);
+ if (h->env->real_subj)
+ hash_insert (ctx->subj_hash, h->env->real_subj, h, 1);
+
+ h->lines = 0;
fgets (buf, sizeof (buf), msg->fp);
while (!feof (msg->fp))
{
- ctx->hdrs[msgno]->lines++;
+ h->lines++;
fgets (buf, sizeof (buf), msg->fp);
}
- ctx->hdrs[msgno]->content->length = ftell (msg->fp) -
- ctx->hdrs[msgno]->content->offset;
+ h->content->length = ftell (msg->fp) - h->content->offset;
/* This needs to be done in case this is a multipart message */
#ifdef HAVE_PGP
- ctx->hdrs[msgno]->pgp = pgp_query (ctx->hdrs[msgno]->content);
+ h->pgp = pgp_query (h->content);
#endif /* HAVE_PGP */
mutt_clear_error();
@@ -405,7 +421,7 @@ int imap_append_message (CONTEXT *ctx, MESSAGE *msg)
if ((fp = fopen (msg->path, "r")) == NULL)
{
mutt_perror (msg->path);
- return (-1);
+ goto fail;
}
for (last = EOF, len = 0; (c = fgetc(fp)) != EOF; last = c)
@@ -438,7 +454,7 @@ int imap_append_message (CONTEXT *ctx, MESSAGE *msg)
mutt_error ("%s", pc);
sleep (1);
fclose (fp);
- return (-1);
+ goto fail;
}
mutt_message _("Uploading message ...");
@@ -474,10 +490,15 @@ int imap_append_message (CONTEXT *ctx, MESSAGE *msg)
pc = imap_next_word (pc);
mutt_error ("%s", pc);
sleep (1);
- return (-1);
+ goto fail;
}
+ FREE (&mx.mbox);
return 0;
+
+ fail:
+ FREE (&mx.mbox);
+ return -1;
}
/* imap_copy_messages: use server COPY command to copy messages to another
@@ -510,7 +531,7 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete)
{
dprint (3, (debugfile, "imap_copy_message: %s not same server as %s\n",
dest, ctx->path));
- return 1;
+ goto fail;
}
imap_fix_path (idata, mx.mbox, cmd, sizeof (cmd));
@@ -522,7 +543,7 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete)
if (!rc)
{
dprint (1, (debugfile, "imap_copy_messages: No messages tagged\n"));
- return -1;
+ goto fail;
}
mutt_message (_("Copying %d messages to %s..."), rc, cmd);
}
@@ -543,17 +564,17 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete)
if (strncmp (imap_get_qualifier (idata->buf), "[TRYCREATE]", 11))
{
imap_error ("imap_copy_messages", idata->buf);
- return -1;
+ goto fail;
}
dprint (2, (debugfile, "imap_copy_messages: server suggests TRYCREATE\n"));
snprintf (buf, sizeof (buf), _("Create %s?"), mbox);
if (option (OPTCONFIRMCREATE) && mutt_yesorno (buf, 1) < 1)
{
mutt_clear_error ();
- return -1;
+ goto fail;
}
- if (imap_create_mailbox (ctx, mbox) < 0)
- return -1;
+ if (imap_create_mailbox (idata, mbox) < 0)
+ goto fail;
/* try again */
rc = imap_exec (idata, cmd, 0);
@@ -561,7 +582,7 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete)
if (rc != 0)
{
imap_error ("imap_copy_messages", idata->buf);
- return -1;
+ goto fail;
}
/* cleanup */
@@ -585,7 +606,12 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete)
}
}
+ FREE (&mx.mbox);
return 0;
+
+ fail:
+ FREE (&mx.mbox);
+ return -1;
}
/* imap_add_keywords: concatenate custom IMAP tags to list, if they
diff --git a/imap/util.c b/imap/util.c
index aa64c4a3..51a63112 100644
--- a/imap/util.c
+++ b/imap/util.c
@@ -127,7 +127,8 @@ char *imap_next_word (char *s)
}
/* imap_parse_path: given an IMAP mailbox name, return host, port
- * and a path IMAP servers will recognise. */
+ * and a path IMAP servers will recognise.
+ * mx.mbox is malloc'd, caller must free it */
int imap_parse_path (const char* path, IMAP_MBOX* mx)
{
char tmp[128];
@@ -144,7 +145,7 @@ int imap_parse_path (const char* path, IMAP_MBOX* mx)
return -1;
else
/* walk past closing '}' */
- mx->mbox = strdup (c+1);
+ mx->mbox = safe_strdup (c+1);
/* Defaults */
mx->account.flags = 0;
@@ -161,6 +162,7 @@ int imap_parse_path (const char* path, IMAP_MBOX* mx)
if ((n = sscanf (tmp, "%128[^:/]%128s", mx->account.host, tmp)) < 1)
{
dprint (1, (debugfile, "imap_parse_path: NULL host in %s\n", path));
+ FREE (&mx->mbox);
return -1;
}
@@ -176,6 +178,7 @@ int imap_parse_path (const char* path, IMAP_MBOX* mx)
#endif
{
dprint (1, (debugfile, "imap_parse_path: Unknown connection type in %s\n", path));
+ FREE (&mx->mbox);
return -1;
}
}
@@ -383,12 +386,14 @@ int imap_wait_keepalive (pid_t pid)
sigaction (SIGALRM, &act, &oldalrm);
- alarm (ImapCheckTimeout > 0 ? ImapCheckTimeout : 60);
+ /* RFC 2060 specifies a minimum of 30 minutes before disconnect when in
+ * the AUTHENTICATED state. We'll poll at half that. */
+ alarm (900);
while (waitpid (pid, &rc, 0) < 0 && errno == EINTR)
{
alarm (0); /* cancel a possibly pending alarm */
imap_keepalive ();
- alarm (ImapCheckTimeout > 0 ? ImapCheckTimeout : 60);
+ alarm (900);
}
alarm (0); /* cancel a possibly pending alarm */