#ifdef CNID_DB
#include <atalk/cnid.h>
#endif /* CNID_DB */
+
+#include <atalk/util.h>
+#include <atalk/bstradd.h>
+
#include "desktop.h"
#include "directory.h"
+#include "dircache.h"
#include "file.h"
#include "volume.h"
#include "globals.h"
#define DS_BSIZE 128
-static u_int32_t cur_pos = 0; /* Saved position index (ID) - used to remember "position" across FPCatSearch calls */
-static DIR *dirpos = NULL; /* UNIX structure describing currently opened directory. */
static int save_cidx = -1; /* Saved index of currently scanned directory. */
static struct dsitem *dstack = NULL; /* Directory stack data... */
/* Put new element. Allocate and copy lname and path. */
ds = dstack + dsidx++;
ds->dir = dir;
+ dir->d_flags |= DIRF_CACHELOCK;
ds->pidx = pidx;
ds->checked = 0;
if (pidx >= 0) {
while (dsidx > 0) {
if (dstack[dsidx-1].checked) {
dsidx--;
+ dstack[dsidx].dir->d_flags &= ~DIRF_CACHELOCK;
free(dstack[dsidx].path);
} else
return dsidx - 1;
save_cidx = -1;
while (dsidx > 0) {
dsidx--;
+ dstack[dsidx].dir->d_flags &= ~DIRF_CACHELOCK;
free(dstack[dsidx].path);
}
}
/* -------------------- */
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);
}
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)
/* Check file type ID */
if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.f_type != 0) {
- finfo = unpack_finderinfo(vol, path, &adp, &finderinfo);
+ finfo = unpack_finderinfo(vol, path, &adp, &finderinfo,islnk);
if (finfo->f_type != c1.finfo.f_type)
goto crit_check_ret;
}
/* Check creator ID */
if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.creator != 0) {
if (!finfo) {
- finfo = unpack_finderinfo(vol, path, &adp, &finderinfo);
+ finfo = unpack_finderinfo(vol, path, &adp, &finderinfo,islnk);
}
if (finfo->creator != c1.finfo.creator)
goto crit_check_ret;
/* Check finder info attributes */
if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.attrs != 0) {
if (!finfo) {
- finfo = unpack_finderinfo(vol, path, &adp, &finderinfo);
+ finfo = unpack_finderinfo(vol, path, &adp, &finderinfo,islnk);
}
if ((finfo->attrs & c2.finfo.attrs) != c1.finfo.attrs)
/* Check label */
if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.label != 0) {
if (!finfo) {
- finfo = unpack_finderinfo(vol, path, &adp, &finderinfo);
+ finfo = unpack_finderinfo(vol, path, &adp, &finderinfo,islnk);
}
if ((finfo->label & c2.finfo.label) != c1.finfo.label)
goto crit_check_ret;
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)
{
+ 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. */
int cidx, r;
struct dirent *entry;
int result = AFP_OK;
char *rrbuf = rbuf;
time_t start_time;
int num_rounds = NUM_ROUNDS;
- int cached;
int cwd = -1;
+ int error;
if (*pos != 0 && *pos != cur_pos) {
result = AFPERR_CATCHNG;
/* FIXME: Category "offspring count ! */
- /* So we are beginning... */
- start_time = time(NULL);
/* We need to initialize all mandatory structures/variables and change working directory appropriate... */
if (*pos == 0) {
goto catsearch_end;
}
+ /* So we are beginning... */
+ start_time = time(NULL);
+
while ((cidx = reducestack()) != -1) {
- cached = 1;
- if (dirpos == NULL) {
+ error = lchdir(dstack[cidx].path);
+
+ if (!error && dirpos == NULL)
+ dirpos = opendir(".");
+
+ if (dirpos == NULL)
dirpos = opendir(dstack[cidx].path);
- cached = (dstack[cidx].dir->d_child != NULL);
- }
- if (dirpos == NULL) {
+
+ if (error || dirpos == NULL) {
switch (errno) {
case EACCES:
dstack[cidx].checked = 1;
} /* switch (errno) */
goto catsearch_end;
}
- /* FIXME error in chdir, what do we do? */
- chdir(dstack[cidx].path);
-
while ((entry=readdir(dirpos)) != NULL) {
(*pos)++;
ie if in the same loop the parent dir wasn't in the cache
ALL dirsearch_byname will fail.
*/
- if (cached)
- path.d_dir = dirsearch_byname(vol, dstack[cidx].dir, path.u_name);
- else
- path.d_dir = NULL;
- if (!path.d_dir) {
+ int unlen = strlen(path.u_name);
+ path.d_dir = dircache_search_by_name(vol, dstack[cidx].dir, path.u_name, unlen);
+ if (path.d_dir == NULL) {
/* path.m_name is set by adddir */
- if (NULL == (path.d_dir = adddir( vol, dstack[cidx].dir, &path) ) ) {
+ if (NULL == (path.d_dir = dir_add( vol, dstack[cidx].dir, &path, unlen) ) ) {
result = AFPERR_MISC;
goto catsearch_end;
}
}
- path.m_name = path.d_dir->d_m_name;
+ path.m_name = cfrombstring(path.d_dir->d_m_name);
if (addstack(path.u_name, path.d_dir, cidx) == -1) {
result = AFPERR_MISC;
/* Call search */
*rbuflen = 24;
- ret = catsearch(vol, vol->v_dir, rmatches, &catpos[0], rbuf+24, &nrecs, &rsize, ext);
+ ret = catsearch(vol, vol->v_root, rmatches, &catpos[0], rbuf+24, &nrecs, &rsize, ext);
memcpy(rbuf, catpos, sizeof(catpos));
rbuf += sizeof(catpos);