X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Fcatsearch.c;h=bec7b15245b195e1311fde72d72eba838108a9d2;hb=f254fd618b53e97cc5382b23709d4f3de1e70b41;hp=71843e2cd13237863791a396e9e389a8156dcf46;hpb=a83e8197c7b8af45f8d56acf158920c03698bfc6;p=netatalk.git diff --git a/etc/afpd/catsearch.c b/etc/afpd/catsearch.c index 71843e2c..bec7b152 100644 --- a/etc/afpd/catsearch.c +++ b/etc/afpd/catsearch.c @@ -29,6 +29,9 @@ #include "config.h" #endif /* HAVE_CONFIG_H */ +#include +#include +#include #include #include #include @@ -43,7 +46,7 @@ #include #include #include -#include +#include #include #include #include @@ -109,12 +112,8 @@ struct scrit { * */ struct dsitem { -// 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; - char *path; /* absolute UNIX path to this directory */ + cnid_t ds_did; /* CNID of this directory */ + int ds_checked; /* Have we checked this directory ? */ }; @@ -131,7 +130,6 @@ static void clearstack(void) save_cidx = -1; while (dsidx > 0) { dsidx--; - free(dstack[dsidx].path); } } @@ -139,7 +137,6 @@ static void clearstack(void) 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... */ @@ -156,23 +153,8 @@ static int addstack(char *uname, struct dir *dir, int pidx) /* Put new element. Allocate and copy lname and path. */ ds = dstack + dsidx++; -// ds->did = dir->d_did; - ds->pidx = pidx; - ds->checked = 0; - if (pidx >= 0) { - l = dstack[pidx].path_len; - u = strlen(uname) +1; - if (!(ds->path = malloc(l + u + 1) )) - return -1; - memcpy(ds->path, dstack[pidx].path, l); - ds->path[l] = '/'; - memcpy(&ds->path[l+1], uname, u); - ds->path_len = l +u; - } - else { - ds->path = strdup(uname); - ds->path_len = strlen(uname); - } + ds->ds_did = dir->d_did; + ds->ds_checked = 0; return 0; } @@ -187,9 +169,9 @@ static int reducestack(void) } while (dsidx > 0) { - if (dstack[dsidx-1].checked) { + if (dstack[dsidx-1].ds_checked) { dsidx--; - free(dstack[dsidx].path); +// free(dstack[dsidx].path); } else return dsidx - 1; } @@ -211,7 +193,7 @@ static struct adouble *adl_lkup(struct vol *vol, struct path *path, struct adoub isdir = S_ISDIR(path->st.st_mode); - if (!isdir && (of = of_findname(path))) { + if (!isdir && (of = of_findname(vol, path))) { adp = of->of_ad; } else { ad_init(&ad, vol); @@ -521,7 +503,8 @@ static int catsearch(const AFPObj *obj, int num_rounds = NUM_ROUNDS; int cwd = -1; int error; - + int unlen; + if (*pos != 0 && *pos != cur_pos) { result = AFPERR_CATCHNG; goto catsearch_end; @@ -555,20 +538,24 @@ static int catsearch(const AFPObj *obj, start_time = time(NULL); while ((cidx = reducestack()) != -1) { - LOG(log_debug, logtype_afpd, "catsearch: dir: \"%s\"", dstack[cidx].path); + if ((currentdir = dirlookup(vol, dstack[cidx].ds_did)) == NULL) { + result = AFPERR_MISC; + goto catsearch_end; + } + LOG(log_debug, logtype_afpd, "catsearch: current struct dir: \"%s\"", cfrombstr(currentdir->d_fullpath)); - error = lchdir(dstack[cidx].path); + error = movecwd(vol, currentdir); if (!error && dirpos == NULL) dirpos = opendir("."); if (dirpos == NULL) - dirpos = opendir(dstack[cidx].path); + dirpos = opendir(cfrombstr(currentdir->d_fullpath)); if (error || dirpos == NULL) { switch (errno) { case EACCES: - dstack[cidx].checked = 1; + dstack[cidx].ds_checked = 1; continue; case EMFILE: case ENFILE: @@ -583,11 +570,6 @@ static int catsearch(const AFPObj *obj, 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) { (*pos)++; @@ -600,7 +582,7 @@ static int catsearch(const AFPObj *obj, memset(&path, 0, sizeof(path)); path.u_name = entry->d_name; - if (of_stat(&path) != 0) { + if (of_stat(vol, &path) != 0) { switch (errno) { case EACCES: case ELOOP: @@ -615,12 +597,13 @@ static int catsearch(const AFPObj *obj, goto catsearch_end; } } - if (S_ISDIR(path.st.st_mode)) { + switch (S_IFMT & path.st.st_mode) { + case S_IFDIR: /* here we can short cut ie if in the same loop the parent dir wasn't in the cache ALL dirsearch_byname will fail. */ - int unlen = strlen(path.u_name); + unlen = strlen(path.u_name); path.d_dir = dircache_search_by_name(vol, currentdir, path.u_name, @@ -641,8 +624,12 @@ static int catsearch(const AFPObj *obj, result = AFPERR_MISC; goto catsearch_end; } - } else { + break; + case S_IFREG: path.d_dir = currentdir; + break; + default: + continue; } ccr = crit_check(vol, &path); @@ -674,7 +661,7 @@ static int catsearch(const AFPObj *obj, } /* while ((entry=readdir(dirpos)) != NULL) */ closedir(dirpos); dirpos = NULL; - dstack[cidx].checked = 1; + dstack[cidx].ds_checked = 1; } /* while (current_idx = reducestack()) != -1) */ /* We have finished traversing our tree. Return EOF here. */ @@ -756,11 +743,14 @@ static int catsearch_db(const AFPObj *obj, LOG(log_debug, logtype_afpd, "catsearch_db: %s", buffer); - if ((num_matches = cnid_find(vol->v_cdb, - buffer, - strlen(uname), - resbuf, - sizeof(resbuf))) == -1) { + AFP_CNID_START("cnid_find"); + num_matches = cnid_find(vol->v_cdb, + buffer, + strlen(uname), + resbuf, + sizeof(resbuf)); + AFP_CNID_DONE(); + if (num_matches == -1) { result = AFPERR_MISC; goto catsearch_end; } @@ -776,8 +766,12 @@ static int catsearch_db(const AFPObj *obj, memcpy(&cnid, resbuf + cur_pos * sizeof(cnid_t), sizeof(cnid_t)); did = cnid; - if ((name = cnid_resolve(vol->v_cdb, &did, resolvebuf, 12 + MAXPATHLEN + 1)) == NULL) + AFP_CNID_START("cnid_resolve"); + name = cnid_resolve(vol->v_cdb, &did, resolvebuf, 12 + MAXPATHLEN + 1); + AFP_CNID_DONE(); + if (name == NULL) goto next; + LOG(log_debug, logtype_afpd, "catsearch_db: {pos: %u, name:%s, cnid: %u}", cur_pos, name, ntohl(cnid)); if ((dir = dirlookup(vol, did)) == NULL) @@ -789,7 +783,7 @@ static int catsearch_db(const AFPObj *obj, path.u_name = name; path.m_name = utompath(vol, name, cnid, utf8_encoding(vol->v_obj)); - if (of_stat(&path) != 0) { + if (of_stat(vol, &path) != 0) { switch (errno) { case EACCES: case ELOOP: