diff options
author | Thomas Roessler <roessler@does-not-exist.org> | 2000-08-21 15:42:19 +0000 |
---|---|---|
committer | Thomas Roessler <roessler@does-not-exist.org> | 2000-08-21 15:42:19 +0000 |
commit | cbcf88a4a7872274f8c2d979097978313ce02b73 (patch) | |
tree | 5b6f33da796c18573728d9c2d1e6e7ab72030ba8 /imap | |
parent | 2526f63a480644c2b70494cbbbc3c9ce19f682f7 (diff) |
patch-bac.createplus-1
Diffstat (limited to 'imap')
-rw-r--r-- | imap/browse.c | 78 | ||||
-rw-r--r-- | imap/command.c | 2 | ||||
-rw-r--r-- | imap/imap.c | 128 | ||||
-rw-r--r-- | imap/imap.h | 2 | ||||
-rw-r--r-- | imap/imap_private.h | 3 | ||||
-rw-r--r-- | imap/message.c | 62 | ||||
-rw-r--r-- | imap/util.c | 13 |
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 */ |