X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fimap%2Fimap_search.c;h=aaa02dbe23260e4c3fbd8e22aa3317552b09df0f;hb=e6219cc9b27e56e3b41170f864da30fa7b13ee01;hp=4972e98e74216341e90a516ff30e70db99edc5e2;hpb=984583756d062536382d78da5ffc70eba9378bfb;p=citadel.git diff --git a/citadel/modules/imap/imap_search.c b/citadel/modules/imap/imap_search.c index 4972e98e7..aaa02dbe2 100644 --- a/citadel/modules/imap/imap_search.c +++ b/citadel/modules/imap/imap_search.c @@ -1,24 +1,21 @@ /* - * $Id$ - * * Implements IMAP's gratuitously complex SEARCH command. * + * Copyright (c) 2001-2012 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 + * + * + * */ #include "ctdl_module.h" @@ -57,12 +54,11 @@ #include "support.h" #include "config.h" #include "user_ops.h" -#include "policy.h" #include "database.h" #include "msgbase.h" #include "internet_addressing.h" -#include "imap_tools.h" #include "serv_imap.h" +#include "imap_tools.h" #include "imap_fetch.h" #include "imap_search.h" #include "genstamp.h" @@ -80,6 +76,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, int num_items, ConstStr *itemlist, int is_uid) { + citimap *Imap = IMAP; int match = 0; int is_not = 0; int is_or = 0; @@ -116,7 +113,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, } else if (!strcasecmp(itemlist[pos].Key, "ANSWERED")) { - if (IMAP->flags[seq-1] & IMAP_ANSWERED) { + if (Imap->flags[seq-1] & IMAP_ANSWERED) { match = 1; } ++pos; @@ -124,11 +121,11 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, 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].Key)) { match = 1; @@ -141,13 +138,13 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, 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 (!CM_IsEmpty(msg, eTimestamp)) { if (imap_datecmp(itemlist[pos+1].Key, - atol(msg->cm_fields['T'])) < 0) { + atol(msg->cm_fields[eTimestamp])) < 0) { match = 1; } } @@ -167,11 +164,11 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, /* 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].Key)) { + if (bmstrcasestr(msg->cm_fields[eMesageText], itemlist[pos+1].Key)) { match = 1; } } @@ -182,18 +179,18 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, 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].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].Key)) { match = 1; @@ -206,21 +203,21 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, } else if (!strcasecmp(itemlist[pos].Key, "DELETED")) { - if (IMAP->flags[seq-1] & IMAP_DELETED) { + if (Imap->flags[seq-1] & IMAP_DELETED) { match = 1; } ++pos; } else if (!strcasecmp(itemlist[pos].Key, "DRAFT")) { - if (IMAP->flags[seq-1] & IMAP_DRAFT) { + if (Imap->flags[seq-1] & IMAP_DRAFT) { match = 1; } ++pos; } else if (!strcasecmp(itemlist[pos].Key, "FLAGGED")) { - if (IMAP->flags[seq-1] & IMAP_FLAGGED) { + if (Imap->flags[seq-1] & IMAP_FLAGGED) { match = 1; } ++pos; @@ -228,14 +225,14 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, 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].Key)) { + if (bmstrcasestr(msg->cm_fields[eAuthor], itemlist[pos+1].Key)) { match = 1; } - if (bmstrcasestr(msg->cm_fields['F'], itemlist[pos+1].Key)) { + if (bmstrcasestr(msg->cm_fields[erFc822Addr], itemlist[pos+1].Key)) { match = 1; } } @@ -250,7 +247,7 @@ 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; } @@ -280,11 +277,11 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, 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].Key)) { + if (strlen(msg->cm_fields[eMesageText]) > atoi(itemlist[pos+1].Key)) { match = 1; } } @@ -292,14 +289,14 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, } else if (!strcasecmp(itemlist[pos].Key, "NEW")) { - if ( (IMAP->flags[seq-1] & IMAP_RECENT) && (!(IMAP->flags[seq-1] & IMAP_SEEN))) { + if ( (Imap->flags[seq-1] & IMAP_RECENT) && (!(Imap->flags[seq-1] & IMAP_SEEN))) { match = 1; } ++pos; } else if (!strcasecmp(itemlist[pos].Key, "OLD")) { - if (!(IMAP->flags[seq-1] & IMAP_RECENT)) { + if (!(Imap->flags[seq-1] & IMAP_RECENT)) { match = 1; } ++pos; @@ -307,13 +304,13 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, 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 (!CM_IsEmpty(msg, eTimestamp)) { if (imap_datecmp(itemlist[pos+1].Key, - atol(msg->cm_fields['T'])) == 0) { + atol(msg->cm_fields[eTimestamp])) == 0) { match = 1; } } @@ -322,14 +319,14 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, } else if (!strcasecmp(itemlist[pos].Key, "RECENT")) { - if (IMAP->flags[seq-1] & IMAP_RECENT) { + if (Imap->flags[seq-1] & IMAP_RECENT) { match = 1; } ++pos; } else if (!strcasecmp(itemlist[pos].Key, "SEEN")) { - if (IMAP->flags[seq-1] & IMAP_SEEN) { + if (Imap->flags[seq-1] & IMAP_SEEN) { match = 1; } ++pos; @@ -337,13 +334,13 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, 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 (!CM_IsEmpty(msg, eTimestamp)) { if (imap_datecmp(itemlist[pos+1].Key, - atol(msg->cm_fields['T'])) < 0) { + atol(msg->cm_fields[eTimestamp])) < 0) { match = 1; } } @@ -353,13 +350,13 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, 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 (!CM_IsEmpty(msg, eTimestamp)) { if (imap_datecmp(itemlist[pos+1].Key, - atol(msg->cm_fields['T'])) == 0) { + atol(msg->cm_fields[eTimestamp])) == 0) { match = 1; } } @@ -369,13 +366,13 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, 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 (!CM_IsEmpty(msg, eTimestamp)) { if (imap_datecmp(itemlist[pos+1].Key, - atol(msg->cm_fields['T'])) >= 0) { + atol(msg->cm_fields[eTimestamp])) >= 0) { match = 1; } } @@ -385,13 +382,13 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, 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 (!CM_IsEmpty(msg, eTimestamp)) { if (imap_datecmp(itemlist[pos+1].Key, - atol(msg->cm_fields['T'])) >= 0) { + atol(msg->cm_fields[eTimestamp])) >= 0) { match = 1; } } @@ -401,11 +398,11 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, 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].Key)) { + if (strlen(msg->cm_fields[eMesageText]) < atoi(itemlist[pos+1].Key)) { match = 1; } } @@ -414,11 +411,11 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, 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].Key)) { + if (bmstrcasestr(msg->cm_fields[eMsgSubject], itemlist[pos+1].Key)) { match = 1; } } @@ -427,7 +424,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, 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) { @@ -442,11 +439,11 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, 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].Key)) { + if (bmstrcasestr(msg->cm_fields[eRecipient], itemlist[pos+1].Key)) { match = 1; } } @@ -463,7 +460,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, /* FIXME this is b0rken. fix it. */ else if (!strcasecmp(itemlist[pos].Key, "UID")) { - if (is_msg_in_sequence_set(itemlist[pos+1].Key, IMAP->msgids[seq-1])) { + if (is_msg_in_sequence_set(itemlist[pos+1].Key, Imap->msgids[seq-1])) { match = 1; } pos += 2; @@ -475,28 +472,28 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, */ else if (!strcasecmp(itemlist[pos].Key, "UNANSWERED")) { - if ((IMAP->flags[seq-1] & IMAP_ANSWERED) == 0) { + if ((Imap->flags[seq-1] & IMAP_ANSWERED) == 0) { match = 1; } ++pos; } else if (!strcasecmp(itemlist[pos].Key, "UNDELETED")) { - if ((IMAP->flags[seq-1] & IMAP_DELETED) == 0) { + if ((Imap->flags[seq-1] & IMAP_DELETED) == 0) { match = 1; } ++pos; } else if (!strcasecmp(itemlist[pos].Key, "UNDRAFT")) { - if ((IMAP->flags[seq-1] & IMAP_DRAFT) == 0) { + if ((Imap->flags[seq-1] & IMAP_DRAFT) == 0) { match = 1; } ++pos; } else if (!strcasecmp(itemlist[pos].Key, "UNFLAGGED")) { - if ((IMAP->flags[seq-1] & IMAP_FLAGGED) == 0) { + if ((Imap->flags[seq-1] & IMAP_FLAGGED) == 0) { match = 1; } ++pos; @@ -508,7 +505,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, } else if (!strcasecmp(itemlist[pos].Key, "UNSEEN")) { - if ((IMAP->flags[seq-1] & IMAP_SEEN) == 0) { + if ((Imap->flags[seq-1] & IMAP_SEEN) == 0) { match = 1; } ++pos; @@ -545,6 +542,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, * validated and boiled down the request a bit. */ 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; @@ -558,12 +556,12 @@ void imap_do_search(int num_items, ConstStr *itemlist, int is_uid) { for (i=0; iCmd, + TokenCutLeft(&Imap->Cmd, &itemlist[i], 1); } if (itemlist[i].Key[itemlist[i].len-1] == ')') { - TokenCutRight(&IMAP->Cmd, + TokenCutRight(&Imap->Cmd, &itemlist[i], 1); } @@ -577,23 +575,23 @@ void imap_do_search(int num_items, ConstStr *itemlist, int is_uid) { 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) { @@ -604,24 +602,24 @@ void imap_do_search(int num_items, ConstStr *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(); } @@ -633,7 +631,7 @@ void imap_search(int num_parms, ConstStr *Params) { int i; if (num_parms < 3) { - cprintf("%s BAD invalid parameters\r\n", Params[0].Key); + IReply("BAD invalid parameters"); return; } @@ -642,7 +640,7 @@ void imap_search(int num_parms, ConstStr *Params) { } imap_do_search(num_parms-2, &Params[2], 0); - cprintf("%s OK SEARCH completed\r\n", Params[0].Key); + IReply("OK SEARCH completed"); } /* @@ -652,7 +650,7 @@ void imap_uidsearch(int num_parms, ConstStr *Params) { int i; if (num_parms < 4) { - cprintf("%s BAD invalid parameters\r\n", Params[0].Key); + IReply("BAD invalid parameters"); return; } @@ -661,7 +659,7 @@ void imap_uidsearch(int num_parms, ConstStr *Params) { } imap_do_search(num_parms-3, &Params[3], 1); - cprintf("%s OK UID SEARCH completed\r\n", Params[0].Key); + IReply("OK UID SEARCH completed"); }