X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Fcatsearch.c;h=6115a4e4c306f068509d9036a91859b5d6565e72;hb=5f5367aa2eedd7e8538566a83d163cc549c9d68f;hp=50a3564c3ebe8c0c7d59630ce69bdb0c78b36606;hpb=3265cc2a0d2e99eef895f505246388d295fbf553;p=netatalk.git diff --git a/etc/afpd/catsearch.c b/etc/afpd/catsearch.c index 50a3564c..6115a4e4 100644 --- a/etc/afpd/catsearch.c +++ b/etc/afpd/catsearch.c @@ -28,9 +28,9 @@ #include #include #include -#include -#include #include +#include +#include #if STDC_HEADERS #include @@ -41,14 +41,12 @@ #endif /* ! HAVE_MEMCPY */ #endif -#include -#include #include #include -#include #include #include +#include #ifdef CNID_DB #include #endif /* CNID_DB */ @@ -64,11 +62,13 @@ struct finderinfo { u_int32_t f_type; u_int32_t creator; - u_int8_t attrs; /* File attributes (8 bits)*/ - u_int8_t label; /* Label (8 bits)*/ + u_int16_t attrs; /* File attributes (high 8 bits)*/ + u_int16_t label; /* Label (low 8 bits )*/ char reserved[22]; /* Unknown (at least for now...) */ }; +typedef char packed_finder[ADEDLEN_FINDERI]; + /* Known attributes: * 0x04 - has a custom icon * 0x20 - name/icon is locked @@ -94,9 +94,10 @@ struct scrit { time_t mdate; /* Last modification date */ time_t bdate; /* Last backup date */ u_int32_t pdid; /* Parent DID */ - u_int16_t offcnt; /* Offspring count */ + u_int16_t offcnt; /* Offspring count */ struct finderinfo finfo; /* Finder info */ - char lname[32]; /* Long name */ + char lname[64]; /* Long name */ + char utf8name[514]; /* UTF8 or UCS2 name */ /* for convert_charset dest_len parameter +2 */ }; /* @@ -108,8 +109,6 @@ struct scrit { * */ struct dsitem { - char *m_name; /* Mac name */ - char *u_name; /* unix name (== strrchr('/', path)) */ struct dir *dir; /* Structure describing this directory */ int pidx; /* Parent's dsitem structure index. */ int checked; /* Have we checked this directory ? */ @@ -118,7 +117,7 @@ struct dsitem { #define DS_BSIZE 128 -static int cur_pos = 0; /* Saved position index (ID) - used to remember "position" across FPCatSearch calls */ +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. */ @@ -129,7 +128,7 @@ static int dsidx = 0; /* First free item index... */ static struct scrit c1, c2; /* search criteria */ /* Puts new item onto directory stack. */ -static int addstack(char *uname, char *mname, struct dir *dir, int pidx) +static int addstack(char *uname, struct dir *dir, int pidx) { struct dsitem *ds; int l; @@ -144,18 +143,15 @@ static int addstack(char *uname, char *mname, struct dir *dir, int pidx) /* Put new element. Allocate and copy lname and path. */ ds = dstack + dsidx++; - if (!(ds->m_name = strdup(mname))) - return -1; ds->dir = dir; ds->pidx = pidx; if (pidx >= 0) { - l = strlen(dstack[pidx].path); - if (!(ds->path = malloc(l + strlen(uname) + 2) )) + l = strlen(dstack[pidx].path); + if (!(ds->path = malloc(l + strlen(uname) + 2) )) return -1; strcpy(ds->path, dstack[pidx].path); strcat(ds->path, "/"); strcat(ds->path, uname); - ds->u_name = ds->path +l +1; } ds->checked = 0; @@ -164,7 +160,7 @@ static int addstack(char *uname, char *mname, struct dir *dir, int pidx) } /* 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) { @@ -176,89 +172,78 @@ static int reducestack() while (dsidx > 0) { if (dstack[dsidx-1].checked) { dsidx--; - free(dstack[dsidx].m_name); free(dstack[dsidx].path); - /* Check if we need to free (or release) dir structures */ } else return dsidx - 1; - } // while + } return -1; -} /* reducestack() */ +} /* Clears directory stack. */ -static void clearstack() +static void clearstack(void) { save_cidx = -1; while (dsidx > 0) { dsidx--; - free(dstack[dsidx].m_name); free(dstack[dsidx].path); - /* Check if we need to free (or release) dir structures */ } -} /* clearstack() */ - -/* Fills in dir field of dstack[cidx]. Must fill parent dirs' fields if needed... */ -static int resolve_dir(struct vol *vol, int cidx) -{ - struct dir *dir, *cdir; - - if (dstack[cidx].dir != NULL) - return 1; - - if (dstack[cidx].pidx < 0) - return 0; - - if (dstack[dstack[cidx].pidx].dir == NULL && resolve_dir(vol, dstack[cidx].pidx) == 0) - return 0; +} - cdir = dstack[dstack[cidx].pidx].dir; - dir = cdir->d_child; - while (dir) { - if (strcmp(dir->d_m_name, dstack[cidx].m_name) == 0) - break; - dir = (dir == cdir->d_child->d_prev) ? NULL : dir->d_next; - } /* while */ - - if (!dir) { - struct path path; - - path.u_name = dstack[cidx].path; - if (of_stat(&path)==-1) { - syslog(LOG_DEBUG, "resolve_dir: stat %s: %s", dstack[cidx].path, strerror(errno)); - return 0; - } - path.m_name = dstack[cidx].m_name; - path.u_name = dstack[cidx].u_name; - /* adddir works with a filename not absolute pathname */ - if ((dir = adddir(vol, cdir, &path)) == NULL) - return 0; - } - dstack[cidx].dir = dir; - - 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, struct adouble *adp) { static struct adouble ad; - struct adouble *adp; + struct ofork *of; - int isdir = S_ISDIR(path->st.st_mode); + int isdir; + + if (adp) + return adp; + + isdir = S_ISDIR(path->st.st_mode); if (!isdir && (of = of_findname(path))) { adp = of->of_ad; } else { - memset(&ad, 0, sizeof(ad)); + ad_init(&ad, vol->v_adouble, vol->v_ad_options); adp = &ad; } - if ( ad_open( path->u_name, ADFLAGS_HF | (isdir)?ADFLAGS_DIR:0, O_RDONLY, 0, adp) < 0 ) { - return NULL; - } + if ( ad_metadata( path->u_name, ((isdir)?ADFLAGS_DIR:0), adp) < 0 ) { + adp = NULL; /* FIXME without resource fork adl_lkup will be call again */ + } + return adp; } +/* -------------------- */ +static struct finderinfo *unpack_buffer(struct finderinfo *finfo, char *buffer) +{ + memcpy(&finfo->f_type, buffer +FINDERINFO_FRTYPEOFF, sizeof(finfo->f_type)); + memcpy(&finfo->creator, buffer +FINDERINFO_FRCREATOFF, sizeof(finfo->creator)); + memcpy(&finfo->attrs, buffer +FINDERINFO_FRFLAGOFF, sizeof(finfo->attrs)); + memcpy(&finfo->label, buffer +FINDERINFO_FRFLAGOFF, sizeof(finfo->label)); + finfo->attrs &= 0xff00; /* high 8 bits */ + finfo->label &= 0xff; /* low 8 bits */ + + return finfo; +} + +/* -------------------- */ +static struct finderinfo * +unpack_finderinfo(struct vol *vol, struct path *path, struct adouble **adp, struct finderinfo *finfo) +{ + packed_finder buf; + void *ptr; + + *adp = adl_lkup(vol, path, *adp); + ptr = get_finderinfo(vol, path->u_name, *adp, &buf); + return unpack_buffer(finfo, ptr); +} + +/* -------------------- */ #define CATPBIT_PARTIAL 31 /* Criteria checker. This function returns a 2-bit value. */ /* bit 0 means if checked file meets given criteria. */ @@ -267,20 +252,47 @@ static struct adouble *adl_lkup(struct path *path) * fname - our fname (translated to UNIX) * cidx - index in directory stack */ -static int crit_check(struct vol *vol, struct path *path, int cidx) { - int r = 0; - u_int16_t attr; +static int crit_check(struct vol *vol, struct path *path) { + int result = 0; + u_int16_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; + static char convbuf[514]; /* for convert_charset dest_len parameter +2 */ + size_t len; if (S_ISDIR(path->st.st_mode)) { - r = 2; if (!c1.dbitmap) - return r; + return 0; + } + else { + if (!c1.fbitmap) + return 0; + + /* compute the Mac name + * first try without id (it's slow to find it) + * An other option would be to call get_id in utompath but + * we need to pass parent dir + */ + if (!(path->m_name = utompath(vol, path->u_name, 0 , utf8_encoding()) )) { + /*retry with the right id */ + + cnid_t id; + + adp = adl_lkup(vol, path, adp); + id = get_id(vol, adp, &path->st, path->d_dir->d_did, path->u_name, strlen(path->u_name)); + if (!id) { + /* FIXME */ + return 0; + } + /* save the id for getfilparm */ + path->id = id; + if (!(path->m_name = utompath(vol, path->u_name, id , utf8_encoding()))) { + return 0; + } + } } - else if (!c1.fbitmap) - return 0; /* Kind of optimization: * -- first check things we've already have - filename @@ -289,14 +301,30 @@ static int crit_check(struct vol *vol, struct path *path, int cidx) { */ /* Check for filename */ - if (c1.rbitmap & (1<v_maccharset, CH_UCS2, path->m_name, strlen(path->m_name), convbuf, 512)) ) + goto crit_check_ret; + + if ((c1.rbitmap & (1<m_name, strlen(path->m_name), convbuf, 512, &flags))) { + goto crit_check_ret; + } + if (c1.rbitmap & (1<u_name, c1.lname) == NULL) + if (strcasestr_w((ucs2_t *) convbuf, (ucs2_t*)c1.utf8name) == NULL) goto crit_check_ret; } else - if (strcasecmp(path->u_name, c1.lname) != 0) + if (strcasecmp_w((ucs2_t *)convbuf, (ucs2_t*)c1.utf8name) != 0) goto crit_check_ret; - } /* if (c1.rbitmap & ... */ + } /* FIXME */ @@ -307,47 +335,47 @@ static int crit_check(struct vol *vol, struct path *path, int cidx) { if ((unsigned)c2.bdate > 0x7fffffff) c2.bdate = 0x7fffffff; - /* Check for modification date FIXME: should we look at adouble structure ? */ - if ((c1.rbitmap & (1<st.st_mtime < c1.mdate || path->st.st_mtime > c2.mdate) goto crit_check_ret; - + } + /* Check for creation date... */ - if (c1.rbitmap & (1<= 0) - c_date = AD_DATE_TO_UNIX(c_date); - else c_date = path->st.st_mtime; - } else c_date = path->st.st_mtime; + if ((c1.rbitmap & (1<st.st_mtime; + adp = adl_lkup(vol, path, adp); + if (adp && ad_getdate(adp, AD_DATE_CREATE, &ac_date) >= 0) + c_date = AD_DATE_TO_UNIX(ac_date); + if (c_date < c1.cdate || c_date > c2.cdate) goto crit_check_ret; } /* Check for backup date... */ - if (c1.rbitmap & (1<= 0) - b_date = AD_DATE_TO_UNIX(b_date); - else b_date = path->st.st_mtime; - } else b_date = path->st.st_mtime; + if ((c1.rbitmap & (1<st.st_mtime; + adp = adl_lkup(vol, path, adp); + if (adp && ad_getdate(adp, AD_DATE_BACKUP, &ab_date) >= 0) + b_date = AD_DATE_TO_UNIX(ab_date); + if (b_date < c1.bdate || b_date > c2.bdate) goto crit_check_ret; } /* Check attributes */ if ((c1.rbitmap & (1<m_name, adp, &finderinfo); + finfo = unpack_finderinfo(vol, path, &adp, &finderinfo); if (finfo->f_type != c1.finfo.f_type) goto crit_check_ret; } @@ -355,9 +383,7 @@ static int crit_check(struct vol *vol, struct path *path, int cidx) { /* Check creator ID */ if ((c1.rbitmap & (1<m_name, adp, &finderinfo); + finfo = unpack_finderinfo(vol, path, &adp, &finderinfo); } if (finfo->creator != c1.finfo.creator) goto crit_check_ret; @@ -365,77 +391,85 @@ static int crit_check(struct vol *vol, struct path *path, int cidx) { /* Check finder info attributes */ if ((c1.rbitmap & (1<attrs; - } - else if (*path->u_name == '.') { - attrs = htons(FINDERINFO_INVISIBLE); + if (!finfo) { + finfo = unpack_finderinfo(vol, path, &adp, &finderinfo); } - if ((attrs & c2.finfo.attrs) != c1.finfo.attrs) + if ((finfo->attrs & c2.finfo.attrs) != c1.finfo.attrs) goto crit_check_ret; } /* Check label */ if ((c1.rbitmap & (1<label & c2.finfo.label) != c1.finfo.label) - goto crit_check_ret; - } else goto crit_check_ret; + if (!finfo) { + finfo = unpack_finderinfo(vol, path, &adp, &finderinfo); + } + if ((finfo->label & c2.finfo.label) != c1.finfo.label) + goto crit_check_ret; } /* FIXME: Attributes check ! */ /* All criteria are met. */ - r |= 1; + result |= 1; crit_check_ret: if (adp != NULL) - ad_close(adp, ADFLAGS_HF); - return r; + ad_close_metadata(adp); + return result; } - -/* Adds an item to resultset. */ -static int rslt_add(struct vol *vol, char *fname, short cidx, int isdir, char **rbuf) +/* ------------------------------ */ +static int rslt_add ( struct vol *vol, struct path *path, char **buf, int ext) { - char *p = *rbuf; - int l = fname != NULL ? strlen(fname) : 0; - u_int32_t did; - char p0; - - p0 = p[0] = cidx != -1 ? l + 7 : l + 5; - if (p0 & 1) p[0]++; - p[1] = isdir ? 128 : 0; - p += 2; - if (cidx != -1) { - if (dstack[cidx].dir == NULL && resolve_dir(vol, cidx) == 0) - return 0; - did = dstack[cidx].dir->d_did; - memcpy(p, &did, sizeof(did)); - p += sizeof(did); - } - /* Fill offset of returned file name */ - if (fname != NULL) { - *p++ = 0; - *p = (int)(p - *rbuf) - 1; + char *p = *buf; + int ret; + size_t tbuf =0; + u_int16_t resultsize; + int isdir = S_ISDIR(path->st.st_mode); + + /* Skip resultsize */ + if (ext) { + p += sizeof(resultsize); + } + else { p++; - p[0] = l; - strcpy(p+1, fname); - p += l + 1; } + *p++ = isdir ? FILDIRBIT_ISDIR : FILDIRBIT_ISFILE; /* IsDir ? */ - if (p0 & 1) - *p++ = 0; + if (ext) { + *p++ = 0; /* Pad */ + } + + if ( isdir ) { + ret = getdirparams(vol, c1.dbitmap, path, path->d_dir, p , &tbuf ); + } + else { + /* FIXME slow if we need the file ID, we already know it, done ? */ + ret = getfilparams ( vol, c1.fbitmap, path, path->d_dir, p, &tbuf); + } - *rbuf = p; - /* *rbuf[0] = (int)(p-*rbuf); */ - return 1; -} /* rslt_add */ + if ( ret != AFP_OK ) + return 0; + /* Make sure entry length is even */ + if ((tbuf & 1)) { + *p++ = 0; + tbuf++; + } + + if (ext) { + resultsize = htons(tbuf); + memcpy ( *buf, &resultsize, sizeof(resultsize) ); + *buf += tbuf + 4; + } + else { + **buf = tbuf; + *buf += tbuf + 2; + } + + return 1; +} + #define VETO_STR \ "./../.AppleDouble/.AppleDB/Network Trash Folder/TheVolumeSettingsFolder/TheFindByContentFolder/.AppleDesktop/.Parent/" @@ -447,27 +481,34 @@ static int rslt_add(struct vol *vol, char *fname, short cidx, int isdir, char ** * pos - position we've stopped recently * rbuf - output buffer * rbuflen - output buffer length -*/ + */ +#define NUM_ROUNDS 100 static int catsearch(struct vol *vol, struct dir *dir, - int rmatches, int *pos, char *rbuf, u_int32_t *nrecs, int *rsize) + int rmatches, u_int32_t *pos, char *rbuf, u_int32_t *nrecs, int *rsize, int ext) { int cidx, r; - char *fname = NULL; struct dirent *entry; int result = AFP_OK; int ccr; - struct path path; + 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; - if (*pos != 0 && *pos != cur_pos) - return AFPERR_CATCHNG; + if (*pos != 0 && *pos != cur_pos) { + result = AFPERR_CATCHNG; + goto catsearch_end; + } /* 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) { clearstack(); @@ -476,12 +517,12 @@ static int catsearch(struct vol *vol, struct dir *dir, dirpos = NULL; } - if (addstack("","", dir, -1) == -1) { + if (addstack("", dir, -1) == -1) { result = AFPERR_MISC; goto catsearch_end; } dstack[0].path = strdup(vpath); - /* FIXME: Sometimes DID is given by klient ! (correct this one above !) */ + /* FIXME: Sometimes DID is given by client ! (correct this one above !) */ } /* Save current path */ @@ -496,8 +537,11 @@ static int catsearch(struct vol *vol, struct dir *dir, } /* while() */ while ((cidx = reducestack()) != -1) { - if (dirpos == NULL) - dirpos = opendir(dstack[cidx].path); + cached = 1; + if (dirpos == NULL) { + dirpos = opendir(dstack[cidx].path); + cached = (dstack[cidx].dir->d_child != NULL); + } if (dirpos == NULL) { switch (errno) { case EACCES: @@ -515,13 +559,17 @@ static int catsearch(struct vol *vol, struct dir *dir, } /* switch (errno) */ goto catsearch_end; } + /* FIXME error in chdir, what do we do? */ chdir(dstack[cidx].path); + + while ((entry=readdir(dirpos)) != NULL) { (*pos)++; - if (!(fname = path.m_name = check_dirent(vol, entry->d_name))) + if (!check_dirent(vol, entry->d_name)) continue; + memset(&path, 0, sizeof(path)); path.u_name = entry->d_name; if (of_stat(&path) != 0) { switch (errno) { @@ -536,29 +584,41 @@ static int catsearch(struct vol *vol, struct dir *dir, default: result = AFPERR_MISC; goto catsearch_end; - } /* switch (errno) */ - } /* if (stat(entry->d_name, &path.st) != 0) */ -#if 0 - for (i = 0; fname[i] != 0; i++) - fname[i] = tolower(fname[i]); -#endif - ccr = crit_check(vol, &path, cidx); - /* bit 1 means that we have to descend into this directory. */ - if ((ccr & 2) && S_ISDIR(path.st.st_mode)) { - if (addstack(entry->d_name, fname, NULL, cidx) == -1) { + } + } + if (S_ISDIR(path.st.st_mode)) { + /* here we can short cut + 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) { + /* path.m_name is set by adddir */ + if (NULL == (path.d_dir = adddir( vol, dstack[cidx].dir, &path) ) ) { + result = AFPERR_MISC; + goto catsearch_end; + } + } + path.m_name = path.d_dir->d_m_name; + + if (addstack(path.u_name, path.d_dir, cidx) == -1) { result = AFPERR_MISC; goto catsearch_end; } - } - - /* bit 0 means that criteria has ben met */ + } + 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 */ if ((ccr & 1)) { - r = rslt_add(vol, - (c1.fbitmap&(1<= 448) goto catsearch_pause; - } + } + /* MacOS 9 doesn't like servers executing commands longer than few seconds */ + if (--num_rounds <= 0) { + if (start_time != time(NULL)) { + result=AFP_OK; + goto catsearch_pause; + } + num_rounds = NUM_ROUNDS; + } } /* while ((entry=readdir(dirpos)) != NULL) */ closedir(dirpos); dirpos = NULL; @@ -594,18 +662,30 @@ catsearch_end: /* Exiting catsearch: error condition */ return result; } /* catsearch() */ - -int afp_catsearch(AFPObj *obj, char *ibuf, int ibuflen, - char *rbuf, int *rbuflen) +/* -------------------------- */ +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; + 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]; + + *rbuflen = 0; + + /* min header size */ + if (ibuflen < 32) { + return AFPERR_PARAM; + } memset(&c1, 0, sizeof(c1)); memset(&c2, 0, sizeof(c2)); @@ -614,7 +694,6 @@ int afp_catsearch(AFPObj *obj, char *ibuf, int ibuflen, memcpy(&vid, ibuf, sizeof(vid)); ibuf += sizeof(vid); - *rbuflen = 0; if ((vol = getvolbyvid(vid)) == NULL) { return AFPERR_PARAM; } @@ -645,21 +724,32 @@ int afp_catsearch(AFPObj *obj, char *ibuf, int ibuflen, return AFPERR_BITMAP; } + if ( ext) { + memcpy(&spec_len, ibuf, sizeof(spec_len)); + spec_len = ntohs(spec_len); + } + else { + /* with catsearch only name and parent id are allowed */ + c1.fbitmap &= (1<v_maccharset, CH_UCS2, tmppath, strlen(tmppath), c1.lname, sizeof(c1.lname)); + if (len == (size_t)(-1)) + return AFPERR_PARAM; + #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]); + /* 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; #endif } + /* UTF8 Name */ + if (c1.rbitmap & (1 << FILPBIT_PDINFO)) { + /* offset */ + memcpy(&namelen, spec1, sizeof(namelen)); + namelen = ntohs (namelen); + spec1 = bspec1+namelen+4; /* Skip Unicode Hint */ + + /* length */ + memcpy(&namelen, spec1, sizeof(namelen)); + namelen = ntohs (namelen); + if (namelen > 255) /* Safeguard */ + namelen = 255; + + memcpy (c1.utf8name, spec1+2, namelen); + c1.utf8name[(namelen+1)] =0; + + /* 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; + } + /* Call search */ *rbuflen = 24; - ret = catsearch(vol, vol->v_dir, rmatches, &catpos[0], rbuf+24, &nrecs, &rsize); + ret = catsearch(vol, vol->v_dir, rmatches, &catpos[0], rbuf+24, &nrecs, &rsize, ext); memcpy(rbuf, catpos, sizeof(catpos)); rbuf += sizeof(catpos); @@ -766,7 +882,21 @@ int afp_catsearch(AFPObj *obj, char *ibuf, int ibuflen, *rbuflen += rsize; return ret; -} /* afp_catsearch */ +} /* catsearch_afp */ + +/* -------------------------- */ +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, size_t ibuflen, + char *rbuf, size_t *rbuflen) +{ + return catsearch_afp( obj, ibuf, ibuflen, rbuf, rbuflen, 1); +} /* FIXME: we need a clean separation between afp stubs and 'real' implementation */ /* (so, all buffer packing/unpacking should be done in stub, everything else