]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/desktop.c
- added a cache for directories offspring count.
[netatalk.git] / etc / afpd / desktop.c
index 344eb08bf9d916d3da401d1d0ed1ee3a2900945d..230fe718a72acaf9f28b74573bc55e0fb142789b 100644 (file)
@@ -1,7 +1,12 @@
 /*
- * $Id: desktop.c,v 1.12 2002-03-24 01:23:40 sibaz Exp $
+ * $Id: desktop.c,v 1.19 2002-10-11 14:18:26 didg Exp $
  *
  * See COPYRIGHT.
+ *
+ * bug:
+ * afp_XXXcomment are (the only) functions able to open
+ * a ressource fork when there's no data fork, eg after
+ * it was removed with samba.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -40,6 +45,9 @@
 #include "fork.h"
 #include "globals.h"
 #include "desktop.h"
+#ifdef FILE_MANGLING
+#include "mangle.h"
+#endif /* CNID_DB */
 
 int afp_opendt(obj, ibuf, ibuflen, rbuf, rbuflen )
 AFPObj      *obj;
@@ -571,7 +579,7 @@ char *dtfile(const struct vol *vol, u_char creator[], char *ext )
 {
     static char        path[ MAXPATHLEN + 1];
     char       *p;
-    int                i;
+    unsigned int i;
 
     strcpy( path, vol->v_path );
     strcat( path, "/.AppleDesktop/" );
@@ -601,16 +609,28 @@ char *dtfile(const struct vol *vol, u_char creator[], char *ext )
     return( path );
 }
 
+/* 
+ * mpath is only a filename 
+*/
 char *mtoupath(const struct vol *vol, char *mpath)
 {
     static char  upath[ MAXPATHLEN + 1];
     char       *m, *u;
     int                 i = 0;
-
+    int          changed = 0;
+    
     if ( *mpath == '\0' ) {
         return( "." );
     }
 
+#ifdef FILE_MANGLING
+    m = demangle(vol, mpath);
+    if (m != mpath) {
+        changed = 1;
+        mpath = m;
+    }
+#endif /* FILE_MANGLING */
+
     m = mpath;
     u = upath;
     while ( *m != '\0' ) {
@@ -626,6 +646,18 @@ char *mtoupath(const struct vol *vol, char *mpath)
         if (vol->v_mtoupage && ((*m & 0x80) ||
                                 vol->v_flags & AFPVOL_MAPASCII)) {
             *u = vol->v_mtoupage->map[(unsigned char) *m].value;
+            changed = 1;
+            if (!*u && *m) {
+                /* if conversion failed, encode in hex
+                 * to prevent silly truncation
+                 * H.P. Jansen <hpj@urpla.net> */
+#ifdef DEBUG
+                LOG(log_debug, logtype_afpd, "mtoupath: hex encode: 0x%x", (unsigned char) *m);
+#endif /* DEBUG */
+                *u++ = ':';
+                *u++ = hexdig[ ( *m & 0xf0 ) >> 4 ];
+                *u = hexdig[ *m & 0x0f ];
+            }
         } else
 #endif /* 1 */
 #if AD_VERSION == AD_VERSION1
@@ -643,6 +675,7 @@ char *mtoupath(const struct vol *vol, char *mpath)
                 *u++ = ':';
                 *u++ = hexdig[ ( *m & 0xf0 ) >> 4 ];
                 *u = hexdig[ *m & 0x0f ];
+                changed = 1;
             } else
                 *u = *m;
         u++;
@@ -651,7 +684,11 @@ char *mtoupath(const struct vol *vol, char *mpath)
     }
     *u = '\0';
 
-    return( upath );
+#ifdef DEBUG
+    LOG(log_debug, logtype_afpd, "mtoupath: '%s':'%s'", mpath, upath);
+#endif /* DEBUG */
+
+    return( (changed)?upath:mpath );
 }
 
 #define hextoint( c )  ( isdigit( c ) ? c - '0' : c + 10 - 'a' )
@@ -694,6 +731,15 @@ char *utompath(const struct vol *vol, char *upath)
         m++;
     }
     *m = '\0';
+
+#ifdef FILE_MANGLING
+    strcpy(mpath,mangle(vol, mpath));
+#endif /* FILE_MANGLING */
+
+#ifdef DEBUG
+    LOG(log_debug, logtype_afpd, "utompath: '%s':'%s'", upath, mpath);
+#endif /* DEBUG */
+
     return( mpath );
 }
 
@@ -706,7 +752,8 @@ int         ibuflen, *rbuflen;
     struct vol         *vol;
     struct dir         *dir;
     struct ofork        *of;
-    char               *path, *name;
+    struct path         *path;
+    char                *name, *upath;
     int                        clen;
     u_int32_t           did;
     u_int16_t          vid;
@@ -722,7 +769,7 @@ int         ibuflen, *rbuflen;
 
     memcpy( &did, ibuf, sizeof( did ));
     ibuf += sizeof( did );
