X-Git-Url: http://git.madism.org/?a=blobdiff_plain;f=imap%2Fimap.c;h=69d35d624da15d7b5ac2ace36fadf6c72dde9e0c;hb=ccdd901a5b45890fffa6a1173dbb50a4c46971e1;hp=23269b19113b4274085e7222b805f31d535aa45e;hpb=be393b838c5e0b8dfe9bedcc7a4a63f05caae7c4;p=apps%2Fmadmutt.git diff --git a/imap/imap.c b/imap/imap.c index 23269b1..69d35d6 100644 --- a/imap/imap.c +++ b/imap/imap.c @@ -16,7 +16,8 @@ #endif #include "mutt.h" -#include "mutt_curses.h" +#include "ascii.h" +#include "buffer.h" #include "mx.h" #include "globals.h" #include "sort.h" @@ -181,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; @@ -210,6 +211,8 @@ 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) fputc (c, DebugFile); @@ -431,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")); @@ -1224,6 +1225,139 @@ 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) +{ + char term[STRING]; + + 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 *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 @@ -1386,7 +1520,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];