#include <atalk/cnid_dbd_private.h>
#include <atalk/util.h>
#include <atalk/bstradd.h>
+#include <atalk/unicode.h>
+#include <atalk/globals.h>
#include "desktop.h"
#include "directory.h"
#include "dircache.h"
#include "file.h"
#include "volume.h"
-#include "globals.h"
#include "filedir.h"
#include "fork.h"
struct finderinfo {
- u_int32_t f_type;
- u_int32_t creator;
- u_int16_t attrs; /* File attributes (high 8 bits)*/
- u_int16_t label; /* Label (low 8 bits )*/
+ uint32_t f_type;
+ uint32_t creator;
+ uint16_t attrs; /* File attributes (high 8 bits)*/
+ uint16_t label; /* Label (low 8 bits )*/
char reserved[22]; /* Unknown (at least for now...) */
};
/* This is our search-criteria structure. */
struct scrit {
- u_int32_t rbitmap; /* Request bitmap - which values should we check ? */
- u_int16_t fbitmap, dbitmap; /* file & directory bitmap - which values should we return ? */
- u_int16_t attr; /* File attributes */
+ uint32_t rbitmap; /* Request bitmap - which values should we check ? */
+ uint16_t fbitmap, dbitmap; /* file & directory bitmap - which values should we return ? */
+ uint16_t attr; /* File attributes */
time_t cdate; /* Creation date */
time_t mdate; /* Last modification date */
time_t bdate; /* Last backup date */
- u_int32_t pdid; /* Parent DID */
- u_int16_t offcnt; /* Offspring count */
+ uint32_t pdid; /* Parent DID */
+ uint16_t offcnt; /* Offspring count */
struct finderinfo finfo; /* Finder info */
char lname[64]; /* Long name */
char utf8name[514]; /* UTF8 or UCS2 name */ /* for convert_charset dest_len parameter +2 */
*
*/
struct dsitem {
- struct dir *dir; /* Structure describing this directory */
+// 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;
/* Put new element. Allocate and copy lname and path. */
ds = dstack + dsidx++;
- ds->dir = dir;
- dir->d_flags |= DIRF_CACHELOCK;
+// ds->did = dir->d_did;
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 int crit_check(struct vol *vol, struct path *path) {
int result = 0;
- u_int16_t attr, flags = CONV_PRECOMPOSE;
+ uint16_t attr, flags = CONV_PRECOMPOSE;
struct finderinfo *finfo = NULL, finderinfo;
struct adouble *adp = NULL;
time_t c_date, b_date;
- u_int32_t ac_date, ab_date;
+ uint32_t ac_date, ab_date;
static char convbuf[514]; /* for convert_charset dest_len parameter +2 */
size_t len;
int islnk;
char *p = *buf;
int ret;
size_t tbuf =0;
- u_int16_t resultsize;
+ uint16_t resultsize;
int isdir = S_ISDIR(path->st.st_mode);
/* Skip resultsize */
int *rsize,
int ext)
{
- static u_int32_t cur_pos; /* Saved position index (ID) - used to remember "position" across FPCatSearch calls */
+ static uint32_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 *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)
} /* switch (errno) */
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) {
+ 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) {
ALL dirsearch_byname will fail.
*/
int unlen = strlen(path.u_name);
- path.d_dir = dircache_search_by_name(vol, dstack[cidx].dir, path.u_name, unlen, path.st.st_ctime);
+ path.d_dir = dircache_search_by_name(vol,
+ currentdir,
+ path.u_name,
+ unlen);
if (path.d_dir == NULL) {
/* path.m_name is set by adddir */
- if (NULL == (path.d_dir = dir_add( vol, dstack[cidx].dir, &path, unlen) ) ) {
+ if ((path.d_dir = dir_add(vol,
+ currentdir,
+ &path,
+ unlen)) == NULL) {
result = AFPERR_MISC;
goto catsearch_end;
}
result = AFPERR_MISC;
goto catsearch_end;
}
+ } else {
+ path.d_dir = currentdir;
}
- else {
- /* yes it sucks for directory d_dir is the directory, for file it's the parent directory*/
- path.d_dir = dstack[cidx].dir;
- }
+
ccr = crit_check(vol, &path);
/* bit 0 means that criteria has been met */
*
* @param vol (r) volume we are searching on ...
* @param dir (rw) directory we are starting from ...
+ * @param uname (r) UNIX name of object to search
* @param rmatches (r) maximum number of matches we can return
* @param pos (r) position we've stopped recently
* @param rbuf (w) output buffer
* @param rsize (w) length of data written to output buffer
* @param ext (r) extended search flag
*/
-#define NUM_ROUNDS 200
static int catsearch_db(struct vol *vol,
struct dir *dir,
+ const char *uname,
int rmatches,
uint32_t *pos,
char *rbuf,
int ext)
{
static char resbuf[DBD_MAX_SRCH_RSLTS * sizeof(cnid_t)];
- static uint32_t cur_pos; /* Saved position index (ID) - used to remember "position" across FPCatSearch calls */
- int num_matches, ccr ,r;
+ static uint32_t cur_pos;
+ static int num_matches;
+ int ccr ,r;
int result = AFP_OK;
struct path path;
char *rrbuf = rbuf;
+ char buffer[MAXPATHLEN +2];
+ uint16_t flags = CONV_TOLOWER;
+
+ LOG(log_debug, logtype_afpd, "catsearch_db(req pos: %u): {pos: %u, name: %s}",
+ *pos, cur_pos, uname);
if (*pos != 0 && *pos != cur_pos) {
result = AFPERR_CATCHNG;
}
if (cur_pos == 0 || *pos == 0) {
+ if (convert_charset(vol->v_volcharset,
+ vol->v_volcharset,
+ vol->v_maccharset,
+ uname,
+ strlen(uname),
+ buffer,
+ MAXPATHLEN,
+ &flags) == (size_t)-1) {
+ LOG(log_error, logtype_afpd, "catsearch_db: conversion error");
+ result = AFPERR_MISC;
+ goto catsearch_end;
+ }
+
+ LOG(log_debug, logtype_afpd, "catsearch_db: %s", buffer);
+
if ((num_matches = cnid_find(vol->v_cdb,
- c1.utf8name,
- strlen(c1.utf8name),
+ buffer,
+ strlen(uname),
resbuf,
sizeof(resbuf))) == -1) {
result = AFPERR_MISC;
if ((name = cnid_resolve(vol->v_cdb, &did, resolvebuf, 12 + MAXPATHLEN + 1)) == 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)
goto next;
if (movecwd(vol, dir) < 0 )
switch (errno) {
case EACCES:
case ELOOP:
- case ENOENT:
goto next;
+ case ENOENT:
+
default:
result = AFPERR_MISC;
goto catsearch_end;
catsearch_end: /* Exiting catsearch: error condition */
*rsize = rrbuf - rbuf;
+ LOG(log_debug, logtype_afpd, "catsearch_db(req pos: %u): {pos: %u}", *pos, cur_pos);
return result;
}
char *rbuf, size_t *rbuflen, int ext)
{
struct vol *vol;
- u_int16_t vid;
- u_int16_t spec_len;
- u_int32_t rmatches, reserved;
- u_int32_t catpos[4];
- u_int32_t pdid = 0;
+ uint16_t vid;
+ uint16_t spec_len;
+ uint32_t rmatches, reserved;
+ uint32_t catpos[4];
+ uint32_t pdid = 0;
int ret, rsize;
- u_int32_t nrecs = 0;
+ uint32_t nrecs = 0;
unsigned char *spec1, *spec2, *bspec1, *bspec2;
size_t len;
- u_int16_t namelen;
- u_int16_t flags;
- char tmppath[256];
+ uint16_t namelen;
+ uint16_t flags;
+ char tmppath[256];
+ char *uname;
*rbuflen = 0;
/* length */
memcpy(&namelen, spec1, sizeof(namelen));
namelen = ntohs (namelen);
- if (namelen > 255) /* Safeguard */
- namelen = 255;
+ if (namelen > UTF8FILELEN_EARLY) /* Safeguard */
+ namelen = UTF8FILELEN_EARLY;
memcpy (c1.utf8name, spec1+2, namelen);
c1.utf8name[namelen] = 0;
+ if ((uname = mtoupath(vol, c1.utf8name, 0, utf8_encoding())) == NULL)
+ return AFPERR_PARAM;
/* convert charset */
flags = CONV_PRECOMPOSE;
/* Call search */
*rbuflen = 24;
- if ((c1.rbitmap & (1 << FILPBIT_PDINFO)) && (strcmp(vol->v_cnidscheme, "dbd") == 0))
+ if ((c1.rbitmap & (1 << FILPBIT_PDINFO))
+ && (strcmp(vol->v_cnidscheme, "dbd") == 0)
+ && (vol->v_flags & AFPVOL_SEARCHDB))
/* we've got a name and it's a dbd volume, so search CNID database */
- ret = catsearch_db(vol, vol->v_root, rmatches, &catpos[0], rbuf+24, &nrecs, &rsize, ext);
+ ret = catsearch_db(vol, vol->v_root, uname, rmatches, &catpos[0], rbuf+24, &nrecs, &rsize, ext);
else
/* perform a slow filesystem tree search */
ret = catsearch(vol, vol->v_root, rmatches, &catpos[0], rbuf+24, &nrecs, &rsize, ext);