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
{
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;
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)
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)++;
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) {
*/
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;
goto catsearch_end;
}
} else {
- path.d_dir = curdir;
+ path.d_dir = currentdir;
}
ccr = crit_check(vol, &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, '/');
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]),
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;
if (ret != 0)
return NULL;
+ LOG(log_debug, logtype_afpd, "dirlookup_bypath: result: \"%s\"",
+ cfrombstr(dir->d_fullpath));
+
return dir;
}
#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
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));