-    if (( dir = dirsearch( vol, did )) == NULL ) {
+    if (( dir = dirlookup( vol, did )) == NULL ) {
         return( AFPERR_NOOBJ );
     }
 
@@ -737,22 +784,28 @@ int               ibuflen, *rbuflen;
     clen = (u_char)*ibuf++;
     clen = min( clen, 199 );
 
-    if ((*path == '\0') || !(of = of_findname(vol, curdir, path))) {
+    upath = path->u_name;
+    if (check_access(upath, OPENACC_WR ) < 0) {
+        return AFPERR_ACCESS;
+    }
+
+    if (*path->m_name == '\0' || !(of = of_findname(path))) {
         memset(&ad, 0, sizeof(ad));
         adp = &ad;
     } else
         adp = of->of_ad;
-    if (ad_open( mtoupath( vol, path ), vol_noadouble(vol) |
-                 (( *path == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
+
+    if (ad_open( upath , vol_noadouble(vol) |
+                 (( *path->m_name == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
                  O_RDWR|O_CREAT, 0666, adp) < 0 ) {
         return( AFPERR_ACCESS );
     }
 
-    if ( ad_getoflags( adp, ADFLAGS_HF ) & O_CREAT ) {
-        if ( *path == '\0' ) {
-            name = curdir->d_name;
+    if ( (ad_getoflags( adp, ADFLAGS_HF ) & O_CREAT) ) {
+        if ( *path->m_name == '\0' ) {
+            name = curdir->d_m_name;
         } else {
-            name = path;
+            name = path->m_name;
         }
         ad_setentrylen( adp, ADEID_NAME, strlen( name ));
         memcpy( ad_entry( adp, ADEID_NAME ), name,
@@ -775,7 +828,8 @@ int         ibuflen, *rbuflen;
     struct vol         *vol;
     struct dir         *dir;
     struct ofork        *of;
-    char               *path;
+    struct path         *s_path;
+    char               *path, *upath;
     u_int32_t          did;
     u_int16_t          vid;
 
@@ -790,20 +844,23 @@ int               ibuflen, *rbuflen;
 
     memcpy( &did, ibuf, sizeof( did ));
     ibuf += sizeof( did );
-    if (( dir = dirsearch( vol, did )) == NULL ) {
+    if (( dir = dirlookup( vol, did )) == NULL ) {
         return( AFPERR_NOOBJ );
     }
 
-    if (( path = cname( vol, dir, &ibuf )) == NULL ) {
+    if (( s_path = cname( vol, dir, &ibuf )) == NULL ) {
         return( AFPERR_NOOBJ );
     }
 
-    if ((*path == '\0') || !(of = of_findname(vol, curdir, path))) {
+    upath = s_path->u_name;
+    path  = s_path->m_name;
+
+    if (*path == '\0' || !(of = of_findname(s_path))) {
         memset(&ad, 0, sizeof(ad));
         adp = &ad;
     } else
         adp = of->of_ad;
-    if ( ad_open( mtoupath( vol, path ),
+    if ( ad_open( upath,
                   (( *path == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
                   O_RDONLY, 0666, adp) < 0 ) {
         return( AFPERR_NOITEM );
@@ -823,6 +880,8 @@ int         ibuflen, *rbuflen;
             ad_getentrylen( adp, ADEID_COMMENT ));
     *rbuflen = ad_getentrylen( adp, ADEID_COMMENT ) + 1;
     ad_close( adp, ADFLAGS_HF );
+
+    /* return AFPERR_NOITEM if len == 0 ? */
     return( AFP_OK );
 }
 
@@ -835,7 +894,8 @@ int         ibuflen, *rbuflen;
     struct vol         *vol;
     struct dir         *dir;
     struct ofork        *of;
-    char               *path;
+    struct path         *s_path;
+    char               *path, *upath;
     u_int32_t          did;
     u_int16_t          vid;
 
@@ -850,20 +910,27 @@ int               ibuflen, *rbuflen;
 
     memcpy( &did, ibuf, sizeof( did ));
     ibuf += sizeof( did );
-    if (( dir = dirsearch( vol, did )) == NULL ) {
+    if (( dir = dirlookup( vol, did )) == NULL ) {
         return( AFPERR_NOOBJ );
     }
 
-    if (( path = cname( vol, dir, &ibuf )) == NULL ) {
+    if (( s_path = cname( vol, dir, &ibuf )) == NULL ) {
         return( AFPERR_NOOBJ );
     }
 
-    if ((*path == '\0') || !(of = of_findname(vol, curdir, path))) {
+    upath = s_path->u_name;
+    path  = s_path->m_name;
+    if (check_access(upath, OPENACC_WR ) < 0) {
+        return AFPERR_ACCESS;
+    }
+
+    if (path == '\0' || !(of = of_findname(s_path))) {
         memset(&ad, 0, sizeof(ad));
         adp = &ad;
     } else
         adp = of->of_ad;
-    if ( ad_open( mtoupath( vol, path ),
+
+    if ( ad_open( upath,
                   (( *path == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
                   O_RDWR, 0, adp) < 0 ) {
         switch ( errno ) {