X-Git-Url: https://git.llucax.com/software/mutt-debian.git/blobdiff_plain/19304f7c526fbe36ba0db2fb80bcaf3bd974d81d..9275549093fd4bae96f4119e7b66dd3cc6478e78:/imap/util.c diff --git a/imap/util.c b/imap/util.c index 45e5673..b38268e 100644 --- a/imap/util.c +++ b/imap/util.c @@ -1,22 +1,22 @@ /* * Copyright (C) 1996-8 Michael R. Elkins * Copyright (C) 1996-9 Brandon Long - * Copyright (C) 1999-2008 Brendan Cully - * + * Copyright (C) 1999-2009 Brendan Cully + * * 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 * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ + */ /* general IMAP utility functions */ @@ -54,6 +54,7 @@ int imap_expand_path (char* path, size_t len) { IMAP_MBOX mx; + IMAP_DATA* idata; ciss_url_t url; char fixedpath[LONG_STRING]; int rc; @@ -61,8 +62,9 @@ int imap_expand_path (char* path, size_t len) if (imap_parse_path (path, &mx) < 0) return -1; + idata = imap_conn_find (&mx.account, M_IMAP_CONN_NONEW); mutt_account_tourl (&mx.account, &url); - imap_fix_path(NULL, mx.mbox, fixedpath, sizeof (fixedpath)); + imap_fix_path (idata, mx.mbox, fixedpath, sizeof (fixedpath)); url.path = fixedpath; rc = url_ciss_tostring (&url, path, len, U_DECODE_PASSWD); @@ -127,6 +129,8 @@ HEADER* imap_hcache_get (IMAP_DATA* idata, unsigned int uid) { if (*uv == idata->uid_validity) h = mutt_hcache_restore ((unsigned char*)uv, NULL); + else + dprint (3, (debugfile, "hcache uidvalidity mismatch: %u", *uv)); FREE (&uv); } @@ -224,7 +228,7 @@ int imap_parse_path (const char* path, IMAP_MBOX* mx) else /* walk past closing '}' */ mx->mbox = safe_strdup (c+1); - + if ((c = strrchr (tmp, '@'))) { *c = '\0'; @@ -232,14 +236,14 @@ int imap_parse_path (const char* path, IMAP_MBOX* mx) strfcpy (tmp, c+1, sizeof (tmp)); mx->account.flags |= M_ACCT_USER; } - + if ((n = sscanf (tmp, "%127[^:/]%127s", mx->account.host, tmp)) < 1) { dprint (1, (debugfile, "imap_parse_path: NULL host in %s\n", path)); FREE (&mx->mbox); return -1; } - + if (n > 1) { if (sscanf (tmp, ":%hu%127s", &(mx->account.port), tmp) >= 1) mx->account.flags |= M_ACCT_PORT; @@ -266,10 +270,28 @@ int imap_parse_path (const char* path, IMAP_MBOX* mx) /* silly helper for mailbox name string comparisons, because of INBOX */ int imap_mxcmp (const char* mx1, const char* mx2) { + char* b1; + char* b2; + int rc; + + if (!mx1 || !*mx1) + mx1 = "INBOX"; + if (!mx2 || !*mx2) + mx2 = "INBOX"; if (!ascii_strcasecmp (mx1, "INBOX") && !ascii_strcasecmp (mx2, "INBOX")) return 0; - - return mutt_strcmp (mx1, mx2); + + b1 = safe_malloc (strlen (mx1) + 1); + b2 = safe_malloc (strlen (mx2) + 1); + + imap_fix_path (NULL, mx1, b1, strlen (mx1) + 1); + imap_fix_path (NULL, mx2, b2, strlen (mx2) + 1); + + rc = mutt_strcmp (b1, b2); + FREE (&b1); + FREE (&b2); + + return rc; } /* imap_pretty_mailbox: called by mutt_pretty_mailbox to make IMAP paths @@ -296,7 +318,7 @@ void imap_pretty_mailbox (char* path) { if (! hlen) home_match = 1; - else + else if (ImapDelimChars) for (delim = ImapDelimChars; *delim != '\0'; delim++) if (target.mbox[hlen] == *delim) home_match = 1; @@ -389,25 +411,27 @@ void imap_free_idata (IMAP_DATA** idata) * are not required to do this. * Moreover, IMAP servers may dislike the path ending with the delimiter. */ -char *imap_fix_path (IMAP_DATA *idata, char *mailbox, char *path, +char *imap_fix_path (IMAP_DATA *idata, const char *mailbox, char *path, size_t plen) { int i = 0; - char delim; - + char delim = '\0'; + if (idata) delim = idata->delim; - else if (ImapDelimChars && ImapDelimChars[0]) - delim = ImapDelimChars[0]; - else - delim = '/'; while (mailbox && *mailbox && i < plen - 1) { - if (strchr(ImapDelimChars, *mailbox) || *mailbox == delim) + if ((ImapDelimChars && strchr(ImapDelimChars, *mailbox)) + || (delim && *mailbox == delim)) { - while (*mailbox && - (strchr(ImapDelimChars, *mailbox) || *mailbox == delim)) + /* use connection delimiter if known. Otherwise use user delimiter */ + if (!idata) + delim = *mailbox; + + while (*mailbox + && ((ImapDelimChars && strchr(ImapDelimChars, *mailbox)) + || (delim && *mailbox == delim))) mailbox++; path[i] = delim; } @@ -514,7 +538,7 @@ time_t imap_parse_date (char *s) struct tm t; time_t tz; - t.tm_mday = (s[0] == ' '? s[1] - '0' : (s[0] - '0') * 10 + (s[1] - '0')); + t.tm_mday = (s[0] == ' '? s[1] - '0' : (s[0] - '0') * 10 + (s[1] - '0')); s += 2; if (*s != '-') return 0; @@ -556,6 +580,21 @@ time_t imap_parse_date (char *s) return (mutt_mktime (&t, 0) + tz); } +/* format date in IMAP style: DD-MMM-YYYY HH:MM:SS +ZZzz. + * Caller should provide a buffer of IMAP_DATELEN bytes */ +void imap_make_date (char *buf, time_t timestamp) +{ + struct tm* tm = localtime (×tamp); + time_t tz = mutt_local_tz (timestamp); + + tz /= 60; + + snprintf (buf, IMAP_DATELEN, "%02d-%s-%d %02d:%02d:%02d %+03d%02d", + tm->tm_mday, Months[tm->tm_mon], tm->tm_year + 1900, + tm->tm_hour, tm->tm_min, tm->tm_sec, + (int) tz / 60, (int) abs (tz) % 60); +} + /* imap_qualify_path: make an absolute IMAP folder target, given IMAP_MBOX * and relative path. */ void imap_qualify_path (char *dest, size_t len, IMAP_MBOX *mx, char* path) @@ -582,7 +621,7 @@ void imap_quote_string (char *dest, size_t dlen, const char *src) *pt++ = '"'; /* save room for trailing quote-char */ dlen -= 2; - + for (; *s && dlen; s++) { if (strchr (quote, *s)) @@ -662,7 +701,7 @@ void imap_unmunge_mbox_name (char *s) imap_utf7_decode (&buf); strncpy (s, buf, strlen (s)); } - + FREE (&buf); } @@ -688,10 +727,10 @@ int imap_wordcasecmp(const char *a, const char *b) return ascii_strcasecmp(a, tmp); } -/* +/* * Imap keepalive: poll the current folder to keep the * connection alive. - * + * */ static RETSIGTYPE alrm_handler (int sig) @@ -710,6 +749,8 @@ void imap_keepalive (void) { if (conn->account.type == M_ACCT_TYPE_IMAP) { + int need_free = 0; + idata = (IMAP_DATA*) conn->data; if (idata->state >= IMAP_AUTHENTICATED @@ -721,9 +762,17 @@ void imap_keepalive (void) { ctx = safe_calloc (1, sizeof (CONTEXT)); ctx->data = idata; + /* imap_close_mailbox will set ctx->iadata->ctx to NULL, so we can't + * rely on the value of iadata->ctx to determine if this placeholder + * context needs to be freed. + */ + need_free = 1; } + /* if the imap connection closes during this call, ctx may be invalid + * after this point, and thus should not be read. + */ imap_check_mailbox (ctx, NULL, 1); - if (!idata->ctx) + if (need_free) FREE (&ctx); } } @@ -740,7 +789,7 @@ int imap_wait_keepalive (pid_t pid) int rc; short imap_passive = option (OPTIMAPPASSIVE); - + set_option (OPTIMAPPASSIVE); set_option (OPTKEEPQUIET); @@ -765,7 +814,7 @@ int imap_wait_keepalive (pid_t pid) } alarm (0); /* cancel a possibly pending alarm */ - + sigaction (SIGALRM, &oldalrm, NULL); sigprocmask (SIG_SETMASK, &oldmask, NULL);