X-Git-Url: https://arthur.barton.de/gitweb/?a=blobdiff_plain;f=etc%2Fafpd%2Fcatsearch.c;h=46192e35465bf9de01e3030fac1c045893ef37b8;hb=2bf71d3ccf20c072bc67a9d075b6ac8b0798021e;hp=82d66adc87a160b75b24153e29ae0eb3798788a9;hpb=b8c1894353b62eb52e59d4e0150fd3c25dcd86ba;p=netatalk.git diff --git a/etc/afpd/catsearch.c b/etc/afpd/catsearch.c index 82d66adc..46192e35 100644 --- a/etc/afpd/catsearch.c +++ b/etc/afpd/catsearch.c @@ -111,6 +111,7 @@ struct dsitem { struct dir *dir; /* Structure describing 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 */ }; @@ -130,7 +131,7 @@ static struct scrit c1, c2; /* search criteria */ static int addstack(char *uname, struct dir *dir, int pidx) { struct dsitem *ds; - int l; + size_t l, u; /* check if we have some space on stack... */ if (dsidx >= dssize) { @@ -144,17 +145,21 @@ static int addstack(char *uname, struct dir *dir, int pidx) ds = dstack + dsidx++; ds->dir = dir; ds->pidx = pidx; + ds->checked = 0; if (pidx >= 0) { - l = strlen(dstack[pidx].path); - if (!(ds->path = malloc(l + strlen(uname) + 2) )) + l = dstack[pidx].path_len; + u = strlen(uname) +1; + if (!(ds->path = malloc(l + u + 1) )) return -1; - strcpy(ds->path, dstack[pidx].path); - strcat(ds->path, "/"); - strcat(ds->path, uname); + 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->checked = 0; - return 0; } @@ -210,7 +215,7 @@ static struct adouble *adl_lkup(struct vol *vol, struct path *path, struct adoub adp = &ad; } - if ( ad_metadata( path->u_name, ((isdir)?ADFLAGS_DIR:0), adp) < 0 ) { + if ( ad_metadata( path->u_name, ((isdir) ? ADFLAGS_DIR : 0), adp) < 0 ) { adp = NULL; /* FIXME without resource fork adl_lkup will be call again */ } @@ -232,13 +237,13 @@ static struct finderinfo *unpack_buffer(struct finderinfo *finfo, char *buffer) /* -------------------- */ static struct finderinfo * -unpack_finderinfo(struct vol *vol, struct path *path, struct adouble **adp, struct finderinfo *finfo) +unpack_finderinfo(struct vol *vol, struct path *path, struct adouble **adp, struct finderinfo *finfo, int islnk) { packed_finder buf; void *ptr; *adp = adl_lkup(vol, path, *adp); - ptr = get_finderinfo(vol, path->u_name, *adp, &buf); + ptr = get_finderinfo(vol, path->u_name, *adp, &buf,islnk); return unpack_buffer(finfo, ptr); } @@ -260,6 +265,8 @@ static int crit_check(struct vol *vol, struct path *path) { u_int32_t ac_date, ab_date; static char convbuf[514]; /* for convert_charset dest_len parameter +2 */ size_t len; + int islnk; + islnk=S_ISLNK(path->st.st_mode); if (S_ISDIR(path->st.st_mode)) { if (!c1.dbitmap) @@ -374,7 +381,7 @@ static int crit_check(struct vol *vol, struct path *path) { /* Check file type ID */ if ((c1.rbitmap & (1<f_type != c1.finfo.f_type) goto crit_check_ret; } @@ -382,7 +389,7 @@ static int crit_check(struct vol *vol, struct path *path) { /* Check creator ID */ if ((c1.rbitmap & (1<creator != c1.finfo.creator) goto crit_check_ret; @@ -391,7 +398,7 @@ static int crit_check(struct vol *vol, struct path *path) { /* Check finder info attributes */ if ((c1.rbitmap & (1<attrs & c2.finfo.attrs) != c1.finfo.attrs) @@ -401,7 +408,7 @@ static int crit_check(struct vol *vol, struct path *path) { /* Check label */ if ((c1.rbitmap & (1<label & c2.finfo.label) != c1.finfo.label) goto crit_check_ret; @@ -481,7 +488,7 @@ static int rslt_add ( struct vol *vol, struct path *path, char **buf, int ext) * rbuf - output buffer * rbuflen - output buffer length */ -#define NUM_ROUNDS 100 +#define NUM_ROUNDS 200 static int catsearch(struct vol *vol, struct dir *dir, int rmatches, u_int32_t *pos, char *rbuf, u_int32_t *nrecs, int *rsize, int ext) { @@ -490,13 +497,12 @@ static int catsearch(struct vol *vol, struct dir *dir, int result = AFP_OK; int ccr; struct path path; - char *orig_dir = NULL; - int orig_dir_len = 128; char *vpath = vol->v_path; char *rrbuf = rbuf; time_t start_time; int num_rounds = NUM_ROUNDS; int cached; + int cwd = -1; if (*pos != 0 && *pos != cur_pos) { result = AFPERR_CATCHNG; @@ -516,24 +522,18 @@ static int catsearch(struct vol *vol, struct dir *dir, dirpos = NULL; } - if (addstack("", dir, -1) == -1) { + if (addstack(vpath, dir, -1) == -1) { result = AFPERR_MISC; goto catsearch_end; } - dstack[0].path = strdup(vpath); /* FIXME: Sometimes DID is given by client ! (correct this one above !) */ } /* Save current path */ - orig_dir = (char*)malloc(orig_dir_len); - while (getcwd(orig_dir, orig_dir_len-1)==NULL) { - if (errno != ERANGE) { - result = AFPERR_MISC; - goto catsearch_end; - } - orig_dir_len += 128; - orig_dir = realloc(orig_dir, orig_dir_len); - } /* while() */ + if ((cwd = open(".", O_RDONLY)) < 0) { + result = AFPERR_MISC; + goto catsearch_end; + } while ((cidx = reducestack()) != -1) { cached = 1; @@ -654,10 +654,12 @@ catsearch_pause: catsearch_end: /* Exiting catsearch: error condition */ *rsize = rrbuf - rbuf; - if (orig_dir != NULL) { - chdir(orig_dir); - free(orig_dir); - } + if (cwd != -1) { + if ((fchdir(cwd)) != 0) { + LOG(log_debug, logtype_afpd, "error chdiring back: %s", strerror(errno)); + } + close(cwd); + } return result; } /* catsearch() */