]> arthur.barton.de Git - netatalk.git/commitdiff
Fix catsearch
authorFrank Lahm <franklahm@googlemail.com>
Mon, 7 Nov 2011 14:23:48 +0000 (15:23 +0100)
committerFrank Lahm <franklahm@googlemail.com>
Mon, 7 Nov 2011 14:23:48 +0000 (15:23 +0100)
NEWS
etc/afpd/catsearch.c
etc/afpd/directory.c
include/atalk/errchk.h
libatalk/cnid/cnid.c

diff --git a/NEWS b/NEWS
index 662e64290e3752ad366bc7d5177ed4aae6e29647..36d7649a707f247b775f0738592f19d2c34acf47 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,7 @@ Changes in 2.2.2
        which lead to a possible Finder crash
 * FIX: afpd: Read-only filesystems lead to afpd processes running as root
 * FIX: afpd: Fix for filesystem without NFSv4 ACL support on Solaris
+* FIX: afpd: Fix catsearch bug, NetAFP Bug ID #12
 * FIX: dbd: Better checking for duplicated or bogus CNIDs from AppleDouble files
 * FIX: Fix compilation error when AppleTalk support is disabled
 * FIX: Portability fixes
index a488501e6b67e3c101660b844aa218bb460a1da5..71d1a44608af098cefa519234a15bdb216461e1d 100644 (file)
@@ -504,7 +504,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 *curdir;          /* struct dir of current directory */
+    struct dir *currentdir;      /* struct dir of current directory */
        int cidx, r;
        struct dirent *entry;
        int result = AFP_OK;
@@ -550,6 +550,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,10 +578,11 @@ static int catsearch(struct vol *vol,
                        goto catsearch_end;
                }
 
-        if ((curdir = dirlookup_bypath(vol, dstack[cidx].path)) == NULL) {
+        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) {
                        (*pos)++;
@@ -587,6 +590,9 @@ static int catsearch(struct vol *vol,
                        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) {
@@ -611,13 +617,13 @@ static int catsearch(struct vol *vol,
                                */
                 int unlen = strlen(path.u_name);
                 path.d_dir = dircache_search_by_name(vol,
-                                                     curdir,
+                                                     currentdir,
                                                      path.u_name,
                                                      unlen);
                if (path.d_dir == NULL) {
                        /* path.m_name is set by adddir */
                    if ((path.d_dir = dir_add(vol,
-                                              curdir,
+                                              currentdir,
                                               &path,
                                               unlen)) == NULL) {
                                                result = AFPERR_MISC;
@@ -631,7 +637,7 @@ static int catsearch(struct vol *vol,
                                        goto catsearch_end;
                                } 
             } else {
-               path.d_dir = curdir;
+               path.d_dir = currentdir;
             }
 
                        ccr = crit_check(vol, &path);
index da7eb6c4eae973c2d2bc2811eea9a4dc3117f550..50e3df32eb8e46fa6cf7c443b6b0afa4fb0f1d2e 100644 (file)
@@ -463,7 +463,15 @@ struct dir *dirlookup_bypath(const struct vol *vol, const char *path)
     cnid = htonl(2);
     dir = vol->v_root;
 
+    LOG(log_debug, logtype_afpd, "dirlookup_bypath(\"%s\")", path);
+
+    if (strcmp(vol->v_path, path) == 0)
+        return dir;
+
     EC_NULL(rpath = rel_path_in_vol(path, vol->v_path)); /* 1. */
+
+    LOG(log_debug, logtype_afpd, "dirlookup_bypath: rpath: \"%s\"", cfrombstr(rpath));
+
     EC_NULL(statpath = bfromcstr(vol->v_path));          /* 2. */
 
     l = bsplit(rpath, '/');
@@ -471,6 +479,9 @@ struct dir *dirlookup_bypath(const struct vol *vol, const char *path)
         did = cnid;
         EC_ZERO(bcatcstr(statpath, "/"));
         EC_ZERO(bconcat(statpath, l->entry[i]));
+
+        LOG(log_debug, logtype_afpd, "dirlookup_bypath: statpath: \"%s\"", cfrombstr(statpath));
+
         EC_ZERO_LOGSTR(lstat(cfrombstr(statpath), &st),
                        "lstat(rpath: %s, elem: %s): %s: %s",
                        cfrombstr(rpath), cfrombstr(l->entry[i]),
@@ -483,14 +494,14 @@ struct dir *dirlookup_bypath(const struct vol *vol, const char *path)
                                            dir,
                                            cfrombstr(l->entry[i]),
                                            blength(l->entry[i]))) == NULL) {
+
             if ((cnid = cnid_add(vol->v_cdb,             /* 6. */
                                  &st,
                                  did,
                                  cfrombstr(l->entry[i]),
                                  blength(l->entry[i]),
-                                 0)) == CNID_INVALID) {
+                                 0)) == CNID_INVALID)
                 EC_FAIL;
-            }
 
             if ((dir = dirlookup(vol, cnid)) == NULL) /* 7. */
                 EC_FAIL;
@@ -504,6 +515,9 @@ EC_CLEANUP:
     if (ret != 0)
         return NULL;
 
+    LOG(log_debug, logtype_afpd, "dirlookup_bypath: result: \"%s\"",
+        cfrombstr(dir->d_fullpath));
+
     return dir;
 }
 
index 64a12764525282e0c19a4431e0ed362c413e683c..78e530a8e95227eac265a01e27dcdedbc7081216 100644 (file)
@@ -17,7 +17,7 @@
 
 #define EC_INIT int ret = 0
 #define EC_STATUS(a) ret = (a)
-#define EC_FAIL ret = -1; goto cleanup
+#define EC_FAIL do { ret = -1; goto cleanup; } while (0)
 #define EC_CLEANUP cleanup
 #define EC_EXIT return ret
 
index 68136f9f196594325119d762eae8ec1154f06397..8bb6373ee373e91acd57912a71414b3eebaafc30 100644 (file)
@@ -216,7 +216,10 @@ u_int32_t flags;
 cnid_t cnid_add(struct _cnid_db *cdb, const struct stat *st, const cnid_t did, 
                 const char *name, const size_t len, cnid_t hint)
 {
-cnid_t ret;
+    cnid_t ret;
+
+    if (len == 0)
+        return CNID_INVALID;
 
     block_signal(cdb->flags);
     ret = valide(cdb->cnid_add(cdb, st, did, name, len, hint));