]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/catsearch.c
Merge branch 'master' of git://netatalk.git.sourceforge.net/gitroot/netatalk/netatalk...
[netatalk.git] / etc / afpd / catsearch.c
index 0faeef9494b92619dd6cbcf2f905d6ce88a12dd8..89a6d5733aed67b6c13de4d41f8b3f357928d0c2 100644 (file)
 #include <atalk/util.h>
 #include <atalk/bstradd.h>
 #include <atalk/unicode.h>
+#include <atalk/globals.h>
 
 #include "desktop.h"
 #include "directory.h"
 #include "dircache.h"
 #include "file.h"
 #include "volume.h"
-#include "globals.h"
 #include "filedir.h"
 #include "fork.h"
 
@@ -108,7 +108,8 @@ struct scrit {
  *
  */
 struct dsitem {
-       struct dir *dir; /* Structure describing this directory */
+//     struct dir *dir; /* Structure describing this directory */
+//  cnid_t did;      /* CNID of this directory           */
        int pidx;        /* Parent's dsitem structure index. */
        int checked;     /* Have we checked this directory ? */
        int path_len;
@@ -118,31 +119,43 @@ struct dsitem {
 
 #define DS_BSIZE 128
 static int save_cidx = -1; /* Saved index of currently scanned directory. */
-
 static struct dsitem *dstack = NULL; /* Directory stack data... */
 static int dssize = 0;              /* Directory stack (allocated) size... */
 static int dsidx = 0;               /* First free item index... */
-
 static struct scrit c1, c2;          /* search criteria */
 
+/* Clears directory stack. */
+static void clearstack(void) 
+{
+       save_cidx = -1;
+       while (dsidx > 0) {
+               dsidx--;
+               free(dstack[dsidx].path);
+       }
+}
+
 /* Puts new item onto directory stack. */
 static int addstack(char *uname, struct dir *dir, int pidx)
 {
        struct dsitem *ds;
        size_t         l, u;
+    struct dsitem *tmpds = NULL;
 
        /* check if we have some space on stack... */
        if (dsidx >= dssize) {
                dssize += DS_BSIZE;
-               dstack = realloc(dstack, dssize * sizeof(struct dsitem));       
-               if (dstack == NULL)
+               tmpds = realloc(dstack, dssize * sizeof(struct dsitem));        
+               if (tmpds == NULL) {
+            clearstack();
+            free(dstack);
                        return -1;
+        }
+        dstack = tmpds;
        }
 
        /* Put new element. Allocate and copy lname and path. */
        ds = dstack + dsidx++;
-       ds->dir = dir;
-    dir->d_flags |= DIRF_CACHELOCK;
+//     ds->did = dir->d_did;
        ds->pidx = pidx;
        ds->checked = 0;
        if (pidx >= 0) {
@@ -175,7 +188,6 @@ static int reducestack(void)
        while (dsidx > 0) {
                if (dstack[dsidx-1].checked) {
                        dsidx--;
-            dstack[dsidx].dir->d_flags &= ~DIRF_CACHELOCK;
                        free(dstack[dsidx].path);
                } else
                        return dsidx - 1;
@@ -183,17 +195,6 @@ static int reducestack(void)
        return -1;
 } 
 
-/* Clears directory stack. */
-static void clearstack(void) 
-{
-       save_cidx = -1;
-       while (dsidx > 0) {
-               dsidx--;
-        dstack[dsidx].dir->d_flags &= ~DIRF_CACHELOCK;
-               free(dstack[dsidx].path);
-       }
-} 
-
 /* Looks up for an opened adouble structure, opens resource fork of selected file. 
  * FIXME What about noadouble?
 */
@@ -506,6 +507,7 @@ static int catsearch(struct vol *vol,
 {
     static u_int32_t cur_pos;    /* Saved position index (ID) - used to remember "position" across FPCatSearch calls */
     static DIR *dirpos;                 /* UNIX structure describing currently opened directory. */
+    struct dir *currentdir;      /* struct dir of current directory */
        int cidx, r;
        struct dirent *entry;
        int result = AFP_OK;
@@ -551,6 +553,8 @@ static int catsearch(struct vol *vol,
     start_time = time(NULL);
 
        while ((cidx = reducestack()) != -1) {
+        LOG(log_debug, logtype_afpd, "catsearch: dir: \"%s\"", dstack[cidx].path);
+
                error = lchdir(dstack[cidx].path);
 
                if (!error && dirpos == NULL)
@@ -576,13 +580,22 @@ static int catsearch(struct vol *vol,
                        } /* switch (errno) */
                        goto catsearch_end;
                }
+
+        if ((currentdir = dirlookup_bypath(vol, dstack[cidx].path)) == NULL) {
+            result = AFPERR_MISC;
+            goto catsearch_end;
+        }
+        LOG(log_debug, logtype_afpd, "catsearch: current struct dir: \"%s\"", cfrombstr(currentdir->d_fullpath));
                
-               while ((entry=readdir(dirpos)) != NULL) {
+               while ((entry = readdir(dirpos)) != NULL) {
                        (*pos)++;
 
                        if (!check_dirent(vol, entry->d_name))
                           continue;
 
+            LOG(log_debug, logtype_afpd, "catsearch(\"%s\"): dirent: \"%s\"",
+                cfrombstr(currentdir->d_fullpath), entry->d_name);
+
                        memset(&path, 0, sizeof(path));
                        path.u_name = entry->d_name;
                        if (of_stat(&path) != 0) {
@@ -606,10 +619,16 @@ static int catsearch(struct vol *vol,
                                   ALL dirsearch_byname will fail.
                                */
                 int unlen = strlen(path.u_name);
-                path.d_dir = dircache_search_by_name(vol, dstack[cidx].dir, path.u_name, unlen, path.st.st_ctime);
+                path.d_dir = dircache_search_by_name(vol,
+                                                     currentdir,
+                                                     path.u_name,
+                                                     unlen);
                if (path.d_dir == NULL) {
                        /* path.m_name is set by adddir */
-                   if (NULL == (path.d_dir = dir_add( vol, dstack[cidx].dir, &path, unlen) ) ) {
+                   if ((path.d_dir = dir_add(vol,
+                                              currentdir,
+                                              &path,
+                                              unlen)) == NULL) {
                                                result = AFPERR_MISC;
                                                goto catsearch_end;
                                        }
@@ -620,11 +639,10 @@ static int catsearch(struct vol *vol,
                                        result = AFPERR_MISC;
                                        goto catsearch_end;
                                } 
+            } else {
+               path.d_dir = currentdir;
             }
-            else {
-               /* yes it sucks for directory d_dir is the directory, for file it's the parent directory*/
-               path.d_dir = dstack[cidx].dir;
-            }
+
                        ccr = crit_check(vol, &path);
 
                        /* bit 0 means that criteria has been met */
@@ -728,7 +746,7 @@ static int catsearch_db(struct vol *vol,
                             buffer,
                             MAXPATHLEN,
                             &flags) == (size_t)-1) {
-            LOG(log_error, logtype_cnid, "catsearch_db: conversion error");
+            LOG(log_error, logtype_afpd, "catsearch_db: conversion error");
             result = AFPERR_MISC;
             goto catsearch_end;
         }
@@ -1014,8 +1032,8 @@ static int catsearch_afp(AFPObj *obj _U_, char *ibuf, size_t ibuflen,
                /* length */
                memcpy(&namelen, spec1, sizeof(namelen));
                namelen = ntohs (namelen);
-               if (namelen > 255)  /* Safeguard */
-                       namelen = 255;
+               if (namelen > UTF8FILELEN_EARLY)  /* Safeguard */
+                       namelen = UTF8FILELEN_EARLY;
 
                memcpy (c1.utf8name, spec1+2, namelen);
                c1.utf8name[namelen] = 0;
@@ -1032,6 +1050,7 @@ static int catsearch_afp(AFPObj *obj _U_, char *ibuf, size_t ibuflen,
     /* Call search */
     *rbuflen = 24;
     if ((c1.rbitmap & (1 << FILPBIT_PDINFO))
+        && !(c1.rbitmap & (1<<CATPBIT_PARTIAL))
         && (strcmp(vol->v_cnidscheme, "dbd") == 0)
         && (vol->v_flags & AFPVOL_SEARCHDB))
         /* we've got a name and it's a dbd volume, so search CNID database */