validate_recipients() remove extra copy of recipients
[citadel.git] / citadel / server / modules / imap / imap_search.c
index 03678d296db47ab9819d4b22036f1d407d01fa13..1ea13ad3e024243fc1dae7b4da369ee68bff4eff 100644 (file)
@@ -1,20 +1,10 @@
-/*
- * 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>
@@ -45,6 +35,7 @@
 #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;
@@ -72,7 +63,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
        if (num_items == 0) {
                return(0);
        }
-       msg = supplied_msg;
+       msg = msg_in;
 
        /* Initially we start at the beginning. */
        pos = 0;
@@ -108,7 +99,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
                        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;
@@ -151,7 +142,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
                                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;
                                }
                        }
@@ -173,7 +164,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
                                }
                        }
                        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;
@@ -264,7 +255,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
                        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;
                        }
                }
@@ -385,7 +376,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
                        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;
                        }
                }
@@ -525,10 +516,9 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
 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
@@ -549,13 +539,15 @@ void imap_do_search(int num_items, ConstStr *itemlist, int is_uid) {
         */
        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;
                                                        }
                                                }
@@ -570,8 +562,8 @@ void imap_do_search(int num_items, ConstStr *itemlist, int is_uid) {
                                        Imap->flags[j] = Imap->flags[j] & ~IMAP_SELECTED;
                                }
                        }
-                       if (fts_msgs) {
-                               free(fts_msgs);
+                       if (fts) {
+                               array_free(fts);
                        }
                }
        }