X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fimap%2Fimap_search.c;h=efc19920274401a412b275376c29a705af801c6f;hb=7a9b0685e406cc83597171cc39d008c7e5459ca8;hp=1cb38c97b940472232e5f29be992a33d0c0afd64;hpb=8c47559cb5ae97ec0fa35660ee16fd61a9451c72;p=citadel.git diff --git a/citadel/modules/imap/imap_search.c b/citadel/modules/imap/imap_search.c index 1cb38c97b..efc199202 100644 --- a/citadel/modules/imap/imap_search.c +++ b/citadel/modules/imap/imap_search.c @@ -1,26 +1,20 @@ /* - * $Id$ - * * Implements IMAP's gratuitously complex SEARCH command. * + * Copyright (c) 2001-2020 by the citadel.org team * - * Copyright (c) 2001-2009 by the citadel.org team - * - * 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 3 of the License, or - * (at your option) any later version. + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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. */ +#include "ctdl_module.h" + + #include "sysdep.h" #include #include @@ -30,18 +24,7 @@ #include #include #include - -#if TIME_WITH_SYS_TIME -# include -# include -#else -# if HAVE_SYS_TIME_H -# include -# else -# include -# endif -#endif - +#include #include #include #include @@ -53,9 +36,7 @@ #include "citserver.h" #include "support.h" #include "config.h" -#include "room_ops.h" #include "user_ops.h" -#include "policy.h" #include "database.h" #include "msgbase.h" #include "internet_addressing.h" @@ -76,8 +57,9 @@ * be loaded only if one or more search criteria require it. */ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, - int num_items, char **itemlist, int is_uid) { + int num_items, ConstStr *itemlist, int is_uid) { + citimap *Imap = IMAP; int match = 0; int is_not = 0; int is_or = 0; @@ -96,39 +78,39 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, pos = 0; /* Check for the dreaded NOT criterion. */ - if (!strcasecmp(itemlist[0], "NOT")) { + if (!strcasecmp(itemlist[0].Key, "NOT")) { is_not = 1; pos = 1; } /* Check for the dreaded OR criterion. */ - if (!strcasecmp(itemlist[0], "OR")) { + if (!strcasecmp(itemlist[0].Key, "OR")) { is_or = 1; pos = 1; } /* Now look for criteria. */ - if (!strcasecmp(itemlist[pos], "ALL")) { + if (!strcasecmp(itemlist[pos].Key, "ALL")) { match = 1; ++pos; } - else if (!strcasecmp(itemlist[pos], "ANSWERED")) { - if (IMAP->flags[seq-1] & IMAP_ANSWERED) { + else if (!strcasecmp(itemlist[pos].Key, "ANSWERED")) { + if (Imap->flags[seq-1] & IMAP_ANSWERED) { match = 1; } ++pos; } - else if (!strcasecmp(itemlist[pos], "BCC")) { + else if (!strcasecmp(itemlist[pos].Key, "BCC")) { if (msg == NULL) { - msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); need_to_free_msg = 1; } if (msg != NULL) { - fieldptr = rfc822_fetch_field(msg->cm_fields['M'], "Bcc"); + fieldptr = rfc822_fetch_field(msg->cm_fields[eMesageText], "Bcc"); if (fieldptr != NULL) { - if (bmstrcasestr(fieldptr, itemlist[pos+1])) { + if (bmstrcasestr(fieldptr, itemlist[pos+1].Key)) { match = 1; } free(fieldptr); @@ -137,15 +119,15 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, pos += 2; } - else if (!strcasecmp(itemlist[pos], "BEFORE")) { + else if (!strcasecmp(itemlist[pos].Key, "BEFORE")) { if (msg == NULL) { - msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); need_to_free_msg = 1; } if (msg != NULL) { - if (msg->cm_fields['T'] != NULL) { - if (imap_datecmp(itemlist[pos+1], - atol(msg->cm_fields['T'])) < 0) { + if (!CM_IsEmpty(msg, eTimestamp)) { + if (imap_datecmp(itemlist[pos+1].Key, + atol(msg->cm_fields[eTimestamp])) < 0) { match = 1; } } @@ -153,23 +135,23 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, pos += 2; } - else if (!strcasecmp(itemlist[pos], "BODY")) { + else if (!strcasecmp(itemlist[pos].Key, "BODY")) { /* If fulltext indexing is active, on this server, * all messages have already been qualified. */ - if (config.c_enable_fulltext) { + if (CtdlGetConfigInt("c_enable_fulltext")) { match = 1; } /* Otherwise, we have to do a slow search. */ else { if (msg == NULL) { - msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); need_to_free_msg = 1; } if (msg != NULL) { - if (bmstrcasestr(msg->cm_fields['M'], itemlist[pos+1])) { + if (bmstrcasestr(msg->cm_fields[eMesageText], itemlist[pos+1].Key)) { match = 1; } } @@ -178,22 +160,22 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, pos += 2; } - else if (!strcasecmp(itemlist[pos], "CC")) { + else if (!strcasecmp(itemlist[pos].Key, "CC")) { if (msg == NULL) { - msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); need_to_free_msg = 1; } if (msg != NULL) { - fieldptr = msg->cm_fields['Y']; + fieldptr = msg->cm_fields[eCarbonCopY]; if (fieldptr != NULL) { - if (bmstrcasestr(fieldptr, itemlist[pos+1])) { + if (bmstrcasestr(fieldptr, itemlist[pos+1].Key)) { match = 1; } } else { - fieldptr = rfc822_fetch_field(msg->cm_fields['M'], "Cc"); + fieldptr = rfc822_fetch_field(msg->cm_fields[eMesageText], "Cc"); if (fieldptr != NULL) { - if (bmstrcasestr(fieldptr, itemlist[pos+1])) { + if (bmstrcasestr(fieldptr, itemlist[pos+1].Key)) { match = 1; } free(fieldptr); @@ -203,44 +185,44 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, pos += 2; } - else if (!strcasecmp(itemlist[pos], "DELETED")) { - if (IMAP->flags[seq-1] & IMAP_DELETED) { + else if (!strcasecmp(itemlist[pos].Key, "DELETED")) { + if (Imap->flags[seq-1] & IMAP_DELETED) { match = 1; } ++pos; } - else if (!strcasecmp(itemlist[pos], "DRAFT")) { - if (IMAP->flags[seq-1] & IMAP_DRAFT) { + else if (!strcasecmp(itemlist[pos].Key, "DRAFT")) { + if (Imap->flags[seq-1] & IMAP_DRAFT) { match = 1; } ++pos; } - else if (!strcasecmp(itemlist[pos], "FLAGGED")) { - if (IMAP->flags[seq-1] & IMAP_FLAGGED) { + else if (!strcasecmp(itemlist[pos].Key, "FLAGGED")) { + if (Imap->flags[seq-1] & IMAP_FLAGGED) { match = 1; } ++pos; } - else if (!strcasecmp(itemlist[pos], "FROM")) { + else if (!strcasecmp(itemlist[pos].Key, "FROM")) { if (msg == NULL) { - msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); need_to_free_msg = 1; } if (msg != NULL) { - if (bmstrcasestr(msg->cm_fields['A'], itemlist[pos+1])) { + if (bmstrcasestr(msg->cm_fields[eAuthor], itemlist[pos+1].Key)) { match = 1; } - if (bmstrcasestr(msg->cm_fields['F'], itemlist[pos+1])) { + if (bmstrcasestr(msg->cm_fields[erFc822Addr], itemlist[pos+1].Key)) { match = 1; } } pos += 2; } - else if (!strcasecmp(itemlist[pos], "HEADER")) { + else if (!strcasecmp(itemlist[pos].Key, "HEADER")) { /* We've got to do a slow search for this because the client * might be asking for an RFC822 header field that has not been @@ -248,75 +230,70 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, * examining the message body. */ if (msg == NULL) { - msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); need_to_free_msg = 1; } if (msg != NULL) { - CC->redirect_buffer = malloc(SIZ); - CC->redirect_len = 0; - CC->redirect_alloc = SIZ; + CC->redirect_buffer = NewStrBufPlain(NULL, SIZ); CtdlOutputPreLoadedMsg(msg, MT_RFC822, HEADERS_FAST, 0, 1, 0); - fieldptr = rfc822_fetch_field(CC->redirect_buffer, itemlist[pos+1]); + fieldptr = rfc822_fetch_field(ChrPtr(CC->redirect_buffer), itemlist[pos+1].Key); if (fieldptr != NULL) { - if (bmstrcasestr(fieldptr, itemlist[pos+2])) { + if (bmstrcasestr(fieldptr, itemlist[pos+2].Key)) { match = 1; } free(fieldptr); } - free(CC->redirect_buffer); - CC->redirect_buffer = NULL; - CC->redirect_len = 0; - CC->redirect_alloc = 0; + FreeStrBuf(&CC->redirect_buffer); } pos += 3; /* Yes, three */ } - else if (!strcasecmp(itemlist[pos], "KEYWORD")) { + else if (!strcasecmp(itemlist[pos].Key, "KEYWORD")) { /* not implemented */ pos += 2; } - else if (!strcasecmp(itemlist[pos], "LARGER")) { + else if (!strcasecmp(itemlist[pos].Key, "LARGER")) { if (msg == NULL) { - msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); need_to_free_msg = 1; } if (msg != NULL) { - if (strlen(msg->cm_fields['M']) > atoi(itemlist[pos+1])) { + if (msg->cm_lengths[eMesageText] > atoi(itemlist[pos+1].Key)) { match = 1; } } pos += 2; } - else if (!strcasecmp(itemlist[pos], "NEW")) { - if ( (IMAP->flags[seq-1] & IMAP_RECENT) && (!(IMAP->flags[seq-1] & IMAP_SEEN))) { + else if (!strcasecmp(itemlist[pos].Key, "NEW")) { + if ( (Imap->flags[seq-1] & IMAP_RECENT) && (!(Imap->flags[seq-1] & IMAP_SEEN))) { match = 1; } ++pos; } - else if (!strcasecmp(itemlist[pos], "OLD")) { - if (!(IMAP->flags[seq-1] & IMAP_RECENT)) { + else if (!strcasecmp(itemlist[pos].Key, "OLD")) { + if (!(Imap->flags[seq-1] & IMAP_RECENT)) { match = 1; } ++pos; } - else if (!strcasecmp(itemlist[pos], "ON")) { + else if (!strcasecmp(itemlist[pos].Key, "ON")) { if (msg == NULL) { - msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); need_to_free_msg = 1; } if (msg != NULL) { - if (msg->cm_fields['T'] != NULL) { - if (imap_datecmp(itemlist[pos+1], - atol(msg->cm_fields['T'])) == 0) { + if (!CM_IsEmpty(msg, eTimestamp)) { + if (imap_datecmp(itemlist[pos+1].Key, + atol(msg->cm_fields[eTimestamp])) == 0) { match = 1; } } @@ -324,29 +301,29 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, pos += 2; } - else if (!strcasecmp(itemlist[pos], "RECENT")) { - if (IMAP->flags[seq-1] & IMAP_RECENT) { + else if (!strcasecmp(itemlist[pos].Key, "RECENT")) { + if (Imap->flags[seq-1] & IMAP_RECENT) { match = 1; } ++pos; } - else if (!strcasecmp(itemlist[pos], "SEEN")) { - if (IMAP->flags[seq-1] & IMAP_SEEN) { + else if (!strcasecmp(itemlist[pos].Key, "SEEN")) { + if (Imap->flags[seq-1] & IMAP_SEEN) { match = 1; } ++pos; } - else if (!strcasecmp(itemlist[pos], "SENTBEFORE")) { + else if (!strcasecmp(itemlist[pos].Key, "SENTBEFORE")) { if (msg == NULL) { - msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); need_to_free_msg = 1; } if (msg != NULL) { - if (msg->cm_fields['T'] != NULL) { - if (imap_datecmp(itemlist[pos+1], - atol(msg->cm_fields['T'])) < 0) { + if (!CM_IsEmpty(msg, eTimestamp)) { + if (imap_datecmp(itemlist[pos+1].Key, + atol(msg->cm_fields[eTimestamp])) < 0) { match = 1; } } @@ -354,15 +331,15 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, pos += 2; } - else if (!strcasecmp(itemlist[pos], "SENTON")) { + else if (!strcasecmp(itemlist[pos].Key, "SENTON")) { if (msg == NULL) { - msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); need_to_free_msg = 1; } if (msg != NULL) { - if (msg->cm_fields['T'] != NULL) { - if (imap_datecmp(itemlist[pos+1], - atol(msg->cm_fields['T'])) == 0) { + if (!CM_IsEmpty(msg, eTimestamp)) { + if (imap_datecmp(itemlist[pos+1].Key, + atol(msg->cm_fields[eTimestamp])) == 0) { match = 1; } } @@ -370,15 +347,15 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, pos += 2; } - else if (!strcasecmp(itemlist[pos], "SENTSINCE")) { + else if (!strcasecmp(itemlist[pos].Key, "SENTSINCE")) { if (msg == NULL) { - msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); need_to_free_msg = 1; } if (msg != NULL) { - if (msg->cm_fields['T'] != NULL) { - if (imap_datecmp(itemlist[pos+1], - atol(msg->cm_fields['T'])) >= 0) { + if (!CM_IsEmpty(msg, eTimestamp)) { + if (imap_datecmp(itemlist[pos+1].Key, + atol(msg->cm_fields[eTimestamp])) >= 0) { match = 1; } } @@ -386,15 +363,15 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, pos += 2; } - else if (!strcasecmp(itemlist[pos], "SINCE")) { + else if (!strcasecmp(itemlist[pos].Key, "SINCE")) { if (msg == NULL) { - msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); need_to_free_msg = 1; } if (msg != NULL) { - if (msg->cm_fields['T'] != NULL) { - if (imap_datecmp(itemlist[pos+1], - atol(msg->cm_fields['T'])) >= 0) { + if (!CM_IsEmpty(msg, eTimestamp)) { + if (imap_datecmp(itemlist[pos+1].Key, + atol(msg->cm_fields[eTimestamp])) >= 0) { match = 1; } } @@ -402,40 +379,40 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, pos += 2; } - else if (!strcasecmp(itemlist[pos], "SMALLER")) { + else if (!strcasecmp(itemlist[pos].Key, "SMALLER")) { if (msg == NULL) { - msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); need_to_free_msg = 1; } if (msg != NULL) { - if (strlen(msg->cm_fields['M']) < atoi(itemlist[pos+1])) { + if (msg->cm_lengths[eMesageText] < atoi(itemlist[pos+1].Key)) { match = 1; } } pos += 2; } - else if (!strcasecmp(itemlist[pos], "SUBJECT")) { + else if (!strcasecmp(itemlist[pos].Key, "SUBJECT")) { if (msg == NULL) { - msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); need_to_free_msg = 1; } if (msg != NULL) { - if (bmstrcasestr(msg->cm_fields['U'], itemlist[pos+1])) { + if (bmstrcasestr(msg->cm_fields[eMsgSubject], itemlist[pos+1].Key)) { match = 1; } } pos += 2; } - else if (!strcasecmp(itemlist[pos], "TEXT")) { + else if (!strcasecmp(itemlist[pos].Key, "TEXT")) { if (msg == NULL) { - msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); need_to_free_msg = 1; } if (msg != NULL) { for (i='A'; i<='Z'; ++i) { - if (bmstrcasestr(msg->cm_fields[i], itemlist[pos+1])) { + if (bmstrcasestr(msg->cm_fields[i], itemlist[pos+1].Key)) { match = 1; } } @@ -443,13 +420,13 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, pos += 2; } - else if (!strcasecmp(itemlist[pos], "TO")) { + else if (!strcasecmp(itemlist[pos].Key, "TO")) { if (msg == NULL) { - msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1); + msg = CtdlFetchMessage(Imap->msgids[seq-1], 1); need_to_free_msg = 1; } if (msg != NULL) { - if (bmstrcasestr(msg->cm_fields['R'], itemlist[pos+1])) { + if (bmstrcasestr(msg->cm_fields[eRecipient], itemlist[pos+1].Key)) { match = 1; } } @@ -457,16 +434,16 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, } /* FIXME this is b0rken. fix it. */ - else if (imap_is_message_set(itemlist[pos])) { - if (is_msg_in_sequence_set(itemlist[pos], seq)) { + else if (imap_is_message_set(itemlist[pos].Key)) { + if (is_msg_in_sequence_set(itemlist[pos].Key, seq)) { match = 1; } pos += 1; } /* FIXME this is b0rken. fix it. */ - else if (!strcasecmp(itemlist[pos], "UID")) { - if (is_msg_in_sequence_set(itemlist[pos+1], IMAP->msgids[seq-1])) { + else if (!strcasecmp(itemlist[pos].Key, "UID")) { + if (is_msg_in_sequence_set(itemlist[pos+1].Key, Imap->msgids[seq-1])) { match = 1; } pos += 2; @@ -477,41 +454,41 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, * can't there be *one* way to do things? More gratuitous complexity. */ - else if (!strcasecmp(itemlist[pos], "UNANSWERED")) { - if ((IMAP->flags[seq-1] & IMAP_ANSWERED) == 0) { + else if (!strcasecmp(itemlist[pos].Key, "UNANSWERED")) { + if ((Imap->flags[seq-1] & IMAP_ANSWERED) == 0) { match = 1; } ++pos; } - else if (!strcasecmp(itemlist[pos], "UNDELETED")) { - if ((IMAP->flags[seq-1] & IMAP_DELETED) == 0) { + else if (!strcasecmp(itemlist[pos].Key, "UNDELETED")) { + if ((Imap->flags[seq-1] & IMAP_DELETED) == 0) { match = 1; } ++pos; } - else if (!strcasecmp(itemlist[pos], "UNDRAFT")) { - if ((IMAP->flags[seq-1] & IMAP_DRAFT) == 0) { + else if (!strcasecmp(itemlist[pos].Key, "UNDRAFT")) { + if ((Imap->flags[seq-1] & IMAP_DRAFT) == 0) { match = 1; } ++pos; } - else if (!strcasecmp(itemlist[pos], "UNFLAGGED")) { - if ((IMAP->flags[seq-1] & IMAP_FLAGGED) == 0) { + else if (!strcasecmp(itemlist[pos].Key, "UNFLAGGED")) { + if ((Imap->flags[seq-1] & IMAP_FLAGGED) == 0) { match = 1; } ++pos; } - else if (!strcasecmp(itemlist[pos], "UNKEYWORD")) { + else if (!strcasecmp(itemlist[pos].Key, "UNKEYWORD")) { /* FIXME */ pos += 2; } - else if (!strcasecmp(itemlist[pos], "UNSEEN")) { - if ((IMAP->flags[seq-1] & IMAP_SEEN) == 0) { + else if (!strcasecmp(itemlist[pos].Key, "UNSEEN")) { + if ((Imap->flags[seq-1] & IMAP_SEEN) == 0) { match = 1; } ++pos; @@ -537,7 +514,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, } if (need_to_free_msg) { - CtdlFreeMessage(msg); + CM_Free(msg); } return(match); } @@ -547,7 +524,8 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, * imap_search() calls imap_do_search() to do its actual work, once it's * validated and boiled down the request a bit. */ -void imap_do_search(int num_items, char **itemlist, int is_uid) { +void imap_do_search(int num_items, ConstStr *itemlist, int is_uid) { + citimap *Imap = IMAP; int i, j, k; int fts_num_msgs = 0; long *fts_msgs = NULL; @@ -559,11 +537,16 @@ void imap_do_search(int num_items, char **itemlist, int is_uid) { * client software. Revisit later... */ for (i=0; iCmd, + &itemlist[i], + 1); } - if (itemlist[i][strlen(itemlist[i])-1] == ')') { - itemlist[i][strlen(itemlist[i])-1] = 0; + if (itemlist[i].Key[itemlist[i].len-1] == ')') { + TokenCutRight(&Imap->Cmd, + &itemlist[i], + 1); } } @@ -571,27 +554,27 @@ void imap_do_search(int num_items, char **itemlist, int is_uid) { * text index to disqualify messages that don't have any chance of * matching. (Only do this if the index is enabled!!) */ - if (config.c_enable_fulltext) for (i=0; i<(num_items-1); ++i) { - if (!strcasecmp(itemlist[i], "BODY")) { - CtdlModuleDoSearch(&fts_num_msgs, &fts_msgs, itemlist[i+1], "fulltext"); + if (CtdlGetConfigInt("c_enable_fulltext")) for (i=0; i<(num_items-1); ++i) { + if (!strcasecmp(itemlist[i].Key, "BODY")) { + CtdlModuleDoSearch(&fts_num_msgs, &fts_msgs, itemlist[i+1].Key, "fulltext"); if (fts_num_msgs > 0) { - for (j=0; j < IMAP->num_msgs; ++j) { - if (IMAP->flags[j] & IMAP_SELECTED) { + for (j=0; j < Imap->num_msgs; ++j) { + if (Imap->flags[j] & IMAP_SELECTED) { is_in_list = 0; for (k=0; kmsgids[j] == fts_msgs[k]) { + if (Imap->msgids[j] == fts_msgs[k]) { ++is_in_list; } } } if (!is_in_list) { - IMAP->flags[j] = IMAP->flags[j] & ~IMAP_SELECTED; + Imap->flags[j] = Imap->flags[j] & ~IMAP_SELECTED; } } } else { /* no hits on the index; disqualify every message */ - for (j=0; j < IMAP->num_msgs; ++j) { - IMAP->flags[j] = IMAP->flags[j] & ~IMAP_SELECTED; + for (j=0; j < Imap->num_msgs; ++j) { + Imap->flags[j] = Imap->flags[j] & ~IMAP_SELECTED; } } if (fts_msgs) { @@ -602,24 +585,24 @@ void imap_do_search(int num_items, char **itemlist, int is_uid) { /* Now go through the messages and apply all search criteria. */ buffer_output(); - cprintf("* SEARCH "); - if (IMAP->num_msgs > 0) - for (i = 0; i < IMAP->num_msgs; ++i) - if (IMAP->flags[i] & IMAP_SELECTED) { + IAPuts("* SEARCH "); + if (Imap->num_msgs > 0) + for (i = 0; i < Imap->num_msgs; ++i) + if (Imap->flags[i] & IMAP_SELECTED) { if (imap_do_search_msg(i+1, NULL, num_items, itemlist, is_uid)) { if (num_results != 0) { - cprintf(" "); + IAPuts(" "); } if (is_uid) { - cprintf("%ld", IMAP->msgids[i]); + IAPrintf("%ld", Imap->msgids[i]); } else { - cprintf("%d", i+1); + IAPrintf("%d", i+1); } ++num_results; } } - cprintf("\r\n"); + IAPuts("\r\n"); unbuffer_output(); } @@ -627,11 +610,11 @@ void imap_do_search(int num_items, char **itemlist, int is_uid) { /* * This function is called by the main command loop. */ -void imap_search(int num_parms, char *parms[]) { +void imap_search(int num_parms, ConstStr *Params) { int i; if (num_parms < 3) { - cprintf("%s BAD invalid parameters\r\n", parms[0]); + IReply("BAD invalid parameters"); return; } @@ -639,18 +622,18 @@ void imap_search(int num_parms, char *parms[]) { IMAP->flags[i] |= IMAP_SELECTED; } - imap_do_search(num_parms-2, &parms[2], 0); - cprintf("%s OK SEARCH completed\r\n", parms[0]); + imap_do_search(num_parms-2, &Params[2], 0); + IReply("OK SEARCH completed"); } /* * This function is called by the main command loop. */ -void imap_uidsearch(int num_parms, char *parms[]) { +void imap_uidsearch(int num_parms, ConstStr *Params) { int i; if (num_parms < 4) { - cprintf("%s BAD invalid parameters\r\n", parms[0]); + IReply("BAD invalid parameters"); return; } @@ -658,8 +641,8 @@ void imap_uidsearch(int num_parms, char *parms[]) { IMAP->flags[i] |= IMAP_SELECTED; } - imap_do_search(num_parms-3, &parms[3], 1); - cprintf("%s OK UID SEARCH completed\r\n", parms[0]); + imap_do_search(num_parms-3, &Params[3], 1); + IReply("OK UID SEARCH completed"); }