]> arthur.barton.de Git - netatalk.git/commitdiff
allow extended characters in volume names
authorbfernhomberg <bfernhomberg>
Sat, 15 Nov 2003 00:00:30 +0000 (00:00 +0000)
committerbfernhomberg <bfernhomberg>
Sat, 15 Nov 2003 00:00:30 +0000 (00:00 +0000)
etc/afpd/directory.c
etc/afpd/filedir.c
etc/afpd/volume.c
etc/afpd/volume.h

index 8f9ad2ae2559f6df53c7a2e7a50cdc578b50fce4..d92345dbac283d26f380920861643964f4101137 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: directory.c,v 1.71.2.4.2.4 2003-10-30 07:11:31 bfernhomberg Exp $
+ * $Id: directory.c,v 1.71.2.4.2.5 2003-11-15 00:00:30 bfernhomberg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -565,9 +565,10 @@ struct vol *vol;
 struct dir     *dir;
 struct path *path;
 {
+    char *save_m_name;
 
     if ( path->u_name == NULL) {
-        path->u_name = mtoupath(vol, path->m_name, dir->d_did, utf8_encoding() );
+        path->u_name = mtoupath(vol, path->m_name, dir->d_did, (path->m_type==3) );
     }
     path->dir = NULL;
 
@@ -583,8 +584,23 @@ struct path *path;
         return( NULL );
     }
 
-    if (( dir = adddir( vol, dir, path)) == NULL ) {
-        return( NULL );
+    /* FIXME: if this is an AFP3 connection and path->m_type != 3 we might screw dircache here */
+    if ( utf8_encoding() && path->m_type != 3)
+    {
+       save_m_name = path->m_name;
+       path->m_name = NULL;
+        if (( dir = adddir( vol, dir, path)) == NULL ) {
+           free(save_m_name);
+            return( NULL );
+        }
+       path->m_name = save_m_name;
+        LOG(log_debug, logtype_afpd, "AFP3 connection, mismatch in mtype: %u, unix: %s, mac: %s",
+            path->m_type, path->u_name, path->m_name);
+    }
+    else { 
+        if (( dir = adddir( vol, dir, path)) == NULL ) {
+            return( NULL );
+        }
     }
 
     path->dir = dir;
@@ -2248,7 +2264,8 @@ int               ibuflen, *rbuflen;
             if (( pw = getpwuid( id )) == NULL ) {
                 return( AFPERR_NOITEM );
             }
-            name = pw->pw_name;
+           len = convert_string_allocate( obj->options.unixcharset, ((sfunc == 1)?obj->options.maccharset:CH_UTF8_MAC),
+                                            pw->pw_name, strlen(pw->pw_name), &name);
             break;
 
         case 2 :
@@ -2256,7 +2273,8 @@ int               ibuflen, *rbuflen;
             if (NULL == ( gr = (struct group *)getgrgid( id ))) {
                 return( AFPERR_NOITEM );
             }
-            name = gr->gr_name;
+           len = convert_string_allocate( obj->options.unixcharset, (sfunc == 1)?obj->options.maccharset:CH_UTF8_MAC,
+                                            gr->gr_name, strlen(gr->gr_name), &name);
             break;
 
         default :
@@ -2282,6 +2300,8 @@ int               ibuflen, *rbuflen;
         memcpy( rbuf, name, len );
     }
     *rbuflen += len;
+    if (name)
+       free(name);
     return( AFP_OK );
 }
 
index 2bf4e61f2523fe318df62fae5f74b4923ec4ab49..a92580855e2607a9d51da4529380c0ef6469a5ee 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: filedir.c,v 1.45.2.2.2.3 2003-10-30 05:57:44 bfernhomberg Exp $
+ * $Id: filedir.c,v 1.45.2.2.2.4 2003-11-15 00:00:34 bfernhomberg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -351,6 +351,7 @@ int         isdir;
     struct ofork       *opened = NULL;
     struct path         path;
     cnid_t      id;
+    ucs2_t *oldname_w, *newname_w;
 
     ad_init(&ad, vol->v_adouble);
     adp = &ad;
@@ -411,9 +412,24 @@ int         isdir;
             return AFP_OK;
 
         /* deal with case insensitive, case-preserving filesystems. */
-        if ((stat(upath, st) == 0) && strdiacasecmp(oldname, newname))
-            return AFPERR_EXIST;
-
+        if ((stat(upath, st) == 0)) {
+           if ((size_t)-1 == (convert_string_allocate(CH_UCS2, vol->v_volcharset, oldname,
+                                strlen(oldname), (char**) &oldname_w)) ) {
+                return AFPERR_MISC; /* conversion error has already been logged */
+            }
+           if ((size_t)-1 == (convert_string_allocate(CH_UCS2, vol->v_volcharset, newname, 
+                                strlen(newname), (char**) &newname_w)) ) {
+                free(oldname_w);
+                return AFPERR_MISC; /* conversion error has already been logged */
+            }
+           if (!strcasecmp_w(oldname_w, newname_w)) {
+               free(oldname_w);
+               free(newname_w);
+                return AFPERR_EXIST;
+           }
+           free (oldname_w);   
+           free (newname_w);   
+        }
     } else if (stat(upath, st ) == 0)
         return AFPERR_EXIST;
 
