]> arthur.barton.de Git - netatalk.git/commitdiff
CatSearch fixes, base on TSUBAKIMOTO Hiroya patch.
authordidg <didg>
Sat, 12 Feb 2005 11:22:04 +0000 (11:22 +0000)
committerdidg <didg>
Sat, 12 Feb 2005 11:22:04 +0000 (11:22 +0000)
etc/afpd/catsearch.c
etc/afpd/desktop.h
etc/afpd/file.c
etc/afpd/mangle.c
include/atalk/adouble.h
libatalk/adouble/ad_open.c

index dc14dea61f3d18cbf9fe002374bf563148b564a1..3d95d14b5414f6c8bfd45cdbb51d8805a9085144 100644 (file)
 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
@@ -92,7 +94,7 @@ 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[64];             /* Long name */ 
        char utf8name[512];         /* UTF8 name */
@@ -107,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 ? */
@@ -128,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;
@@ -143,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;
@@ -175,14 +172,12 @@ 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;
        } 
        return -1;
-} /* reducestack() */
+} 
 
 /* Clears directory stack. */
 static void clearstack() 
@@ -190,62 +185,24 @@ static void clearstack()
        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) {
-                       LOG(log_debug, logtype_afpd, "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. 
  * FIXME What about noadouble?
 */
-static struct adouble *adl_lkup(struct vol *vol, struct path *path)
+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;
@@ -254,12 +211,38 @@ static struct adouble *adl_lkup(struct vol *vol, struct path *path)
                adp = &ad;
        } 
 
-       if ( ad_metadata( path->u_name, ((isdir)?ADFLAGS_DIR: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(char *upath, struct adouble *adp, struct finderinfo *finfo)
+{
+       packed_finder  buf;
+       void           *ptr;
+       
+       ptr = get_finderinfo(upath, 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. */
@@ -268,8 +251,8 @@ static struct adouble *adl_lkup(struct vol *vol, 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;
+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;
@@ -279,12 +262,34 @@ static int crit_check(struct vol *vol, struct path *path, int cidx) {
        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;
+               }
+               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
@@ -293,27 +298,22 @@ static int crit_check(struct vol *vol, struct path *path, int cidx) {
         */
 
        /* 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 ((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)) )
                        goto crit_check_ret;
                convbuf[len] = 0; 
-               if (c1.rbitmap & (1<<CATPBIT_PARTIAL)) {
+               if ((c1.rbitmap & (1<<CATPBIT_PARTIAL))) {
                        if (strcasestr_w( (ucs2_t*) convbuf, (ucs2_t*) c1.lname) == NULL)
                                goto crit_check_ret;
                } else
                        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)) )
+               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)
@@ -321,8 +321,7 @@ static int crit_check(struct vol *vol, struct path *path, int cidx) {
                } else
                        if (strcasecmp_w((ucs2_t *)convbuf, (ucs2_t*)c1.utf8name) != 0)
                                goto crit_check_ret;
-       } /* if (c1.rbitmap & ... */
-
+       } 
 
 
        /* FIXME */
@@ -333,47 +332,48 @@ 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<<DIRPBIT_MDATE))) 
+       /* Check for modification date */
+       if ((c1.rbitmap & (1<<DIRPBIT_MDATE))) {
                if (path->st.st_mtime < c1.mdate || path->st.st_mtime > c2.mdate)
                        goto crit_check_ret;
-
+       }
+       
        /* Check for creation date... */
-       if (c1.rbitmap & (1<<DIRPBIT_CDATE)) {
-               if (adp || (adp = adl_lkup(vol, path))) {
-                       if (ad_getdate(adp, AD_DATE_CREATE, &ac_date) >= 0)
-                               c_date = AD_DATE_TO_UNIX(ac_date);
-                       else c_date = path->st.st_mtime;
-               } else c_date = path->st.st_mtime;
+       if ((c1.rbitmap & (1<<DIRPBIT_CDATE))) {
+               c_date = path->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<<DIRPBIT_BDATE)) {
-               if (adp || (adp == adl_lkup(vol, path))) {
-                       if (ad_getdate(adp, AD_DATE_BACKUP, &ab_date) >= 0)
-                               b_date = AD_DATE_TO_UNIX(ab_date);
-                       else b_date = path->st.st_mtime;
-               } else b_date = path->st.st_mtime;
+       if ((c1.rbitmap & (1<<DIRPBIT_BDATE))) {
+               b_date = path->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<<DIRPBIT_ATTR)) && c2.attr != 0) {
-               if (adp || (adp = adl_lkup(vol, path))) {
+               if ((adp = adl_lkup(vol, path, adp))) {
                        ad_getattr(adp, &attr);
                        if ((attr & c2.attr) != c1.attr)
                                goto crit_check_ret;
-               } else goto crit_check_ret;
+               } else 
+                       goto crit_check_ret;
        }               
 
         /* Check file type ID */
        if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.f_type != 0) {
-               if (!adp)
-                       adp = adl_lkup(vol, path);
-               finfo = get_finderinfo(path->m_name, adp, &finderinfo);
+               adp = adl_lkup(vol, path, adp);
+           finfo = unpack_finderinfo(path->u_name, adp, &finderinfo);
                if (finfo->f_type != c1.finfo.f_type)
                        goto crit_check_ret;
        }
@@ -381,9 +381,8 @@ static int crit_check(struct vol *vol, struct path *path, int cidx) {
        /* Check creator ID */
        if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.creator != 0) {
                if (!finfo) {
-                       if (!adp)
-                               adp = adl_lkup(vol, path);
-                       finfo = get_finderinfo(path->m_name, adp, &finderinfo);
+               adp = adl_lkup(vol, path, adp);
+                       finfo = unpack_finderinfo(path->u_name, adp, &finderinfo);
                }
                if (finfo->creator != c1.finfo.creator)
                        goto crit_check_ret;
@@ -391,79 +390,36 @@ static int crit_check(struct vol *vol, struct path *path, int cidx) {
                
        /* Check finder info attributes */
        if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.attrs != 0) {
-               u_int8_t attrs = 0;
-
-               if (adp || (adp = adl_lkup(vol, path))) {
-                       finfo = (struct finderinfo*)ad_entry(adp, ADEID_FINDERI);
-                       attrs = finfo->attrs;
-               }
-               else if (*path->u_name == '.') {
-                       /* FIXME 0x4000 becomes 0x00 on bigendian */
-                       attrs = htons(FINDERINFO_INVISIBLE);
+               if (!finfo) {
+               adp = adl_lkup(vol, path, adp);
+                       finfo = unpack_finderinfo(path->u_name, 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<<DIRPBIT_FINFO)) && c2.finfo.label != 0) {
-               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;
-               } else goto crit_check_ret;
+               if (!finfo) {
+               adp = adl_lkup(vol, path, adp);
+                       finfo = unpack_finderinfo(path->u_name, 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;
+       return result;
 }  
 
-
-/* Adds an item to resultset. */
-static int rslt_add(struct vol *vol, char *fname, short cidx, int isdir, char **rbuf)
-{
-       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;
-               p++;
-               p[0] = l;
-               strcpy(p+1, fname);
-               p += l + 1;
-       }
-
-       if (p0 & 1)
-               *p++ = 0;
-
-       *rbuf = p;
-       /* *rbuf[0] = (int)(p-*rbuf); */
-       return 1;
-} /* rslt_add */
-
-static int rslt_add_ext ( struct vol *vol, struct path *path, char **buf, short cidx)
+/* ------------------------------ */
+static int rslt_add ( struct vol *vol, struct path *path, char **buf, int ext)
 {
 
        char            *p = *buf;
@@ -471,49 +427,49 @@ static int rslt_add_ext ( struct vol *vol, struct path *path, char **buf, short
        u_int16_t       resultsize;
        int             isdir = S_ISDIR(path->st.st_mode); 
 
-       if (dstack[cidx].dir == NULL && resolve_dir(vol, cidx) == 0)
-               return 0;
-
-       p += sizeof(resultsize); /* Skip resultsize */
+       /* Skip resultsize */
+       if (ext) {
+               p += sizeof(resultsize); 
+       }
+       else {
+               p++;
+       }
        *p++ = isdir ? FILDIRBIT_ISDIR : FILDIRBIT_ISFILE;    /* IsDir ? */
-       *p++ = 0;                  /* Pad */
+
+       if (ext) {
+               *p++ = 0;                  /* Pad */
+       }
        
-       if ( isdir )
-       {
-               struct dir* dir = NULL;
-
-               dir = dirsearch_byname(dstack[cidx].dir, path->u_name);
-               if (!dir) {
-                       if ((dir = adddir( vol, dstack[cidx].dir, path)) == NULL) {
-                               return 0;
-                       }
-               }
-               ret = getdirparams(vol, c1.dbitmap, path, dir, p , &tbuf ); 
+       if ( isdir ) {
+        ret = getdirparams(vol, c1.dbitmap, path, path->d_dir, p , &tbuf ); 
        }
-       else
-       {
-               ret = getfilparams ( vol, c1.fbitmap, path, dstack[cidx].dir, p, &tbuf);
+       else {
+           /* FIXME slow if we need the file ID, we already know it */
+               ret = getfilparams ( vol, c1.fbitmap, path, path->d_dir, p, &tbuf);
        }
 
        if ( ret != AFP_OK )
                return 0;
 
        /* Make sure entry length is even */
-       if (tbuf & 1) {
+       if ((tbuf & 1)) {
           *p++ = 0;
           tbuf++;
        }
 
-       resultsize = htons(tbuf);
-       memcpy ( *buf, &resultsize, sizeof(resultsize) );
-       
-       *buf += tbuf + 4;
+       if (ext) {
+               resultsize = htons(tbuf);
+               memcpy ( *buf, &resultsize, sizeof(resultsize) );
+               *buf += tbuf + 4;
+       }
+       else {
+               **buf = tbuf;
+               *buf += tbuf + 2;
+       }
 
        return 1;
-} /* rslr_add_ext */
-       
+} 
        
-
 #define VETO_STR \
         "./../.AppleDouble/.AppleDB/Network Trash Folder/TheVolumeSettingsFolder/TheFindByContentFolder/.AppleDesktop/.Parent/"
 
@@ -531,17 +487,17 @@ static int catsearch(struct vol *vol, struct dir *dir,
                     int rmatches, int *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;
+    time_t start_time;
+    int num_rounds = NUM_ROUNDS;
+    int cached;
         
        if (*pos != 0 && *pos != cur_pos) 
                return AFPERR_CATCHNG;
@@ -549,7 +505,7 @@ static int catsearch(struct vol *vol, struct dir *dir,
        /* FIXME: Category "offspring count ! */
 
        /* So we are beginning... */
-        start_time = time(NULL);
+    start_time = time(NULL);
 
        /* We need to initialize all mandatory structures/variables and change working directory appropriate... */
        if (*pos == 0) {
@@ -559,7 +515,7 @@ 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;
                }
@@ -579,8 +535,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:
@@ -598,21 +557,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;
 
-                       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.m_name = NULL;
                        path.u_name = entry->d_name;
                        if (of_stat(&path) != 0) {
                                switch (errno) {
@@ -627,35 +582,40 @@ 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(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;
                                } 
-                       }
+            }
+            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) {
-                               if ( ext ) { 
-                                       r = rslt_add_ext ( vol, &path, &rrbuf, cidx);
-                               }
-                               else
-                               {
-                                       r = rslt_add(vol,  
-                                                    (c1.fbitmap&(1<<FILPBIT_LNAME))|(c1.dbitmap&(1<<DIRPBIT_LNAME)) ? 
-                                                        fname : NULL,  
-                                                    (c1.fbitmap&(1<<FILPBIT_PDID))|(c1.dbitmap&(1<<DIRPBIT_PDID)) ? 
-                                                        cidx : -1, 
-                                                    S_ISDIR(path.st.st_mode), &rrbuf); 
-                               }
+                       if ((ccr & 1)) {
+                               r = rslt_add ( vol, &path, &rrbuf, ext);
                                
                                if (r == 0) {
                                        result = AFPERR_MISC;
@@ -669,11 +629,11 @@ static int catsearch(struct vol *vol, struct dir *dir,
                                if (rrbuf - rbuf >= 448)
                                        goto catsearch_pause;
                        }
-                        /* MacOS 9 doesn't like servers executing commands longer than few seconds */
+                       /* 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;
+                                       result=AFP_OK;
+                                       goto catsearch_pause;
                            }
                            num_rounds = NUM_ROUNDS;
                        }
@@ -700,6 +660,7 @@ catsearch_end: /* Exiting catsearch: error condition */
        return result;
 } /* catsearch() */
 
+/* -------------------------- */
 int catsearch_afp(AFPObj *obj, char *ibuf, int ibuflen,
                   char *rbuf, int *rbuflen, int ext)
 {
@@ -717,6 +678,13 @@ int catsearch_afp(AFPObj *obj, char *ibuf, int ibuflen,
     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));
 
@@ -724,7 +692,6 @@ int catsearch_afp(AFPObj *obj, char *ibuf, int ibuflen,
     memcpy(&vid, ibuf, sizeof(vid));
     ibuf += sizeof(vid);
 
-    *rbuflen = 0;
     if ((vol = getvolbyvid(vid)) == NULL) {
         return AFPERR_PARAM;
     }
@@ -760,6 +727,9 @@ int catsearch_afp(AFPObj *obj, char *ibuf, int ibuflen,
         spec_len = ntohs(spec_len);
     }
     else {
+        /* with catsearch only name and parent id are allowed */
+       c1.fbitmap &= (1<<FILPBIT_LNAME) | (1<<FILPBIT_PDID);
+       c1.dbitmap &= (1<<DIRPBIT_LNAME) | (1<<DIRPBIT_PDID);
         spec_len = *(unsigned char*)ibuf;
     }
 
@@ -821,70 +791,75 @@ int catsearch_afp(AFPObj *obj, char *ibuf, int ibuflen,
 
     /* Finder info */
     if (c1.rbitmap & (1 << FILPBIT_FINFO)) {
-           memcpy(&c1.finfo, spec1, sizeof(c1.finfo));
-           spec1 += sizeof(c1.finfo);
-           memcpy(&c2.finfo, spec2, sizeof(c2.finfo));
-           spec2 += sizeof(c2.finfo);
+       packed_finder buf;
+       
+           memcpy(buf, spec1, sizeof(buf));
+           unpack_buffer(&c1.finfo, buf);      
+           spec1 += sizeof(buf);
+
+           memcpy(buf, spec2, sizeof(buf));
+           unpack_buffer(&c2.finfo, buf);
+           spec2 += sizeof(buf);
     } /* Finder info */
 
     if ((c1.rbitmap & (1 << DIRPBIT_OFFCNT)) != 0) {
         /* Offspring count - only directories */
-       if (c1.fbitmap == 0) {
-           memcpy(&c1.offcnt, spec1, sizeof(c1.offcnt));
-           spec1 += sizeof(c1.offcnt);
-           c1.offcnt = ntohs(c1.offcnt);
-           memcpy(&c2.offcnt, spec2, sizeof(c2.offcnt));
-           spec2 += sizeof(c2.offcnt);
-           c2.offcnt = ntohs(c2.offcnt);
-       }
-       else if (c1.dbitmap == 0) {
-               /* ressource fork length */
-       }
-       else {
-           return AFPERR_BITMAP;  /* error */
-       }
+               if (c1.fbitmap == 0) {
+               memcpy(&c1.offcnt, spec1, sizeof(c1.offcnt));
+               spec1 += sizeof(c1.offcnt);
+               c1.offcnt = ntohs(c1.offcnt);
+               memcpy(&c2.offcnt, spec2, sizeof(c2.offcnt));
+               spec2 += sizeof(c2.offcnt);
+               c2.offcnt = ntohs(c2.offcnt);
+               }
+               else if (c1.dbitmap == 0) {
+                       /* ressource fork length */
+               }
+               else {
+               return AFPERR_BITMAP;  /* error */
+               }
     } /* Offspring count/ressource fork length */
 
     /* Long name */
     if (c1.rbitmap & (1 << FILPBIT_LNAME)) {
         /* 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);
+               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;
+               c1.lname[len] = 0;
 
 #if 0  
-       /* 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;
+               /* 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);
+               /* offset */
+               memcpy(&namelen, spec1, sizeof(namelen));
+               namelen = ntohs (namelen);
 
-       spec1 = bspec1+namelen+4; /* Skip Unicode Hint */
+               spec1 = bspec1+namelen+4; /* Skip Unicode Hint */
 
-       /* length */
-       memcpy(&namelen, spec1, sizeof(namelen));
-       namelen = ntohs (namelen);
-       if (namelen > 255)  /* Safeguard */
-               namelen = 255;
+               /* 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;
+               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);
+               /* 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;
+               c1.utf8name[len]=0;
     }
     
     /* Call search */
@@ -909,6 +884,7 @@ int catsearch_afp(AFPObj *obj, char *ibuf, int ibuflen,
     return ret;
 } /* catsearch_afp */
 
+/* -------------------------- */
 int afp_catsearch (AFPObj *obj, char *ibuf, int ibuflen,
                   char *rbuf, int *rbuflen)
 {
index 8fe75b7302c3bb6bc24eb0c34394bb55608955f1..f9fdcd7c14ed26af833ebe77fa7f97111685cf17 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: desktop.h,v 1.3.6.3.2.1 2005-01-31 19:50:35 didg Exp $
+ * $Id: desktop.h,v 1.3.6.3.2.2 2005-02-12 11:22:04 didg Exp $
  *
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
  * All Rights Reserved.
 #include "globals.h"
 #include "volume.h"
 
-/* various finder info bits */
-#define FINDERINFO_FRFLAGOFF   8
-#define FINDERINFO_FRVIEWOFF  14 
-#define FINDERINFO_INVISIBLE  (1<<14)
-#define FINDERINFO_CLOSEDVIEW 0x100   
-
 struct savedt {
     u_char     sdt_creator[ 4 ];
     int                sdt_fd;
index c97a4eff978c1bee4fc6e599fd59622edeee6fd2..9ce184a1e04b6c6ea847d85ec1bc319a216dcfbc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: file.c,v 1.92.2.2.2.31.2.10 2005-02-10 01:23:12 didg Exp $
+ * $Id: file.c,v 1.92.2.2.2.31.2.11 2005-02-12 11:22:04 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -68,15 +68,15 @@ char *strchr (), *strrchr ();
  *                           putawayID    4  home directory id
  */
 
-const u_char ufinderi[] = {
+const u_char ufinderi[ADEDLEN_FINDERI] = {
                               0, 0, 0, 0, 0, 0, 0, 0,
                               1, 0, 0, 0, 0, 0, 0, 0,
                               0, 0, 0, 0, 0, 0, 0, 0,
                               0, 0, 0, 0, 0, 0, 0, 0
                           };
 
-/* FIXME mpath : unix or mac name ? (for now it's mac name ) */
-void *get_finderinfo(const char *mpath, struct adouble *adp, void *data)
+/* FIXME path : unix or mac name ? (for now it's unix name ) */
+void *get_finderinfo(const char *upath, struct adouble *adp, void *data)
 {
     struct extmap      *em;
     void                *ad_finder = NULL;
@@ -85,18 +85,24 @@ void *get_finderinfo(const char *mpath, struct adouble *adp, void *data)
     if (adp)
         ad_finder = ad_entry(adp, ADEID_FINDERI);
 
-    if ((ad_finder != NULL)) {
-        memcpy(data, ad_finder, 32);
+    if (ad_finder) {
+        memcpy(data, ad_finder, ADEDLEN_FINDERI);
         /* default type ? */
         if (!memcmp(ad_finder, ufinderi, 8))
             chk_ext = 1;
     }
     else {
-        memcpy(data, ufinderi, 32);
+        memcpy(data, ufinderi, ADEDLEN_FINDERI);
         chk_ext = 1;
+        if (*upath == '.') { /* make it invisible */
+            u_int16_t ashort;
+            
+            ashort = htons(FINDERINFO_INVISIBLE);
+            memcpy(data + FINDERINFO_FRFLAGOFF, &ashort, sizeof(ashort));
+        }
     }
     /** Only enter if no appledouble information and no finder information found. */
-    if (chk_ext && (em = getextmap( mpath ))) {
+    if (chk_ext && (em = getextmap( upath ))) {
         memcpy(data, em->em_type, sizeof( em->em_type ));
         memcpy((char *)data + 4, em->em_creator, sizeof(em->em_creator));
     }
@@ -316,14 +322,8 @@ int getmetadata(struct vol *vol,
             break;
 
         case FILPBIT_FINFO :
-           get_finderinfo(path->m_name, adp, (char *)data);
-            if (!adp) {
-                if (*upath == '.') { /* make it invisible */
-                    ashort = htons(FINDERINFO_INVISIBLE);
-                    memcpy(data + FINDERINFO_FRFLAGOFF, &ashort, sizeof(ashort));
-                }
-            }
-            data += 32;
+           get_finderinfo(upath, adp, (char *)data);
+            data += ADEDLEN_FINDERI;
             break;
 
         case FILPBIT_LNAME :
@@ -1131,7 +1131,7 @@ u_int32_t   hint;
             if (afp_version >= 30) {
                 /* convert it to UTF8 
                 */
-                if ((plen = mtoUTF8(vol, ibuf, plen, newname, AFPOBJ_TMPSIZ)) == -1)
+                if ((plen = mtoUTF8(vol, ibuf, plen, newname, AFPOBJ_TMPSIZ)) == (size_t)-1)
                    return -1;
             }
             else {
@@ -1782,7 +1782,11 @@ int              ibuflen, *rbuflen;
     memcpy(&id, ibuf, sizeof( id ));
     ibuf += sizeof(id);
     cnid = id;
-
+    
+    if (!id) {
+        /* some MacOS versions after a catsearch do a *lot* of afp_resolveid with 0 */
+        return AFPERR_NOID;
+    }
 retry:
     if (NULL == (upath = cnid_resolve(vol->v_cdb, &id, buffer, len)) ) {
         return AFPERR_NOID; /* was AFPERR_BADID, but help older Macs */
index eb8cf78eb93d5558a57b4167d484d55cb0e61d41..5bd7baa3fa3840c7a277ab98dec59aed951ce68f 100644 (file)
@@ -1,5 +1,5 @@
 /* 
- * $Id: mangle.c,v 1.16.2.1.2.12.2.1 2005-01-31 19:50:37 didg Exp $ 
+ * $Id: mangle.c,v 1.16.2.1.2.12.2.2 2005-02-12 11:22:05 didg Exp $ 
  *
  * Copyright (c) 2002. Joe Marcus Clarke (marcus@marcuscom.com)
  * All Rights Reserved.  See COPYRIGHT.
@@ -245,6 +245,11 @@ mangle(const struct vol *vol, unsigned char *filename, size_t filenamelen, unsig
     if (!(flags & 1) && filenamelen <= maxlen) {
        return filename;
     }
+
+    if (!id) {
+        /* we don't have the file id! only catsearch call mangle with id == 0 */
+        return NULL;
+    }
     /* First, attempt to locate a file extension. */
     if (NULL != (ext = strrchr(uname, '.')) ) {
        ext_len = strlen(ext);
index 11ccd52f7ec55ab081ca68166407a8ae2ac32a55..6f284181c2d4569b7763a942489567aac813bb08 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: adouble.h,v 1.21.6.20.2.2 2005-02-10 01:23:16 didg Exp $
+ * $Id: adouble.h,v 1.21.6.20.2.3 2005-02-12 11:22:05 didg Exp $
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
  * All Rights Reserved.
  *
@@ -324,6 +324,29 @@ struct adouble {
 #define AD_DATE_DELTA         946684800
 #define AD_DATE_FROM_UNIX(x)  htonl((x) - AD_DATE_DELTA)
 #define AD_DATE_TO_UNIX(x)    (ntohl(x) + AD_DATE_DELTA)
+
+/* various finder offset and info bits */
+#define FINDERINFO_FRTYPEOFF   0
+#define FINDERINFO_FRCREATOFF  4
+
+#define FINDERINFO_FRFLAGOFF   8
+/* finderinfo flags */
+#define FINDERINFO_ISONDESK      (1)
+#define FINDERINFO_COLOR         (0x0e)
+#define FINDERINFO_ISHARED       (1<<6)
+#define FINDERINFO_HASNOINITS    (1<<7)
+#define FINDERINFO_HASBEENINITED (1<<8)
+#define FINDERINFO_HASCUSTOMICON (1<<10)
+#define FINDERINFO_ISSTATIONNERY (1<<11)
+#define FINDERINFO_NAMELOCKED    (1<<12)
+#define FINDERINFO_HASBUNDLE     (1<<13)
+#define FINDERINFO_INVISIBLE     (1<<14)
+#define FINDERINFO_ISALIAS       (1<<15)
+
+#define FINDERINFO_FRVIEWOFF  14 
+#define FINDERINFO_CUSTOMICON 0x4
+#define FINDERINFO_CLOSEDVIEW 0x100   
+
  
 /* private AFPFileInfo bits */
 #define AD_AFPFILEI_OWNER       (1 << 0) /* any owner */
index bb445ae06008f589b076409708f7839c38572402..b68c50f03843e9f6e26cf53592084cf3c653d8e9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: ad_open.c,v 1.30.6.18.2.3 2005-02-10 01:23:18 didg Exp $
+ * $Id: ad_open.c,v 1.30.6.18.2.4 2005-02-12 11:22:05 didg Exp $
  *
  * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu)
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
 /* we keep local copies of a bunch of stuff so that we can initialize things 
  * correctly. */
 
-/* Bits in the finderinfo data. 
- * see etc/afpd/{directory.c,file.c} for the finderinfo structure
- * layout. */
-#define FINDERINFO_CUSTOMICON 0x4
-#define FINDERINFO_CLOSEDVIEW 0x100
-
-/* offsets in finderinfo */
-#define FINDERINFO_FRTYPEOFF   0
-#define FINDERINFO_FRCREATOFF  4
-#define FINDERINFO_FRFLAGOFF   8
-#define FINDERINFO_FRVIEWOFF  14
-
 /* invisible bit for dot files */
 #define ATTRBIT_INVISIBLE     (1 << 0)
-#define FINDERINFO_INVISIBLE  (1 << 14)
 
 /* this is to prevent changing timezones from causing problems with
    localtime volumes. the screw-up is 30 years. we use a delta of 5