]> 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 bf4b28636dd98cb388a0300c3ea2cd6aee69b799..230fe718a72acaf9f28b74573bc55e0fb142789b 100644 (file)
@@ -1,7 +1,12 @@
 /*
- * $Id: desktop.c,v 1.11 2002-01-04 04:45:47 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;
@@ -106,7 +114,7 @@ u_char      creator[ 4 ];
             *adts = '/';
 
             if (( si.sdt_fd = open( dtf, flags, ad_mode( dtf, mode ))) < 0 ) {
-                LOG(log_error, logtype_default, "iconopen: open %s: %s", dtf, strerror(errno) );
+                LOG(log_error, logtype_afpd, "iconopen: open %s: %s", dtf, strerror(errno) );
                 return -1;
             }
         } else {
@@ -171,7 +179,7 @@ int         ibuflen, *rbuflen;
     if (lseek( si.sdt_fd, (off_t) 0L, SEEK_SET ) < 0) {
         close(si.sdt_fd);
         si.sdt_fd = -1;
-        LOG(log_error, logtype_default, "afp_addicon: lseek: %s", strerror(errno) );
+        LOG(log_error, logtype_afpd, "afp_addicon: lseek: %s", strerror(errno) );
         cc = AFPERR_PARAM;
         goto addicon_err;
     }
@@ -206,7 +214,7 @@ int         ibuflen, *rbuflen;
         }
 
         if ( lseek( si.sdt_fd, (off_t) rsize, SEEK_CUR ) < 0 ) {
-            LOG(log_error, logtype_default, "afp_addicon: lseek: %s", strerror(errno) );
+            LOG(log_error, logtype_afpd, "afp_addicon: lseek: %s", strerror(errno) );
             cc = AFPERR_PARAM;
         }
     }
@@ -216,7 +224,7 @@ int         ibuflen, *rbuflen;
      */
 addicon_err:
     if ( cc < 0 ) {
-        LOG(log_error, logtype_default, "afp_addicon: %s", strerror(errno) );
+        LOG(log_error, logtype_afpd, "afp_addicon: %s", strerror(errno) );
         if (obj->proto == AFPPROTO_DSI) {
             dsi_writeinit(obj->handle, rbuf, buflen);
             dsi_writeflush(obj->handle);
@@ -257,7 +265,7 @@ addicon_err:
         }
 
         if ( writev( si.sdt_fd, iov, iovcnt ) < 0 ) {
-            LOG(log_error, logtype_default, "afp_addicon: writev: %s", strerror(errno) );
+            LOG(log_error, logtype_afpd, "afp_addicon: writev: %s", strerror(errno) );
             return( AFPERR_PARAM );
         }
         break;
@@ -270,13 +278,13 @@ addicon_err:
 
             /* add headers at end of file */
             if ((cc == 0) && (write(si.sdt_fd, imh, sizeof(imh)) < 0)) {
-                LOG(log_error, logtype_default, "afp_addicon: write: %s", strerror(errno));
+                LOG(log_error, logtype_afpd, "afp_addicon: write: %s", strerror(errno));
                 dsi_writeflush(dsi);
                 return AFPERR_PARAM;
             }
 
             if ((cc = write(si.sdt_fd, rbuf, iovcnt)) < 0) {
-                LOG(log_error, logtype_default, "afp_addicon: write: %s", strerror(errno));
+                LOG(log_error, logtype_afpd, "afp_addicon: write: %s", strerror(errno));
                 dsi_writeflush(dsi);
                 return AFPERR_PARAM;
             }
@@ -288,7 +296,7 @@ addicon_err:
                 }
 
                 if ((cc = write(si.sdt_fd, rbuf, iovcnt)) < 0) {
-                    LOG(log_error, logtype_default, "afp_addicon: write: %s", strerror(errno));
+                    LOG(log_error, logtype_afpd, "afp_addicon: write: %s", strerror(errno));
                     dsi_writeflush(dsi);
                     return AFPERR_PARAM;
                 }
@@ -402,7 +410,7 @@ int         ibuflen, *rbuflen;
         memcpy( &bsize, ih + 10, sizeof( bsize ));
         bsize = ntohs(bsize);
         if ( lseek( si.sdt_fd, (off_t) bsize, SEEK_CUR ) < 0 ) {
-            LOG(log_error, logtype_default, "afp_iconinfo: lseek: %s", strerror(errno) );
+            LOG(log_error, logtype_afpd, "afp_iconinfo: lseek: %s", strerror(errno) );
             return( AFPERR_PARAM );
         }
         if ( si.sdt_index == iindex ) {
@@ -461,7 +469,7 @@ int         ibuflen, *rbuflen;
     if ( lseek( si.sdt_fd, (off_t) 0L, SEEK_SET ) < 0 ) {
         close(si.sdt_fd);
         si.sdt_fd = -1;
-        LOG(log_error, logtype_default, "afp_geticon: lseek: %s", strerror(errno));
+        LOG(log_error, logtype_afpd, "afp_geticon: lseek: %s", strerror(errno));
         return( AFPERR_PARAM );
     }
 
@@ -477,14 +485,14 @@ int               ibuflen, *rbuflen;
         memcpy( &rsize, ih + 10, sizeof( rsize ));
         rsize = ntohs( rsize );
         if ( lseek( si.sdt_fd, (off_t) rsize, SEEK_CUR ) < 0 ) {
-            LOG(log_error, logtype_default, "afp_geticon: lseek: %s", strerror(errno) );
+            LOG(log_error, logtype_afpd, "afp_geticon: lseek: %s", strerror(errno) );
             return( AFPERR_PARAM );
         }
         offset += rsize;
     }
 
     if ( rc < 0 ) {
-        LOG(log_error, logtype_default, "afp_geticon: read: %s", strerror(errno));
+        LOG(log_error, logtype_afpd, "afp_geticon: read: %s", strerror(errno));
         return( AFPERR_PARAM );
     }
 
@@ -551,7 +559,7 @@ geticon_done:
         return AFP_OK;
 
 geticon_exit:
-        LOG(log_info, logtype_default, "afp_geticon: %s", strerror(errno));
+        LOG(log_info, logtype_afpd, "afp_geticon: %s", strerror(errno));
         dsi_readdone(dsi);
         obj->exit(1);
         return AFP_OK;
@@ -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 ) {