#include <stdio.h>
#include <stdlib.h>
-#include <dirent.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
u_int16_t offcnt; /* Offspring count */
struct finderinfo finfo; /* Finder info */
char lname[64]; /* Long name */
- char utf8name[512]; /* UTF8 name */
+ char utf8name[514]; /* UTF8 or UCS2 name */ /* for convert_charset dest_len parameter +2 */
};
/*
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 */
};
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) {
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;
}
/* Removes checked items from top of directory stack. Returns index of the first unchecked elements or -1. */
-static int reducestack()
+static int reducestack(void)
{
int r;
if (save_cidx != -1) {
}
/* Clears directory stack. */
-static void clearstack()
+static void clearstack(void)
{
save_cidx = -1;
while (dsidx > 0) {
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 */
}
/* -------------------- */
static struct finderinfo *
-unpack_finderinfo(char *upath, 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;
- ptr = get_finderinfo(upath, adp, &buf);
+ *adp = adl_lkup(vol, path, *adp);
+ ptr = get_finderinfo(vol, path->u_name, *adp, &buf,islnk);
return unpack_buffer(finfo, ptr);
}
struct adouble *adp = NULL;
time_t c_date, b_date;
u_int32_t ac_date, ab_date;
- static char convbuf[512];
+ 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 for filename */
if ((c1.rbitmap & (1<<DIRPBIT_LNAME))) {
- if ( (size_t)(-1) == (len = convert_string(vol->v_maccharset, CH_UCS2, path->m_name, strlen(path->m_name), convbuf, 512)) )
+ if ( (size_t)(-1) == (len = convert_string(vol->v_maccharset, CH_UCS2, path->m_name, -1, convbuf, 512)) )
goto crit_check_ret;
- convbuf[len] = 0;
+
if ((c1.rbitmap & (1<<CATPBIT_PARTIAL))) {
if (strcasestr_w( (ucs2_t*) convbuf, (ucs2_t*) c1.lname) == NULL)
goto crit_check_ret;
if ( (size_t)(-1) == (len = convert_charset( CH_UTF8_MAC, CH_UCS2, CH_UTF8, path->m_name, strlen(path->m_name), convbuf, 512, &flags))) {
goto crit_check_ret;
}
- convbuf[len] = 0;
+
if (c1.rbitmap & (1<<CATPBIT_PARTIAL)) {
if (strcasestr_w((ucs2_t *) convbuf, (ucs2_t*)c1.utf8name) == NULL)
goto crit_check_ret;
/* Check file type ID */
if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.f_type != 0) {
- adp = adl_lkup(vol, path, adp);
- finfo = unpack_finderinfo(path->u_name, 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) {
- adp = adl_lkup(vol, path, adp);
- finfo = unpack_finderinfo(path->u_name, 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) {
- adp = adl_lkup(vol, path, adp);
- finfo = unpack_finderinfo(path->u_name, 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) {
- adp = adl_lkup(vol, path, adp);
- finfo = unpack_finderinfo(path->u_name, adp, &finderinfo);
+ finfo = unpack_finderinfo(vol, path, &adp, &finderinfo,islnk);
}
if ((finfo->label & c2.finfo.label) != c1.finfo.label)
goto crit_check_ret;
result |= 1;
crit_check_ret:
if (adp != NULL)
- ad_close(adp, ADFLAGS_HF);
+ ad_close_metadata(adp);
return result;
}
{
char *p = *buf;
- int ret, tbuf =0;
+ int ret;
+ size_t tbuf =0;
u_int16_t resultsize;
int isdir = S_ISDIR(path->st.st_mode);
* 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)
{
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;
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;
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() */
/* -------------------------- */
-int catsearch_afp(AFPObj *obj _U_, char *ibuf, int ibuflen,
- char *rbuf, int *rbuflen, int ext)
+static int catsearch_afp(AFPObj *obj _U_, char *ibuf, size_t ibuflen,
+ char *rbuf, size_t *rbuflen, int ext)
{
struct vol *vol;
u_int16_t vid;
}
/* Parse file specifications */
- spec1 = ibuf;
- spec2 = ibuf + spec_len + 2;
+ spec1 = (unsigned char*)ibuf;
+ spec2 = (unsigned char*)ibuf + spec_len + 2;
spec1 += 2;
spec2 += 2;
/* Get the long filename */
memcpy(tmppath, bspec1 + spec1[1] + 1, (bspec1 + spec1[1])[0]);
tmppath[(bspec1 + spec1[1])[0]]= 0;
- len = convert_string ( vol->v_maccharset, CH_UCS2, tmppath, strlen(tmppath), c1.lname, 64);
+ len = convert_string ( vol->v_maccharset, CH_UCS2, tmppath, -1, c1.lname, sizeof(c1.lname));
if (len == (size_t)(-1))
return AFPERR_PARAM;
- c1.lname[len] = 0;
#if 0
/* FIXME: do we need it ? It's always null ! */
len = convert_charset(CH_UTF8_MAC, CH_UCS2, CH_UTF8, c1.utf8name, namelen, c1.utf8name, 512, &flags);
if (len == (size_t)(-1))
return AFPERR_PARAM;
- c1.utf8name[len]=0;
}
/* Call search */
} /* catsearch_afp */
/* -------------------------- */
-int afp_catsearch (AFPObj *obj, char *ibuf, int ibuflen,
- char *rbuf, int *rbuflen)
+int afp_catsearch (AFPObj *obj, char *ibuf, size_t ibuflen,
+ char *rbuf, size_t *rbuflen)
{
return catsearch_afp( obj, ibuf, ibuflen, rbuf, rbuflen, 0);
}
-int afp_catsearch_ext (AFPObj *obj, char *ibuf, int ibuflen,
- char *rbuf, int *rbuflen)
+int afp_catsearch_ext (AFPObj *obj, char *ibuf, size_t ibuflen,
+ char *rbuf, size_t *rbuflen)
{
return catsearch_afp( obj, ibuf, ibuflen, rbuf, rbuflen, 1);
}