-/*
- * Implements IMAP's gratuitously complex SEARCH command.
- *
- * Copyright (c) 2001-2020 by the citadel.org team
- *
- * 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.
- */
+// Implements IMAP's gratuitously complex SEARCH command.
+//
+// Copyright (c) 2001-2024 by the citadel.org team
+//
+// This program is open source software. Use, duplication, or disclosure is subject to the GNU General Public License v3.
#include "../../ctdl_module.h"
-
-
#include "../../sysdep.h"
#include <stdlib.h>
#include <unistd.h>
#include "imap_fetch.h"
#include "imap_search.h"
#include "../../genstamp.h"
+#include "../fulltext/serv_fulltext.h"
/*
* message after it has been fetched from the disk. This function returns
* nonzero if there is a match.
*
- * supplied_msg MAY be used to pass a pointer to the message in memory,
+ * msg_in MAY be used to pass a pointer to the message in memory,
* if for some reason it's already been loaded. If not, the message will
* be loaded only if one or more search criteria require it.
*/
-int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
+int imap_do_search_msg(int seq, struct CtdlMessage *msg_in,
int num_items, ConstStr *itemlist, int is_uid) {
citimap *Imap = IMAP;
if (num_items == 0) {
return(0);
}
- msg = supplied_msg;
+ msg = msg_in;
/* Initially we start at the beginning. */
pos = 0;
need_to_free_msg = 1;
}
if (msg != NULL) {
- fieldptr = rfc822_fetch_field(msg->cm_fields[eMesageText], "Bcc");
+ fieldptr = rfc822_fetch_field(msg->cm_fields[eMessageText], "Bcc");
if (fieldptr != NULL) {
if (bmstrcasestr(fieldptr, itemlist[pos+1].Key)) {
match = 1;
need_to_free_msg = 1;
}
if (msg != NULL) {
- if (bmstrcasestr(msg->cm_fields[eMesageText], itemlist[pos+1].Key)) {
+ if (bmstrcasestr(msg->cm_fields[eMessageText], itemlist[pos+1].Key)) {
match = 1;
}
}
}
}
else {
- fieldptr = rfc822_fetch_field(msg->cm_fields[eMesageText], "Cc");
+ fieldptr = rfc822_fetch_field(msg->cm_fields[eMessageText], "Cc");
if (fieldptr != NULL) {
if (bmstrcasestr(fieldptr, itemlist[pos+1].Key)) {
match = 1;
need_to_free_msg = 1;
}
if (msg != NULL) {
- if (msg->cm_lengths[eMesageText] > atoi(itemlist[pos+1].Key)) {
+ if (msg->cm_lengths[eMessageText] > atoi(itemlist[pos+1].Key)) {
match = 1;
}
}
need_to_free_msg = 1;
}
if (msg != NULL) {
- if (msg->cm_lengths[eMesageText] < atoi(itemlist[pos+1].Key)) {
+ if (msg->cm_lengths[eMessageText] < atoi(itemlist[pos+1].Key)) {
match = 1;
}
}
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;
int is_in_list = 0;
int num_results = 0;
+ Array *fts = NULL;
/* Strip parentheses. We realize that this method will not work
* in all cases, but it seems to work with all currently available
*/
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) {
+ fts = CtdlFullTextSearch(itemlist[i+1].Key);
+ if ((fts) && (array_len(fts) > 0)) {
for (j=0; j < Imap->num_msgs; ++j) {
if (Imap->flags[j] & IMAP_SELECTED) {
is_in_list = 0;
- for (k=0; k<fts_num_msgs; ++k) {
- if (Imap->msgids[j] == fts_msgs[k]) {
+ for (k=0; k<array_len(fts); ++k) {
+ long smsgnum;
+ memcpy(&smsgnum, array_get_element_at(fts, k), sizeof(long));
+ if (Imap->msgids[j] == smsgnum) {
++is_in_list;
}
}
Imap->flags[j] = Imap->flags[j] & ~IMAP_SELECTED;
}
}
- if (fts_msgs) {
- free(fts_msgs);
+ if (fts) {
+ array_free(fts);
}
}
}