dammit, learn to spell
[citadel.git] / citadel / server / modules / autocompletion / serv_autocompletion.c
index 732bd714534d2bd8896a9f80daa7eda38dac6e51..413bf472b739920999baeff92ae7e3768206cecb 100644 (file)
@@ -1,27 +1,19 @@
-/*
- * Autocompletion of email recipients, etc.
- *
- * Copyright (c) 1987-2022 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.
- */
-
+// Autocompletion of email recipients, etc.
+//
+// Copyright (c) 1987-2023 by the citadel.org team
+//
+// This program is open source software.  Use, duplication, or disclosure
+// is subject to the terms of the GNU General Public License version 3.
 
 #include "../../ctdl_module.h"
 #include "serv_autocompletion.h"
 #include "../../config.h"
+#include "../../room_ops.h"
+#include "../fulltext/serv_fulltext.h"
 
 
-/*
- * Convert a structured name into a friendly name.  Caller must free the
- * returned pointer.
- */
+// Convert a structured name into a friendly name.  Caller must free the
+// returned pointer.
 char *n_to_fn(char *value) {
        char *nnn = NULL;
        int i;
@@ -41,16 +33,12 @@ char *n_to_fn(char *value) {
        for (i=0; i<strlen(nnn); ++i) {
                if (!strncmp(&nnn[i], "  ", 2)) strcpy(&nnn[i], &nnn[i+1]);
        }
-       striplt(nnn);
+       string_trim(nnn);
        return(nnn);
 }
 
 
-
-
-/*
- * Back end for cmd_auto()
- */
+// Back end for cmd_auto()
 void hunt_for_autocomplete(long msgnum, char *search_string) {
        struct CtdlMessage *msg;
        struct vCard *v;
@@ -62,14 +50,12 @@ void hunt_for_autocomplete(long msgnum, char *search_string) {
        msg = CtdlFetchMessage(msgnum, 1);
        if (msg == NULL) return;
 
-       v = vcard_load(msg->cm_fields[eMesageText]);
+       v = vcard_load(msg->cm_fields[eMessageText]);
        CM_Free(msg);
 
-       /*
-        * Try to match from a friendly name (the "fn" field).  If there is
-        * a match, return the entry in the form of:
-        *     Display Name <user@domain.org>
-        */
+       // Try to match from a friendly name (the "fn" field).  If there is
+       // a match, return the entry in the form of:
+       //     Display Name <user@domain.org>
        value = vcard_get_prop(v, "fn", 0, 0, 0);
        if (value != NULL) if (bmstrcasestr(value, search_string)) {
                value2 = vcard_get_prop(v, "email", 1, 0, 0);
@@ -79,11 +65,9 @@ void hunt_for_autocomplete(long msgnum, char *search_string) {
                return;
        }
 
-       /*
-        * Try to match from a structured name (the "n" field).  If there is
-        * a match, return the entry in the form of:
-        *     Display Name <user@domain.org>
-        */
+       // Try to match from a structured name (the "n" field).  If there is
+       // a match, return the entry in the form of:
+       //     Display Name <user@domain.org>
        value = vcard_get_prop(v, "n", 0, 0, 0);
        if (value != NULL) if (bmstrcasestr(value, search_string)) {
 
@@ -96,9 +80,7 @@ void hunt_for_autocomplete(long msgnum, char *search_string) {
                return;
        }
 
-       /*
-        * Try a partial match on all listed email addresses.
-        */
+       // Try a partial match on all listed email addresses.
        i = 0;
        while (value = vcard_get_prop(v, "email", 1, i++, 0), value != NULL) {
                if (bmstrcasestr(value, search_string)) {
@@ -109,7 +91,6 @@ void hunt_for_autocomplete(long msgnum, char *search_string) {
                                nnn = n_to_fn(vcard_get_prop(v, "n", 0, 0, 0));
                                cprintf("%s <%s>\n", nnn, value);
                                free(nnn);
-                       
                        }
                        else {
                                cprintf("%s\n", value);
@@ -123,90 +104,74 @@ void hunt_for_autocomplete(long msgnum, char *search_string) {
 }
 
 
-
-/*
- * Attempt to autocomplete an address based on a partial...
- */
+// Attempt to autocomplete an address based on a partial...
 void cmd_auto(char *argbuf) {
        char hold_rm[ROOMNAMELEN];
        char search_string[256];
        long *msglist = NULL;
        int num_msgs = 0;
-       long *fts_msgs = NULL;
-       int fts_num_msgs = 0;
-       struct cdbdata *cdbfr;
        int r = 0;
        int i = 0;
        int j = 0;
        int search_match = 0;
        char *rooms_to_try[] = { USERCONTACTSROOM, ADDRESS_BOOK_ROOM };
+       Array *fts = NULL;
                
        if (CtdlAccessCheck(ac_logged_in)) return;
        extract_token(search_string, argbuf, 0, '|', sizeof search_string);
        if (IsEmptyStr(search_string)) {
-               cprintf("%d You supplied an empty partial.\n",
-                       ERROR + ILLEGAL_VALUE);
+               cprintf("%d You supplied an empty partial.\n", ERROR + ILLEGAL_VALUE);
                return;
        }
 
-       strcpy(hold_rm, CC->room.QRname);       /* save current room */
+       strcpy(hold_rm, CC->room.QRname);                        // save where we were so we can go back
        cprintf("%d try these:\n", LISTING_FOLLOWS);
 
-       /*
-        * Gather up message pointers in rooms containing vCards
-        */
+       // Gather up message pointers in rooms containing vCards
        for (r=0; r < (sizeof(rooms_to_try) / sizeof(char *)); ++r) {
                if (CtdlGetRoom(&CC->room, rooms_to_try[r]) == 0) {
-                       cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->room.QRnumber, sizeof(long));
-                       if (cdbfr != NULL) {
-                               msglist = realloc(msglist, (num_msgs * sizeof(long)) + cdbfr->len + 1);
-                               memcpy(&msglist[num_msgs], cdbfr->ptr, cdbfr->len);
-                               num_msgs += (cdbfr->len / sizeof(long));
-                               cdb_free(cdbfr);
-                       }
-               }
-       }
-
-       /*
-        * Search-reduce the results if we have the full text index available
-        */
-       if (CtdlGetConfigInt("c_enable_fulltext")) {
-               CtdlModuleDoSearch(&fts_num_msgs, &fts_msgs, search_string, "fulltext");
-               if (fts_msgs) {
-                       for (i=0; i<num_msgs; ++i) {
-                               search_match = 0;
-                               for (j=0; j<fts_num_msgs; ++j) {
-                                       if (msglist[i] == fts_msgs[j]) {
-                                               search_match = 1;
-                                               j = fts_num_msgs + 1;   /* end the search */
+                       num_msgs = CtdlFetchMsgList(CC->room.QRnumber, &msglist);
+
+                       // Search-reduce the results if we have the full text index available
+                       if (CtdlGetConfigInt("c_enable_fulltext")) {
+                               fts = CtdlFullTextSearch(search_string);
+                               if (fts) {
+                                       for (i=0; i<num_msgs; ++i) {
+                                               search_match = 0;
+                                               for (j=0; j<array_len(fts); ++j) {
+                                                       long smsgnum;
+                                                       memcpy(&smsgnum, array_get_element_at(fts, j), sizeof(long));
+                                                       if (msglist[i] == smsgnum) {
+                                                               search_match = 1;
+                                                               j = array_len(fts) + 1; // end the search 
+                                                       }
+                                               }
+                                               if (!search_match) {
+                                                       msglist[i] = 0;                 // invalidate this result
+                                               }
                                        }
+                                       array_free(fts);
                                }
-                               if (!search_match) {
-                                       msglist[i] = 0;         /* invalidate this result */
+                               else {
+                                       // If no results, invalidate the whole list
+                                       free(msglist);
+                                       msglist = NULL;
+                                       num_msgs = 0;
+                               }
+                       }
+               
+                       // Now output the ones that look interesting
+                       if (num_msgs > 0) for (i=0; i<num_msgs; ++i) {
+                               if (msglist[i] != 0) {
+                                       hunt_for_autocomplete(msglist[i], search_string);
                                }
                        }
-                       free(fts_msgs);
-               }
-               else {
-                       /* If no results, invalidate the whole list */
-                       free(msglist);
-                       msglist = NULL;
-                       num_msgs = 0;
-               }
-       }
-
-       /*
-        * Now output the ones that look interesting
-        */
-       if (num_msgs > 0) for (i=0; i<num_msgs; ++i) {
-               if (msglist[i] != 0) {
-                       hunt_for_autocomplete(msglist[i], search_string);
                }
        }
        
        cprintf("000\n");
        if (strcmp(CC->room.QRname, hold_rm)) {
-               CtdlGetRoom(&CC->room, hold_rm);    /* return to saved room */
+               CtdlGetRoom(&CC->room, hold_rm);                                        // return to saved room
        }
 
        if (msglist) {
@@ -216,10 +181,11 @@ void cmd_auto(char *argbuf) {
 }
 
 
+// Initialization function, called from modules_init.c
 char *ctdl_module_init_autocompletion(void) {
        if (!threading) {
                CtdlRegisterProtoHook(cmd_auto, "AUTO", "Do recipient autocompletion");
        }
-       /* return our module name for the log */
+       // return our module name for the log
        return "autocompletion";
 }