diff options
author | Thomas Roessler <roessler@does-not-exist.org> | 1999-10-25 15:25:13 +0000 |
---|---|---|
committer | Thomas Roessler <roessler@does-not-exist.org> | 1999-10-25 15:25:13 +0000 |
commit | fc526d87f1d2a8c7526b95e27502093adc0fbc52 (patch) | |
tree | 92fdddd68b39bbe6f3f9bff5e642954cf6771044 /imap | |
parent | fde4d8443419cfc54d54bd64c3694db31c47e534 (diff) |
Brendan Cully's IMAP code movements patch.
Diffstat (limited to 'imap')
-rw-r--r-- | imap/.cvsignore | 3 | ||||
-rw-r--r-- | imap/BUGS | 11 | ||||
-rw-r--r-- | imap/Makefile.am | 6 | ||||
-rw-r--r-- | imap/browse.c | 9 | ||||
-rw-r--r-- | imap/command.c | 257 | ||||
-rw-r--r-- | imap/imap.c | 272 | ||||
-rw-r--r-- | imap/imap.h | 4 | ||||
-rw-r--r-- | imap/imap_private.h | 13 | ||||
-rw-r--r-- | imap/message.c | 1 | ||||
-rw-r--r-- | imap/util.c | 23 |
10 files changed, 319 insertions, 280 deletions
diff --git a/imap/.cvsignore b/imap/.cvsignore new file mode 100644 index 00000000..e9955884 --- /dev/null +++ b/imap/.cvsignore @@ -0,0 +1,3 @@ +.deps +Makefile +Makefile.in @@ -9,12 +9,9 @@ In no particular order: files. I haven't been able to reproduce this, and am not sure how to track it down. But it's very naughty indeed. -* Rex Walters reports that STORE on folders with lr is attempting to - store null flags instead of skipping the STORE. Strange, there are - checks against exactly this in imap_sync_mailbox. - -* Mutt seems to sometimes handle new messages which arrive in the middle - of downloading old messages incorrectly. It counts too many. +* Mutt sometimes doesn't notice new mail has arrived until you've opened + another folder, leading to the wrong number of messages being downloaded. + To make matters worse, imap_read_headers doesn't detect the * BAD response. * Mutt marks your connection for logout as soon as you say quit, even if you bail out with ^G later. @@ -36,4 +33,4 @@ In no particular order: * The mutt_pretty routines don't work well when the delimiter isn't '/'. Brendan Cully <brendan@kublai.com> -Updated 19991001 +Updated 19991013 diff --git a/imap/Makefile.am b/imap/Makefile.am index 11d10a64..f3cb6dd4 100644 --- a/imap/Makefile.am +++ b/imap/Makefile.am @@ -2,12 +2,12 @@ AUTOMAKE_OPTIONS = foreign -EXTRA_DIST = BUGS TODO README +EXTRA_DIST = BUGS README TODO AM_CPPFLAGS = -I../intl noinst_LIBRARIES = libimap.a noinst_HEADERS = imap_private.h imap_socket.h md5.h message.h -libimap_a_SOURCES = auth.c browse.c imap.c imap.h md5c.c message.c socket.c \ - util.c +libimap_a_SOURCES = auth.c browse.c command.c imap.c imap.h md5c.c message.c \ + socket.c util.c diff --git a/imap/browse.c b/imap/browse.c index 6c32cda7..35af24dc 100644 --- a/imap/browse.c +++ b/imap/browse.c @@ -23,9 +23,7 @@ #include <ctype.h> #include "mutt.h" -#include "imap.h" #include "imap_private.h" -#include "imap_socket.h" /* -- forward declarations -- */ static int add_list_result (CONNECTION *conn, const char *seq, const char *cmd, @@ -307,7 +305,12 @@ static void imap_add_folder (char delim, char *folder, int noselect, if (state->entrylen + 2 == state->entrymax) { safe_realloc ((void **) &state->entry, - sizeof (struct folder_file) * (state->entrymax += 256)); + sizeof (struct folder_file) * (state->entrymax += 256)); + /* apparently linux+glibc2.1 was zeroing this for me? Jon Hellan reports + * that the browser segfaults on more than 256 entries. I never had this + * problem */ + memset (state->entry + state->entrylen, 0, + (sizeof (struct folder_file) * (state->entrymax - state->entrylen))); } /* render superiors as unix-standard ".." */ diff --git a/imap/command.c b/imap/command.c new file mode 100644 index 00000000..3b05d93a --- /dev/null +++ b/imap/command.c @@ -0,0 +1,257 @@ +/* + * Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu> + * Copyright (C) 1996-9 Brandon Long <blong@fiction.net> + * Copyright (C) 1999 Brendan Cully <brendan@kublai.com> + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* command.c: routines for sending commands to an IMAP server and parsing + * responses */ + +#include "mutt.h" +#include "imap_private.h" +#include "mx.h" + +#include <ctype.h> +#include <stdlib.h> + +/* forward declarations */ +static void cmd_parse_capabilities (IMAP_DATA *idata, char *s); + +static char *Capabilities[] = {"IMAP4", "IMAP4rev1", "STATUS", "ACL", + "NAMESPACE", "AUTH=CRAM-MD5", "AUTH=KERBEROS_V4", "AUTH=GSSAPI", + "AUTH=LOGIN", "AUTH-LOGIN", "AUTH=PLAIN", "AUTH=SKEY", "IDLE", + "LOGIN-REFERRALS", "MAILBOX-REFERRALS", "QUOTA", "SCAN", "SORT", + "THREAD=ORDEREDSUBJECT", "UIDPLUS", "AUTH=ANONYMOUS", NULL}; + +/* imap_code: returns 1 if the command result was OK, or 0 if NO or BAD */ +int imap_code (const char *s) +{ + s += SEQLEN; + SKIPWS (s); + return (mutt_strncasecmp ("OK", s, 2) == 0); +} + +/* imap_exec: execute a command, and wait for the response from the server. + * Also, handle untagged responses + * If flags == IMAP_OK_FAIL, then the calling procedure can handle a response + * failing, this is used for checking for a mailbox on append and login + * Return 0 on success, -1 on Failure, -2 on OK Failure + */ +int imap_exec (char* buf, size_t buflen, IMAP_DATA* idata, const char* cmd, + int flags) +{ + char* out; + int outlen; + char seq[8]; + int count; + + /* create sequence for command */ + imap_make_sequence (seq, sizeof (seq)); + /* seq, space, cmd, \r\n\0 */ + outlen = strlen (seq) + strlen (cmd) + 4; + out = (char*) safe_malloc (outlen); + snprintf (out, outlen, "%s %s\r\n", seq, cmd); + + mutt_socket_write (idata->conn, out); + + safe_free ((void**) &out); + + do + { + if (mutt_socket_read_line_d (buf, buflen, idata->conn) < 0) + return (-1); + + if (buf[0] == '*' && imap_handle_untagged (idata, buf) != 0) + return (-1); + } + while (mutt_strncmp (buf, seq, SEQLEN) != 0); + + if ((idata->state == IMAP_SELECTED) && + !idata->selected_ctx->closing && + (idata->status == IMAP_NEW_MAIL || + idata->status == IMAP_EXPUNGE)) + { + + count = idata->newMailCount; + + if (idata->status == IMAP_NEW_MAIL && count > idata->selected_ctx->msgcount) + { + /* read new mail messages */ + dprint (1, (debugfile, "imap_exec(): new mail detected\n")); + + while (count > idata->selected_ctx->hdrmax) + mx_alloc_memory (idata->selected_ctx); + + count = imap_read_headers (idata->selected_ctx, + idata->selected_ctx->msgcount, count - 1) + 1; + idata->check_status = IMAP_NEW_MAIL; + } + else + { + imap_reopen_mailbox (idata->selected_ctx, NULL); + idata->check_status = IMAP_REOPENED; + } + + idata->status = 0; + + mutt_clear_error (); + } + + if (!imap_code (buf)) + { + char *pc; + + if (flags == IMAP_OK_FAIL) + return (-2); + dprint (1, (debugfile, "imap_exec(): command failed: %s\n", buf)); + pc = buf + SEQLEN; + SKIPWS (pc); + pc = imap_next_word (pc); + mutt_error (pc); + sleep (1); + return (-1); + } + + return 0; +} + +/* imap_handle_untagged: fallback parser for otherwise unhandled messages */ +int imap_handle_untagged (IMAP_DATA *idata, char *s) +{ + char *pn; + int count; + + s = imap_next_word (s); + + if ((idata->state == IMAP_SELECTED) && isdigit (*s)) + { + pn = s; + s = imap_next_word (s); + + /* EXISTS and EXPUNGE are always related to the SELECTED mailbox for the + * connection, so update that one. + */ + if (mutt_strncasecmp ("EXISTS", s, 6) == 0) + { + /* new mail arrived */ + count = atoi (pn); + + if ( (idata->status != IMAP_EXPUNGE) && + count < idata->selected_ctx->msgcount) + { + /* something is wrong because the server reported fewer messages + * than we previously saw + */ + mutt_error _("Fatal error. Message count is out of sync!"); + idata->status = IMAP_FATAL; + mx_fastclose_mailbox (idata->selected_ctx); + return -1; + } + else + { + if (idata->status != IMAP_EXPUNGE) + { + dprint(2, (debugfile, + "imap_handle_untagged: New mail in %s - %d messages total.\n", + idata->selected_mailbox, count)); + idata->status = IMAP_NEW_MAIL; + } + idata->newMailCount = count; + } + } + else if (mutt_strncasecmp ("EXPUNGE", s, 7) == 0) + idata->status = IMAP_EXPUNGE; + } + else if (mutt_strncasecmp ("CAPABILITY", s, 10) == 0) + /* parse capabilities */ + cmd_parse_capabilities (idata, s); + else if (mutt_strncasecmp ("MYRIGHTS", s, 8) == 0) + { + s = imap_next_word (s); + s = imap_next_word (s); + while (*s && !isspace(*s)) + { + switch (*s) + { + case 'l': + mutt_bit_set (idata->rights, IMAP_ACL_LOOKUP); + break; + case 'r': + mutt_bit_set (idata->rights, IMAP_ACL_READ); + break; + case 's': + mutt_bit_set (idata->rights, IMAP_ACL_SEEN); + break; + case 'w': + mutt_bit_set (idata->rights, IMAP_ACL_WRITE); + break; + case 'i': + mutt_bit_set (idata->rights, IMAP_ACL_INSERT); + break; + case 'p': + mutt_bit_set (idata->rights, IMAP_ACL_POST); + break; + case 'c': + mutt_bit_set (idata->rights, IMAP_ACL_CREATE); + break; + case 'd': + mutt_bit_set (idata->rights, IMAP_ACL_DELETE); + break; + case 'a': + mutt_bit_set (idata->rights, IMAP_ACL_ADMIN); + break; + } + s++; + } + } + else if (mutt_strncasecmp ("BYE", s, 3) == 0) + { + /* server shut down our connection */ + s += 3; + SKIPWS (s); + mutt_error (s); + idata->status = IMAP_BYE; + if (idata->state == IMAP_SELECTED) + mx_fastclose_mailbox (idata->selected_ctx); + return (-1); + } + else + { + dprint (1, (debugfile, "imap_handle_untagged(): unhandled request: %s\n", + s)); + } + + return 0; +} + +/* cmd_parse_capabilities: set capability bits according to CAPABILITY + * response */ +static void cmd_parse_capabilities (IMAP_DATA *idata, char *s) +{ + int x; + + while (*s) + { + for (x = 0; x < CAPMAX; x++) + if (imap_wordcasecmp(Capabilities[x], s) == 0) + { + mutt_bit_set (idata->capabilities, x); + break; + } + s = imap_next_word (s); + } +} diff --git a/imap/imap.c b/imap/imap.c index 24b63e1c..fd598700 100644 --- a/imap/imap.c +++ b/imap/imap.c @@ -27,9 +27,7 @@ #include "globals.h" #include "sort.h" #include "browser.h" -#include "imap.h" #include "imap_private.h" -#include "imap_socket.h" #include <unistd.h> #include <ctype.h> @@ -38,16 +36,7 @@ #include <sys/types.h> #include <sys/stat.h> -static char *Capabilities[] = {"IMAP4", "IMAP4rev1", "STATUS", "ACL", - "NAMESPACE", "AUTH=CRAM-MD5", "AUTH=KERBEROS_V4", "AUTH=GSSAPI", - "AUTH=LOGIN", "AUTH-LOGIN", "AUTH=PLAIN", "AUTH=SKEY", "IDLE", - "LOGIN-REFERRALS", "MAILBOX-REFERRALS", "QUOTA", "SCAN", "SORT", - "THREAD=ORDEREDSUBJECT", "UIDPLUS", "AUTH=ANONYMOUS", NULL}; - /* imap forward declarations */ -static int imap_wordcasecmp(const char *a, const char *b); -static void imap_parse_capabilities (IMAP_DATA *idata, char *s); -static int imap_reopen_mailbox (CONTEXT *ctx, int *index_hint); static int imap_get_delim (IMAP_DATA *idata, CONNECTION *conn); static char* imap_get_flags (LIST** hflags, char* s); static int imap_check_acl (IMAP_DATA *idata); @@ -127,167 +116,14 @@ int imap_read_bytes (FILE *fp, CONNECTION *conn, long bytes) return 0; } -/* returns 1 if the command result was OK, or 0 if NO or BAD */ -int imap_code (const char *s) -{ - s += SEQLEN; - SKIPWS (s); - return (mutt_strncasecmp ("OK", s, 2) == 0); -} - -/* a is a word, b a string of words */ -static int imap_wordcasecmp(const char *a, const char *b) -{ - char tmp[SHORT_STRING]; - char *s = (char *)b; - int i; - - tmp[SHORT_STRING-1] = 0; - for(i=0;i < SHORT_STRING-2;i++,s++) - { - if (!*s || ISSPACE(*s)) - { - tmp[i] = 0; - break; - } - tmp[i] = *s; - } - tmp[i+1] = 0; - return mutt_strcasecmp(a, tmp); - -} - -static void imap_parse_capabilities (IMAP_DATA *idata, char *s) -{ - int x; - - while (*s) - { - for (x = 0; x < CAPMAX; x++) - if (imap_wordcasecmp(Capabilities[x], s) == 0) - { - mutt_bit_set (idata->capabilities, x); - break; - } - s = imap_next_word (s); - } -} - -int imap_handle_untagged (IMAP_DATA *idata, char *s) -{ - char *pn; - int count; - - s = imap_next_word (s); - - if ((idata->state == IMAP_SELECTED) && isdigit (*s)) - { - pn = s; - s = imap_next_word (s); - - /* EXISTS and EXPUNGE are always related to the SELECTED mailbox for the - * connection, so update that one. - */ - if (mutt_strncasecmp ("EXISTS", s, 6) == 0) - { - /* new mail arrived */ - count = atoi (pn); - - if ( (idata->status != IMAP_EXPUNGE) && - count < idata->selected_ctx->msgcount) - { - /* something is wrong because the server reported fewer messages - * than we previously saw - */ - mutt_error _("Fatal error. Message count is out of sync!"); - idata->status = IMAP_FATAL; - mx_fastclose_mailbox (idata->selected_ctx); - return (-1); - } - else - { - if (idata->status != IMAP_EXPUNGE) - idata->status = IMAP_NEW_MAIL; - idata->newMailCount = count; - } - } - else if (mutt_strncasecmp ("EXPUNGE", s, 7) == 0) - { - idata->status = IMAP_EXPUNGE; - } - } - else if (mutt_strncasecmp ("CAPABILITY", s, 10) == 0) - { - /* parse capabilities */ - imap_parse_capabilities (idata, s); - } - else if (mutt_strncasecmp ("MYRIGHTS", s, 8) == 0) - { - s = imap_next_word (s); - s = imap_next_word (s); - while (*s && !isspace(*s)) - { - switch (*s) - { - case 'l': - mutt_bit_set (idata->rights, IMAP_ACL_LOOKUP); - break; - case 'r': - mutt_bit_set (idata->rights, IMAP_ACL_READ); - break; - case 's': - mutt_bit_set (idata->rights, IMAP_ACL_SEEN); - break; - case 'w': - mutt_bit_set (idata->rights, IMAP_ACL_WRITE); - break; - case 'i': - mutt_bit_set (idata->rights, IMAP_ACL_INSERT); - break; - case 'p': - mutt_bit_set (idata->rights, IMAP_ACL_POST); - break; - case 'c': - mutt_bit_set (idata->rights, IMAP_ACL_CREATE); - break; - case 'd': - mutt_bit_set (idata->rights, IMAP_ACL_DELETE); - break; - case 'a': - mutt_bit_set (idata->rights, IMAP_ACL_ADMIN); - break; - } - s++; - } - } - else if (mutt_strncasecmp ("BYE", s, 3) == 0) - { - /* server shut down our connection */ - s += 3; - SKIPWS (s); - mutt_error (s); - idata->status = IMAP_BYE; - if (idata->state == IMAP_SELECTED) - mx_fastclose_mailbox (idata->selected_ctx); - return (-1); - } - else - { - dprint (1, (debugfile, "imap_handle_untagged(): unhandled request: %s\n", - s)); - } - - return 0; -} - -/* reopen an imap mailbox. This is used when the server sends an - * EXPUNGE message, indicating that some messages may have been deleted. - * This is a heavy handed approach, as it reparses all of the headers, - * but it should guarantee correctness. Later, we might implement +/* imap_reopen_mailbox: Reopen an imap mailbox. This is used when the + * server sends an EXPUNGE message, indicating that some messages may have + * been deleted. This is a heavy handed approach, as it reparses all of the + * headers, but it should guarantee correctness. Later, we might implement * something to actually only remove the messages that are marked * EXPUNGE. */ -static int imap_reopen_mailbox (CONTEXT *ctx, int *index_hint) +int imap_reopen_mailbox (CONTEXT *ctx, int *index_hint) { HEADER **old_hdrs; int old_msgcount; @@ -475,91 +311,6 @@ static int imap_reopen_mailbox (CONTEXT *ctx, int *index_hint) return 0; } -/* - * Execute a command, and wait for the response from the server. - * Also, handle untagged responses - * If flags == IMAP_OK_FAIL, then the calling procedure can handle a response - * failing, this is used for checking for a mailbox on append and login - * Return 0 on success, -1 on Failure, -2 on OK Failure - */ -int imap_exec (char* buf, size_t buflen, IMAP_DATA* idata, const char* cmd, - int flags) -{ - char* out; - int outlen; - char seq[8]; - int count; - - /* create sequence for command */ - imap_make_sequence (seq, sizeof (seq)); - /* seq, space, cmd, \r\n\0 */ - outlen = strlen (seq) + strlen (cmd) + 4; - out = (char*) safe_malloc (outlen); - snprintf (out, outlen, "%s %s\r\n", seq, cmd); - - mutt_socket_write (idata->conn, out); - - safe_free ((void**) &out); - - do - { - if (mutt_socket_read_line_d (buf, buflen, idata->conn) < 0) - return (-1); - - if (buf[0] == '*' && imap_handle_untagged (idata, buf) != 0) - return (-1); - } - while (mutt_strncmp (buf, seq, SEQLEN) != 0); - - if ((idata->state == IMAP_SELECTED) && - !idata->selected_ctx->closing && - (idata->status == IMAP_NEW_MAIL || - idata->status == IMAP_EXPUNGE)) - { - - count = idata->newMailCount; - - if (idata->status == IMAP_NEW_MAIL && count > idata->selected_ctx->msgcount) - { - /* read new mail messages */ - dprint (1, (debugfile, "imap_exec(): new mail detected\n")); - - while (count > idata->selected_ctx->hdrmax) - mx_alloc_memory (idata->selected_ctx); - - count = imap_read_headers (idata->selected_ctx, - idata->selected_ctx->msgcount, count - 1) + 1; - idata->check_status = IMAP_NEW_MAIL; - } - else - { - imap_reopen_mailbox (idata->selected_ctx, NULL); - idata->check_status = IMAP_REOPENED; - } - - idata->status = 0; - - mutt_clear_error (); - } - - if (!imap_code (buf)) - { - char *pc; - - if (flags == IMAP_OK_FAIL) - return (-2); - dprint (1, (debugfile, "imap_exec(): command failed: %s\n", buf)); - pc = buf + SEQLEN; - SKIPWS (pc); - pc = imap_next_word (pc); - mutt_error (pc); - sleep (1); - return (-1); - } - - return 0; -} - static int imap_get_delim (IMAP_DATA *idata, CONNECTION *conn) { char buf[LONG_STRING]; @@ -1187,11 +938,12 @@ int imap_make_msg_set (char* buf, size_t buflen, CONTEXT* ctx, int flag, * expunge: 0 or 1 - do expunge? */ int imap_sync_mailbox (CONTEXT* ctx, int expunge) { - char buf[LONG_STRING]; + char buf[HUGE_STRING]; char flags[LONG_STRING]; char tmp[LONG_STRING]; int deleted; int n; + int err_continue = M_NO; /* continue on error? */ if (CTX_DATA->state != IMAP_SELECTED) { @@ -1268,12 +1020,12 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge) /* after all this it's still possible to have no flags, if you * have no ACL rights */ - if (*flags && imap_exec (buf, sizeof (buf), CTX_DATA, buf, 0) != 0) + if (*flags && (imap_exec (buf, sizeof (buf), CTX_DATA, buf, 0) != 0) && + (err_continue != M_YES)) { - imap_error ("imap_sync_mailbox: STORE failed", buf); - /* give up on this message if we pass here again */ - ctx->hdrs[n]->changed = 0; - return -1; + err_continue = imap_error ("imap_sync_mailbox: STORE failed", buf); + if (err_continue != M_YES) + return -1; } ctx->hdrs[n]->changed = 0; diff --git a/imap/imap.h b/imap/imap.h index 59a6506d..1afecf4f 100644 --- a/imap/imap.h +++ b/imap/imap.h @@ -33,9 +33,11 @@ void imap_fastclose_mailbox (CONTEXT *ctx); int imap_buffy_check (char *path); int imap_mailbox_check (char *path, int new); int imap_subscribe (char *path, int subscribe); -int imap_init_browse (char *path, struct browser_state *state); int imap_complete (char* dest, size_t dlen, char* path); +/* browse.c */ +int imap_init_browse (char *path, struct browser_state *state); + /* message.c */ int imap_append_message (CONTEXT* ctx, MESSAGE* msg); int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete); diff --git a/imap/imap_private.h b/imap/imap_private.h index 5b569247..4d1e128f 100644 --- a/imap/imap_private.h +++ b/imap/imap_private.h @@ -20,6 +20,7 @@ #ifndef _IMAP_PRIVATE_H #define _IMAP_PRIVATE_H 1 +#include "imap.h" #include "imap_socket.h" /* -- symbols -- */ @@ -147,11 +148,7 @@ typedef struct /* -- private IMAP functions -- */ /* imap.c */ -int imap_code (const char* s); int imap_create_mailbox (IMAP_DATA* idata, char* mailbox); -int imap_exec (char* buf, size_t buflen, IMAP_DATA* idata, const char* cmd, - int flags); -int imap_handle_untagged (IMAP_DATA* idata, char* s); int imap_make_msg_set (char* buf, size_t buflen, CONTEXT* ctx, int flag, int changed); int imap_open_connection (IMAP_DATA* idata, CONNECTION* conn); @@ -159,10 +156,17 @@ time_t imap_parse_date (char* s); int imap_parse_list_response(CONNECTION* conn, char* buf, int buflen, char** name, int* noselect, int* noinferiors, char* delim); int imap_read_bytes (FILE* fp, CONNECTION* conn, long bytes); +int imap_reopen_mailbox (CONTEXT *ctx, int *index_hint); /* auth.c */ int imap_authenticate (IMAP_DATA *idata, CONNECTION *conn); +/* command.c */ +int imap_code (const char* s); +int imap_exec (char* buf, size_t buflen, IMAP_DATA* idata, const char* cmd, + int flags); +int imap_handle_untagged (IMAP_DATA* idata, char* s); + /* message.c */ void imap_add_keywords (char* s, HEADER* keywords, LIST* mailbox_flags); void imap_free_header_data (void** data); @@ -177,4 +181,5 @@ void imap_make_sequence (char *buf, size_t buflen); char* imap_next_word (char* s); void imap_quote_string (char* dest, size_t slen, const char* src); void imap_unquote_string (char* s); +int imap_wordcasecmp(const char *a, const char *b); #endif diff --git a/imap/message.c b/imap/message.c index 6498bd74..870df194 100644 --- a/imap/message.c +++ b/imap/message.c @@ -23,7 +23,6 @@ #include <ctype.h> #include "mutt.h" -#include "imap.h" #include "imap_private.h" #include "message.h" #include "mx.h" diff --git a/imap/util.c b/imap/util.c index 37bcced4..ad305017 100644 --- a/imap/util.c +++ b/imap/util.c @@ -21,7 +21,6 @@ /* general IMAP utility functions */ #include "mutt.h" -#include "imap.h" #include "imap_private.h" #include <stdlib.h> @@ -226,3 +225,25 @@ void imap_unquote_string (char *s) } *d = '\0'; } + +/* imap_wordcasecmp: find word a in word list b */ +int imap_wordcasecmp(const char *a, const char *b) +{ + char tmp[SHORT_STRING]; + char *s = (char *)b; + int i; + + tmp[SHORT_STRING-1] = 0; + for(i=0;i < SHORT_STRING-2;i++,s++) + { + if (!*s || ISSPACE(*s)) + { + tmp[i] = 0; + break; + } + tmp[i] = *s; + } + tmp[i+1] = 0; + + return mutt_strcasecmp(a, tmp); +} |