]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/catsearch.c
Symlink patch from Anton Starikov
[netatalk.git] / etc / afpd / catsearch.c
index 82d66adc87a160b75b24153e29ae0eb3798788a9..42790807cb9dde9e0cab793d6cacfe4149a472c8 100644 (file)
@@ -111,6 +111,7 @@ struct dsitem {
        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 */
 };
  
@@ -130,7 +131,7 @@ static struct scrit c1, c2;          /* search criteria */
 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) {
@@ -144,17 +145,21 @@ static int addstack(char *uname, struct dir *dir, int pidx)
        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;
 }
 
@@ -210,7 +215,7 @@ static struct adouble *adl_lkup(struct vol *vol, struct path *path, struct adoub
                adp = &ad;
        } 
 
-    if ( ad_metadata( path->u_name, ((isdir)?ADFLAGS_DIR:0), adp) < 0 ) {
+    if ( ad_metadata( path->u_name, vol_noadouble(vol) | ((isdir)?ADFLAGS_DIR:0), adp) < 0 ) {
         adp = NULL; /* FIXME without resource fork adl_lkup will be call again */
     }
     
@@ -232,13 +237,13 @@ static struct finderinfo *unpack_buffer(struct finderinfo *finfo, char *buffer)
 
 /* -------------------- */
 static struct finderinfo *
-unpack_finderinfo(struct vol *vol, struct path *path, 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;
        
     *adp = adl_lkup(vol, path, *adp);
-       ptr = get_finderinfo(vol, path->u_name, *adp, &buf);
+       ptr = get_finderinfo(vol, path->u_name, *adp, &buf,islnk);
        return unpack_buffer(finfo, ptr);
 }
 
@@ -260,6 +265,8 @@ static int crit_check(struct vol *vol, struct path *path) {
        u_int32_t ac_date, ab_date;
        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)
@@ -374,7 +381,7 @@ static int crit_check(struct vol *vol, struct path *path) {
 
         /* Check file type ID */
        if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.f_type != 0) {
-           finfo = unpack_finderinfo(vol, path, &adp, &finderinfo);
+           finfo = unpack_finderinfo(vol, path, &adp, &finderinfo,islnk);
                if (finfo->f_type != c1.finfo.f_type)
                        goto crit_check_ret;
        }
@@ -382,7 +389,7 @@ static int crit_check(struct vol *vol, struct path *path) {
        /* Check creator ID */
        if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.creator != 0) {
                if (!finfo) {
-                       finfo = unpack_finderinfo(vol, path, &adp, &finderinfo);
+                       finfo = unpack_finderinfo(vol, path, &adp, &finderinfo,islnk);
                }
                if (finfo->creator != c1.finfo.creator)
                        goto crit_check_ret;
@@ -391,7 +398,7 @@ static int crit_check(struct vol *vol, struct path *path) {
        /* Check finder info attributes */
        if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.attrs != 0) {
                if (!finfo) {
-                       finfo = unpack_finderinfo(vol, path, &adp, &finderinfo);
+                       finfo = unpack_finderinfo(vol, path, &adp, &finderinfo,islnk);
                }
 
                if ((finfo->attrs & c2.finfo.attrs) != c1.finfo.attrs)
@@ -401,7 +408,7 @@ static int crit_check(struct vol *vol, struct path *path) {
        /* Check label */
        if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.label != 0) {
                if (!finfo) {
-                       finfo = unpack_finderinfo(vol, path, &adp, &finderinfo);
+                       finfo = unpack_finderinfo(vol, path, &adp, &finderinfo,islnk);
                }
                if ((finfo->label & c2.finfo.label) != c1.finfo.label)
                        goto crit_check_ret;
@@ -481,7 +488,7 @@ static int rslt_add ( struct vol *vol, struct path *path, char **buf, int ext)
  * 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)
 {
@@ -516,11 +523,10 @@ static int catsearch(struct vol *vol, struct dir *dir,
                        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 !) */
        }