X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=imap%2Fimap.c;h=db9901a114ebc56957f94a72498c1a6562871570;hp=06e14edbc6fa15be2f79fda4d5757b68eb4041fc;hb=ea912b20ba2b3b9dfdbbae758ad56263c9aa41b3;hpb=bbc4fd52516a8afefbd14c77e34f8389d6f0a6ed diff --git a/imap/imap.c b/imap/imap.c index 06e14ed..db9901a 100644 --- a/imap/imap.c +++ b/imap/imap.c @@ -18,7 +18,6 @@ #include "mutt.h" #include "ascii.h" #include "buffer.h" -#include "mutt_curses.h" #include "mx.h" #include "globals.h" #include "sort.h" @@ -183,7 +182,7 @@ void imap_logout_all (void) /* imap_read_literal: read bytes bytes from server into file. Not explicitly * buffered, relies on FILE buffering. NOTE: strips \r from \r\n. * Apparently even literals use \r\n-terminated strings ?! */ -int imap_read_literal (FILE * fp, IMAP_DATA * idata, long bytes) +int imap_read_literal (FILE * fp, IMAP_DATA * idata, long bytes, progress_t* bar) { long pos; char c; @@ -212,8 +211,10 @@ int imap_read_literal (FILE * fp, IMAP_DATA * idata, long bytes) r = 0; #endif fputc (c, fp); + if (bar && !(pos % 1024)) + mutt_progress_bar (bar, pos); #ifdef DEBUG - if (DebugLevel >= IMAP_LOG_LTRL) + if (DebugFile && DebugLevel >= IMAP_LOG_LTRL) fputc (c, DebugFile); #endif } @@ -433,10 +434,8 @@ int imap_open_connection (IMAP_DATA * idata) if ((rc = imap_exec (idata, "STARTTLS", IMAP_CMD_FAIL_OK)) == -1) goto bail; if (rc != -2) { -#ifdef USE_SSL +#if defined (USE_SSL) || defined (USE_GNUTLS) if (mutt_ssl_starttls (idata->conn)) -#elif USE_GNUTLS - if (mutt_gnutls_starttls (idata->conn)) #endif { mutt_error (_("Could not negotiate TLS connection")); @@ -1137,9 +1136,12 @@ int imap_check_mailbox (CONTEXT * ctx, int *index_hint, int force) return result; } -/* returns count of recent messages if new = 1, else count of total messages. - * (useful for at least postponed function) - * Question of taste: use RECENT or UNSEEN for new? +/* + * count messages: + * new == 1: recent + * new == 2: unseen + * otherwise: total + * return: * 0+ number of messages in mailbox * -1 error while polling mailboxes */ @@ -1187,7 +1189,7 @@ int imap_mailbox_check (char *path, int new) else if (mutt_bit_isset (idata->capabilities, IMAP4REV1) || mutt_bit_isset (idata->capabilities, STATUS)) { snprintf (buf, sizeof (buf), "STATUS %s (%s)", mbox, - new ? "RECENT" : "MESSAGES"); + new == 1 ? "RECENT" : (new == 2 ? "UNSEEN" : "MESSAGES")); } else /* Server does not support STATUS, and this is not the current mailbox. @@ -1226,6 +1228,138 @@ int imap_mailbox_check (char *path, int new) return msgcount; } +/* returns number of patterns in the search that should be done server-side + * (eg are full-text) */ +static int do_search (const pattern_t* search, int allpats) +{ + int rc = 0; + const pattern_t* pat; + + for (pat = search; pat; pat = pat->next) { + switch (pat->op) { + case M_BODY: + case M_HEADER: + case M_WHOLE_MSG: + if (pat->stringmatch) + rc++; + break; + default: + if (pat->child && do_search (pat->child, 1)) + rc++; + } + + if (!allpats) + break; + } + + return rc; +} + +/* convert mutt pattern_t to IMAP SEARCH command containing only elements +* that require full-text search (mutt already has what it needs for most +* match types, and does a better job (eg server doesn't support regexps). */ +static int imap_compile_search (const pattern_t* pat, BUFFER* buf) +{ + if (! do_search (pat, 0)) + return 0; + + if (pat->not) + mutt_buffer_addstr (buf, "NOT "); + + if (pat->child) { + int clauses; + + if ((clauses = do_search (pat->child, 1)) > 0) { + const pattern_t* clause = pat->child; + + mutt_buffer_addch (buf, '('); + + while (clauses) { + if (do_search (clause, 0)) { + if (pat->op == M_OR && clauses > 1) + mutt_buffer_addstr (buf, "OR "); + clauses--; + if (imap_compile_search (clause, buf) < 0) + return -1; + + if (clauses) + mutt_buffer_addch (buf, ' '); + + clause = clause->next; + } + } + + mutt_buffer_addch (buf, ')'); + } + } else { + char term[STRING]; + char *delim; + + switch (pat->op) { + case M_HEADER: + mutt_buffer_addstr (buf, "HEADER "); + + /* extract header name */ + if (! (delim = strchr (pat->str, ':'))) { + mutt_error (_("Header search without header name: %s"), pat->str); + return -1; + } + *delim = '\0'; + imap_quote_string (term, sizeof (term), pat->str); + mutt_buffer_addstr (buf, term); + mutt_buffer_addch (buf, ' '); + + /* and field */ + *delim = ':'; + delim++; + SKIPWS(delim); + imap_quote_string (term, sizeof (term), delim); + mutt_buffer_addstr (buf, term); + break; + + case M_BODY: + mutt_buffer_addstr (buf, "BODY "); + imap_quote_string (term, sizeof (term), pat->str); + mutt_buffer_addstr (buf, term); + break; + + case M_WHOLE_MSG: + mutt_buffer_addstr (buf, "TEXT "); + imap_quote_string (term, sizeof (term), pat->str); + mutt_buffer_addstr (buf, term); + break; + } + } + + return 0; +} + +int imap_search (CONTEXT* ctx, const pattern_t* pat) { + BUFFER buf; + IMAP_DATA* idata = (IMAP_DATA*)ctx->data; + int i; + + for (i = 0; i < ctx->msgcount; i++) + ctx->hdrs[i]->matched = 0; + + if (!do_search (pat, 1)) + return 0; + + memset (&buf, 0, sizeof (buf)); + mutt_buffer_addstr (&buf, "UID SEARCH "); + if (imap_compile_search (pat, &buf) < 0) { + mem_free (&buf.data); + return -1; + } + if (imap_exec (idata, buf.data, 0) < 0) { + mem_free (&buf.data); + return -1; + } + + mem_free (&buf.data); + return 0; +} + /* all this listing/browsing is a mess. I don't like that name is a pointer * into idata->buf (used to be a pointer into the passed in buffer, just * as bad), nor do I like the fact that the fetch is done here. This @@ -1310,7 +1444,7 @@ int imap_subscribe (char *path, int subscribe) BUFFER err, token; IMAP_MBOX mx; - if (mx_get_magic (path) == M_IMAP || imap_parse_path (path, &mx)) { + if (mx_get_magic (path) != M_IMAP || imap_parse_path (path, &mx) < 0) { mutt_error (_("Bad mailbox name")); return -1; } @@ -1388,7 +1522,7 @@ static int imap_complete_hosts (char *dest, size_t len) { } } - for (conn = mutt_socket_head (); conn->next; conn = conn->next) { + for (conn = mutt_socket_head (); conn && conn->next; conn = conn->next) { ciss_url_t url; char urlstr[LONG_STRING];