From f83562711551ac01e345fb3b6d80958ad925a4ba Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Thu, 8 Jul 2010 08:14:59 +0200 Subject: [PATCH] Cleanup contrib --- contrib/patches/patch.afp_vfs | 1678 ------------------- contrib/patches/patch.mangled_trash_with_ip | 252 --- contrib/patches/patch.vfs | 1115 ------------ contrib/permtest/add_permtest.patch | 38 - contrib/permtest/permtest.cfg | 25 - contrib/permtest/permtest.pl.in | 224 --- 6 files changed, 3332 deletions(-) delete mode 100644 contrib/patches/patch.afp_vfs delete mode 100644 contrib/patches/patch.mangled_trash_with_ip delete mode 100644 contrib/patches/patch.vfs delete mode 100644 contrib/permtest/add_permtest.patch delete mode 100644 contrib/permtest/permtest.cfg delete mode 100755 contrib/permtest/permtest.pl.in diff --git a/contrib/patches/patch.afp_vfs b/contrib/patches/patch.afp_vfs deleted file mode 100644 index f2c08ee8..00000000 --- a/contrib/patches/patch.afp_vfs +++ /dev/null @@ -1,1678 +0,0 @@ -First try for a netatalk vfs layer - -current schemes -adouble=v1,v2 classic adouble format -adouble=osx ._ 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 -+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<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 -+#endif -+ -+#include -+ -+#include -+#include -+#include -+ -+#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, ¶m, 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, ¶m, 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 index 38976fcd..00000000 --- a/contrib/patches/patch.mangled_trash_with_ip +++ /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.." -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 index 06295d07..00000000 --- a/contrib/patches/patch.vfs +++ /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 /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 index 6fdf38c1..00000000 --- a/contrib/permtest/add_permtest.patch +++ /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 index 941d4e62..00000000 --- a/contrib/permtest/permtest.cfg +++ /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 index 87de19a0..00000000 --- a/contrib/permtest/permtest.pl.in +++ /dev/null @@ -1,224 +0,0 @@ -#!@PERL@ -w - -########################################################################### -# -# Characterization testing netatalks permission model -# -# (c) 2008 by Frank Lahm -# -# 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 () { - 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); - } -} -- 2.39.2