]> arthur.barton.de Git - netatalk.git/commitdiff
Case-insensitive name search with the CNID db
authorFrank Lahm <franklahm@googlemail.com>
Tue, 7 Dec 2010 16:02:05 +0000 (17:02 +0100)
committerFrank Lahm <franklahm@googlemail.com>
Tue, 7 Dec 2010 16:02:05 +0000 (17:02 +0100)
NEWS
etc/afpd/catsearch.c
etc/afpd/volume.c
etc/cnid_dbd/main.c
etc/cnid_dbd/pack.c

diff --git a/NEWS b/NEWS
index 453f20e6f97c8aba9733495d27b7b26f1328654d..6db4f23a58a75ee6a170cc587f808b0d75aafd80 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ Changes in 2.2alpha5
 
 * UPD: afpd: new option "searchdb" which enables fast catalog searches
        using the CNID db.
+* FIX: Case-insensitive fast search with the CNID db
 
 Changes in 2.2alpha4
 ====================
index 4ef8be4317fee15b6e57469e43cda62b23b9947a..0faeef9494b92619dd6cbcf2f905d6ce88a12dd8 100644 (file)
@@ -46,6 +46,7 @@
 #include <atalk/cnid_dbd_private.h>
 #include <atalk/util.h>
 #include <atalk/bstradd.h>
+#include <atalk/unicode.h>
 
 #include "desktop.h"
 #include "directory.h"
@@ -707,6 +708,8 @@ static int catsearch_db(struct vol *vol,
        int result = AFP_OK;
     struct path path;
        char *rrbuf = rbuf;
+    char buffer[MAXPATHLEN +2];
+    uint16_t flags = CONV_TOLOWER;
 
     LOG(log_debug, logtype_afpd, "catsearch_db(req pos: %u): {pos: %u, name: %s}",
         *pos, cur_pos, uname);
@@ -717,8 +720,23 @@ static int catsearch_db(struct vol *vol,
        }
 
     if (cur_pos == 0 || *pos == 0) {
+        if (convert_charset(vol->v_volcharset,
+                            vol->v_volcharset,
+                            vol->v_maccharset,
+                            uname,
+                            strlen(uname),
+                            buffer,
+                            MAXPATHLEN,
+                            &flags) == (size_t)-1) {
+            LOG(log_error, logtype_cnid, "catsearch_db: conversion error");
+            result = AFPERR_MISC;
+            goto catsearch_end;
+        }
+
+        LOG(log_debug, logtype_afpd, "catsearch_db: %s", buffer);
+
         if ((num_matches = cnid_find(vol->v_cdb,
-                                     uname,
+                                     buffer,
                                      strlen(uname),
                                      resbuf,
                                      sizeof(resbuf))) == -1) {
index 507a8eeb9782b45db4815c148cda7e163e378fec..e53599b0149202940c62436733b307106c42abee 100644 (file)
@@ -1939,7 +1939,7 @@ static int volume_openDB(struct vol *volume)
     }
 #endif
 
-    volume->v_cdb = cnid_open(volume->v_dbpath ? volume->v_dbpath : volume->v_path,
+    volume->v_cdb = cnid_open(volume->v_path,
                               volume->v_umask,
                               volume->v_cnidscheme,
                               flags,
index 91027157292ea7dea5d85373b1c948cf95959d37..7c895eaea36724f57b8035ff2077baebcd8af317 100644 (file)
@@ -32,6 +32,7 @@
 #include <netatalk/endian.h>
 #include <atalk/cnid_dbd_private.h>
 #include <atalk/logger.h>
+#include <atalk/volinfo.h>
 
 #include "db_param.h"
 #include "dbif.h"
  */
 #define DBOPTIONS (DB_CREATE | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_TXN | DB_RECOVER)
 
-static DBD *dbd;
+/* Global */
+struct volinfo volinfo;
 
+static DBD *dbd;
 static int exit_sig = 0;
 
 static void sig_exit(int signo)
@@ -338,14 +341,24 @@ int main(int argc, char *argv[])
     logconfig = strdup(argv[4]);
     setuplog(logconfig);
 
+    /* Load .volinfo file */
+    if (loadvolinfo(dir, &volinfo) == -1) {
+        LOG(log_error, logtype_cnid, "Cant load volinfo for \"%s\"", dir);
+        exit(EXIT_FAILURE);
+    }
+    dir = volinfo.v_dbpath;
+    if (vol_load_charsets(&volinfo) == -1) {
+        LOG(log_error, logtype_cnid, "Error loading charsets!");
+        exit(EXIT_FAILURE);
+    }
+    LOG(log_note, logtype_cnid, "db dir: \"%s\"", dir);
+
     switch_to_user(dir);
 
     /* Before we do anything else, check if there is an instance of cnid_dbd
        running already and silently exit if yes. */
     lockfd = get_lock();
 
-    LOG(log_info, logtype_cnid, "Startup, DB dir %s", dir);
-
     set_signal();
 
     /* SIGINT and SIGTERM are always off, unless we are in pselect */
index eb90d85809b5f45af70e5736e7990e8d1beb26eb..7350f8032595d19b54174d6313620ee3db7592e8 100644 (file)
 #include <netatalk/endian.h>
 
 #include <string.h>
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif /* HAVE_SYS_TYPES_H */
+#include <inttypes.h>
 #include <sys/param.h>
 #include <sys/cdefs.h>
 #include <db.h>
 
+#include <atalk/unicode.h>
+#include <atalk/volinfo.h>
+#include <atalk/logger.h>
 #include <atalk/cnid_dbd_private.h>
 #include "pack.h"
 
+/* in main.c */
+extern struct volinfo volinfo;
+
 /* --------------- */
 /*
  *  This implementation is portable, but could probably be faster by using htonl
@@ -74,9 +78,24 @@ int devino(DB *dbp _U_, const DBT *pkey _U_,  const DBT *pdata, DBT *skey)
 /* --------------- */
 int idxname(DB *dbp _U_, const DBT *pkey _U_,  const DBT *pdata, DBT *skey)
 {
+    char buffer[MAXPATHLEN +2];
+    uint16_t flags = CONV_TOLOWER;
     memset(skey, 0, sizeof(DBT));
     skey->data = (char *)pdata->data + CNID_NAME_OFS;
-    skey->size = strlen((char *)skey->data) + 1;
+
+    if (convert_charset(volinfo.v_volcharset,
+                        volinfo.v_volcharset,
+                        volinfo.v_maccharset,
+                        (char *)pdata->data + CNID_NAME_OFS,
+                        strlen((char *)pdata->data + CNID_NAME_OFS),
+                        buffer,
+                        MAXPATHLEN,
+                        &flags) == (size_t)-1) {
+        LOG(log_error, logtype_cnid, "idxname: conversion error");
+    }
+
+    skey->data = buffer;
+    skey->size = strlen(skey->data);
     return (0);
 }