]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/catsearch.c
options need strdup, remove a syslog call
[netatalk.git] / etc / afpd / catsearch.c
index 6432ed5bd2e47c94a41bcb4e72f0ae9f5f220ac2..207061e0cd2a653ddbdc928da1282d2e991edbb7 100644 (file)
@@ -28,7 +28,6 @@
 #include <stdlib.h>
 #include <dirent.h>
 #include <errno.h>
-#include <syslog.h>
 #include <unistd.h>
 #include <ctype.h>
 #include <string.h>
@@ -99,8 +98,8 @@ struct scrit {
        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 */
 };
 
 /*
@@ -228,7 +227,7 @@ static int resolve_dir(struct vol *vol, int cidx)
 
                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;
@@ -242,8 +241,10 @@ static int resolve_dir(struct vol *vol, int cidx)
        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;
@@ -253,11 +254,11 @@ static struct adouble *adl_lkup(struct path *path)
        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;     
@@ -273,10 +274,12 @@ static struct adouble *adl_lkup(struct path *path)
  */
 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;
@@ -294,20 +297,32 @@ 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 ( (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 & ... */
 
@@ -328,7 +343,7 @@ static int crit_check(struct vol *vol, struct path *path, int cidx) {
 
        /* 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;
@@ -339,7 +354,7 @@ static int crit_check(struct vol *vol, struct path *path, int cidx) {
 
        /* 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;
@@ -350,7 +365,7 @@ static int crit_check(struct vol *vol, struct path *path, int cidx) {
                                
        /* 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;
@@ -360,7 +375,7 @@ static int crit_check(struct vol *vol, struct path *path, int cidx) {
         /* 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;
@@ -370,7 +385,7 @@ static int crit_check(struct vol *vol, struct path *path, int cidx) {
        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)
@@ -381,7 +396,7 @@ static int crit_check(struct vol *vol, struct path *path, int cidx) {
        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;
                }
@@ -395,7 +410,7 @@ static int crit_check(struct vol *vol, struct path *path, int cidx) {
        
        /* 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;
@@ -592,6 +607,14 @@ static int catsearch(struct vol *vol, struct dir *dir,
                        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) {
@@ -684,12 +707,17 @@ int catsearch_afp(AFPObj *obj, char *ibuf, int ibuflen,
 {
     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));
@@ -729,32 +757,29 @@ int catsearch_afp(AFPObj *obj, char *ibuf, int ibuflen,
            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 */
@@ -797,7 +822,7 @@ int catsearch_afp(AFPObj *obj, char *ibuf, int ibuflen,
     }
 
     /* 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));
@@ -825,24 +850,21 @@ int catsearch_afp(AFPObj *obj, char *ibuf, int ibuflen,
     /* 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));
@@ -859,10 +881,12 @@ int catsearch_afp(AFPObj *obj, char *ibuf, int ibuflen,
        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 */