index 711e1f2f4f847194e6faf51a2c3833363c29f4a2..6473b79d1841400587ad1509e2d922e88cf78113 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: volume.c,v 1.51.2.7.2.9 2003-10-30 05:57:44 bfernhomberg Exp $
+ * $Id: volume.c,v 1.51.2.7.2.10 2003-11-15 00:00:35 bfernhomberg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -477,11 +477,11 @@ static void volset(struct vol_option *options, struct vol_option *save,
 }
 
 /* ----------------- */
-static void showvol(const char *name)
+static void showvol(const ucs2_t *name)
 {
     struct vol *volume;
     for ( volume = Volumes; volume; volume = volume->v_next ) {
-        if ( !strcasecmp( volume->v_name, name ) && volume->v_hide) {
+        if ( !strcasecmp_w( volume->v_name, name ) && volume->v_hide) {
             volume->v_hide = 0;
             return;
         }
@@ -498,6 +498,7 @@ static int creatvol(AFPObj *obj, struct passwd *pwd,
     struct vol *volume;
     int                vlen;
     int         hide = 0;
+    ucs2_t     tmpname[512];
 
     if ( name == NULL || *name == '\0' ) {
         if ((name = strrchr( path, '/' )) == NULL) {
@@ -509,8 +510,18 @@ static int creatvol(AFPObj *obj, struct passwd *pwd,
             return -1;
     }
 
+    vlen = strlen( name );
+    if ( vlen > AFPVOL_NAMELEN ) {
+        vlen = AFPVOL_NAMELEN;
+        name[AFPVOL_NAMELEN] = '\0';
+    }
+
+    /* convert name to UCS2 first */
+    if ( 0 >= ( vlen = convert_string(obj->options.unixcharset, CH_UCS2, name, vlen, tmpname, 512)) )
+        return -1;
+
     for ( volume = Volumes; volume; volume = volume->v_next ) {
-        if ( strcasecmp( volume->v_name, name ) == 0 ) {
+        if ( strcasecmp_w( volume->v_name, tmpname ) == 0 ) {
            if (volume->v_deleted) {
                hide = 1;
            }
@@ -520,17 +531,12 @@ static int creatvol(AFPObj *obj, struct passwd *pwd,
         }
     }
 
-    vlen = strlen( name );
-    if ( vlen > AFPVOL_NAMELEN ) {
-        vlen = AFPVOL_NAMELEN;
-        name[AFPVOL_NAMELEN] = '\0';
-    }
 
     if (!( volume = (struct vol *)calloc(1, sizeof( struct vol ))) ) {
         LOG(log_error, logtype_afpd, "creatvol: malloc: %s", strerror(errno) );
         return -1;
     }
-    if (! ( volume->v_name = (char *)malloc( vlen + 1 ) ) ) {
+    if ( NULL == ( volume->v_name = strdup_w(tmpname))) {
         LOG(log_error, logtype_afpd, "creatvol: malloc: %s", strerror(errno) );
         free(volume);
         return -1;
@@ -542,7 +548,6 @@ static int creatvol(AFPObj *obj, struct passwd *pwd,
         return -1;
     }
     volume->v_hide = hide;
-    strcpy( volume->v_name, name);
     strcpy( volume->v_path, path );
 
 #ifdef __svr4__
@@ -1316,9 +1321,13 @@ int              *buflen;
     if ( nameoff ) {
         ashort = htons( data - buf );
         memcpy(nameoff, &ashort, sizeof( ashort ));
-        aint = strlen( vol->v_name );
+       aint = ucs2_to_charset( (utf8_encoding()?CH_UTF8_MAC:vol->v_maccharset), vol->v_name, data+1, 255);
+       if ( aint <= 0 ) {
+           *buflen = 0;
+            return AFPERR_MISC;
+        }
+               
         *data++ = aint;
-        memcpy(data, vol->v_name, aint );
         data += aint;
     }
     if ( isad ) {
@@ -1340,7 +1349,7 @@ int static stat_vol(u_int16_t bitmap, struct vol *vol, char *rbuf, int *rbuflen)
     }
 
     buflen = *rbuflen - sizeof( bitmap );
-    if (( ret = getvolparams( bitmap, vol, &st,
+    if (( ret = getvolparams(bitmap, vol, &st,
                               rbuf + sizeof( bitmap ), &buflen )) != AFP_OK ) {
         *rbuflen = 0;
         return( ret );
@@ -1415,6 +1424,7 @@ int       ibuflen, *rbuflen;
     struct stat                st;
     struct vol         *volume;
     char       *data;
+    char               *namebuf;
     int                        vcnt, len;
 
     load_volumes(obj);
@@ -1445,10 +1455,15 @@ int     ibuflen, *rbuflen;
            off.. <shirsch@ibm.net> */
         *data |= (volume->v_flags & AFPVOL_A2VOL) ? AFPSRVR_CONFIGINFO : 0;
         *data++ |= 0; /* UNIX PRIVS BIT ..., OSX doesn't seem to use it, so we don't either */
-        len = strlen( volume->v_name );
+
+       len = ucs2_to_charset_allocate((utf8_encoding()?CH_UTF8_MAC:obj->options.maccharset),
+                                       &namebuf, volume->v_name);
+       if (len <= 0)
+               continue;
         *data++ = len;
-        memcpy(data, volume->v_name, len );
+        memcpy(data, namebuf, len );
         data += len;
+       free(namebuf);
         vcnt++;
     }
 
@@ -1480,6 +1495,7 @@ int               ibuflen, *rbuflen;
     struct vol *volume;
     struct dir *dir;
     int                len, ret;
+    size_t     namelen;
     u_int16_t  bitmap;
 
     ibuf += 2;
@@ -1493,8 +1509,13 @@ int              ibuflen, *rbuflen;
 
     len = (unsigned char)*ibuf++;
     volname = obj->oldtmp;
-    memcpy(volname, ibuf, len );
-    *(volname +  len) = '\0';
+    namelen = convert_string( (utf8_encoding()?CH_UTF8_MAC:obj->options.maccharset), CH_UCS2,
+                              ibuf, len, volname, sizeof(obj->oldtmp));
+    if ( namelen <= 0){
+        *rbuflen = 0;
+        return AFPERR_PARAM;
+    }
+
     ibuf += len;
     if ((len + 1) & 1) /* pad to an even boundary */
         ibuf++;
@@ -1502,7 +1523,7 @@ int               ibuflen, *rbuflen;
     load_volumes(obj);
 
     for ( volume = Volumes; volume; volume = volume->v_next ) {
-        if ( strcasecmp( volname, volume->v_name ) == 0 ) {
+        if ( strcasecmp_w( (ucs2_t*) volname, volume->v_name ) == 0 ) {
             break;
         }
     }
@@ -1539,11 +1560,33 @@ int             ibuflen, *rbuflen;
     volume->v_dir = volume->v_root = NULL;
 
     /* FIXME unix name != mac name */
-    if ((dir = dirnew(volume->v_name, volume->v_name) ) == NULL) {
+    char *vol_uname;
+    char *vol_mname;
+
+    len = convert_string_allocate( CH_UCS2, (utf8_encoding()?CH_UTF8_MAC:obj->options.maccharset),
+                                      volume->v_name, namelen, &vol_mname);
+    if ( !vol_mname || len <= 0) {
+        ret = AFPERR_MISC;
+        goto openvol_err;
+    }
+       
+    len = convert_string_allocate( CH_UCS2 , volume->v_volcharset, volume->v_name, namelen, &vol_uname);
+
+    if ( !vol_uname || len <= 0) {
+       free(vol_mname);
+        ret = AFPERR_MISC;
+        goto openvol_err;
+    }
+       
+    if ((dir = dirnew(vol_mname, vol_uname) ) == NULL) {
+       free(vol_mname);
+       free(vol_uname);
         LOG(log_error, logtype_afpd, "afp_openvol: malloc: %s", strerror(errno) );
         ret = AFPERR_MISC;
         goto openvol_err;
     }
+    free(vol_mname);
+    free(vol_uname);
 
     dir->d_did = DIRDID_ROOT;
     dir->d_color = DIRTREE_COLOR_BLACK; /* root node is black */
@@ -1648,6 +1691,8 @@ int               ibuflen, *rbuflen;
 
             /* FIXME find db time stamp */
             cnid_getstamp(volume->v_cdb, volume->v_stamp, sizeof(volume->v_stamp));
+       }
+       else {
             p = Trash;
             cname( volume, volume->v_dir, &p );
         }
@@ -1850,9 +1895,12 @@ struct vol       *vol;
     /* a little granularity */
     if (vol->v_mtime < tv.tv_sec) {
         vol->v_mtime = tv.tv_sec;
+#if 0
+/* if 0ed, we're sending too many */
         if (afp_version > 21 && obj->options.server_notif) {
             obj->attention(obj->handle, AFPATTN_NOTIFY | AFPATTN_VOLCHANGED);
         }
+#endif
     }
 }
 
index 93673fed81f3574e60509a2463e7a8fb5a1533d7..b1270aa0df1e209892fd7df5f01860139d8e4823 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: volume.h,v 1.19.2.5.2.3 2003-09-30 12:24:49 didg Exp $
+ * $Id: volume.h,v 1.19.2.5.2.4 2003-11-15 00:00:37 bfernhomberg Exp $
  *
  * Copyright (c) 1990,1994 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -25,7 +25,7 @@
 
 struct vol {
     struct vol         *v_next;
-    char               *v_name;
+    ucs2_t             *v_name;
     char               *v_path;
     struct dir         *v_dir, *v_root;
     int                        v_flags;