]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/catsearch.c
move static variables only used in catsearch inside the function, test for chdir...
[netatalk.git] / etc / afpd / catsearch.c
index 1197ecd9eca6d574136876348771fae212233977..58aab8e18360bf74e40f0bb7969b2c44cc9d0b51 100644 (file)
@@ -117,8 +117,6 @@ struct dsitem {
  
 
 #define DS_BSIZE 128
-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. */
 
 static struct dsitem *dstack = NULL; /* Directory stack data... */
@@ -215,7 +213,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, ((isdir) ? ADFLAGS_DIR : 0), adp) < 0 ) {
         adp = NULL; /* FIXME without resource fork adl_lkup will be call again */
     }
     
@@ -237,13 +235,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);
 }
 
@@ -265,6 +263,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)
@@ -379,7 +379,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;
        }
@@ -387,7 +387,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;
@@ -396,7 +396,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)
@@ -406,7 +406,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;
@@ -490,18 +490,20 @@ static int rslt_add ( struct vol *vol, struct path *path, char **buf, int ext)
 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)
 {
+    static u_int32_t cur_pos;    /* Saved position index (ID) - used to remember "position" across FPCatSearch calls */
+    static DIR *dirpos;                 /* UNIX structure describing currently opened directory. */
        int cidx, r;
        struct dirent *entry;
        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;
+    int error;
         
        if (*pos != 0 && *pos != cur_pos) {
                result = AFPERR_CATCHNG;
@@ -510,8 +512,6 @@ static int catsearch(struct vol *vol, struct dir *dir,
 
        /* 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) {
@@ -529,23 +529,25 @@ static int catsearch(struct vol *vol, struct dir *dir,
        }
 
        /* 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;
+    }
        
+       /* So we are beginning... */
+    start_time = time(NULL);
+
        while ((cidx = reducestack()) != -1) {
                cached = 1;
-               if (dirpos == NULL) {
-                       dirpos = opendir(dstack[cidx].path);
+
+               /* XXX use lchdir */
+               error = chdir(dstack[cidx].path);
+
+               if (!error && dirpos == NULL) {
+                       dirpos = opendir(".");
                        cached = (dstack[cidx].dir->d_child != NULL);
                }
-               if (dirpos == NULL) {
+               if (error || dirpos == NULL) {
                        switch (errno) {
                        case EACCES:
                                dstack[cidx].checked = 1;
@@ -562,10 +564,7 @@ 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)++;
 
@@ -658,10 +657,12 @@ catsearch_pause:
 
 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() */