]> arthur.barton.de Git - netatalk.git/commitdiff
Cleanup contrib
authorFrank Lahm <franklahm@googlemail.com>
Thu, 8 Jul 2010 06:14:59 +0000 (08:14 +0200)
committerFrank Lahm <franklahm@googlemail.com>
Thu, 8 Jul 2010 06:14:59 +0000 (08:14 +0200)
contrib/patches/patch.afp_vfs [deleted file]
contrib/patches/patch.mangled_trash_with_ip [deleted file]
contrib/patches/patch.vfs [deleted file]
contrib/permtest/add_permtest.patch [deleted file]
contrib/permtest/permtest.cfg [deleted file]
contrib/permtest/permtest.pl.in [deleted file]

diff --git a/contrib/patches/patch.afp_vfs b/contrib/patches/patch.afp_vfs
deleted file mode 100644 (file)
index f2c08ee..0000000
+++ /dev/null
@@ -1,1678 +0,0 @@
-First try for a netatalk vfs layer
-
-current schemes
-adouble=v1,v2 classic adouble format
-adouble=osx  ._<filename> OSX resource fork.
-adouble=ads  NT like alternate data stream. 
-
-Note for ads:
-* cf. patch.vfs for samba ADS vfs layer and patch.samba.xx for samba tree patch.
-
-* It's using Afp_AfpInfo name (MS SFM name) but it's not yet compatible with SFM.
-  from cdrecord source code Afp_AfpInfo is the raw HFS data, we are storing an appledouble file.
-
-* Server side copy and Macintosh copy only deal with resource fork, other NT ADS are lost.
-  unfixable for Macintosh copy but doable for server side.
-
-* It's ok for rename, delete, chown and chmod.
-
-* Copy from a NT box should work.
-
-* Last but not least : only on a new volume!
-
-TODO
-indirection for metadata, aka stored in EA, a different file, whatever.
-
-diff -Nur -X .cvsignore -x CVS ../src.dev2/etc/afpd/Makefile.am ./etc/afpd/Makefile.am
---- ../src.dev2/etc/afpd/Makefile.am   Mon Feb  9 22:45:51 2004
-+++ ./etc/afpd/Makefile.am     Fri Jun 18 19:15:47 2004
-@@ -8,14 +8,14 @@
-        file.c enumerate.c desktop.c filedir.c fork.c appl.c gettok.c \
-        mangle.c status.c afp_options.c afp_asp.c afp_dsi.c messages.c  \
-        afp_config.c nfsquota.c quota.c uam.c afs.c uid.c afp_util.c \
--         catsearch.c afprun.c
-+         catsearch.c afprun.c vfs_adouble.c
- afpd_LDADD =  $(top_builddir)/libatalk/cnid/libcnid.la $(top_builddir)/libatalk/libatalk.la
- afpd_LDFLAGS = -export-dynamic
- noinst_HEADERS = auth.h afp_config.h desktop.h directory.h file.h \
-        filedir.h fork.h globals.h icon.h mangle.h misc.h status.h switch.h \
--       uam_auth.h uid.h unix.h volume.h
-+       uam_auth.h uid.h unix.h volume.h afp_vfs.h
- LIBS = @LIBS@ @PAM_LIBS@ @QUOTA_LIBS@ @SLP_LIBS@
-diff -Nur -X .cvsignore -x CVS ../src.dev2/etc/afpd/afp_vfs.h ./etc/afpd/afp_vfs.h
---- ../src.dev2/etc/afpd/afp_vfs.h     Thu Jan  1 00:00:00 1970
-+++ ./etc/afpd/afp_vfs.h       Wed Jun 23 03:56:15 2004
-@@ -0,0 +1,49 @@
-+/*
-+   Copyright (c) 2004 Didier Gautheron
-+ 
-+   This program is free software; you can redistribute it and/or modify
-+   it under the terms of the GNU General Public License as published by
-+   the Free Software Foundation; either version 2 of the License, or
-+   (at your option) any later version.
-+ 
-+   This program is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+   GNU General Public License for more details.
-+ 
-+   You should have received a copy of the GNU General Public License
-+   along with this program; if not, write to the Free Software
-+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+
-+   vfs layer for afp
-+*/
-+
-+#ifndef _AFP_VFS_H
-+#define _AFP_VFS_H
-+
-+#include <atalk/adouble.h>
-+struct vol;
-+
-+struct vfs_ops {
-+    /* low level adouble fn */
-+    char *(*ad_path)(const char *, int);
-+
-+    /* */
-+    int (*validupath)(const struct vol *, const char *);
-+    int (*rf_chown)(const struct vol *, const char *path, uid_t owner, gid_t group);
-+    int (*rf_renamedir)(const struct vol *, const char *oldpath, const char *newpath);
-+    int (*rf_deletecurdir)(const struct vol *);
-+    int (*rf_setfilmode)(const struct vol *, const char * name, mode_t mode, struct stat *st);
-+    int (*rf_setdirmode)(const struct vol *, const char * name, mode_t mode, struct stat *st);
-+    int (*rf_setdirunixmode)(const struct vol *, const char * name, mode_t mode, struct stat *st);
-+
-+    int (*rf_setdirowner)(const struct vol *, const char *path, uid_t owner, gid_t group);
-+
-+    int (*rf_deletefile)(const struct vol *, const char * );
-+    int (*rf_renamefile)(const struct vol *, const char *oldpath, const char *newpath);
-+
-+};
-+
-+void initvol_vfs(struct vol *vol);
-+
-+#endif
-diff -Nur -X .cvsignore -x CVS ../src.dev2/etc/afpd/directory.c ./etc/afpd/directory.c
---- ../src.dev2/etc/afpd/directory.c   Mon Jul 12 08:46:03 2004
-+++ ./etc/afpd/directory.c     Sat Jun 19 14:07:14 2004
-@@ -610,7 +610,7 @@
-    system rmdir with afp error code.
-    ENOENT is not an error.
-  */
--static int netatalk_rmdir(const char *name)
-+int netatalk_rmdir(const char *name)
- {
-     if (rmdir(name) < 0) {
-         switch ( errno ) {
-@@ -2075,15 +2075,11 @@
-         }
-     }
--    if (vol->v_adouble == AD_VERSION2_OSX) {
--        /* We simply move the corresponding ad file as well */
--        char   tempbuf[258]="._";
--        rename(vol->ad_path(src,0),strcat(tempbuf,dst));
--    }
-+    vol->vfs->rf_renamedir(vol, src, dst);
-     len = strlen( newname );
-     /* rename() succeeded so we need to update our tree even if we can't open
--     * .Parent
-+     * metadata
-     */
-     
-     ad_init(&ad, vol->v_adouble);
-@@ -2132,12 +2128,9 @@
-     return( AFP_OK );
- }
--#define DOT_APPLEDOUBLE_LEN 13
- /* delete an empty directory */
--int deletecurdir( vol, path, pathlen )
-+int deletecurdir( vol)
- const struct vol      *vol;
--char *path;
--int pathlen;
- {
-     struct dirent *de;
-     struct stat st;
-@@ -2162,42 +2155,9 @@
-             return  AFPERR_OLOCK;
-         }
-     }
--
--    if (vol->v_adouble == AD_VERSION2_OSX) {
--       
--        if ((err = netatalk_unlink(vol->ad_path(".",0) )) ) {
--            return err;
--        }
--    }
--    else {
--        /* delete stray .AppleDouble files. this happens to get .Parent files
--           as well. */
--        if ((dp = opendir(".AppleDouble"))) {
--            strcpy(path, ".AppleDouble/");
--            while ((de = readdir(dp))) {
--                /* skip this and previous directory */
--                if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
--                    continue;
--
--                /* bail if the file exists in the current directory.
--                 * note: this will not fail with dangling symlinks */
--                if (stat(de->d_name, &st) == 0) {
--                    closedir(dp);
--                    return AFPERR_DIRNEMPT;
--                }
--
--                strcpy(path + DOT_APPLEDOUBLE_LEN, de->d_name);
--                if ((err = netatalk_unlink(path))) {
--                    closedir(dp);
--                    return err;
--                }
--            }
--            closedir(dp);
--        }
--
--        if ( (err = netatalk_rmdir( ".AppleDouble" ))  ) {
--            return err;
--        }
-+    err = vol->vfs->rf_deletecurdir(vol);
-+    if (err) {
-+        return err;
-     }
-     /* now get rid of dangling symlinks */
-diff -Nur -X .cvsignore -x CVS ../src.dev2/etc/afpd/directory.h ./etc/afpd/directory.h
---- ../src.dev2/etc/afpd/directory.h   Mon May 10 18:40:32 2004
-+++ ./etc/afpd/directory.h     Sat Jun 19 03:23:18 2004
-@@ -196,7 +196,7 @@
- extern struct dir       *dirinsert __P((struct vol *, struct dir *));
- extern int              movecwd __P((const struct vol *, struct dir *));
--extern int              deletecurdir __P((const struct vol *, char *, int));
-+extern int              deletecurdir __P((const struct vol *));
- extern struct path      *cname __P((const struct vol *, struct dir *,
-                              char **));
- extern mode_t           mtoumode __P((struct maccess *));
-@@ -215,6 +215,7 @@
- extern int  check_access __P((char *name , int mode));
- extern int file_access   __P((struct path *path, int mode));
-+extern int netatalk_rmdir __P((const char *name));
- extern int netatalk_unlink __P((const char *name));
- /* from enumerate.c */
-diff -Nur -X .cvsignore -x CVS ../src.dev2/etc/afpd/enumerate.c ./etc/afpd/enumerate.c
---- ../src.dev2/etc/afpd/enumerate.c   Mon Jul 12 08:46:03 2004
-+++ ./etc/afpd/enumerate.c     Thu Jun 24 04:26:35 2004
-@@ -166,7 +166,7 @@
-     if (!strcmp(name, "..") || !strcmp(name, "."))
-         return NULL;
--    if (!vol->validupath(vol, name))
-+    if (!vol->vfs->validupath(vol, name))
-         return NULL;
-     /* check for vetoed filenames */
-diff -Nur -X .cvsignore -x CVS ../src.dev2/etc/afpd/file.c ./etc/afpd/file.c
---- ../src.dev2/etc/afpd/file.c        Tue Jun 15 22:53:54 2004
-+++ ./etc/afpd/file.c  Mon Jun 21 00:21:24 2004
-@@ -901,7 +901,7 @@
-     /* second try with adouble open 
-     */
--    if (ad_open( upath, vol_noadouble(vol) | ADFLAGS_HF,
-+    if ( ad_open( upath, vol_noadouble(vol) | ADFLAGS_HF,
-                  O_RDWR|O_CREAT, 0666, adp) < 0) {
-         /* for some things, we don't need an adouble header */
-         if (f_bitmap & ~(1<<FILPBIT_MDATE)) {
-@@ -1020,7 +1020,6 @@
- char  *src, *dst, *newname;
- struct adouble    *adp;
- {
--    char      adsrc[ MAXPATHLEN + 1];
-     int               rc;
- #ifdef DEBUG
-@@ -1055,38 +1054,10 @@
-         }
-     }
--    strcpy( adsrc, vol->ad_path( src, 0 ));
--
--    if (unix_rename( adsrc, vol->ad_path( dst, 0 )) < 0 ) {
--        struct stat st;
-+    if (vol->vfs->rf_renamefile(vol, src, dst) < 0 ) {
-         int err;
-         
-         err = errno;        
--      if (errno == ENOENT) {
--          struct adouble    ad;
--
--            if (stat(adsrc, &st)) /* source has no ressource fork, */
--                return AFP_OK;
--            
--            /* We are here  because :
--             * -there's no dest folder. 
--             * -there's no .AppleDouble in the dest folder.
--             * if we use the struct adouble passed in parameter it will not
--             * create .AppleDouble if the file is already opened, so we
--             * use a diff one, it's not a pb,ie it's not the same file, yet.
--             */
--            ad_init(&ad, vol->v_adouble); 
--            if (!ad_open(dst, ADFLAGS_HF, O_RDWR | O_CREAT, 0666, &ad)) {
--              ad_close(&ad, ADFLAGS_HF);
--              if (!unix_rename( adsrc, vol->ad_path( dst, 0 )) ) 
--                   err = 0;
--                else 
--                   err = errno;
--            }
--            else { /* it's something else, bail out */
--              err = errno;
--          }
--      }
-       /* try to undo the data fork rename,
-        * we know we are on the same device 
-       */
-@@ -1436,6 +1407,7 @@
-     if (ret_err) {
-         deletefile(d_vol, dst, 0);
-     }
-+    /* ADS here */
-     /* set dest modification date to src date */
-     if (!stat(src, &st)) {
-@@ -1562,14 +1534,12 @@
-     if (adp && ad_tmplock( &ad, ADEID_DFORK, ADLOCK_WR, 0, 0, 0 ) < 0) {
-         err = AFPERR_BUSY;
-     }
--    else if (!(err = netatalk_unlink( vol->ad_path( file, ADFLAGS_HF)) ) &&
--             !(err = netatalk_unlink( file )) ) {
-+    else if (!(err = vol->vfs->rf_deletefile(vol, file)) && !(err = netatalk_unlink( file )) ) {
-         cnid_t id;
-         if (checkAttrib && (id = cnid_get(vol->v_cdb, curdir->d_did, file, strlen(file)))) 
-         {
-             cnid_delete(vol->v_cdb, id);
-         }
--
-     }
-     if (adp)
-         ad_close( &ad, adflags );  /* ad_close removes locks if any */
-diff -Nur -X .cvsignore -x CVS ../src.dev2/etc/afpd/filedir.c ./etc/afpd/filedir.c
---- ../src.dev2/etc/afpd/filedir.c     Mon May 10 18:40:32 2004
-+++ ./etc/afpd/filedir.c       Sat Jun 19 15:09:08 2004
-@@ -73,7 +73,7 @@
-         return AFPERR_NOOBJ ;
-     }
--    adpath = vol->ad_path( upath, ADFLAGS_HF );
-+    adpath = vol->vfs->ad_path( upath, ADFLAGS_HF );
-     /* FIXME dirsearch doesn't move cwd to did ! */
-     if (( dir = dirlookup( vol, did )) == NULL ) {
-         LOG(log_error, logtype_afpd, "matchfile2dirperms: Unable to get directory info.");
-@@ -313,7 +313,7 @@
-     if ((vol->v_flags & AFPVOL_NOHEX) && strchr(name, '/'))
-         return AFPERR_PARAM;
--    if (!vol->validupath(vol, name))
-+    if (!vol->vfs->validupath(vol, name))
-         return AFPERR_EXIST;
-     /* check for vetoed filenames */
-@@ -582,7 +582,7 @@
-           rc = AFPERR_ACCESS;
-       }
-       else {
--            rc = deletecurdir( vol, obj->oldtmp, AFPOBJ_TMPSIZ);
-+            rc = deletecurdir( vol);
-         }
-     } else if (of_findname(s_path)) {
-         rc = AFPERR_BUSY;
-@@ -764,7 +764,7 @@
-                 int  admode = ad_mode("", 0777);
-                 setfilmode(upath, admode, NULL);
--                setfilmode(vol->ad_path( upath, ADFLAGS_HF ), ad_hf_mode(admode), NULL);
-+                vol->vfs->rf_setfilmode(vol, upath, admode, NULL);
-             }
-         setvoltime(obj, vol );
-     }
-diff -Nur -X .cvsignore -x CVS ../src.dev2/etc/afpd/unix.c ./etc/afpd/unix.c
---- ../src.dev2/etc/afpd/unix.c        Tue Jun 15 22:53:55 2004
-+++ ./etc/afpd/unix.c  Wed Jun 23 04:04:01 2004
-@@ -260,8 +260,8 @@
-    rwx-wx-wx or rwx-wx-- 
-    rwx----wx (is not asked by a Mac with OS >= 8.0 ?)
- */
--static int stickydirmode(name, mode, dropbox)
--char * name;
-+int stickydirmode(name, mode, dropbox)
-+const char * name;
- const mode_t mode;
- const int dropbox;
- {
-@@ -405,12 +405,12 @@
-     if (setfilmode( path->u_name, mode, &path->st) < 0)
-         return -1;
-     /* we need to set write perm if read set for resource fork */
--    return setfilmode(vol->ad_path( path->u_name, ADFLAGS_HF ), ad_hf_mode(mode), &path->st);
-+    return vol->vfs->rf_setfilmode(vol, path->u_name, mode, &path->st);
- }
- /* --------------------- */
- int setfilmode(name, mode, st)
--char * name;
-+const char * name;
- mode_t mode;
- struct stat *st;
- {
-@@ -436,29 +436,18 @@
- const char       *name;
- const mode_t     mode;
- {
--char *adouble = vol->ad_path( name, ADFLAGS_DIR );
-     int dropbox = (vol->v_flags & AFPVOL_DROPBOX);
-     if (dir_rx_set(mode)) {
--      /* extending right? dir first then .AppleDouble */
-+      /* extending right? dir first then .AppleDouble in rf_setdirmode */
-       if ( stickydirmode(name, DIRBITS | mode, dropbox) < 0 )
-               return -1;
--      if (vol->v_adouble != AD_VERSION2_OSX) {
--            if (stickydirmode(ad_dir(adouble), DIRBITS | mode, dropbox) < 0 && !vol_noadouble(vol)) {
--                return  -1 ;
--            }
--        }
-     }
--    if (setfilmode(adouble, ad_hf_mode(mode), NULL) < 0 && !vol_noadouble(vol)) {
-+    if (vol->vfs->rf_setdirunixmode(vol, name, mode, NULL) < 0 && !vol_noadouble(vol)) {
-         return  -1 ;
-     }
-     if (!dir_rx_set(mode)) {
--      if (vol->v_adouble != AD_VERSION2_OSX) {
--            if (stickydirmode(ad_dir(adouble), DIRBITS | mode, dropbox) < 0 && !vol_noadouble(vol)) {
--                return  -1 ;
--            }
--        }
-       if ( stickydirmode(name, DIRBITS | mode, dropbox) < 0 )
-             return -1;
-     }
-@@ -471,26 +460,17 @@
- const char       *name;
- const mode_t mode;
- {
--    char              buf[ MAXPATHLEN + 1];
-     struct stat               st;
--    char              *m;
-     struct dirent     *dirp;
-     DIR                       *dir;
-     int                 osx = vol->v_adouble == AD_VERSION2_OSX;
-     int                 hf_mode = ad_hf_mode(mode);
-     int                 dropbox = (vol->v_flags & AFPVOL_DROPBOX);
--    char                *adouble = vol->ad_path( name, ADFLAGS_DIR );
--    char                *adouble_p = ad_dir(adouble);
-     
-     if (dir_rx_set(mode)) {
--      /* extending right? dir first then .AppleDouble */
-+      /* extending right? dir first */
-       if ( stickydirmode(name, DIRBITS | mode, dropbox) < 0 )
-               return -1;
--      if (!osx) {
--            if (stickydirmode(adouble_p, DIRBITS | mode, dropbox) < 0 && !vol_noadouble(vol)) {
--                return  -1 ;
--            }
--        }
-     }
-     
-     if (( dir = opendir( name )) == NULL ) {
-@@ -516,61 +496,13 @@
-                 return -1;
-            }
-         }
--#if 0
--        /* Don't change subdir perm */
--        else if (S_ISDIR(st.st_mode)) {
--                if (stickydirmode(dirp->d_name, DIRBITS | mode, dropbox) < 0)
--                    return (-1);
--            } else if (stickydirmode(dirp->d_name, mode, dropbox) < 0)
--                return (-1);
--        }
--#endif
-     }
-     closedir( dir );
-     
--    if (osx) {
--        goto setdirmode_noadouble;
--    }
--    
--    /* change perm of .AppleDouble's files
--    */
--    if (( dir = opendir( adouble_p )) == NULL ) {
--        if (vol_noadouble(vol))
--            goto setdirmode_noadouble;
--        LOG(log_error, logtype_afpd, "setdirmode: opendir %s: %s", fullpathname(".AppleDouble"),strerror(errno) );
--        return( -1 );
--    }
--    strcpy( buf, adouble_p);
--    strcat( buf, "/" );
--    m = strchr( buf, '\0' );
--    for ( dirp = readdir( dir ); dirp != NULL; dirp = readdir( dir )) {
--        if ( strcmp( dirp->d_name, "." ) == 0 ||
--                strcmp( dirp->d_name, ".." ) == 0 ) {
--            continue;
--        }
--        *m = '\0';
--        strcat( buf, dirp->d_name );
--
--        if ( stat( buf, &st ) < 0 ) {
--            LOG(log_error, logtype_afpd, "setdirmode: stat %s: %s", buf, strerror(errno) );
--            continue;
--        }
--        if (!S_ISDIR(st.st_mode)) {
--           if (setfilmode(buf, hf_mode , &st) < 0) {
--               /* FIXME what do we do then? */
--           }
--        }
--    } /* end for */
--    closedir( dir );
--
--    if (!dir_rx_set(mode)) {
--        /* XXX: need to preserve special modes */
--        if (stickydirmode(adouble_p, DIRBITS | mode, dropbox) < 0 ) {
--                return  -1 ;
--        }
-+    if (vol->vfs->rf_setdirmode(vol, name, mode, NULL) < 0 && !vol_noadouble(vol)) {
-+        return  -1 ;
-     }
--setdirmode_noadouble:
-     if (!dir_rx_set(mode)) {
-       if ( stickydirmode(name, DIRBITS | mode, dropbox) < 0 )
-               return -1;
-@@ -578,6 +510,7 @@
-     return( 0 );
- }
-+/* ----------------------------- */
- int setdeskowner( uid, gid )
- const uid_t   uid;
- const gid_t   gid;
-@@ -648,8 +581,6 @@
- const gid_t   gid;
- struct path* path;
- {
--    struct stat st;
--    char  *ad_p;
-     if (!path->st_valid) {
-         of_stat(path);
-@@ -665,22 +596,15 @@
-       return -1;
-     }
--    ad_p = vol->ad_path( path->u_name, ADFLAGS_HF );
--
--    if ( stat( ad_p, &st ) < 0 ) {
--      /* ignore */
--        return 0;
--    }
--    if ( chown( ad_p, uid, gid ) < 0 &&
--            errno != EPERM ) {
--        LOG(log_debug, logtype_afpd, "setfilowner: chown %d/%d %s: %s",
--            uid, gid, ad_p, strerror(errno) );
-+    if (vol->vfs->rf_chown(vol, path->u_name, uid, gid ) < 0 && errno != EPERM) {
-+        LOG(log_debug, logtype_afpd, "setfilowner: rf_chown %d/%d %s: %s",
-+            uid, gid, path->u_name, strerror(errno) );
-         return -1;
-     }
-+
-     return 0;
- }
--
- /* --------------------------------- 
-  * uid/gid == 0 need to be handled as special cases. they really mean
-  * that user/group should inherit from other, but that doesn't fit
-@@ -692,15 +616,10 @@
- const uid_t   uid;
- const gid_t   gid;
- {
--    char              buf[ MAXPATHLEN + 1];
-     struct stat               st;
--    char              *m;
-     struct dirent     *dirp;
-     DIR                       *dir;
-     int                 osx = vol->v_adouble == AD_VERSION2_OSX;
--    int                 noadouble = vol_noadouble(vol);
--    char                *adouble; 
--    char                *adouble_p;
-     if (( dir = opendir( name )) == NULL ) {
-         return( -1 );
-@@ -723,56 +642,15 @@
-         }
-     }
-     closedir( dir );
--    
--    if (osx) {
--       goto setdirowner_noadouble;
--    }
--    adouble = vol->ad_path( name, ADFLAGS_DIR );
--    adouble_p = ad_dir(adouble);
--    if (( dir = opendir( adouble_p )) == NULL ) {
--        if (noadouble)
--            goto setdirowner_noadouble;
--        return( -1 );
--    }
--    strcpy( buf, adouble_p );
--    strcat( buf, "/" );
--    m = strchr( buf, '\0' );
--    for ( dirp = readdir( dir ); dirp != NULL; dirp = readdir( dir )) {
--        if ( strcmp( dirp->d_name, "." ) == 0 ||
--                strcmp( dirp->d_name, ".." ) == 0 ) {
--            continue;
--        }
--        *m = '\0';
--        strcat( buf, dirp->d_name );
--        if ( chown( buf, uid, gid ) < 0 && errno != EPERM ) {
--            LOG(log_debug, logtype_afpd, "setdirowner: chown %d/%d %s: %s",
--                uid, gid, fullpathname(buf), strerror(errno) );
--            /* return ( -1 ); Sometimes this is okay */
--        }
--    }
--    closedir( dir );
--
--    /*
--     * We cheat: we know that chown doesn't do anything.
--     */
--    if ( stat( ".AppleDouble", &st ) < 0 ) {
--        LOG(log_error, logtype_afpd, "setdirowner: stat %s: %s", fullpathname(".AppleDouble"), strerror(errno) );
--        return( -1 );
--    }
--    if ( gid && gid != st.st_gid && chown( ".AppleDouble", uid, gid ) < 0 &&
--            errno != EPERM ) {
--        LOG(log_debug, logtype_afpd, "setdirowner: chown %d/%d %s: %s",
--            uid, gid,fullpathname(".AppleDouble"), strerror(errno) );
--        /* return ( -1 ); Sometimes this is okay */
-+    if (vol->vfs->rf_setdirowner(vol, name, uid, gid) < 0) {
-+        return -1;
-     }
--
--setdirowner_noadouble:
-+    
-     if ( stat( ".", &st ) < 0 ) {
-         return( -1 );
-     }
--    if ( gid && gid != st.st_gid && chown( ".", uid, gid ) < 0 &&
--            errno != EPERM ) {
-+    if ( gid && gid != st.st_gid && chown( ".", uid, gid ) < 0 && errno != EPERM ) {
-         LOG(log_debug, logtype_afpd, "setdirowner: chown %d/%d %s: %s",
-             uid, gid, fullpathname("."), strerror(errno) );
-     }
-diff -Nur -X .cvsignore -x CVS ../src.dev2/etc/afpd/unix.h ./etc/afpd/unix.h
---- ../src.dev2/etc/afpd/unix.h        Mon May 10 18:40:33 2004
-+++ ./etc/afpd/unix.h  Wed Jun 23 03:43:28 2004
-@@ -221,11 +221,12 @@
- extern int setdirmode       __P((const struct vol *, const char *, const mode_t));
- extern int setdeskowner     __P((const uid_t, const gid_t));
- extern int setdirowner      __P((const struct vol *, const char *, const uid_t, const gid_t));
--extern int setfilmode       __P((char *, mode_t , struct stat *));
-+extern int setfilmode       __P((const char *, mode_t , struct stat *));
- extern int setfilunixmode   __P((const struct vol *, struct path*, const mode_t));
- extern int setfilowner      __P((const struct vol *, const uid_t, const gid_t, struct path*));
- extern int unix_rename      __P((const char *oldpath, const char *newpath));
- extern int dir_rx_set       __P((mode_t mode));
-+extern int stickydirmode    __P((const char * name, const mode_t mode, const int dropbox));
- extern void accessmode      __P((char *, struct maccess *, struct dir *, struct stat *));
- extern char *fullpathname   __P((const char *));
-diff -Nur -X .cvsignore -x CVS ../src.dev2/etc/afpd/vfs_adouble.c ./etc/afpd/vfs_adouble.c
---- ../src.dev2/etc/afpd/vfs_adouble.c Thu Jan  1 00:00:00 1970
-+++ ./etc/afpd/vfs_adouble.c   Wed Jun 30 19:31:49 2004
-@@ -0,0 +1,749 @@
-+/*
-+    Copyright (c) 2004 Didier Gautheron
-+ 
-+   This program is free software; you can redistribute it and/or modify
-+   it under the terms of the GNU General Public License as published by
-+   the Free Software Foundation; either version 2 of the License, or
-+   (at your option) any later version.
-+ 
-+   This program is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+   GNU General Public License for more details.
-+ 
-+   You should have received a copy of the GNU General Public License
-+   along with this program; if not, write to the Free Software
-+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ 
-+*/
-+#ifdef HAVE_CONFIG_H
-+#include "config.h"
-+#endif /* HAVE_CONFIG_H */
-+
-+#ifdef STDC_HEADERS
-+#include <string.h>
-+#endif
-+
-+#include <stdio.h>
-+    
-+#include <atalk/adouble.h>
-+#include <atalk/logger.h>
-+#include <atalk/util.h>
-+
-+#include "directory.h"
-+#include "volume.h"
-+#include "unix.h"
-+
-+struct perm {
-+    uid_t uid;
-+    gid_t gid;
-+};
-+
-+typedef int (*rf_loop)(struct dirent *, char *, void *, int );
-+
-+/* ----------------------------- */
-+static int 
-+for_each_adouble(const char *from, const char *name, rf_loop fn, void *data, int flag)
-+{
-+    char            buf[ MAXPATHLEN + 1];
-+    char            *m;
-+    DIR             *dp;
-+    struct dirent   *de;
-+    int             ret;
-+    
-+
-+    if (NULL == ( dp = opendir( name)) ) {
-+        if (!flag) {
-+            LOG(log_error, logtype_afpd, "%s: opendir %s: %s", from, fullpathname(name),strerror(errno) );
-+            return -1;
-+        }
-+        return 0;
-+    }
-+    strlcpy( buf, name, sizeof(buf));
-+    strlcat( buf, "/", sizeof(buf) );
-+    m = strchr( buf, '\0' );
-+    ret = 0;
-+    while ((de = readdir(dp))) {
-+        if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
-+                continue;
-+        }
-+        
-+        strlcat(buf, de->d_name, sizeof(buf));
-+        if (fn && (ret = fn(de, buf, data, flag))) {
-+           closedir(dp);
-+           return ret;
-+        }
-+        *m = 0;
-+    }
-+    closedir(dp);
-+    return ret;
-+}
-+
-+/* ------------------------------ */
-+static int ads_chown_loop(struct dirent *de, char *name, void *data, int flag)
-+{
-+    struct perm   *owner  = data;
-+    
-+    if (chown( name , owner->uid, owner->gid ) < 0) {
-+        return -1;
-+    }
-+    return 0;
-+}
-+
-+static int RF_chown_ads(const struct vol *vol, const char *path, uid_t uid, gid_t gid)
-+
-+{
-+    struct        stat st;
-+    char          *ad_p;
-+    struct perm   owner;
-+    
-+    owner.uid = uid;
-+    owner.gid = gid;
-+
-+
-+    ad_p = ad_dir(vol->vfs->ad_path(path, ADFLAGS_HF ));
-+
-+    if ( stat( ad_p, &st ) < 0 ) {
-+      /* ignore */
-+        return 0;
-+    }
-+    
-+    if (chown( ad_p, uid, gid ) < 0) {
-+      return -1;
-+    }
-+    return for_each_adouble("chown_ads", ad_p, ads_chown_loop, &owner, 1);
-+}
-+
-+/* --------------------------------- */
-+static int deletecurdir_ads1_loop(struct dirent *de, char *name, void *data, int flag)
-+{
-+    return netatalk_unlink(name);
-+}
-+
-+static int ads_delete_rf(char *name) 
-+{
-+    int err;
-+
-+    if ((err = for_each_adouble("deletecurdir", name, deletecurdir_ads1_loop, NULL, 1))) 
-+        return err;
-+    return netatalk_rmdir(name);
-+}
-+
-+static int deletecurdir_ads_loop(struct dirent *de, char *name, void *data, int flag)
-+{
-+    struct stat st;
-+    
-+    /* bail if the file exists in the current directory.
-+     * note: this will not fail with dangling symlinks */
-+    
-+    if (stat(de->d_name, &st) == 0) {
-+        return AFPERR_DIRNEMPT;
-+    }
-+    return ads_delete_rf(name);
-+}
-+
-+static int RF_deletecurdir_ads(const struct vol *vol)
-+{
-+    int err;
-+    
-+    /* delete stray .AppleDouble files. this happens to get .Parent files as well. */
-+    if ((err = for_each_adouble("deletecurdir", ".AppleDouble", deletecurdir_ads_loop, NULL, 1))) 
-+        return err;
-+    return netatalk_rmdir( ".AppleDouble" );
-+}
-+
-+/* ------------------- */
-+struct set_mode {
-+    mode_t mode;
-+    struct stat *st;
-+};
-+
-+static int ads_setfilmode_loop(struct dirent *de, char *name, void *data, int flag)
-+{
-+    struct set_mode *param = data;
-+
-+    return setfilmode(name, param->mode, param->st);
-+}
-+
-+static int ads_setfilmode(const char * name, mode_t mode, struct stat *st)
-+{
-+    mode_t dir_mode = mode;
-+    mode_t file_mode = ad_hf_mode(mode);
-+    struct set_mode param;
-+
-+    if ((dir_mode & (S_IRUSR | S_IWUSR )))
-+        dir_mode |= S_IXUSR;
-+    if ((dir_mode & (S_IRGRP | S_IWGRP )))
-+        dir_mode |= S_IXGRP;
-+    if ((dir_mode & (S_IROTH | S_IWOTH )))
-+        dir_mode |= S_IXOTH;  
-+    
-+      /* change folder */
-+      dir_mode |= DIRBITS;
-+    if (dir_rx_set(dir_mode)) {
-+        if (chmod( name,  dir_mode ) < 0)
-+            return -1;
-+    }
-+    param.st = st;
-+    param.mode = file_mode;
-+    if (for_each_adouble("setfilmode_ads", name, ads_setfilmode_loop, &param, 0) < 0)
-+        return -1;
-+
-+    if (!dir_rx_set(dir_mode)) {
-+        if (chmod( name,  dir_mode ) < 0)
-+            return -1;
-+    }
-+
-+    return 0;
-+}
-+
-+static int RF_setfilmode_ads(const struct vol *vol, const char * name, mode_t mode, struct stat *st)
-+{
-+    return ads_setfilmode(ad_dir(vol->vfs->ad_path( name, ADFLAGS_HF )), mode, st);
-+}
-+
-+/* ------------------- */
-+static int RF_setdirunixmode_ads(const struct vol *vol, const char * name, mode_t mode, struct stat *st)
-+{
-+    char *adouble = vol->vfs->ad_path( name, ADFLAGS_DIR );
-+    char   ad_p[ MAXPATHLEN + 1];
-+    int dropbox = (vol->v_flags & AFPVOL_DROPBOX);
-+
-+    strlcpy(ad_p,ad_dir(adouble), MAXPATHLEN + 1);
-+
-+    if (dir_rx_set(mode)) {
-+
-+        /* .AppleDouble */
-+        if (stickydirmode(ad_dir(ad_p), DIRBITS | mode, dropbox) < 0 && !vol_noadouble(vol)) 
-+            return -1;
-+
-+        /* .AppleDouble/.Parent */
-+        if (stickydirmode(ad_p, DIRBITS | mode, dropbox) < 0 && !vol_noadouble(vol)) 
-+            return -1;
-+    }
-+
-+    if (ads_setfilmode(ad_dir(vol->vfs->ad_path( name, ADFLAGS_DIR)), mode, st) < 0)
-+        return -1;
-+
-+    if (!dir_rx_set(mode)) {
-+        if (stickydirmode(ad_p, DIRBITS | mode, dropbox) < 0 && !vol_noadouble(vol)) 
-+            return  -1 ;
-+        if (stickydirmode(ad_dir(ad_p), DIRBITS | mode, dropbox) < 0 && !vol_noadouble(vol)) 
-+            return -1;
-+    }
-+    return 0;
-+}
-+
-+/* ------------------- */
-+struct dir_mode {
-+    mode_t mode;
-+    int    dropbox;
-+};
-+
-+static int setdirmode_ads_loop(struct dirent *de, char *name, void *data, int flag)
-+{
-+
-+    struct dir_mode *param = data;
-+    int    ret = 0; /* 0 ignore error, -1 */
-+
-+    if (dir_rx_set(param->mode)) {
-+        if (stickydirmode(name, DIRBITS | param->mode, param->dropbox) < 0) {
-+            if (flag) {
-+                return 0;
-+            }
-+            return ret;
-+        }
-+    }
-+    if (ads_setfilmode(name, param->mode, NULL) < 0)
-+        return ret;
-+
-+    if (!dir_rx_set(param->mode)) {
-+        if (stickydirmode(name, DIRBITS | param->mode, param->dropbox) < 0) {
-+            if (flag) {
-+                return 0;
-+            }
-+            return ret;
-+        }
-+    }
-+    return 0;
-+}
-+
-+static int RF_setdirmode_ads(const struct vol *vol, const char * name, mode_t mode, struct stat *st)
-+{
-+    char *adouble = vol->vfs->ad_path( name, ADFLAGS_DIR );
-+    char   ad_p[ MAXPATHLEN + 1];
-+    struct dir_mode param;
-+
-+    param.mode = mode;
-+    param.dropbox = (vol->v_flags & AFPVOL_DROPBOX);
-+
-+    strlcpy(ad_p,ad_dir(adouble), sizeof(ad_p));
-+
-+    if (dir_rx_set(mode)) {
-+        /* .AppleDouble */
-+        if (stickydirmode(ad_dir(ad_p), DIRBITS | mode, param.dropbox) < 0 && !vol_noadouble(vol)) 
-+            return -1;
-+    }
-+
-+    if (for_each_adouble("setdirmode_ads", ad_dir(ad_p), setdirmode_ads_loop, &param, vol_noadouble(vol)))
-+        return -1;
-+
-+    if (!dir_rx_set(mode)) {
-+        if (stickydirmode(ad_dir(ad_p), DIRBITS | mode, param.dropbox) < 0 && !vol_noadouble(vol)) 
-+            return -1;
-+    }
-+    return 0;
-+}
-+
-+/* ------------------- */
-+static int setdirowner_ads1_loop(struct dirent *de, char *name, void *data, int flag)
-+{
-+    struct perm   *owner  = data;
-+
-+    if ( chown( name, owner->uid, owner->gid ) < 0 && errno != EPERM ) {
-+         LOG(log_debug, logtype_afpd, "setdirowner: chown %d/%d %s: %s",
-+                owner->uid, owner->gid, fullpathname(name), strerror(errno) );
-+         /* return ( -1 ); Sometimes this is okay */
-+    }
-+    return 0;
-+}
-+
-+static int setdirowner_ads_loop(struct dirent *de, char *name, void *data, int flag)
-+{
-+    struct perm   *owner  = data;
-+
-+    if (for_each_adouble("setdirowner", name, setdirowner_ads1_loop, data, flag) < 0)
-+        return -1;
-+
-+    if ( chown( name, owner->uid, owner->gid ) < 0 && errno != EPERM ) {
-+         LOG(log_debug, logtype_afpd, "setdirowner: chown %d/%d %s: %s",
-+                owner->uid, owner->gid, fullpathname(name), strerror(errno) );
-+         /* return ( -1 ); Sometimes this is okay */
-+    }
-+    return 0;
-+}
-+
-+static int RF_setdirowner_ads(const struct vol *vol, const char *name, uid_t uid, gid_t gid)
-+{
-+    int           noadouble = vol_noadouble(vol);
-+    char          adouble_p[ MAXPATHLEN + 1];
-+    struct stat   st;
-+    struct perm   owner;
-+    
-+    owner.uid = uid;
-+    owner.gid = gid;
-+
-+    strlcpy(adouble_p, ad_dir(vol->vfs->ad_path( name, ADFLAGS_DIR )), sizeof(adouble_p));
-+
-+    if (for_each_adouble("setdirowner", ad_dir(adouble_p), setdirowner_ads_loop, &owner, noadouble)) 
-+        return -1;
-+
-+    /*
-+     * We cheat: we know that chown doesn't do anything.
-+     */
-+    if ( stat( ".AppleDouble", &st ) < 0) {
-+        if (errno == ENOENT && noadouble)
-+            return 0;
-+        LOG(log_error, logtype_afpd, "setdirowner: stat %s: %s", fullpathname(".AppleDouble"), strerror(errno) );
-+        return -1;
-+    }
-+    if ( gid && gid != st.st_gid && chown( ".AppleDouble", uid, gid ) < 0 && errno != EPERM ) {
-+        LOG(log_debug, logtype_afpd, "setdirowner: chown %d/%d %s: %s",
-+            uid, gid,fullpathname(".AppleDouble"), strerror(errno) );
-+        /* return ( -1 ); Sometimes this is okay */
-+    }
-+    return 0;
-+}
-+
-+/* ------------------- */
-+static int RF_deletefile_ads(const struct vol *vol, const char *file )
-+{
-+    char *ad_p = ad_dir(vol->vfs->ad_path(file, ADFLAGS_HF ));
-+
-+    return ads_delete_rf(ad_p);
-+}
-+
-+/* --------------------------- */
-+int RF_renamefile_ads(const struct vol *vol, const char *src, const char *dst)
-+{
-+    char  adsrc[ MAXPATHLEN + 1];
-+    int   err = 0;
-+
-+    strcpy( adsrc, ad_dir(vol->vfs->ad_path( src, 0 )));
-+    if (unix_rename( adsrc, ad_dir(vol->vfs->ad_path( dst, 0 ))) < 0) {
-+        struct stat st;
-+
-+        err = errno;
-+        if (errno == ENOENT) {
-+              struct adouble    ad;
-+
-+            if (stat(adsrc, &st)) /* source has no ressource fork, */
-+                return AFP_OK;
-+            
-+            /* We are here  because :
-+             * -there's no dest folder. 
-+             * -there's no .AppleDouble in the dest folder.
-+             * if we use the struct adouble passed in parameter it will not
-+             * create .AppleDouble if the file is already opened, so we
-+             * use a diff one, it's not a pb,ie it's not the same file, yet.
-+             */
-+            ad_init(&ad, vol->v_adouble); 
-+            if (!ad_open(dst, ADFLAGS_HF, O_RDWR | O_CREAT, 0666, &ad)) {
-+              ad_close(&ad, ADFLAGS_HF);
-+
-+              /* We must delete it */
-+              RF_deletefile_ads(vol, dst );
-+              if (!unix_rename( adsrc, ad_dir(vol->vfs->ad_path( dst, 0 ))) ) 
-+                   err = 0;
-+                else 
-+                   err = errno;
-+            }
-+            else { /* it's something else, bail out */
-+                  err = errno;
-+              }
-+          }
-+      }
-+      if (err) {
-+              errno = err;
-+              return -1;
-+      }
-+      return 0;
-+}
-+
-+/* ===================================================
-+ classic adouble format 
-+*/
-+
-+static int validupath_adouble(const struct vol *vol, const char *name) 
-+{
-+    return (vol->v_flags & AFPVOL_USEDOTS) ? strncasecmp(name,".Apple", 6) && strcasecmp(name, ".Parent")
-+                                           : name[0] != '.';
-+}
-+
-+/* ----------------- */
-+static int RF_chown_adouble(const struct vol *vol, const char *path, uid_t uid, gid_t gid)
-+
-+{
-+    struct stat st;
-+    char        *ad_p;
-+
-+    ad_p = vol->vfs->ad_path(path, ADFLAGS_HF );
-+
-+    if ( stat( ad_p, &st ) < 0 )
-+        return 0; /* ignore */
-+
-+    return chown( ad_p, uid, gid );
-+}
-+
-+/* ----------------- */
-+int RF_renamedir_adouble(const struct vol *vol, const char *oldpath, const char *newpath)
-+{
-+    return 0;
-+}
-+
-+/* ----------------- */
-+static int deletecurdir_adouble_loop(struct dirent *de, char *name, void *data, int flag)
-+{
-+    struct stat st;
-+    int         err;
-+    
-+    /* bail if the file exists in the current directory.
-+     * note: this will not fail with dangling symlinks */
-+    
-+    if (stat(de->d_name, &st) == 0)
-+        return AFPERR_DIRNEMPT;
-+
-+    if ((err = netatalk_unlink(name)))
-+        return err;
-+
-+    return 0;
-+}
-+
-+static int RF_deletecurdir_adouble(const struct vol *vol)
-+{
-+    int err;
-+
-+    /* delete stray .AppleDouble files. this happens to get .Parent files
-+       as well. */
-+    if ((err = for_each_adouble("deletecurdir", ".AppleDouble", deletecurdir_adouble_loop, NULL, 1))) 
-+        return err;
-+    return netatalk_rmdir( ".AppleDouble" );
-+}
-+
-+/* ----------------- */
-+static int adouble_setfilmode(const char * name, mode_t mode, struct stat *st)
-+{
-+    return setfilmode(name, ad_hf_mode(mode), st);
-+}
-+
-+static int RF_setfilmode_adouble(const struct vol *vol, const char * name, mode_t mode, struct stat *st)
-+{
-+    return adouble_setfilmode(vol->vfs->ad_path( name, ADFLAGS_HF ), mode, st);
-+}
-+
-+/* ----------------- */
-+static int RF_setdirunixmode_adouble(const struct vol *vol, const char * name, mode_t mode, struct stat *st)
-+{
-+    char *adouble = vol->vfs->ad_path( name, ADFLAGS_DIR );
-+    int  dropbox = (vol->v_flags & AFPVOL_DROPBOX);
-+
-+    if (dir_rx_set(mode)) {
-+        if (stickydirmode(ad_dir(adouble), DIRBITS | mode, dropbox) < 0 && !vol_noadouble(vol)) 
-+            return -1;
-+    }
-+
-+    if (adouble_setfilmode(vol->vfs->ad_path( name, ADFLAGS_DIR ), mode, st) < 0) 
-+        return -1;
-+
-+    if (!dir_rx_set(mode)) {
-+        if (stickydirmode(ad_dir(adouble), DIRBITS | mode, dropbox) < 0 && !vol_noadouble(vol)) 
-+            return  -1 ;
-+    }
-+    return 0;
-+}
-+
-+/* ----------------- */
-+static int setdirmode_adouble_loop(struct dirent *de, char *name, void *data, int flag)
-+{
-+    int         hf_mode = *(int *)data;
-+    struct stat st;
-+
-+    if ( stat( name, &st ) < 0 ) {
-+        if (flag)
-+            return 0;
-+        LOG(log_error, logtype_afpd, "setdirmode: stat %s: %s", name, strerror(errno) );
-+    }
-+    else if (!S_ISDIR(st.st_mode)) {
-+        if (setfilmode(name, hf_mode , &st) < 0) {
-+               /* FIXME what do we do then? */
-+        }
-+    }
-+    return 0;
-+}
-+
-+static int RF_setdirmode_adouble(const struct vol *vol, const char * name, mode_t mode, struct stat *st1)
-+{
-+    int   dropbox = (vol->v_flags & AFPVOL_DROPBOX);
-+    int   hf_mode = ad_hf_mode(mode);
-+    char  *adouble = vol->vfs->ad_path( name, ADFLAGS_DIR );
-+    char  *adouble_p = ad_dir(adouble);
-+
-+    if (dir_rx_set(mode)) {
-+        if (stickydirmode(ad_dir(adouble), DIRBITS | mode, dropbox) < 0 && !vol_noadouble(vol)) 
-+            return -1;
-+    }
-+
-+    if (for_each_adouble("setdirmode", adouble_p, setdirmode_adouble_loop, &hf_mode, vol_noadouble(vol)))
-+        return -1;
-+
-+    if (!dir_rx_set(mode)) {
-+        if (stickydirmode(ad_dir(adouble), DIRBITS | mode, dropbox) < 0 && !vol_noadouble(vol)) 
-+            return  -1 ;
-+    }
-+    return 0;
-+}
-+
-+/* ----------------- */
-+static int setdirowner_adouble_loop(struct dirent *de, char *name, void *data, int flag)
-+{
-+    struct perm   *owner  = data;
-+
-+    if ( chown( name, owner->uid, owner->gid ) < 0 && errno != EPERM ) {
-+         LOG(log_debug, logtype_afpd, "setdirowner: chown %d/%d %s: %s",
-+                owner->uid, owner->gid, fullpathname(name), strerror(errno) );
-+         /* return ( -1 ); Sometimes this is okay */
-+    }
-+    return 0;
-+}
-+
-+static int RF_setdirowner_adouble(const struct vol *vol, const char *name, uid_t uid, gid_t gid)
-+
-+{
-+    int           noadouble = vol_noadouble(vol);
-+    char          *adouble_p;
-+    struct stat   st;
-+    struct perm   owner;
-+    
-+    owner.uid = uid;
-+    owner.gid = gid;
-+
-+    adouble_p = ad_dir(vol->vfs->ad_path( name, ADFLAGS_DIR ));
-+
-+    if (for_each_adouble("setdirowner", adouble_p, setdirowner_adouble_loop, &owner, noadouble)) 
-+        return -1;
-+
-+    /*
-+     * We cheat: we know that chown doesn't do anything.
-+     */
-+    if ( stat( ".AppleDouble", &st ) < 0) {
-+        if (errno == ENOENT && noadouble)
-+            return 0;
-+        LOG(log_error, logtype_afpd, "setdirowner: stat %s: %s", fullpathname(".AppleDouble"), strerror(errno) );
-+        return -1;
-+    }
-+    if ( gid && gid != st.st_gid && chown( ".AppleDouble", uid, gid ) < 0 && errno != EPERM ) {
-+        LOG(log_debug, logtype_afpd, "setdirowner: chown %d/%d %s: %s",
-+            uid, gid,fullpathname(".AppleDouble"), strerror(errno) );
-+        /* return ( -1 ); Sometimes this is okay */
-+    }
-+    return 0;
-+}
-+
-+/* ----------------- */
-+static int RF_deletefile_adouble(const struct vol *vol, const char *file )
-+{
-+      return netatalk_unlink(vol->vfs->ad_path( file, ADFLAGS_HF));
-+}
-+
-+/* ----------------- */
-+int RF_renamefile_adouble(const struct vol *vol, const char *src, const char *dst)
-+{
-+    char  adsrc[ MAXPATHLEN + 1];
-+    int   err = 0;
-+
-+    strcpy( adsrc, vol->vfs->ad_path( src, 0 ));
-+    if (unix_rename( adsrc, vol->vfs->ad_path( dst, 0 )) < 0) {
-+        struct stat st;
-+
-+        err = errno;
-+        if (errno == ENOENT) {
-+              struct adouble    ad;
-+
-+            if (stat(adsrc, &st)) /* source has no ressource fork, */
-+                return AFP_OK;
-+            
-+            /* We are here  because :
-+             * -there's no dest folder. 
-+             * -there's no .AppleDouble in the dest folder.
-+             * if we use the struct adouble passed in parameter it will not
-+             * create .AppleDouble if the file is already opened, so we
-+             * use a diff one, it's not a pb,ie it's not the same file, yet.
-+             */
-+            ad_init(&ad, vol->v_adouble); 
-+            if (!ad_open(dst, ADFLAGS_HF, O_RDWR | O_CREAT, 0666, &ad)) {
-+              ad_close(&ad, ADFLAGS_HF);
-+              if (!unix_rename( adsrc, vol->vfs->ad_path( dst, 0 )) ) 
-+                   err = 0;
-+                else 
-+                   err = errno;
-+            }
-+            else { /* it's something else, bail out */
-+                  err = errno;
-+              }
-+          }
-+      }
-+      if (err) {
-+              errno = err;
-+              return -1;
-+      }
-+      return 0;
-+}
-+
-+struct vfs_ops netatalk_adouble = {
-+    /* ad_path:           */ ad_path,
-+    /* validupath:        */ validupath_adouble,
-+    /* rf_chown:          */ RF_chown_adouble,
-+    /* rf_renamedir:      */ RF_renamedir_adouble,
-+    /* rf_deletecurdir:   */ RF_deletecurdir_adouble,
-+    /* rf_setfilmode:     */ RF_setfilmode_adouble,
-+    /* rf_setdirmode:     */ RF_setdirmode_adouble,
-+    /* rf_setdirunixmode: */ RF_setdirunixmode_adouble,
-+    /* rf_setdirowner:    */ RF_setdirowner_adouble,
-+    /* rf_deletefile:     */ RF_deletefile_adouble,
-+    /* rf_renamefile:     */ RF_renamefile_adouble,
-+};
-+
-+/* =======================================
-+ osx adouble format 
-+ */
-+static int validupath_osx(const struct vol *vol, const char *name) 
-+{
-+    return strncasecmp(name,".Apple", 6) && strncasecmp(name,"._", 2);
-+}
-+
-+/* ---------------- */
-+int RF_renamedir_osx(const struct vol *vol, const char *oldpath, const char *newpath)
-+{
-+    /* We simply move the corresponding ad file as well */
-+    char   tempbuf[258]="._";
-+    return rename(vol->vfs->ad_path(oldpath,0),strcat(tempbuf,newpath));
-+}
-+
-+/* ---------------- */
-+int RF_deletecurdir_osx(const struct vol *vol)
-+{
-+    return netatalk_unlink( vol->vfs->ad_path(".",0) );
-+}
-+
-+/* ---------------- */
-+static int RF_setdirunixmode_osx(const struct vol *vol, const char * name, mode_t mode, struct stat *st)
-+{
-+    return adouble_setfilmode(vol->vfs->ad_path( name, ADFLAGS_DIR ), mode, st);
-+}
-+
-+/* ---------------- */
-+static int RF_setdirmode_osx(const struct vol *vol, const char * name, mode_t mode, struct stat *st)
-+{
-+    return 0;
-+}
-+
-+/* ---------------- */
-+static int RF_setdirowner_osx(const struct vol *vol, const char *path, uid_t uid, gid_t gid)
-+{
-+      return 0;
-+}
-+
-+/* ---------------- */
-+int RF_renamefile_osx(const struct vol *vol, const char *src, const char *dst)
-+{
-+    char  adsrc[ MAXPATHLEN + 1];
-+
-+    strcpy( adsrc, vol->vfs->ad_path( src, 0 ));
-+    return unix_rename( adsrc, vol->vfs->ad_path( dst, 0 ));
-+}
-+
-+struct vfs_ops netatalk_adouble_osx = {
-+    /* ad_path:          */ ad_path_osx,
-+    /* validupath:       */ validupath_osx,
-+    /* rf_chown:         */ RF_chown_adouble,
-+    /* rf_renamedir:     */ RF_renamedir_osx,
-+    /* rf_deletecurdir:  */ RF_deletecurdir_osx,
-+    /* rf_setfilmode:    */ RF_setfilmode_adouble,
-+    /* rf_setdirmode:    */ RF_setdirmode_osx,
-+    /* rf_setdirunixmode:*/ RF_setdirunixmode_osx,
-+    /* rf_setdirowner:   */ RF_setdirowner_osx,
-+    /* rf_deletefile:    */ RF_deletefile_adouble,
-+    /* rf_renamefile:    */ RF_renamefile_osx,
-+};
-+
-+/* =======================================
-+   samba ads format 
-+ */
-+struct vfs_ops netatalk_adouble_ads = {
-+    /* ad_path:          */ ad_path_ads,
-+    /* validupath:       */ validupath_adouble,
-+    /* rf_chown:         */ RF_chown_ads,
-+    /* rf_renamedir:     */ RF_renamedir_adouble,
-+    /* rf_deletecurdir:  */ RF_deletecurdir_ads,
-+    /* rf_setfilmode:    */ RF_setfilmode_ads,
-+    /* rf_setdirmode:    */ RF_setdirmode_ads,
-+    /* rf_setdirunixmode:*/ RF_setdirunixmode_ads,
-+    /* rf_setdirowner:   */ RF_setdirowner_ads,
-+    /* rf_deletefile:    */ RF_deletefile_ads,
-+    /* rf_renamefile:    */ RF_renamefile_ads,
-+};
-+
-+/* ---------------- */
-+void initvol_vfs(struct vol *vol)
-+{
-+    if (vol->v_adouble == AD_VERSION2_OSX) {
-+        vol->vfs = &netatalk_adouble_osx;
-+    }
-+    else if (vol->v_adouble == AD_VERSION1_ADS) {
-+        vol->vfs = &netatalk_adouble_ads;
-+    }
-+    else {
-+        vol->vfs = &netatalk_adouble;
-+    }
-+}
-+
-diff -Nur -X .cvsignore -x CVS ../src.dev2/etc/afpd/volume.c ./etc/afpd/volume.c
---- ../src.dev2/etc/afpd/volume.c      Mon Jul 12 08:46:03 2004
-+++ ./etc/afpd/volume.c        Mon Jul 12 00:29:11 2004
-@@ -427,6 +427,8 @@
-             options[VOLOPT_ADOUBLE].i_value = AD_VERSION2;
-         else if (strcasecmp(val + 1, "osx") == 0)
-             options[VOLOPT_ADOUBLE].i_value = AD_VERSION2_OSX;
-+        else if (strcasecmp(val + 1, "ads") == 0)
-+            options[VOLOPT_ADOUBLE].i_value = AD_VERSION1_ADS;
- #endif
-     } else if (optionok(tmp, "options:", val)) {
-         char *p;
-@@ -523,34 +525,6 @@
-     }
- }
--/* ----------------- 
-- * FIXME should be define elsewhere
--*/
--static int validupath_adouble(const struct vol *vol, const char *name) 
--{
--    return (vol->v_flags & AFPVOL_USEDOTS) ? strncasecmp(name,".Apple", 6) && strcasecmp(name, ".Parent")
--                                           : name[0] != '.';
--}                                           
--
--/* ----------------- */
--static int validupath_osx(const struct vol *vol, const char *name) 
--{
--    return strncasecmp(name,".Apple", 6) && strncasecmp(name,"._", 2);
--}             
--
--/* ---------------- */
--static void initvoladouble(struct vol *vol)
--{
--    if (vol->v_adouble == AD_VERSION2_OSX) {
--        vol->validupath  = validupath_osx;
--        vol->ad_path     = ad_path_osx;
--    }
--    else {
--        vol->validupath  = validupath_adouble;
--        vol->ad_path     = ad_path;
--    }
--}
--
- /* ------------------------------- */
- static int creatvol(AFPObj *obj, struct passwd *pwd, 
-                     char *path, char *name, 
-@@ -653,7 +627,8 @@
-           volume->v_adouble = options[VOLOPT_ADOUBLE].i_value;
-       else 
-           volume->v_adouble = AD_VERSION;
--      initvoladouble(volume);
-+
-+      initvol_vfs(volume);
- #ifdef FORCE_UIDGID
-         if (options[VOLOPT_FORCEUID].c_value) {
-             volume->v_forceuid = strdup(options[VOLOPT_FORCEUID].c_value);
-@@ -2231,6 +2206,9 @@
-             break;
-         case AD_VERSION2_OSX:
-             strlcat(buf, "ADOUBLE_VER:osx\n", sizeof(buf));
-+            break;
-+        case AD_VERSION1_ADS:
-+            strlcat(buf, "ADOUBLE_VER:ads\n", sizeof(buf));
-             break;
-     }
-diff -Nur -X .cvsignore -x CVS ../src.dev2/etc/afpd/volume.h ./etc/afpd/volume.h
---- ../src.dev2/etc/afpd/volume.h      Mon Jul 12 08:46:03 2004
-+++ ./etc/afpd/volume.h        Fri Jun 25 22:01:56 2004
-@@ -14,6 +14,7 @@
- #include "atalk/unicode.h"
- #include "globals.h"
-+#include "afp_vfs.h"
- #define AFPVOL_NAMELEN   27
-@@ -75,6 +76,7 @@
-     int                 v_preexec_close;
-     
-     /* adouble indirection */
-+    struct vfs_ops      *vfs;
-     int                 (*validupath)(const struct vol *, const char *);
-     char                *(*ad_path)(const char *, int);
- };
-diff -Nur -X .cvsignore -x CVS ../src.dev2/include/atalk/adouble.h ./include/atalk/adouble.h
---- ../src.dev2/include/atalk/adouble.h        Tue Jun 15 01:08:28 2004
-+++ ./include/atalk/adouble.h  Sun Jun 20 22:33:26 2004
-@@ -82,6 +82,7 @@
- #define AD_VERSION1   0x00010000
- #define AD_VERSION2   0x00020000
- #define AD_VERSION2_OSX       0x00020001
-+#define AD_VERSION1_ADS       0x00010002
- #define AD_VERSION    AD_VERSION2
- /*
-@@ -252,6 +253,7 @@
-                                         the header parameter size is too small.
-                                      */
-     char                *(*ad_path)(const char *, int);
-+    int                 (*ad_mkrf)(char *);
-                            
- #ifdef USE_MMAPPED_HEADERS
-     char                *ad_data;
-@@ -364,6 +366,7 @@
- extern char *ad_dir       __P((const char *));
- extern char *ad_path      __P((const char *, int));
- extern char *ad_path_osx  __P((const char *, int));
-+extern char *ad_path_ads  __P((const char *, int));
- extern int ad_mode        __P((const char *, int));
- extern int ad_mkdir       __P((const char *, int));
-diff -Nur -X .cvsignore -x CVS ../src.dev2/libatalk/adouble/ad_open.c ./libatalk/adouble/ad_open.c
---- ../src.dev2/libatalk/adouble/ad_open.c     Mon Jul 12 02:01:45 2004
-+++ ./libatalk/adouble/ad_open.c       Mon Jul 12 02:12:25 2004
-@@ -697,6 +697,25 @@
-     return( pathbuf );
- }
-+/* -------------------- */
-+static int ad_mkrf(char *path)
-+{
-+    char *slash;
-+    /*
-+     * Probably .AppleDouble doesn't exist, try to mkdir it.
-+     */
-+     if (NULL == ( slash = strrchr( path, '/' )) ) {
-+         return -1;
-+     }
-+     *slash = '\0';
-+     errno = 0;
-+     if ( ad_mkdir( path, 0777 ) < 0 ) {
-+          return -1;
-+     }
-+     *slash = '/';
-+     return 0;
-+}
-+
- /* ---------------------------------------
-  * Put the resource fork where it needs to be:
-  * ._name
-@@ -729,8 +748,97 @@
-     strlcat( pathbuf, slash, MAXPATHLEN +1);
-     return pathbuf;
- }
-+/* -------------------- */
-+static int ad_mkrf_osx(char *path)
-+{
-+    return 0;
-+}
--/*
-+/* ---------------------------------------
-+ * Put the .AppleDouble where it needs to be:
-+ *
-+ *        /   a/.AppleDouble/b/Afp_AfpInfo
-+ *    a/b     
-+ *        \   b/.AppleDouble/.Parent/Afp_AfpInfo
-+ *
-+ */
-+char *
-+ad_path_ads( path, adflags )
-+    const char        *path;
-+    int               adflags;
-+{
-+    static char       pathbuf[ MAXPATHLEN + 1];
-+    char      c, *slash, buf[MAXPATHLEN + 1];
-+    size_t      l;
-+
-+    l = strlcpy(buf, path, MAXPATHLEN +1);
-+    if ( adflags & ADFLAGS_DIR ) {
-+      strcpy( pathbuf, buf);
-+      if ( *buf != '\0' && l < MAXPATHLEN) {
-+          pathbuf[l++] = '/';
-+          pathbuf[l] = 0;
-+      }
-+      slash = ".Parent";
-+    } else {
-+      if (NULL != ( slash = strrchr( buf, '/' )) ) {
-+          c = *++slash;
-+          *slash = '\0';
-+          strcpy( pathbuf, buf);
-+          *slash = c;
-+      } else {
-+          pathbuf[ 0 ] = '\0';
-+          slash = buf;
-+      }
-+    }
-+    strlcat( pathbuf, ".AppleDouble/", MAXPATHLEN +1);
-+    strlcat( pathbuf, slash, MAXPATHLEN +1);
-+
-+    strlcat( pathbuf, "/Afp_AfpInfo", MAXPATHLEN +1);
-+
-+#if 0
-+    if ((adflags & ADFLAGS_HF)) {
-+        strlcat( pathbuf, "Afp_AfpInfo", MAXPATHLEN +1);
-+    else {
-+        strlcat( pathbuf, "Afp_Resource", MAXPATHLEN +1);
-+    }
-+#endif      
-+    return( pathbuf );
-+}
-+
-+/* -------------------- */
-+static int ad_mkrf_ads(char *path)
-+{
-+    char *slash;
-+    /*
-+     * Probably .AppleDouble doesn't exist, try to mkdir it.
-+     */
-+     if (NULL == ( slash = strrchr( path, '/' )) ) {
-+         return -1;
-+     }
-+     *slash = 0;
-+     errno = 0;
-+     if ( ad_mkdir( path, 0777 ) < 0 ) {
-+         if ( errno == ENOENT ) {
-+             char *slash1;
-+             
-+             if (NULL == ( slash1 = strrchr( path, '/' )) ) 
-+                 return -1;
-+             errno = 0;
-+             *slash1 = 0;
-+             if ( ad_mkdir( path, 0777 ) < 0 ) 
-+                  return -1;
-+             *slash1 = '/';
-+             if ( ad_mkdir( path, 0777 ) < 0 )
-+                 return -1;
-+         }
-+         else
-+            return -1;
-+     }     
-+     *slash = '/';
-+     return 0;
-+}
-+
-+/* -------------------------
-  * Support inherited protection modes for AppleDouble files.  The supplied
-  * mode is ANDed with the parent directory's mask value in lieu of "umask",
-  * and that value is returned.
-@@ -914,10 +1022,16 @@
-     memset( ad, 0, sizeof( struct adouble ) );
-     ad->ad_flags = flags;
-     if (flags == AD_VERSION2_OSX) {
--        ad->ad_path     = ad_path_osx;
-+        ad->ad_path = ad_path_osx;
-+        ad->ad_mkrf = ad_mkrf_osx;
-+    }
-+    else if (flags == AD_VERSION1_ADS) {
-+        ad->ad_path = ad_path_ads;
-+        ad->ad_mkrf = ad_mkrf_ads;
-     }
-     else {
--        ad->ad_path     = ad_path;
-+        ad->ad_path = ad_path;
-+        ad->ad_mkrf = ad_mkrf;
-     }
- }
-@@ -931,7 +1045,7 @@
-     struct adouble    *ad;
- {
-     struct stat         st;
--    char              *slash, *ad_p;
-+    char              *ad_p;
-     int                       hoflags, admode;
-     int                 st_invalid;
-     int                 open_df = 0;
-@@ -1031,19 +1145,9 @@
-           st_invalid = ad_mode_st(ad_p, &admode, &st);
-           admode = ad_hf_mode(admode); 
-           if ( errno == ENOENT && !(adflags & ADFLAGS_NOADOUBLE) && ad->ad_flags != AD_VERSION2_OSX) {
--              /*
--               * Probably .AppleDouble doesn't exist, try to
--               * mkdir it.
--               */
--              if (NULL == ( slash = strrchr( ad_p, '/' )) ) {
--                  return ad_error(ad, adflags);
--              }
--              *slash = '\0';
--              errno = 0;
--              if ( ad_mkdir( ad_p, 0777 ) < 0 ) {
-+              if (ad->ad_mkrf( ad_p) < 0) {
-                   return ad_error(ad, adflags);
--              }
--              *slash = '/';
-+              }
-               admode = mode;
-               st_invalid = ad_mode_st(ad_p, &admode, &st);
-               admode = ad_hf_mode(admode); 
diff --git a/contrib/patches/patch.mangled_trash_with_ip b/contrib/patches/patch.mangled_trash_with_ip
deleted file mode 100644 (file)
index 38976fc..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-Workaround for Network Trash and system without byte locking (broken nfs/afs)
-mangle OS9 "Network Trash Folder/Trash Can #2" name to
-"Network Trash Folder/Trash Can #2.<client ip>.<tcp port>"
-So multiple clients can share the same volume and have a working trash.
-
-Index: etc/afpd/directory.c
-===================================================================
-RCS file: /cvsroot/netatalk/netatalk/etc/afpd/directory.c,v
-retrieving revision 1.71.2.4.2.12
-diff -u -r1.71.2.4.2.12 directory.c
---- etc/afpd/directory.c       11 Mar 2004 16:16:40 -0000      1.71.2.4.2.12
-+++ etc/afpd/directory.c       21 Apr 2004 12:42:03 -0000
-@@ -554,6 +554,7 @@
-  * attempt to extend the current dir. tree to include path
-  * as a side-effect, movecwd to that point and return the new dir
-  */
-+
- static struct dir *
-             extenddir( vol, dir, path )
- struct vol    *vol;
-@@ -563,7 +564,25 @@
-     char *save_m_name;
-     if ( path->u_name == NULL) {
--        path->u_name = mtoupath(vol, path->m_name, dir->d_did, (path->m_type==3) );
-+#ifdef DISABLE_LOCKING
-+        int l = strlen(TRASH_PREFIX);
-+        /* XXX replace mac name with unix name */
-+      if (vol->v_trash_id && vol->v_trash_id  == dir->d_did && vol->v_ip &&
-+             !strncmp(TRASH_PREFIX , path->m_name, l ) )
-+      {
-+          static char temp[MAXPATHLEN + 1];
-+          char *u;
-+
-+          strcpy(temp, path->m_name);
-+          u = temp +l;
-+          strcat(temp, ".");
-+          strcat(temp, vol->v_ip);
-+          path->u_name = temp;
-+      
-+      }
-+        else 
-+#endif
-+            path->u_name = mtoupath(vol, path->m_name, dir->d_did, (path->m_type==3) );
-     }
-     path->dir = NULL;
-Index: etc/afpd/enumerate.c
-===================================================================
-RCS file: /cvsroot/netatalk/netatalk/etc/afpd/enumerate.c,v
-retrieving revision 1.39.2.2.2.4
-diff -u -r1.39.2.2.2.4 enumerate.c
---- etc/afpd/enumerate.c       11 Mar 2004 02:01:59 -0000      1.39.2.2.2.4
-+++ etc/afpd/enumerate.c       21 Apr 2004 12:42:04 -0000
-@@ -54,9 +54,39 @@
-     if (id == 0) {
-         return NULL;
-     }
-+    
-+#ifdef DISABLE_LOCKING
-+    if (!path->m_name) {
-+        int l = strlen(TRASH_PREFIX);
-+        /* XXX */
-+      if (vol->v_trash_id && vol->v_trash_id  == dir->d_did && vol->v_ip &&
-+             !strncmp(TRASH_PREFIX , upath, l ) )
-+      {
-+          static char temp[MAXPATHLEN + 1];
-+          char *u;
-+
-+          strcpy(temp, upath);
-+          u = temp +l;
-+          
-+          while (*u >= '0' && *u <= '9') {
-+              u++;
-+          }
-+          if (*u == '.') {
-+              *u = '\0';
-+          }
-+          path->m_name = temp; 
-+      }
-+          
-+        else if(!(path->m_name = utompath(vol, upath, id , utf8_encoding()))) {
-+           return NULL;
-+        }
-+    }
-+#else 
-     if (!path->m_name && !(path->m_name = utompath(vol, upath, id , utf8_encoding()))) {
--        return NULL;
-+       return NULL;
-     }
-+#endif
-+    
-     name  = path->m_name;    
-     if ((cdir = dirnew(name, upath)) == NULL) {
-         LOG(log_error, logtype_afpd, "adddir: malloc: %s", strerror(errno) );
-@@ -185,6 +215,32 @@
-     return name;
- }
-+#ifdef DISABLE_LOCKING
-+/* ----------------------------- */
-+int check_trash(const struct vol *vol, char *name)
-+{
-+int l = strlen(TRASH_PREFIX);
-+char *u;
-+
-+    if (strncmp(TRASH_PREFIX , name, l)) 
-+        return 0;
-+    /* */
-+    u = name +l;
-+    while (*u >= '0' && *u <= '9') {
-+        u++;
-+    }
-+
-+    if (u == name +l)
-+        return 0;
-+
-+    if (*u == '.' && !strcmp(vol->v_ip, u +1)) {
-+        return 0;
-+    }
-+    /* hide this one */
-+    return 1;
-+}
-+#endif
-+
- /* ----------------------------- */
- int 
- for_each_dirent(const struct vol *vol, char *name, dir_loop fn, void *data)
-@@ -193,15 +249,28 @@
-     struct dirent     *de;
-     char            *m_name;
-     int             ret;
-+#ifdef DISABLE_LOCKING
-+    int             mangle_trash = 0;
-+#endif
-     
-     if (NULL == ( dp = opendir( name)) ) {
-         return -1;
-     }
-+
-+#ifdef DISABLE_LOCKING
-+    if (vol->v_trash_id && vol->v_trash_id == curdir->d_did && !strcmp(name, ".")) {
-+        mangle_trash = 1;
-+    }
-+#endif    
-     ret = 0;
-     for ( de = readdir( dp ); de != NULL; de = readdir( dp )) {
-         if (!(m_name = check_dirent(vol, de->d_name)))
-             continue;
-+#ifdef DISABLE_LOCKING
-+        if (mangle_trash && check_trash(vol, de->d_name))
-+            continue;
-+#endif
-         ret++;
-         if (fn && fn(de,m_name, data) < 0) {
-            closedir(dp);
-Index: etc/afpd/volume.c
-===================================================================
-RCS file: /cvsroot/netatalk/netatalk/etc/afpd/volume.c,v
-retrieving revision 1.51.2.7.2.28
-diff -u -r1.51.2.7.2.28 volume.c
---- etc/afpd/volume.c  6 Apr 2004 23:29:37 -0000       1.51.2.7.2.28
-+++ etc/afpd/volume.c  21 Apr 2004 12:42:05 -0000
-@@ -73,7 +73,11 @@
- static struct vol *Volumes = NULL;
- static u_int16_t      lastvid = 0;
--static char           *Trash = "\02\024Network Trash Folder";
-+
-+/* type, len, name */
-+static char           *Trash2 = "\02\024Network Trash Folder";
-+/* type, hint (4 bytes), len (2bytes), name */
-+static char           *Trash3 = "\03\0\0\0\0\0\024Network Trash Folder";
- static struct extmap  *Extmap = NULL, *Defextmap = NULL;
- static int              Extmap_cnt;
-@@ -1038,6 +1042,10 @@
-     free(vol->v_forceuid);
-     free(vol->v_forcegid);
- #endif /* FORCE_UIDGID */
-+
-+#ifdef DISABLE_LOCKING
-+    free(vol->v_ip);
-+#endif    
- }
- /* ------------------------------- */
-@@ -1730,9 +1738,31 @@
-               goto openvol_err;
-           }
-       }
--      else {
--            p = Trash;
--            cname( volume, volume->v_dir, &p );
-+#ifndef DISABLE_LOCKING       
-+      else 
-+#endif        
-+        {
-+            struct path *s_path;
-+
-+            /* use the right name format */
-+            p = (afp_version>= 30)?Trash3:Trash2;
-+            s_path = cname( volume, volume->v_dir, &p );
-+#ifdef DISABLE_LOCKING
-+            if (s_path && *s_path->m_name == '\0' ) {
-+                /* XXXX should do the same with ASP, could use volxlate but there's ':' in $p */
-+                if (obj->proto == AFPPROTO_DSI) {
-+                    DSI *dsi = obj->handle;
-+                
-+                    /* cname moved into dest folder */
-+                    volume->v_trash_id = curdir->d_did;
-+                    volume->v_ip = malloc(MAXPATHLEN +1);
-+                    if (volume->v_ip) {
-+                        sprintf(volume->v_ip, "%s.%u", inet_ntoa(dsi->client.sin_addr),
-+                              ntohs(dsi->client.sin_port));
-+                    }
-+                }
-+            }
-+#endif
-         }
-         return( AFP_OK );
-     }
-Index: etc/afpd/volume.h
-===================================================================
-RCS file: /cvsroot/netatalk/netatalk/etc/afpd/volume.h,v
-retrieving revision 1.19.2.5.2.6
-diff -u -r1.19.2.5.2.6 volume.h
---- etc/afpd/volume.h  11 Mar 2004 02:02:04 -0000      1.19.2.5.2.6
-+++ etc/afpd/volume.h  21 Apr 2004 12:42:05 -0000
-@@ -81,6 +81,12 @@
-     /* adouble indirection */
-     int                 (*validupath)(const struct vol *, const char *);
-     char                *(*ad_path)(const char *, int);
-+
-+#ifdef DISABLE_LOCKING
-+    /* for OS 9 trash when there's no working byte locking (afs, nfs) */
-+    cnid_t            v_trash_id;
-+    char              *v_ip;
-+#endif    
- };
- #ifdef NO_LARGE_VOL_SUPPORT
-@@ -167,6 +173,8 @@
- #define VOLPBIT_BSIZE   11        /* block size */
-+#define TRASH_PREFIX "Trash Can #"
-+
- #define vol_noadouble(vol) (((vol)->v_flags & AFPVOL_NOADOUBLE) ? \
-                           ADFLAGS_NOADOUBLE : 0)
- #ifdef AFP3x
diff --git a/contrib/patches/patch.vfs b/contrib/patches/patch.vfs
deleted file mode 100644 (file)
index 06295d0..0000000
+++ /dev/null
@@ -1,1115 +0,0 @@
-diff -Nur vfs/Makefile vfs.new/Makefile
---- vfs/Makefile       Thu Jan  1 00:00:00 1970
-+++ vfs.new/Makefile   Mon Jul 12 10:48:56 2004
-@@ -0,0 +1,40 @@
-+##########################################################################
-+# Makefile for Samba VFS modules 
-+###########################################################################
-+
-+CC=gcc -g
-+LIBTOOL=/usr/bin/libtool
-+# REPLACE with samba source 
-+SMB=/u/redhat/paris/cvs/samba/smb3.0a20
-+
-+# REPLACE with samba build folder
-+BUILD=/mnt/hdd/build/smb.1.3
-+
-+CFLAGS=-Wall -I $(BUILD)/include \
-+-I$(SMB)/source -I$(SMB)/source/include -I$(SMB)/source/ubiqx -I$(SMB)/source/smbwrapper
-+
-+
-+LDFLAGS=-shared
-+
-+VFS_OBJS=vfs_ads.so
-+
-+SHELL=/bin/sh
-+
-+default: $(VFS_OBJS)
-+
-+# Pattern rules
-+
-+%.so: %.lo
-+      @echo Linking $<
-+      @$(LIBTOOL) --mode=link $(CC) -o $@ $< $(LDFLAGS)
-+
-+%.lo: %.c
-+      @echo Compiling $<
-+      @$(LIBTOOL) --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
-+
-+# Misc targets
-+
-+clean:
-+      rm -rf .libs */.libs
-+      rm -f core *~ *% *.bak *.o */*.o *.lo $(VFS_OBJS)
-+
-diff -Nur vfs/README vfs.new/README
---- vfs/README Thu Jan  1 00:00:00 1970
-+++ vfs.new/README     Tue Jul 13 02:28:21 2004
-@@ -0,0 +1,34 @@
-+This a vfs for NT ADS 
-+you must set SMB and BUILD variables in Makefile.
-+
-+old smb.conf
-+[test_ads]
-+   comment = test ADS Mac/PC directory
-+   path=/home/test_ads/
-+#  /.AppleD* is mandatory 
-+   veto files = /.AppleD*/Network Trash Folder/Icon\r/
-+   delete veto files = True
-+# full path to vfs_ads.so 
-+   vfs object = /usr/src/samba/vfs/vfs_ads.so
-+   browseable = yes
-+   writable = yes
-+
-+new one (current svn tree)
-+copy vfs_ads.so as ads.so in <prefix>/lib/vfs/
-+eg
-+cp vfs_ads.so /opt/lib/vfs/ads.so
-+
-+smb.conf
-+[test_ads]
-+   comment = test ADS Mac/PC directory
-+   path=/home/test_ads/
-+ 
-+#  /.AppleD* is mandatory 
-+   veto files = /.AppleD*/Network Trash Folder/Icon\r/
-+   delete veto files = True
-+   vfs objects = ads
-+   browseable = yes
-+   writable = yes
-+
-+
-+Didier
-diff -Nur vfs/vfs_ads.c vfs.new/vfs_ads.c
---- vfs/vfs_ads.c      Thu Jan  1 00:00:00 1970
-+++ vfs.new/vfs_ads.c  Wed Jul 14 16:37:15 2004
-@@ -0,0 +1,1029 @@
-+/* 
-+ * CAP VFS module for Samba 3.x Version 0.3
-+ *
-+ * Copyright (C) Tim Potter, 1999-2000
-+ * Copyright (C) Alexander Bokovoy, 2002-2003
-+ * Copyright (C) Stefan (metze) Metzmacher, 2003
-+ * Copyright (C) TAKAHASHI Motonobu (monyo), 2003
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *  
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *  
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ *
-+ * modified for alternate data stream
-+ * Copyright (C) Didier Gautheron 2004
-+ * 
-+ * this module should compile with old 3.0 API and 2004-07 svn API
-+ */
-+
-+
-+#include "includes.h"
-+
-+#undef DBGC_CLASS
-+#define DBGC_CLASS DBGC_VFS
-+
-+#define ADS_FOLDER    ".AppleDouble"
-+#define ADOUBLEMODE   0777
-+
-+/* FIXME found a better test */
-+#ifdef        SMB_VFS_OP
-+#define ADS_NEW_MODULE
-+
-+/* for current svn tree */
-+#define ADS_TALLOC_INIT(a) talloc_init(a)
-+
-+#define HANDLE_PARAMETER vfs_handle_struct *handle,
-+#define HANDLE handle,
-+
-+/* ------------------- */
-+#else
-+
-+#define ADS_TALLOC_INIT(a) talloc_init()
-+
-+#define HANDLE_PARAMETER 
-+#define HANDLE
-+
-+/* VFS operations */
-+static struct vfs_ops default_vfs_ops;   /* For passthrough operation */
-+static struct smb_vfs_handle_struct *ads_handle; 
-+
-+#define SMB_VFS_NEXT_DISK_FREE(a,b,c,d,e,f,g)       default_vfs_ops.disk_free(b,c,d,e,f,g)
-+#define SMB_VFS_NEXT_OPENDIR(a,b,c)                 default_vfs_ops.opendir(b,c)
-+#define SMB_VFS_NEXT_READDIR(a,b,c)                 default_vfs_ops.readdir(b,c)
-+#define SMB_VFS_NEXT_MKDIR(a,b,c,d)                 default_vfs_ops.mkdir(b,c,d)
-+#define SMB_VFS_NEXT_RMDIR(a,b,c)                   default_vfs_ops.rmdir(b,c)
-+#define SMB_VFS_NEXT_OPEN(a,b,c,d,e)                default_vfs_ops.open(b,c,d,e)
-+#define SMB_VFS_NEXT_RENAME(a,b,c,d)                default_vfs_ops.rename(b,c,d)
-+#define SMB_VFS_NEXT_STAT(a,b,c,d)                  default_vfs_ops.stat(b,c,d)
-+#define SMB_VFS_NEXT_LSTAT(a,b,c,d)                 default_vfs_ops.lstat(b,c,d)
-+#define SMB_VFS_NEXT_UNLINK(a,b,c)                  default_vfs_ops.unlink(b,c)
-+#define SMB_VFS_NEXT_CHMOD(a,b,c,d)                 default_vfs_ops.chmod(b,c,d)
-+#define SMB_VFS_NEXT_CHOWN(a,b,c,d,e)               default_vfs_ops.chown(b,c,d,e) 
-+#define SMB_VFS_NEXT_CHDIR(a,b,c)                   default_vfs_ops.chdir(b,c)
-+#define SMB_VFS_NEXT_UTIME(a,b,c,d)                 default_vfs_ops.utime(b,c,d)
-+#define SMB_VFS_NEXT_SYMLINK(a,b,c,d)               default_vfs_ops.symlink(b,c,d)
-+#define SMB_VFS_NEXT_READLINK(a,b,c,d,e)            default_vfs_ops.readlink(b,c,d,e)
-+#define SMB_VFS_NEXT_LINK(a,b,c,d)                  default_vfs_ops.link(b,c,d)
-+#define SMB_VFS_NEXT_MKNOD(a,b,c,d,e)               default_vfs_ops.mknod(b,c,d,e)
-+#define SMB_VFS_NEXT_REALPATH(a,b,c,d)              default_vfs_ops.realpath(b,c,d)
-+#define SMB_VFS_NEXT_SET_NT_ACL(a,b,c,d,e)          default_vfs_ops.set_nt_acl(b,c,d,e)
-+#define SMB_VFS_NEXT_CHMOD_ACL(a,b,c,d)             default_vfs_ops.chmod_acl(b,c,d)
-+#define SMB_VFS_NEXT_SYS_ACL_GET_FILE(a,b,c,d)      default_vfs_ops.sys_acl_get_file(b,c,d)
-+#define SMB_VFS_NEXT_SYS_ACL_SET_FILE(a,b,c,d,e)    default_vfs_ops.sys_acl_set_file(b,c,d,e)
-+#define SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(a,b,c) default_vfs_ops.sys_acl_delete_def_file(b,c)
-+/* ads functions */
-+
-+#endif
-+
-+/* ------------------------- 
-+ * format
-+ * .AppleDouble/filename/stream name
-+ * 
-+ * return the *LAST* '/' in path
-+ */
-+static int ads_get_path_ptr(char *path)
-+{
-+      int i   = 0;
-+      int ptr = 0;
-+      
-+      for (i = 0; path[i]; i ++) {
-+              if (path[i] == '/')
-+                      ptr = i;
-+      }
-+      
-+      return ptr;
-+}
-+
-+/* ------------------------------
-+ * return the *FIRST* ':' in path
-+*/
-+static int ads_get_stream_ptr(const char *path)
-+{
-+      int i   = 0;
-+      int ptr = 0;
-+      
-+      for (i = 0; path[i]; i ++) {
-+              if (path[i] == ':') {
-+                      ptr = i;
-+                      break;
-+              }
-+      }
-+      return ptr;
-+}
-+
-+/* ---------------- 
-+ * fname is only a filename
-+*/
-+
-+static char *ads_canonical_dir(TALLOC_CTX *ctx, const char *path, const char *fname, int isdir)
-+{
-+    if (isdir) {
-+        return talloc_asprintf(ctx, "%s/%s/%s/.Parent", path, fname, ADS_FOLDER);
-+    }
-+    return talloc_asprintf(ctx, "%s/%s/%s", path, ADS_FOLDER, fname);
-+    
-+}
-+
-+/* ---------------- 
-+ * return directory pathname for an alternate data stream
-+ * fname is *NOT* an altername name (ie foo:bar)
-+*/
-+static char *ads_dir(TALLOC_CTX *ctx, const char *path, const char *fname, int isdir)
-+{
-+    int ptr0 = 0;
-+    int ptr1 = 0;
-+    char *temp;
-+
-+#if 0
-+    if (fname[0] == '.') ptr0 ++;
-+    if (fname[1] == '/') ptr0 ++;
-+#endif    
-+    temp = talloc_asprintf(ctx, "%s/%s", path, &fname[ptr0]);
-+    ptr1 = ads_get_path_ptr(temp);
-+    temp[ptr1] = '\0';
-+    return ads_canonical_dir(ctx, temp, &temp[ptr1 + 1], isdir);
-+}
-+
-+/* ----------------------------------
-+ * build the pathname for stream, create folder if (mode & O_CREAT)
-+ * return -1 on error
-+ * 0 it's not a stream
-+ * 1 it's a stream
-+ *
-+ * main_path : file fullpathname with :$DATA removed
-+ * ads_path: unix pathname 
-+ * if it's not an ADS then main_path == ads_path
-+ *
-+ */
-+static int ads_build_paths(TALLOC_CTX *ctx, const char *path, const char *fname,
-+                              char **ads_path, char **main_path, SMB_STRUCT_STAT **main_info, int flag)
-+{
-+        int ret = 0;
-+      int ptr0 = 0;
-+      int ptr1 = 0;
-+      int ptr2 = 0;
-+      int ptr3 = 0;
-+      char *dname = 0;
-+      char *name  = 0;
-+      SMB_STRUCT_STAT ads_info;
-+
-+      if (!ctx || !path || !fname || !ads_path || !main_path || !main_info || !*main_info)
-+              return -1;
-+#if 1
-+      DEBUG(3, ("ADS: PATH: %s[%s]\n", path, fname));
-+#endif
-+      if (strstr(path, ADS_FOLDER) || strstr(fname, ADS_FOLDER)) {
-+              DEBUG(1, ("ADS: path %s[%s] already contains %s\n", path, fname, ADS_FOLDER));
-+              return -1;
-+      }
-+
-+#if 0
-+      if (fname[0] == '.') ptr0 ++;
-+      if (fname[1] == '/') ptr0 ++;
-+#endif
-+
-+      *main_path = talloc_asprintf(ctx, "%s/%s", path, &fname[ptr0]);
-+      *ads_path = NULL;
-+
-+      /* get pointer to last '/' */
-+      ptr1 = ads_get_path_ptr(*main_path);
-+      ptr2 = ads_get_stream_ptr(*main_path +ptr1 +1);
-+      /* FIXME
-+       * what about ::$DATA or :name:$DATA
-+      */
-+
-+      if (ptr2) {
-+          /* it's an alternate stream */
-+          ptr2 += ptr1 +1;
-+          (*main_path)[ptr2] = 0;
-+          ptr3 = ads_get_stream_ptr(*main_path +ptr2 +1);
-+          if (ptr3) {
-+              ptr3 += ptr2 +1;
-+              /* check it's $DATA */
-+              if (!strcmp("$DATA", &(*main_path)[ptr3+1])) {
-+                  (*main_path)[ptr3] = 0;
-+              }
-+          }
-+
-+          DEBUG(3, ("ADS: MAIN DATA %s\n", *main_path));
-+
-+          if (sys_lstat(*main_path, *main_info) < 0) {
-+              /* if we can't get the main file give up */
-+              return -1;
-+          }
-+          (*main_path)[ptr2] = ':';
-+          dname = talloc_strdup(ctx, *main_path);
-+          dname[ptr1] = '\0'; 
-+          name = *main_path;
-+          name[ptr2] = '\0';
-+          if (S_ISDIR((*main_info)->st_mode)) {
-+              *ads_path = talloc_asprintf(ctx, "%s/%s/%s/.Parent/%s", dname, &name[ptr1 + 1], ADS_FOLDER, &name[ptr2 + 1]);
-+          }
-+          else {
-+              *ads_path = talloc_asprintf(ctx, "%s/%s/%s/%s", dname, ADS_FOLDER, &name[ptr1 + 1], &name[ptr2 + 1]);
-+          }
-+          /* XXX are we always the right user ?*/
-+          if (sys_lstat(*ads_path, &ads_info) < 0) {
-+              int st_ret;
-+              /* */
-+              if (errno == ENOENT && (flag & O_CREAT))  {
-+                  char *ads_base = ads_canonical_dir(ctx, dname, &name[ptr1 + 1], S_ISDIR((*main_info)->st_mode));
-+                  mode_t mode;
-+                  
-+                  st_ret = mkdir(ads_base, 0777);
-+                  if (st_ret < 0) {
-+                      if (errno == ENOENT) {
-+                          char *ads_double;
-+                          if (S_ISDIR((*main_info)->st_mode)) {
-+                              ads_double = talloc_asprintf(ctx, "%s/%s/%s", dname, &name[ptr1 + 1], ADS_FOLDER);
-+                          }
-+                          else {
-+                              ads_double = talloc_asprintf(ctx, "%s/%s", dname, ADS_FOLDER);
-+                          }
-+                          if (mkdir(ads_double, 0777) < 0)
-+                              return -1;
-+                          if ((st_ret = mkdir(ads_base, 0777)) < 0)
-+                              return -1;
-+                          
-+                          /* we just created .AppleDouble/file/ update mode with dir search 
-+                           * XXX what about acl?
-+                          */
-+                          mode = (*main_info)->st_mode;
-+                          if ((mode & (S_IRUSR | S_IWUSR )))
-+                              mode |= S_IXUSR;
-+                          if ((mode & (S_IRGRP | S_IWGRP )))
-+                              mode |= S_IXGRP;
-+                          if ((mode & (S_IROTH | S_IWOTH ))) 
-+                              mode |= S_IXOTH;
-+                          chmod(ads_base, mode);
-+                      }
-+                      else 
-+                          errno = ENOENT;
-+                  }
-+              }
-+              else 
-+                  return -1;
-+          }
-+          ret = 1;
-+      }
-+      else {
-+          *ads_path = *main_path;
-+          if (sys_lstat(*main_path, *main_info) < 0) {
-+              *main_info = NULL;
-+          }
-+      }
-+#if 1
-+      DEBUG(3, ("ADS: DEBUG:[%s] [%s]\n", *main_path, *ads_path)); 
-+#endif
-+      return ret;
-+}
-+
-+/* ------------------------ */
-+static SMB_BIG_UINT ads_disk_free(HANDLE_PARAMETER connection_struct *conn, const char *path,
-+      BOOL small_query, SMB_BIG_UINT *bsize,
-+      SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
-+{
-+      return SMB_VFS_NEXT_DISK_FREE(handle, conn, path, small_query, bsize, dfree, dsize);
-+}
-+
-+static DIR *ads_opendir(HANDLE_PARAMETER connection_struct *conn, const char *fname)
-+{
-+      return SMB_VFS_NEXT_OPENDIR(handle, conn, fname);
-+}
-+
-+static struct dirent *ads_readdir(HANDLE_PARAMETER connection_struct *conn, DIR *dirp)
-+{
-+        struct dirent *result;
-+      DEBUG(3,("ads: ads_readdir\n"));
-+      result = SMB_VFS_NEXT_READDIR(handle, conn, dirp);
-+      if (result) {
-+        DEBUG(3,("ads: ads_readdir: %s\n", result->d_name));
-+        }
-+        return result;
-+}
-+
-+/* ------------------------- */
-+static int ads_mkdir(HANDLE_PARAMETER connection_struct *conn, const char *path, mode_t mode)
-+{
-+      return SMB_VFS_NEXT_MKDIR(handle, conn, path, mode);
-+}
-+
-+/* ------------------------- */
-+static int unlink_file(const char *path)
-+{
-+int ret = 0;
-+         
-+      become_root();
-+        ret = unlink(path);
-+        unbecome_root();
-+        return ret;
-+}
-+
-+/* ------------------------- */
-+static int unlink_folder(const char *path)
-+{
-+int ret = 0;
-+         
-+      become_root();
-+        ret = rmdir(path);
-+        unbecome_root();
-+        return ret;
-+}
-+
-+/* ------------------------- 
-+   remove all files in an AppleDouble folder
-+*/
-+static void rrmdir(TALLOC_CTX *ctx, char *path)
-+{
-+        int n;
-+        char *dpath;
-+        struct dirent **namelist;
-+ 
-+        if (!path) return;
-+ 
-+        n = scandir(path, &namelist, 0, alphasort);
-+        if (n < 0) {
-+                return;
-+        } 
-+        while (n --) {
-+              if (strcmp(namelist[n]->d_name, ".") == 0 || strcmp(namelist[n]->d_name, "..") == 0) {
-+                      free(namelist[n]);
-+                        continue;
-+                }
-+                if ((dpath = talloc_asprintf(ctx, "%s/%s",path, namelist[n]->d_name))) {
-+                      unlink_file(dpath);
-+                }
-+                free(namelist[n]);
-+        }
-+        free(namelist);
-+        unlink_folder(path);
-+}
-+
-+/* --------------------------- */
-+static void rrm_adsdir(TALLOC_CTX *ctx, char *path)
-+{
-+        int n;
-+        char *dpath;
-+        struct dirent **namelist;
-+ 
-+        if (!path) return;
-+ 
-+        n = scandir(path, &namelist, 0, alphasort);
-+        if (n < 0) {
-+                return;
-+        } 
-+        while (n --) {
-+              if (strcmp(namelist[n]->d_name, ".") == 0 || strcmp(namelist[n]->d_name, "..") == 0) {
-+                      free(namelist[n]);
-+                        continue;
-+                }
-+                if ((dpath = talloc_asprintf(ctx, "%s/%s",path, namelist[n]->d_name))) {
-+                      rrmdir(ctx, dpath);
-+                }
-+                free(namelist[n]);
-+        }
-+        free(namelist);
-+        unlink_folder(path);
-+}
-+
-+/* ------------------------- 
-+ * XXX 
-+ * if in smb.conf there's :
-+ * delete veto files = True
-+ * veto files = /.AppleD* /
-+*/
-+static int ads_rmdir( HANDLE_PARAMETER connection_struct *conn, const char *path)
-+{
-+        BOOL add = False;
-+        TALLOC_CTX *ctx = 0;
-+        char *dpath;
-+        int  ret = 0;
-+ 
-+        if (!conn || !conn->origpath || !path) goto exit_rmdir;
-+
-+      /* .AppleD* */
-+        strstr(path, ADS_FOLDER) ? (add = False) : (add = True);
-+ 
-+        if (!(ctx = ADS_TALLOC_INIT("ads_rmdir")))
-+                goto exit_rmdir;
-+ 
-+        if (!(dpath = talloc_asprintf(ctx, "%s/%s%s",conn->origpath, path, add ? "/"ADS_FOLDER : "")))
-+              goto exit_rmdir;
-+              
-+      /* remove folder .AppleDouble */
-+        rrm_adsdir(ctx, dpath);
-+ 
-+exit_rmdir:
-+      ret = SMB_VFS_NEXT_RMDIR(handle, conn, path);
-+        talloc_destroy(ctx);
-+
-+      return ret;
-+}
-+
-+/* ------------------------- */
-+static int ads_open(HANDLE_PARAMETER connection_struct *conn, const char *fname, int flags, mode_t mode)
-+{
-+      int ret = 0;
-+      char *ads_path = 0;
-+      char *main_path = 0;
-+      TALLOC_CTX *ctx;
-+      SMB_STRUCT_STAT st;
-+      SMB_STRUCT_STAT *main_info = &st;
-+      
-+      DEBUG(3,("ads: ads_open for %s %x\n", fname, flags));
-+      if (!(ctx = ADS_TALLOC_INIT("ads_open")))
-+              return -1;
-+      /* convert to */
-+      if (ads_build_paths(ctx, conn->origpath, fname, &ads_path, &main_path, &main_info, flags) < 0) {
-+          talloc_destroy(ctx);
-+          return -1;
-+      }
-+
-+      ret = SMB_VFS_NEXT_OPEN(handle, conn, ads_path, flags, mode);
-+      talloc_destroy(ctx);
-+      return ret;
-+
-+}
-+
-+static int isDir(SMB_STRUCT_STAT *st)
-+{
-+     if (st == NULL) {
-+         return 0;
-+     }
-+     return S_ISDIR(st->st_mode);
-+}
-+
-+/* ------------------------- */
-+static int ads_rename(HANDLE_PARAMETER connection_struct *conn, const char *old, const char *new)
-+{
-+      int ret = 0;
-+      TALLOC_CTX *ctx;
-+      char *ads_path = 0;
-+      char *main_path = 0;
-+      SMB_STRUCT_STAT st;
-+      SMB_STRUCT_STAT *main_info = &st;
-+      
-+      DEBUG(3,("ads: ads_rename %s --> %sx\n", old, new));
-+      
-+      if (!(ctx = ADS_TALLOC_INIT("ads_rename")))
-+          return -1;
-+
-+      if (ads_build_paths(ctx, conn->origpath, old, &ads_path, &main_path, &main_info, 0) < 0) {
-+          talloc_destroy(ctx);
-+          return -1;
-+      }
-+
-+      if (ads_path != main_path) {
-+          /* you can't rename an ads ! */
-+          talloc_destroy(ctx);
-+          errno = EINVAL;
-+          return -1;
-+      }
-+
-+      ret = SMB_VFS_NEXT_RENAME(handle, conn, old, new);
-+      if (!ret && !isDir(main_info)) {
-+          int  ptr1;
-+          int  ptr2;
-+          
-+          char *ads_old  = ads_dir(ctx, conn->origpath, old, 0);
-+          char *ads_new  = ads_dir(ctx, conn->origpath, new, 0);
-+
-+          /* is dest folder .Adouble there ? */
-+          ptr1 = ads_get_path_ptr(ads_new);
-+          ptr2 = ads_get_path_ptr(ads_old);
-+
-+          ads_new[ptr1] = '\0';
-+          ads_old[ptr2] = '\0';
-+          if (strcmp(ads_new, ads_old)) {
-+              mkdir(ads_new, 0777);
-+          }
-+
-+          ads_new[ptr1] = '/';
-+          ads_old[ptr2] = '/';
-+          
-+          SMB_VFS_NEXT_RENAME(handle, conn, ads_old, ads_new);
-+      }
-+
-+      talloc_destroy(ctx);
-+      return ret;
-+}
-+
-+/* ------------------------- 
-+ * For an ADS what do we need to return , ADS ? main DATA?
-+*/
-+static int ads_stat(HANDLE_PARAMETER connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf)
-+{
-+      int ret = 0;
-+      char *ads_path = 0;
-+      char *main_path = 0;
-+      TALLOC_CTX *ctx;
-+      SMB_STRUCT_STAT st;
-+      SMB_STRUCT_STAT *main_info = &st;
-+
-+      DEBUG(3,("ads: ads_stat for %s\n", fname));
-+
-+      if (!(ctx = ADS_TALLOC_INIT("ads_stat")))
-+          return -1;
-+      /* which inode ?
-+      */
-+      if (ads_build_paths(ctx, conn->origpath, fname, &ads_path, &main_path, &main_info, 0) < 0) {
-+          talloc_destroy(ctx);
-+          return -1;
-+      }
-+
-+      ret = SMB_VFS_NEXT_STAT(handle, conn, ads_path, sbuf);
-+      talloc_destroy(ctx);
-+      return ret;
-+}
-+
-+/* ------------------------- */
-+static int ads_lstat(HANDLE_PARAMETER connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf)
-+{
-+      int ret = 0;
-+      char *ads_path = 0;
-+      char *main_path = 0;
-+      TALLOC_CTX *ctx;
-+      SMB_STRUCT_STAT st;
-+      SMB_STRUCT_STAT *main_info = &st;
-+      
-+      if (!(ctx = ADS_TALLOC_INIT("ads_lstat")))
-+              return -1;
-+      /* which inode ?
-+      */
-+      if (ads_build_paths(ctx, conn->origpath, path, &ads_path, &main_path, &main_info, 0) < 0) {
-+          talloc_destroy(ctx);
-+          return -1;
-+      }
-+
-+      return SMB_VFS_NEXT_LSTAT(handle, conn, ads_path, sbuf);
-+      talloc_destroy(ctx);
-+      return ret;
-+}
-+
-+/* ------------------------- */
-+static int ads_unlink(HANDLE_PARAMETER connection_struct *conn, const char *path)
-+{
-+      int ret = 0;
-+
-+      char *ads_path = 0;
-+      char *main_path = 0;
-+      TALLOC_CTX *ctx;
-+      SMB_STRUCT_STAT st;
-+      SMB_STRUCT_STAT *main_info = &st;
-+      
-+      DEBUG(3,("ads: ads_unlink %s\n", path));
-+      if (!(ctx = ADS_TALLOC_INIT("ads_unlink")))
-+              return -1;
-+
-+      if (ads_build_paths(ctx, conn->origpath, path, &ads_path, &main_path, &main_info, 0) < 0) {
-+          talloc_destroy(ctx);
-+          return -1;
-+      }
-+
-+      ret = SMB_VFS_NEXT_UNLINK(handle, conn, ads_path);
-+      /*
-+         if data stream
-+            for each stream
-+                unlink
-+      */
-+      if (!ret && ads_path == main_path) {
-+          char *ads_base  = ads_dir(ctx, conn->origpath, path, isDir(main_info));
-+          struct dirent *dent = 0;
-+          DIR *dir = opendir(ads_base);
-+          
-+          if (dir) {
-+              char *dpath;
-+              
-+              while (NULL != (dent = readdir(dir))) {
-+                  if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0)
-+                      continue;
-+                  if (!(dpath = talloc_asprintf(ctx, "%s/%s", ads_base, dent->d_name)))
-+                      continue;
-+                  /* XXX need to be root ?  */
-+                  SMB_VFS_NEXT_UNLINK(handle, conn, dpath);               
-+              }
-+              closedir(dir);
-+              rmdir(ads_base);
-+          }
-+      }
-+
-+      talloc_destroy(ctx);
-+      return ret;
-+}
-+
-+/* ------------------------- */
-+static int ads_chmod(HANDLE_PARAMETER connection_struct *conn, const char *path, mode_t mode)
-+{
-+      int ret = 0;
-+      char *ads_path = 0;
-+      char *main_path = 0;
-+      TALLOC_CTX *ctx;
-+      SMB_STRUCT_STAT st;
-+      SMB_STRUCT_STAT *main_info = &st;
-+
-+      DEBUG(3,("ads: ads_chmod %s\n", path));
-+      /* if stream 
-+             error ?, change only the stream
-+      */
-+      if (!(ctx = ADS_TALLOC_INIT("ads_chmod")))
-+              return -1;
-+
-+      if (ads_build_paths(ctx, conn->origpath, path, &ads_path, &main_path, &main_info, 0) < 0) {
-+          talloc_destroy(ctx);
-+          return -1;
-+      }
-+
-+      ret = SMB_VFS_NEXT_CHMOD(handle, conn, ads_path, mode);
-+      /*
-+         if data stream
-+            for each stream
-+                chmod
-+      */
-+      if (!ret && ads_path == main_path) {
-+          char *ads_base  = ads_dir(ctx, conn->origpath, path, isDir(main_info));
-+          struct dirent *dent = 0;
-+          DIR *dir = opendir(ads_base);
-+          
-+          if (dir) {
-+              char *dpath;
-+              
-+              while (NULL != (dent = readdir(dir))) {
-+                  if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0)
-+                      continue;
-+                  if (!(dpath = talloc_asprintf(ctx, "%s/%s", ads_base, dent->d_name)))
-+                      continue;
-+                  /* XXX need to be root ? */
-+                  SMB_VFS_NEXT_CHMOD(handle, conn, dpath, mode);
-+              }
-+              closedir(dir);
-+              /* XXX need to change ads_base too*/
-+          }
-+      }
-+
-+      talloc_destroy(ctx);
-+      return ret;
-+}
-+
-+/* ------------------------- */
-+static int ads_chown(HANDLE_PARAMETER connection_struct *conn, const char *path, uid_t uid, gid_t gid)
-+{
-+      int ret = 0;
-+      char *ads_path = 0;
-+      char *main_path = 0;
-+      TALLOC_CTX *ctx;
-+      SMB_STRUCT_STAT st;
-+      SMB_STRUCT_STAT *main_info = &st;
-+
-+      DEBUG(3,("ads: ads_chown %s\n", path));
-+      /* if stream 
-+             error ?, change only the stream
-+      */
-+      if (!(ctx = ADS_TALLOC_INIT("ads_chown")))
-+              return -1;
-+
-+      if (ads_build_paths(ctx, conn->origpath, path, &ads_path, &main_path, &main_info, 0) < 0) {
-+          talloc_destroy(ctx);
-+          return -1;
-+      }
-+
-+      ret = SMB_VFS_NEXT_CHOWN(handle, conn, ads_path, uid, gid);
-+      /* if data stream
-+            for each stream
-+                chmod
-+      */
-+      if (!ret && ads_path == main_path) {
-+          char *ads_base  = ads_dir(ctx, conn->origpath, path, isDir(main_info));
-+          struct dirent *dent = 0;
-+          DIR *dir = opendir(ads_base);
-+          
-+          if (dir) {
-+              char *dpath;
-+              
-+              while (NULL != (dent = readdir(dir))) {
-+                  if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0)
-+                      continue;
-+                  if (!(dpath = talloc_asprintf(ctx, "%s/%s", ads_base, dent->d_name)))
-+                      continue;
-+                  /* XXX need to be root ?, what do we do in case of error? */
-+                  SMB_VFS_NEXT_CHOWN(handle, conn, dpath, uid, gid);
-+              }
-+              closedir(dir);
-+              SMB_VFS_NEXT_CHOWN(handle, conn, ads_path, uid, gid);
-+          }
-+      }
-+
-+      talloc_destroy(ctx);
-+      return ret;
-+}
-+
-+/* ------------------------- */
-+static int ads_chdir(HANDLE_PARAMETER connection_struct *conn, const char *path)
-+{
-+      DEBUG(3,("ads: ads_chdir for %s\n", path));
-+      return SMB_VFS_NEXT_CHDIR(handle, conn, path);
-+}
-+
-+static int ads_utime(HANDLE_PARAMETER connection_struct *conn, const char *path, struct utimbuf *times)
-+{
-+      return SMB_VFS_NEXT_UTIME(handle, conn, path, times);
-+}
-+
-+
-+static BOOL ads_symlink(HANDLE_PARAMETER connection_struct *conn, const char *oldpath, const char *newpath)
-+{
-+      return SMB_VFS_NEXT_SYMLINK(handle, conn, oldpath, newpath);
-+}
-+
-+static BOOL ads_readlink(HANDLE_PARAMETER connection_struct *conn, const char *path, char *buf, size_t bufsiz)
-+{
-+      return SMB_VFS_NEXT_READLINK(handle, conn, path, buf, bufsiz);
-+}
-+
-+static int ads_link( HANDLE_PARAMETER connection_struct *conn, const char *oldpath, const char *newpath)
-+{
-+      return SMB_VFS_NEXT_LINK(handle, conn, oldpath, newpath);
-+}
-+
-+static int ads_mknod(HANDLE_PARAMETER connection_struct *conn, const char *path, mode_t mode, SMB_DEV_T dev)
-+{
-+      return SMB_VFS_NEXT_MKNOD(handle, conn, path, mode, dev);
-+}
-+
-+static char *ads_realpath(HANDLE_PARAMETER connection_struct *conn, const char *path, char *resolved_path)
-+{
-+      return SMB_VFS_NEXT_REALPATH(handle, conn, path, resolved_path);
-+}
-+
-+static BOOL ads_set_nt_acl(HANDLE_PARAMETER files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor_info *psd)
-+{
-+      return SMB_VFS_NEXT_SET_NT_ACL(handle, fsp, name, security_info_sent, psd);
-+}
-+
-+static int ads_chmod_acl(HANDLE_PARAMETER connection_struct *conn, const char *name, mode_t mode)
-+{
-+      /* If the underlying VFS doesn't have ACL support... */
-+#ifdef ADS_NEW_MODULE
-+        if (!handle->vfs_next.ops.chmod_acl) {                                                                          
-+#else
-+      if (!default_vfs_ops.chmod_acl) {
-+#endif
-+              errno = ENOSYS;
-+              return -1;
-+      }
-+      return SMB_VFS_NEXT_CHMOD_ACL(handle, conn, name, mode);
-+}
-+
-+static SMB_ACL_T ads_sys_acl_get_file(HANDLE_PARAMETER connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type)
-+{
-+      return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, conn, path_p, type);
-+}
-+
-+static int ads_sys_acl_set_file(HANDLE_PARAMETER connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
-+{
-+      return SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, conn, name, acltype, theacl);
-+}
-+
-+static int ads_sys_acl_delete_def_file(HANDLE_PARAMETER connection_struct *conn, const char *path)
-+{
-+      return SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, conn, path);
-+}
-+
-+#ifdef        ADS_NEW_MODULE 
-+static ssize_t ads_getxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, void *value, size_t size)
-+{
-+        return SMB_VFS_NEXT_GETXATTR(handle, conn, path, name, value, size);
-+}
-+
-+static ssize_t ads_lgetxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, void *value, size_t
-+size)
-+{
-+        return SMB_VFS_NEXT_LGETXATTR(handle, conn, path, name, value, size);
-+}
-+
-+static ssize_t ads_fgetxattr(vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size)
-+{
-+        return SMB_VFS_NEXT_FGETXATTR(handle, fsp, fd, name, value, size);
-+}
-+
-+static ssize_t ads_listxattr(vfs_handle_struct *handle, connection_struct *conn,const char *path, char *list, size_t size)
-+{
-+        return SMB_VFS_NEXT_LISTXATTR(handle, conn, path, list, size);
-+}
-+
-+static ssize_t ads_llistxattr(vfs_handle_struct *handle,struct connection_struct *conn,const char *path, char *list, size_t size)
-+{
-+        return SMB_VFS_NEXT_LLISTXATTR(handle, conn, path, list, size);
-+}
-+
-+static int ads_removexattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name)
-+{
-+        return SMB_VFS_NEXT_REMOVEXATTR(handle, conn, path, name);
-+}
-+
-+static int ads_lremovexattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name)
-+{
-+        return SMB_VFS_NEXT_LREMOVEXATTR(handle, conn, path, name);
-+}
-+
-+static int ads_fremovexattr(vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name)
-+{
-+        return SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, fd, name);
-+}
-+
-+static int ads_setxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags)
-+{
-+        return SMB_VFS_NEXT_SETXATTR(handle, conn, path, name, value, size, flags);
-+}
-+
-+static int ads_lsetxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags)
-+{
-+        return SMB_VFS_NEXT_LSETXATTR(handle, conn, path, name, value, size, flags);
-+}
-+
-+static int ads_fsetxattr(vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, const void *value, size_t size, int flags)
-+{
-+        return SMB_VFS_NEXT_FSETXATTR(handle, fsp, fd, name, value, size, flags);
-+}
-+
-+#endif
-+
-+/* ---------------------------------- 
-+ * enumerate 
-+*/
-+static ssize_t ads_listads(HANDLE_PARAMETER struct connection_struct *conn,const char *path, char *list, size_t size)
-+{
-+      char *ads_path = 0;
-+      char *main_path = 0;
-+      TALLOC_CTX *ctx;
-+      size_t     len, total = 0;
-+      SMB_STRUCT_STAT st;
-+      SMB_STRUCT_STAT *main_info = &st;
-+      
-+
-+      if (!list || !path) {
-+              /* aka we have ads functionnality */
-+              return 0;
-+      }
-+
-+      DEBUG(3,("ads: ads_listads %s\n", path));
-+
-+      if (!(ctx = ADS_TALLOC_INIT("ads_listads")))
-+              return -1;
-+
-+      if (ads_build_paths(ctx, conn->origpath, path, &ads_path, &main_path, &main_info, 0) < 0) {
-+          talloc_destroy(ctx);
-+          return -1;
-+      }
-+
-+      /*
-+         if data stream
-+            for each stream
-+      */
-+      if (ads_path == main_path) {
-+          char *ads_base  = ads_dir(ctx, conn->origpath, path, isDir(main_info));
-+          struct dirent *dent = 0;
-+          DIR *dir = opendir(ads_base);
-+          
-+          /* XXX need to be root ? */
-+          if (dir) {
-+              
-+              while (NULL != (dent = readdir(dir))) {
-+                  if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0)
-+                      continue;
-+                  len = strlen(dent->d_name) +8 ;
-+                  total += len;
-+                  if (total >= size) {
-+                      talloc_destroy(ctx);
-+                      errno = ERANGE;
-+                      return -1;
-+                  }
-+                  snprintf (list, len, ":%s:$DATA", dent->d_name);
-+                  list += len;
-+              }
-+              closedir(dir);
-+          }
-+      }
-+
-+      talloc_destroy(ctx);
-+      return total;
-+}
-+
-+/* ------------------------------------
-+ * VFS operations structure */
-+
-+#ifndef SMB_VFS_OP
-+#define SMB_VFS_OP(x) ((void *) x)  
-+#endif
-+
-+static vfs_op_tuple ads_op_tuples[] = {
-+
-+      /* Disk operations */
-+
-+      {SMB_VFS_OP(ads_disk_free),                     SMB_VFS_OP_DISK_FREE,           SMB_VFS_LAYER_TRANSPARENT},
-+      
-+      /* Directory operations */
-+
-+      {SMB_VFS_OP(ads_opendir),                       SMB_VFS_OP_OPENDIR,             SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_readdir),                       SMB_VFS_OP_READDIR,             SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_mkdir),                         SMB_VFS_OP_MKDIR,               SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_rmdir),                         SMB_VFS_OP_RMDIR,               SMB_VFS_LAYER_TRANSPARENT},
-+
-+      /* File operations */
-+
-+      {SMB_VFS_OP(ads_open),                          SMB_VFS_OP_OPEN,                SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_rename),                        SMB_VFS_OP_RENAME,              SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_stat),                          SMB_VFS_OP_STAT,                SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_lstat),                         SMB_VFS_OP_LSTAT,               SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_unlink),                        SMB_VFS_OP_UNLINK,              SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_chmod),                         SMB_VFS_OP_CHMOD,               SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_chown),                         SMB_VFS_OP_CHOWN,               SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_chdir),                         SMB_VFS_OP_CHDIR,               SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_utime),                         SMB_VFS_OP_UTIME,               SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_symlink),                       SMB_VFS_OP_SYMLINK,             SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_readlink),                      SMB_VFS_OP_READLINK,            SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_link),                          SMB_VFS_OP_LINK,                SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_mknod),                         SMB_VFS_OP_MKNOD,               SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_realpath),                      SMB_VFS_OP_REALPATH,            SMB_VFS_LAYER_TRANSPARENT},
-+
-+      /* NT File ACL operations */
-+
-+      {SMB_VFS_OP(ads_set_nt_acl),                    SMB_VFS_OP_SET_NT_ACL,          SMB_VFS_LAYER_TRANSPARENT},
-+
-+      /* POSIX ACL operations */
-+
-+      {SMB_VFS_OP(ads_chmod_acl),                     SMB_VFS_OP_CHMOD_ACL,           SMB_VFS_LAYER_TRANSPARENT},
-+
-+      {SMB_VFS_OP(ads_sys_acl_get_file),              SMB_VFS_OP_SYS_ACL_GET_FILE,            SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_sys_acl_set_file),              SMB_VFS_OP_SYS_ACL_SET_FILE,            SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_sys_acl_delete_def_file),       SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,     SMB_VFS_LAYER_TRANSPARENT},
-+#ifdef        ADS_NEW_MODULE
-+      /* EA operations. */
-+      {SMB_VFS_OP(ads_getxattr),                      SMB_VFS_OP_GETXATTR,                    SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_lgetxattr),                     SMB_VFS_OP_LGETXATTR,                   SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_fgetxattr),                     SMB_VFS_OP_FGETXATTR,                   SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_listxattr),                     SMB_VFS_OP_LISTXATTR,                   SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_llistxattr),                    SMB_VFS_OP_LLISTXATTR,                  SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_removexattr),                   SMB_VFS_OP_REMOVEXATTR,                 SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_lremovexattr),                  SMB_VFS_OP_LREMOVEXATTR,                SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_fremovexattr),                  SMB_VFS_OP_FREMOVEXATTR,                SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_setxattr),                      SMB_VFS_OP_SETXATTR,                    SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_lsetxattr),                     SMB_VFS_OP_LSETXATTR,                   SMB_VFS_LAYER_TRANSPARENT},
-+      {SMB_VFS_OP(ads_fsetxattr),                     SMB_VFS_OP_FSETXATTR,                   SMB_VFS_LAYER_TRANSPARENT},
-+#endif
-+      /* ADS operations */
-+      {SMB_VFS_OP(ads_listads),                       SMB_VFS_OP_LISTADS,                     SMB_VFS_LAYER_TRANSPARENT},
-+
-+      {NULL,                                          SMB_VFS_OP_NOOP,                        SMB_VFS_LAYER_NOOP}
-+};
-+
-+#ifdef ADS_NEW_MODULE
-+
-+#if 0
-+NTSTATUS vfs_ads_init(void)
-+{
-+        return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "ads", ads_op_tuples);
-+}
-+#endif
-+
-+NTSTATUS vfs_ads_init(void)
-+{
-+        DEBUG(3, ("ADS: vfs_ads_init\n"));
-+        return NT_STATUS_OK;
-+}
-+         
-+
-+NTSTATUS init_module(void)
-+{
-+      DEBUG(3, ("ADS: init_module\n" ));
-+        return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "ads", ads_op_tuples);
-+}
-+
-+#else
-+/* VFS initialisation function.  Return vfs_op_tuple array back to SAMBA. */
-+vfs_op_tuple *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops,struct smb_vfs_handle_struct *vfs_handle)
-+{
-+      *vfs_version = SMB_VFS_INTERFACE_VERSION;
-+        memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
-+                   
-+        ads_handle = vfs_handle;
-+        DEBUG(3, ("ADS: vfs module loaded\n"));
-+        return ads_op_tuples;
-+}
-+                                             
-+/* VFS finalization function. */
-+void vfs_done(connection_struct *conn)
-+{
-+      DEBUG(3, ("ADS: vfs module unloaded\n"));
-+}
-+
-+#endif
diff --git a/contrib/permtest/add_permtest.patch b/contrib/permtest/add_permtest.patch
deleted file mode 100644 (file)
index 6fdf38c..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-Index: configure.in
-===================================================================
-RCS file: /cvsroot/netatalk/netatalk/configure.in,v
-retrieving revision 1.205
-diff -u -w -b -r1.205 configure.in
---- configure.in       9 Sep 2006 04:30:01 -0000       1.205
-+++ configure.in       25 Jul 2008 13:48:05 -0000
-@@ -1053,6 +1053,7 @@
-       contrib/shell_utils/apple_rm
-       contrib/shell_utils/asip-status.pl
-       contrib/shell_utils/cleanappledouble.pl
-+      contrib/shell_utils/permtest.pl
-       contrib/timelord/Makefile
-       contrib/a2boot/Makefile
-       distrib/Makefile
-Index: contrib/shell_utils/Makefile.am
-===================================================================
-RCS file: /cvsroot/netatalk/netatalk/contrib/shell_utils/Makefile.am,v
-retrieving revision 1.16
-diff -u -w -b -r1.16 Makefile.am
---- contrib/shell_utils/Makefile.am    28 Apr 2005 20:49:36 -0000      1.16
-+++ contrib/shell_utils/Makefile.am    25 Jul 2008 13:48:05 -0000
-@@ -9,6 +9,9 @@
-       apple_cp apple_mv apple_rm      \
-       cleanappledouble.pl             \
-       asip-status.pl
-+EXTRASCRIPTS = \
-+      permtest.pl \
-+      permtest.cfg
- SUFFIXES = .tmpl .
-@@ -22,4 +25,4 @@
- bin_SCRIPTS = $(PERLSCRIPTS) $(GENERATED_FILES)
--EXTRA_DIST = $(PERLSCRIPTS) $(TEMPLATE_FILES)
-+EXTRA_DIST = $(PERLSCRIPTS) $(TEMPLATE_FILES) $(EXTRASCRIPTS)
diff --git a/contrib/permtest/permtest.cfg b/contrib/permtest/permtest.cfg
deleted file mode 100644 (file)
index 941d4e6..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# Exactly follow this layout! Don't put extra white space in config lines !!
-# Order doesn't matter.
-
-# We use a ssh executed stat command to verify uid,gid and mode. Therefore ssh access with
-# PKI authentication must be setup and working!
-sshLogin = USER@HOST
-
-# self explaining
-mountAFPVolume = afp://USER:PASSWORD@HOST/VOLUME
-
-# These files will be created
-createFile = PATH_TO_FILE_ON_CLIENT
-
-# These files will be stat'ed. You can use different server-side paths here for files
-# created with "createFile" directive
-testFile = PATH_TO_FILE_ON_SERVER,user=USERNAME,group=GROUPNAME,mode=MODE
-
-# These dirs will be created
-createDir = PATH_TO_DIR_ON_CLIENT
-
-# These will be verified.
-testDir = PATH_TO_DIR_ON_CLIENT,user=USERNAME,group=GROUPNAME,mode=MODE
-
-# EOF. Leave this as a last line. We delibaretly chop in perl which might otherwise truncate
-# your last "testDir" definition.
\ No newline at end of file
diff --git a/contrib/permtest/permtest.pl.in b/contrib/permtest/permtest.pl.in
deleted file mode 100755 (executable)
index 87de19a..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-#!@PERL@ -w
-
-###########################################################################
-#
-# Characterization testing netatalks permission model
-#
-# (c) 2008 by Frank Lahm <franklahm@googlemail.com>
-#
-#   This program is free software; you can redistribute it and/or modify
-#   it under the terms of the GNU General Public License as published by
-#   the Free Software Foundation; either version 2 of the License, or
-#   (at your option) any later version.
-# 
-#   This program is distributed in the hope that it will be useful,
-#   but WITHOUT ANY WARRANTY; without even the implied warranty of
-#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#   GNU General Public License for more details.
-# 
-###########################################################################
-
-###########################################################################
-#
-# Usage:
-#
-#  "permtest.cfg" must be in your CWD. Must be run on a OS X host. Tested
-#  with 10.4.11. Uses Applescript through system("osascript ...") to mount
-#  AFP Volumes. Uses `ssh LOGIN@HOST stat FILE|DIR`. Therefor PKI
-#  authentication must be setup and working!
-#  See "permtest.cfg" for more details, it's pretty much self-explaining.
-# 
-###########################################################################
-
-use strict;
-
-my $DEBUG = 0;
-
-###########################################################################
-
-sub parseConfig;
-sub mountAPFVols;
-sub createTestFiles;
-sub createTestDirs;
-sub verifyTestFiles;
-sub verifyTestDirs;
-sub unmountAfp;
-
-my ($sshLogin, $sshResult, %sshStat, @AFPVols, @createFiles, @createDirs, @testFiles, @testDirs);
-my ($dir, $file, $user, $group, $perms, $mode, $cmd);
-
-parseConfig();
-mountAPFVols();
-createTestFiles();
-createTestDirs();
-print "\n";
-verifyTestFiles();
-verifyTestDirs();
-unmountAfp();
-
-exit 0;
-
-###########################################################################
-
-# parse config file
-sub parseConfig
-{
-       open CFG, "permtest.cfg" or die "Config file not found!";
-       while (<CFG>) {
-               chop;
-           if (/^#/) { next; };
-           if (/^sshLogin/) {
-                       $sshLogin = $_;
-                       $sshLogin =~ s/^sshLogin ?= ?// ;
-                       next;
-               }
-               if (/^mountAFPVolume/) {
-                       s/^mountAFPVolume ?= ?// ;
-                       print "Found AFP Volume Definition \"$_\"\n" if $DEBUG;
-                       push @AFPVols, $_;
-                       next;
-               }
-           if (/^createFile/) {
-                       s/^createFile ?= ?// ;
-                       push @createFiles, $_;
-                       next;
-               }
-               if (/^createDir/) {
-                       s/^createDir ?= ?// ;
-                       push @createDirs, $_;
-                       next;
-               }
-               if (/^testFile/) {
-                       push @testFiles, $_;
-                       next;
-               }
-               if (/^testDir/) {
-                       push @testDirs, $_;
-                       next;
-               }
-       }
-       close CFG;
-}
-
-# mount AFP Volumes
-sub mountAPFVols
-{
-       foreach (@AFPVols) {
-               print "Mounting AFP Volume \"$_\"\n";
-               $cmd = "osascript -e 'tell application \"Finder\"' -e 'mount volume \"$_\"' -e 'end tell' &> /dev/null";
-               print "Going to run the following Applescript:\n" . $cmd . "\n\n" if $DEBUG;
-               system($cmd);
-               if ($? != 0) { die "Error mounting \"$_\"\n"; }
-       }
-}
-
-# Create test files
-sub createTestFiles
-{
-       foreach (@createFiles) {
-               s/^createFile ?= ?// ;
-               system("rm \"$_\" &> /dev/null");
-               print "Creating file: \"$_\"\n";
-               system("touch \"$_\"");
-               if ($? != 0) { die "Error creating file \"$_\"\n"; }
-       }
-}
-
-# Create test dirs
-sub createTestDirs
-{
-       foreach (@createDirs) {
-               s/^createDir ?= ?// ;
-               system("rmdir \"$_\" &> /dev/null");
-               print "Creating dir: \"$_\"\n";
-               system("mkdir \"$_\"");
-               if ($? != 0) { die "Error creating dir \"$_\"\n"; }
-       }
-}
-
-# Verify files and dirs
-sub verifyTestFiles
-{
-       foreach (@testFiles) {
-               my @line = split(",");
-               foreach (@line) {
-                       if (/^testFile/) {
-                               $file = $_;
-                               $file =~ s/^testFile ?= ?//;
-                       }
-                       elsif (/^user/) {
-                               $user = $_;
-                               $user =~ s/^user ?= ?//;
-                       }
-                       elsif (/^group/) {
-                               $group = $_;
-                               $group =~ s/^group ?= ?//;
-                       }
-                       elsif (/^mode/) {
-                               $mode = $_;
-                               $mode =~ s/^mode ?= ?//;
-                       }
-               } # foreach (@elems)
-               print "File: $file, User: $user, Group: $group, Perms: $perms\n" if $DEBUG;
-       
-               $sshResult = `ssh $sshLogin stat -c \"user,%U,group,%G,mode,0%a\" \"$file\"`;
-               if ($? != 0) { die "Error stat'ing file \"$file\"\n"; }
-               chop $sshResult;
-               print "ssh stat $file gave us: $sshResult\n" if $DEBUG;
-       
-               %sshStat = split(",", $sshResult);
-               if ( ($sshStat{user} ne $user) or ($sshStat{group} ne $group) or ($sshStat{mode} ne $mode) ) {
-                       print "Creatin error for: \"$file\"!\nExpected:\t$user, $group, $mode.\nGot:\t\t$sshStat{user}, $sshStat{group}, $sshStat{mode}.\n\n";
-               }
-               system("rm \"$file\"");
-               if ($? != 0) { die "Couldn't delete \"$file\"\n"; }
-       }
-}
-
-sub verifyTestDirs
-{
-       foreach (@testDirs) {
-               my @line = split(",");
-               foreach (@line) {
-                       if (/^testDir/) {
-                               $dir = $_;
-                               $dir =~ s/^testDir ?= ?//;
-                       }
-                       elsif (/^user/) {
-                               $user = $_;
-                               $user =~ s/^user ?= ?//;
-                       }
-                       elsif (/^group/) {
-                               $group = $_;
-                               $group =~ s/^group ?= ?//;
-                       }
-                       elsif (/^mode/) {
-                               $mode = $_;
-                               $mode =~ s/^mode ?= ?//;
-                       }
-               } # foreach (@elems)
-               print "Dir: $dir, User: $user, Group: $group, Perms: $perms\n" if $DEBUG;
-       
-               $sshResult = `ssh $sshLogin stat -c \"user,%U,group,%G,mode,0%a\" \"$dir\"`;
-               if ($? != 0) { die "Error stat'ing file \"$dir\"\n"; }
-               chop $sshResult;
-               print "ssh stat $dir gave us: $sshResult\n" if $DEBUG;
-       
-               %sshStat = split(",", $sshResult);
-               if ( ($sshStat{user} ne $user) or ($sshStat{group} ne $group) or ($sshStat{mode} ne $mode) ) {
-                       print "Creatin error for: \"$dir\"!\nExpected:\t$user, $group, $mode.\nGot:\t\t$sshStat{user}, $sshStat{group}, $sshStat{mode}.\n\n";
-               }
-               system("rmdir \"$dir\""); if ($? != 0) { die "Couldn't delete \"$dir\"\n"; }
-       }
-}
-
-sub unmountAfp
-{
-       foreach (@AFPVols) {
-               print "Goint to eject Volume \"$_\"\n";
-               s#^(.*/)## ;
-               $cmd = "osascript -e 'tell application \"Finder\"' -e 'eject \"$_\"' -e 'end tell' &> /dev/null";
-               print "Going to run the following Applescript:\n" . $cmd . "\n\n" if $DEBUG;
-               system($cmd);
-       }
-}