#include <stdlib.h>
#include <dirent.h>
#include <errno.h>
-#include <syslog.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
u_int32_t pdid; /* Parent DID */
u_int16_t offcnt; /* Offspring count */
struct finderinfo finfo; /* Finder info */
- char lname[32]; /* Long name */
- char utf8name[256]; /* UTF8 name */
+ char lname[64]; /* Long name */
+ char utf8name[512]; /* UTF8 name */
};
/*
path.u_name = dstack[cidx].path;
if (of_stat(&path)==-1) {
- syslog(LOG_DEBUG, "resolve_dir: stat %s: %s", dstack[cidx].path, strerror(errno));
+ LOG(log_debug, logtype_afpd, "resolve_dir: stat %s: %s", dstack[cidx].path, strerror(errno));
return 0;
}
path.m_name = dstack[cidx].m_name;
return 1;
} /* resolve_dir */
-/* Looks up for an opened adouble structure, opens resource fork of selected file. */
-static struct adouble *adl_lkup(struct path *path)
+/* Looks up for an opened adouble structure, opens resource fork of selected file.
+ * FIXME What about noadouble?
+*/
+static struct adouble *adl_lkup(struct vol *vol, struct path *path)
{
static struct adouble ad;
struct adouble *adp;
if (!isdir && (of = of_findname(path))) {
adp = of->of_ad;
} else {
- memset(&ad, 0, sizeof(ad));
+ ad_init(&ad, vol->v_adouble);
adp = &ad;
}
- if ( ad_open( path->u_name, ADFLAGS_HF | (isdir)?ADFLAGS_DIR:0, O_RDONLY, 0, adp) < 0 ) {
+ if ( ad_open( path->u_name, ADFLAGS_HF | ((isdir)?ADFLAGS_DIR:0), O_RDONLY, 0, adp) < 0 ) {
return NULL;
}
return adp;
*/
static int crit_check(struct vol *vol, struct path *path, int cidx) {
int r = 0;
- u_int16_t attr;
+ u_int16_t attr, flags = CONV_PRECOMPOSE;
struct finderinfo *finfo = NULL, finderinfo;
struct adouble *adp = NULL;
time_t c_date, b_date;
+ static char convbuf[512];
+ size_t len;
if (S_ISDIR(path->st.st_mode)) {
r = 2;
/* Check for filename */
if (c1.rbitmap & (1<<DIRPBIT_LNAME)) {
+#ifdef DEBUG
+ LOG(log_debug, logtype_afpd, "Crit check: comparing %s/%s to %s", path->m_name, path->u_name, c1.lname);
+#endif
+ if ( (size_t)(-1) == (len = convert_string(vol->v_maccharset, CH_UCS2, path->m_name, strlen(path->m_name), convbuf, 512)) )
+ goto crit_check_ret;
+ convbuf[len] = 0;
if (c1.rbitmap & (1<<CATPBIT_PARTIAL)) {
- if (strcasestr(path->u_name, c1.lname) == NULL)
+ if (strcasestr_w( (ucs2_t*) convbuf, (ucs2_t*) c1.lname) == NULL)
goto crit_check_ret;
} else
- if (strcasecmp(path->u_name, c1.lname) != 0)
+ if (strcasecmp_w((ucs2_t*) convbuf, (ucs2_t*) c1.lname) != 0)
goto crit_check_ret;
} /* if (c1.rbitmap & ... */
if ((c1.rbitmap & (1<<FILPBIT_PDINFO))) {
+#ifdef DEBUG
+ LOG(log_debug, logtype_afpd, "Crit check: comparing %s to %s", path->m_name, c1.utf8name);
+#endif
+ 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(path->u_name, c1.utf8name) == NULL)
+ if (strcasestr_w((ucs2_t *) convbuf, (ucs2_t*)c1.utf8name) == NULL)
goto crit_check_ret;
} else
- if (strcasecmp(path->u_name, c1.utf8name) != 0)
+ if (strcasecmp_w((ucs2_t *)convbuf, (ucs2_t*)c1.utf8name) != 0)
goto crit_check_ret;
} /* if (c1.rbitmap & ... */
/* Check for creation date... */
if (c1.rbitmap & (1<<DIRPBIT_CDATE)) {
- if (adp || (adp = adl_lkup(path))) {
+ if (adp || (adp = adl_lkup(vol, path))) {
if (ad_getdate(adp, AD_DATE_CREATE, (u_int32_t*)&c_date) >= 0)
c_date = AD_DATE_TO_UNIX(c_date);
else c_date = path->st.st_mtime;
/* Check for backup date... */
if (c1.rbitmap & (1<<DIRPBIT_BDATE)) {
- if (adp || (adp == adl_lkup(path))) {
+ if (adp || (adp == adl_lkup(vol, path))) {
if (ad_getdate(adp, AD_DATE_BACKUP, (u_int32_t*)&b_date) >= 0)
b_date = AD_DATE_TO_UNIX(b_date);
else b_date = path->st.st_mtime;
/* Check attributes */
if ((c1.rbitmap & (1<<DIRPBIT_ATTR)) && c2.attr != 0) {
- if (adp || (adp = adl_lkup(path))) {
+ if (adp || (adp = adl_lkup(vol, path))) {
ad_getattr(adp, &attr);
if ((attr & c2.attr) != c1.attr)
goto crit_check_ret;
/* Check file type ID */
if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.f_type != 0) {
if (!adp)
- adp = adl_lkup(path);
+ adp = adl_lkup(vol, path);
finfo = get_finderinfo(path->m_name, adp, &finderinfo);
if (finfo->f_type != c1.finfo.f_type)
goto crit_check_ret;
if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.creator != 0) {
if (!finfo) {
if (!adp)
- adp = adl_lkup(path);
+ adp = adl_lkup(vol, path);
finfo = get_finderinfo(path->m_name, adp, &finderinfo);
}
if (finfo->creator != c1.finfo.creator)
if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.attrs != 0) {
u_int8_t attrs = 0;
- if (adp || (adp = adl_lkup(path))) {
+ if (adp || (adp = adl_lkup(vol, path))) {
finfo = (struct finderinfo*)ad_entry(adp, ADEID_FINDERI);
attrs = finfo->attrs;
}
/* Check label */
if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.label != 0) {
- if (adp || (adp = adl_lkup(path))) {
+ if (adp || (adp = adl_lkup(vol, path))) {
finfo = (struct finderinfo*)ad_entry(adp, ADEID_FINDERI);
if ((finfo->label & c2.finfo.label) != c1.finfo.label)
goto crit_check_ret;
if (!(fname = path.m_name = check_dirent(vol, entry->d_name)))
continue;
+ if (NULL == (fname = path.m_name = utompath(vol, entry->d_name, 0, utf8_encoding())))
+ continue;
+
+ /* now check against too big a file */
+ if (strlen(path.m_name) > vol->max_filename)
+ continue;
+
+
path.u_name = entry->d_name;
if (of_stat(&path) != 0) {
switch (errno) {
{
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;
int ret, rsize;
u_int32_t nrecs = 0;
unsigned char *spec1, *spec2, *bspec1, *bspec2;
+ size_t len;
+ u_int16_t namelen;
+ u_int16_t flags;
+ char tmppath[256];
memset(&c1, 0, sizeof(c1));
memset(&c2, 0, sizeof(c2));
return AFPERR_BITMAP;
}
- if ( ext)
- ibuf++;
+ if ( ext) {
+ memcpy(&spec_len, ibuf, sizeof(spec_len));
+ spec_len = ntohs(spec_len);
+ }
+ else {
+ spec_len = *(unsigned char*)ibuf;
+ }
/* Parse file specifications */
spec1 = ibuf;
- spec2 = ibuf + ibuf[0] + 2;
-
- if (ext)
- {
- spec1++; bspec1 = spec1;
- spec2++; bspec2 = spec2;
- }
- else
- {
- spec1 += 2; bspec1 = spec1;
- spec2 += 2; bspec2 = spec2;
- }
+ spec2 = ibuf + spec_len + 2;
+
+ spec1 += 2;
+ spec2 += 2;
+ bspec1 = spec1;
+ bspec2 = spec2;
/* File attribute bits... */
if (c1.rbitmap & (1 << FILPBIT_ATTR)) {
- memcpy(&c1.attr, ibuf, sizeof(c1.attr));
+ memcpy(&c1.attr, spec1, sizeof(c1.attr));
spec1 += sizeof(c1.attr);
- c1.attr = ntohs(c1.attr);
- memcpy(&c2.attr, ibuf, sizeof(c2.attr));
+ memcpy(&c2.attr, spec2, sizeof(c2.attr));
spec2 += sizeof(c1.attr);
- c2.attr = ntohs(c2.attr);
}
/* Parent DID */
}
/* Finder info */
- if (c1.rbitmap * (1 << FILPBIT_FINFO)) {
+ if (c1.rbitmap & (1 << FILPBIT_FINFO)) {
memcpy(&c1.finfo, spec1, sizeof(c1.finfo));
spec1 += sizeof(c1.finfo);
memcpy(&c2.finfo, spec2, sizeof(c2.finfo));
/* Long name */
if (c1.rbitmap & (1 << FILPBIT_LNAME)) {
/* Get the long filename */
- memcpy(c1.lname, bspec1 + spec1[1] + 1, (bspec1 + spec1[1])[0]);
- c1.lname[(bspec1 + spec1[1])[0]]= 0;
+ 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);
+ if (len == (size_t)(-1))
+ return AFPERR_PARAM;
+ c1.lname[len] = 0;
+
#if 0
- for (i = 0; c1.lname[i] != 0; i++)
- c1.lname[i] = tolower(c1.lname[i]);
-#endif
/* FIXME: do we need it ? It's always null ! */
memcpy(c2.lname, bspec2 + spec2[1] + 1, (bspec2 + spec2[1])[0]);
c2.lname[(bspec2 + spec2[1])[0]]= 0;
-#if 0
- for (i = 0; c2.lname[i] != 0; i++)
- c2.lname[i] = tolower(c2.lname[i]);
#endif
}
/* UTF8 Name */
if (c1.rbitmap & (1 << FILPBIT_PDINFO)) {
- char * tmppath;
- u_int16_t namelen;
/* offset */
memcpy(&namelen, spec1, sizeof(namelen));
memcpy (c1.utf8name, spec1+2, namelen);
c1.utf8name[(namelen+1)] =0;
- /* convert charset */
- tmppath = mtoupath(vol, c1.utf8name, 1);
- memset (c1.utf8name, 0, 256);
- memcpy (c1.utf8name, tmppath, MIN(strlen(tmppath), 255));
+ /* convert charset */
+ flags = CONV_PRECOMPOSE;
+ 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 */