]> arthur.barton.de Git - netatalk.git/commitdiff
add osx like resource fork.
authordidg <didg>
Thu, 11 Mar 2004 02:01:59 +0000 (02:01 +0000)
committerdidg <didg>
Thu, 11 Mar 2004 02:01:59 +0000 (02:01 +0000)
17 files changed:
etc/afpd/desktop.c
etc/afpd/desktop.h
etc/afpd/directory.c
etc/afpd/directory.h
etc/afpd/enumerate.c
etc/afpd/file.c
etc/afpd/file.h
etc/afpd/filedir.c
etc/afpd/fork.c
etc/afpd/unix.c
etc/afpd/unix.h
etc/afpd/volume.c
etc/afpd/volume.h
include/atalk/adouble.h
libatalk/adouble/ad_attr.c
libatalk/adouble/ad_date.c
libatalk/adouble/ad_open.c

index 39b5aef23dd0c01a3f0b2c68a8cef401d8339a56..2fa630487737001230b7e196112f2a2a90d9f589 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: desktop.c,v 1.26.2.4.2.9 2004-03-04 23:57:14 bfernhomberg Exp $
+ * $Id: desktop.c,v 1.26.2.4.2.10 2004-03-11 02:01:59 didg Exp $
  *
  * See COPYRIGHT.
  *
@@ -696,45 +696,14 @@ utompath_error:
     return(m);
 }
 
-/* ----------------------------- */
-int afp_addcomment(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj      *obj;
-char   *ibuf, *rbuf;
-int            ibuflen, *rbuflen;
+/* ------------------------- */
+static int ad_addcomment(struct vol *vol, struct path *path, char *ibuf)
 {
-    struct adouble     ad, *adp;
-    struct vol         *vol;
-    struct dir         *dir;
     struct ofork        *of;
-    struct path         *path;
     char                *name, *upath;
-    int                        clen;
-    u_int32_t           did;
-    u_int16_t          vid;
     int                 isadir;
-
-    *rbuflen = 0;
-    ibuf += 2;
-
-    memcpy( &vid, ibuf, sizeof( vid ));
-    ibuf += sizeof( vid );
-    if (NULL == ( vol = getvolbyvid( vid )) ) {
-        return( AFPERR_PARAM );
-    }
-
-    memcpy( &did, ibuf, sizeof( did ));
-    ibuf += sizeof( did );
-    if (NULL == ( dir = dirlookup( vol, did )) ) {
-       return afp_errno;
-    }
-
-    if (NULL == ( path = cname( vol, dir, &ibuf )) ) {
-       return get_afp_errno(AFPERR_NOOBJ);
-    }
-
-    if ((u_long)ibuf & 1 ) {
-        ibuf++;
-    }
+    int                        clen;
+    struct adouble     ad, *adp;
 
     clen = (u_char)*ibuf++;
     clen = min( clen, 199 );
@@ -743,7 +712,7 @@ int         ibuflen, *rbuflen;
     if (!vol_unix_priv(vol) && check_access(upath, OPENACC_WR ) < 0) {
         return AFPERR_ACCESS;
     }
-
+    
     isadir = path_isadir(path);
     if (isadir || !(of = of_findname(path))) {
         ad_init(&ad, vol->v_adouble);
@@ -757,6 +726,11 @@ int                ibuflen, *rbuflen;
         return( AFPERR_ACCESS );
     }
 
+    if (!ad_getentryoff(adp, ADEID_COMMENT)) {
+        /* not defined, save nothing but return success */
+        return AFP_OK;
+    }
+
     if ( (ad_getoflags( adp, ADFLAGS_HF ) & O_CREAT) ) {
         if ( *path->m_name == '\0' ) {
             name = curdir->d_m_name;
@@ -775,21 +749,18 @@ int               ibuflen, *rbuflen;
     return( AFP_OK );
 }
 
-int afp_getcomment(obj, ibuf, ibuflen, rbuf, rbuflen )
+/* ----------------------------- */
+int afp_addcomment(obj, ibuf, ibuflen, rbuf, rbuflen )
 AFPObj      *obj;
 char   *ibuf, *rbuf;
 int            ibuflen, *rbuflen;
 {
-    struct adouble     ad, *adp;
     struct vol         *vol;
     struct dir         *dir;
-    struct ofork        *of;
-    struct path         *s_path;
-    char               *upath;
-    u_int32_t          did;
+    struct path         *path;
+    u_int32_t           did;
     u_int16_t          vid;
-    int                 isadir;
-    
+
     *rbuflen = 0;
     ibuf += 2;
 
@@ -805,23 +776,43 @@ int               ibuflen, *rbuflen;
        return afp_errno;
     }
 
-    if (NULL == ( s_path = cname( vol, dir, &ibuf )) ) {
+    if (NULL == ( path = cname( vol, dir, &ibuf )) ) {
        return get_afp_errno(AFPERR_NOOBJ);
     }
 
-    upath = s_path->u_name;
-    isadir = path_isadir(s_path);
-    if (isadir || !(of = of_findname(s_path))) {
+    if ((u_long)ibuf & 1 ) {
+        ibuf++;
+    }
+
+    return ad_addcomment(vol, path, ibuf);
+}
+
+/* -------------------- */
+static int ad_getcomment(struct vol *vol, struct path *path, char *rbuf, int *rbuflen)
+{
+    struct adouble     ad, *adp;
+    struct ofork        *of;
+    char               *upath;
+    int                 isadir;
+
+
+    upath = path->u_name;
+    isadir = path_isadir(path);
+    if (isadir || !(of = of_findname(path))) {
         ad_init(&ad, vol->v_adouble);
         adp = &ad;
     } else
         adp = of->of_ad;
+        
     if ( ad_open( upath,
                   ( isadir) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF,
                   O_RDONLY, 0666, adp) < 0 ) {
         return( AFPERR_NOITEM );
     }
 
+    if (!ad_getentryoff(adp, ADEID_COMMENT)) {
+        return AFPERR_NOITEM;
+    }
     /*
      * Make sure the AD file is not bogus.
      */
@@ -841,21 +832,18 @@ int               ibuflen, *rbuflen;
     return( AFP_OK );
 }
 
-int afp_rmvcomment(obj, ibuf, ibuflen, rbuf, rbuflen )
+/* -------------------- */
+int afp_getcomment(obj, ibuf, ibuflen, rbuf, rbuflen )
 AFPObj      *obj;
 char   *ibuf, *rbuf;
 int            ibuflen, *rbuflen;
 {
-    struct adouble     ad, *adp;
     struct vol         *vol;
     struct dir         *dir;
-    struct ofork        *of;
     struct path         *s_path;
-    char               *upath;
     u_int32_t          did;
     u_int16_t          vid;
-    int                 isadir;
-
+    
     *rbuflen = 0;
     ibuf += 2;
 
@@ -871,17 +859,28 @@ int               ibuflen, *rbuflen;
        return afp_errno;
     }
 
-    if (NULL == ( s_path = cname( vol, dir, &ibuf ))) {
+    if (NULL == ( s_path = cname( vol, dir, &ibuf )) ) {
        return get_afp_errno(AFPERR_NOOBJ);
     }
 
-    upath = s_path->u_name;
+    return ad_getcomment(vol, s_path, rbuf, rbuflen);
+}
+
+/* ----------------------- */
+static int ad_rmvcomment(struct vol *vol, struct path *path)
+{
+    struct adouble     ad, *adp;
+    struct ofork        *of;
+    int                 isadir;
+    char               *upath;
+
+    upath = path->u_name;
     if (!vol_unix_priv(vol) && check_access(upath, OPENACC_WR ) < 0) {
         return AFPERR_ACCESS;
     }
 
-    isadir = path_isadir(s_path);
-    if (isadir || !(of = of_findname(s_path))) {
+    isadir = path_isadir(path);
+    if (isadir || !(of = of_findname(path))) {
         ad_init(&ad, vol->v_adouble);
         adp = &ad;
     } else
@@ -900,8 +899,46 @@ int                ibuflen, *rbuflen;
         }
     }
 
+    if (!ad_getentryoff(adp, ADEID_COMMENT)) {
+        return AFP_OK;
+    }
+
     ad_setentrylen( adp, ADEID_COMMENT, 0 );
     ad_flush( adp, ADFLAGS_HF );
     ad_close( adp, ADFLAGS_HF );
     return( AFP_OK );
 }
+
+/* ----------------------- */
+int afp_rmvcomment(obj, ibuf, ibuflen, rbuf, rbuflen )
+AFPObj      *obj;
+char   *ibuf, *rbuf;
+int            ibuflen, *rbuflen;
+{
+    struct vol         *vol;
+    struct dir         *dir;
+    struct path         *s_path;
+    u_int32_t          did;
+    u_int16_t          vid;
+
+    *rbuflen = 0;
+    ibuf += 2;
+
+    memcpy( &vid, ibuf, sizeof( vid ));
+    ibuf += sizeof( vid );
+    if (NULL == ( vol = getvolbyvid( vid )) ) {
+        return( AFPERR_PARAM );
+    }
+
+    memcpy( &did, ibuf, sizeof( did ));
+    ibuf += sizeof( did );
+    if (NULL == ( dir = dirlookup( vol, did )) ) {
+       return afp_errno;
+    }
+
+    if (NULL == ( s_path = cname( vol, dir, &ibuf ))) {
+       return get_afp_errno(AFPERR_NOOBJ);
+    }
+    
+    return ad_rmvcomment(vol, s_path);
+}
index 6e7c9c797ae5abf65bd4c604440f740882166697..d753e588ace55f57ca2d6e696e5708f479ada266 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: desktop.h,v 1.3.6.2 2003-09-28 13:58:56 didg Exp $
+ * $Id: desktop.h,v 1.3.6.3 2004-03-11 02:01:59 didg Exp $
  *
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
  * All Rights Reserved.
@@ -50,10 +50,6 @@ extern char  *mtoupath __P((const struct vol *, char *, cnid_t, int utf8));
 extern char    *utompath __P((const struct vol *, char *, cnid_t, int utf8));
 extern u_char  ucreator[];
 
-#define validupath(vol, name) ((((vol)->v_flags & AFPVOL_USEDOTS) ? \
-   (strncasecmp((name),".Apple", 6) && \
-    strcasecmp((name), ".Parent")) : (name)[0] != '.'))
-
 /* FP functions */
 extern int     afp_opendt __P((AFPObj *, char *, int, char *, int *));
 extern int     afp_addcomment __P((AFPObj *, char *, int, char *, int *));
index b6b0797e050068e4a73f2a607fd50f63d915c433..288df1b94d6cd3af10295214f2bd5d5beeefccc9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: directory.c,v 1.71.2.4.2.10 2004-02-20 21:22:57 didg Exp $
+ * $Id: directory.c,v 1.71.2.4.2.11 2004-03-11 02:01:59 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -730,7 +730,7 @@ static int deletedir(char *dir)
 }
 
 /* do a recursive copy. */
-static int copydir(char *src, char *dst, int noadouble)
+static int copydir(const struct vol *vol, char *src, char *dst)
 {
     char spath[MAXPATHLEN + 1], dpath[MAXPATHLEN + 1];
     DIR *dp;
@@ -739,7 +739,6 @@ static int copydir(char *src, char *dst, int noadouble)
     struct utimbuf      ut;
     size_t slen, dlen;
     size_t srem, drem;
-    
     int err;
 
     /* doesn't exist or the path is too long. */
@@ -785,9 +784,9 @@ static int copydir(char *src, char *dst, int noadouble)
             strcpy(dpath + dlen, de->d_name);
 
             if (S_ISDIR(st.st_mode)) {
-                if (AFP_OK != (err = copydir(spath, dpath, noadouble)))
+                if (AFP_OK != (err = copydir(vol, spath, dpath)))
                     goto copydir_done;
-            } else if (AFP_OK != (err = copyfile(spath, dpath, NULL, noadouble))) {
+            } else if (AFP_OK != (err = copyfile(vol, vol, spath, dpath, NULL))) {
                 goto copydir_done;
 
             } else {
@@ -1029,6 +1028,10 @@ char     **cpath;
                     if ( movecwd( vol, dir->d_parent ) < 0 ) {
                         return NULL;                   
                    }
+                   /* FIXME should we set, don't need to call stat() after:
+                     ret.st_valid = 1;
+                     ret.st_errno = EACCES;
+                   */
                    ret.m_name = dir->d_m_name;
                    ret.u_name = dir->d_u_name;
                    ret.dir = dir;
@@ -1048,6 +1051,11 @@ char     **cpath;
                        ret.u_name =  path +tp;
                        
                    }
+                   /* FIXME should we set :
+                     ret.st_valid = 1;
+                     ret.st_errno = ENOENT;
+                   */
+                   
                    dir_invalidate(vol, dir);
                    return &ret;
                }
@@ -1630,7 +1638,7 @@ int setdirparams(const struct vol *vol,
          * Check to see if a create was necessary. If it was, we'll want
          * to set our name, etc.
          */
-        if ( ad_get_HF_flags( &ad ) & O_CREAT ) {
+        if ( (ad_get_HF_flags( &ad ) & O_CREAT) && ad_getentryoff(&ad, ADEID_NAME)) {
             ad_setentrylen( &ad, ADEID_NAME, strlen( curdir->d_m_name ));
             memcpy( ad_entry( &ad, ADEID_NAME ), curdir->d_m_name,
                     ad_getentrylen( &ad, ADEID_NAME ));
@@ -1731,7 +1739,7 @@ int setdirparams(const struct vol *vol,
                     break;
                 }
             }
-            if ( setdirowner( ntohl(aint), -1, vol_noadouble(vol) ) < 0 ) {
+            if ( setdirowner(vol,  ntohl(aint), -1 ) < 0 ) {
                 switch ( errno ) {
                 case EPERM :
                 case EACCES :
@@ -1777,7 +1785,7 @@ int setdirparams(const struct vol *vol,
             }
 #endif /* 0 */
 
-            if ( setdirowner( -1, ntohl(aint), vol_noadouble(vol) ) < 0 ) {
+            if ( setdirowner(vol, -1, ntohl(aint) ) < 0 ) {
                 switch ( errno ) {
                 case EPERM :
                 case EACCES :
@@ -1824,8 +1832,7 @@ int setdirparams(const struct vol *vol,
             }
 #endif /* 0 */
 
-            if ( setdirmode( mtoumode( &ma ), vol_noadouble(vol),
-                         (vol->v_flags & AFPVOL_DROPBOX)) < 0 ) {
+            if ( setdirmode( vol, mtoumode( &ma )) < 0 ) {
                 switch ( errno ) {
                 case EPERM :
                 case EACCES :
@@ -1882,8 +1889,7 @@ int setdirparams(const struct vol *vol,
             }
 #endif /* 0 */
 
-            if ( setdirunixmode( aint, vol_noadouble(vol),
-                         (vol->v_flags & AFPVOL_DROPBOX)) < 0 ) {
+            if ( setdirunixmode(vol, aint) < 0 ) {
                 switch ( errno ) {
                 case EPERM :
                 case EACCES :
@@ -2021,10 +2027,11 @@ int             ibuflen, *rbuflen;
         return( AFPERR_ACCESS );
     }
 
-    ad_setentrylen( &ad, ADEID_NAME, strlen( s_path->m_name ));
-    memcpy( ad_entry( &ad, ADEID_NAME ), s_path->m_name,
+    if (ad_getentryoff(&ad, ADEID_NAME)) {
+        ad_setentrylen( &ad, ADEID_NAME, strlen( s_path->m_name ));
+        memcpy( ad_entry( &ad, ADEID_NAME ), s_path->m_name,
             ad_getentrylen( &ad, ADEID_NAME ));
-
+    }
     ad_setid( &ad, (vol->v_flags & AFPVOL_NODEV)?0:s_path->st.st_dev,
                    s_path->st.st_ino, dir->d_did, did, vol->v_stamp);
 
@@ -2044,10 +2051,10 @@ createdir_done:
  * newparent curdir
  *
 */
-int renamedir(src, dst, dir, newparent, newname, noadouble)
+int renamedir(vol, src, dst, dir, newparent, newname)
+const struct vol *vol;
 char   *src, *dst, *newname;
 struct dir     *dir, *newparent;
-const int noadouble;
 {
     struct adouble     ad;
     struct dir         *parent;
@@ -2069,7 +2076,7 @@ const int noadouble;
         case EXDEV:
             /* this needs to copy and delete. bleah. that means we have
              * to deal with entire directory hierarchies. */
-            if ((err = copydir(src, dst, noadouble)) < 0) {
+            if ((err = copydir(vol, src, dst)) < 0) {
                 deletedir(dst);
                 return err;
             }
@@ -2081,19 +2088,28 @@ const int noadouble;
         }
     }
 
-    ad_init(&ad, 0);    /* FIXME */
+    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));
+    }
 
     len = strlen( newname );
     /* rename() succeeded so we need to update our tree even if we can't open
      * .Parent
     */
-    if ( !ad_open( dst, ADFLAGS_HF|ADFLAGS_DIR, O_RDWR, 0, &ad)) {
-        ad_setentrylen( &ad, ADEID_NAME, len );
-        memcpy( ad_entry( &ad, ADEID_NAME ), newname, len );
+    
+    ad_init(&ad, vol->v_adouble);
+
+    if (!ad_open( dst, ADFLAGS_HF|ADFLAGS_DIR, O_RDWR, 0, &ad)) {
+        if (ad_getentryoff(&ad, ADEID_NAME)) {
+            ad_setentrylen( &ad, ADEID_NAME, len );
+            memcpy( ad_entry( &ad, ADEID_NAME ), newname, len );
+        }
         ad_flush( &ad, ADFLAGS_HF );
         ad_close( &ad, ADFLAGS_HF );
     }
-    
+
     if (dir->d_m_name == dir->d_u_name)
         dir->d_u_name = NULL;
 
@@ -2164,33 +2180,41 @@ int pathlen;
         }
     }
 
-    /* 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;
-            }
+    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;
+                strcpy(path + DOT_APPLEDOUBLE_LEN, de->d_name);
+                if ((err = netatalk_unlink(path))) {
+                    closedir(dp);
+                    return err;
+                }
             }
+            closedir(dp);
         }
-        closedir(dp);
-    }
 
-    if ( (err = netatalk_rmdir( ".AppleDouble" ))  ) {
-       return err;
+        if ( (err = netatalk_rmdir( ".AppleDouble" ))  ) {
+            return err;
+        }
     }
 
     /* now get rid of dangling symlinks */
index b6e7cd1b66d84fedbbc1ff9b9c0b89dba1540ad0..f9113b237bdadf3c2e7b4e7e1484a2ffff5580be 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: directory.h,v 1.13.2.4 2003-07-21 05:50:54 didg Exp $
+ * $Id: directory.h,v 1.13.2.4.2.1 2004-03-11 02:01:59 didg Exp $
  *
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
  * All Rights Reserved.
@@ -204,8 +204,8 @@ extern void             utommode __P((struct stat *, struct maccess *));
 extern int getdirparams __P((const struct vol *, u_int16_t, struct path *,
                                  struct dir *, char *, int *));
 extern int setdirparams __P((const struct vol *, struct path *, u_int16_t, char *));
-extern int renamedir __P((char *, char *, struct dir *,
-                              struct dir *, char *, const int));
+extern int renamedir __P((const struct vol *, char *, char *, struct dir *,
+                              struct dir *, char *));
 extern int path_error __P((struct path *, int error));
 
 typedef int (*dir_loop)(struct dirent *, char *, void *);
index b7a7b376818cbffe3aebb55c00afd2f749c3850c..4a6e31d7b47fd275ae8a9ac33ad9afde3ead371b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: enumerate.c,v 1.39.2.2.2.3 2004-02-20 21:22:58 didg Exp $
+ * $Id: enumerate.c,v 1.39.2.2.2.4 2004-03-11 02:01:59 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -166,7 +166,7 @@ char *check_dirent(const struct vol *vol, char *name)
     if (!strcmp(name, "..") || !strcmp(name, "."))
         return NULL;
 
-    if (!(validupath(vol, name)))
+    if (!vol->validupath(vol, name))
         return NULL;
 
     /* check for vetoed filenames */
index bcb5d5bb186237f95b346cb5c66eabe72cf5f03b..e4cc7a980514db95d5f11853509ba696ae2393a8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: file.c,v 1.92.2.2.2.17 2004-03-04 23:57:20 bfernhomberg Exp $
+ * $Id: file.c,v 1.92.2.2.2.18 2004-03-11 02:02:00 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -663,9 +663,10 @@ int                ibuflen, *rbuflen;
     }
 
     path = s_path->m_name;
-    ad_setentrylen( adp, ADEID_NAME, strlen( path ));
-    memcpy(ad_entry( adp, ADEID_NAME ), path,
-           ad_getentrylen( adp, ADEID_NAME ));
+    if (ad_getentryoff(adp, ADEID_NAME)) {
+        ad_setentrylen( adp, ADEID_NAME, strlen( path ));
+        memcpy(ad_entry( adp, ADEID_NAME ), path, ad_getentrylen( adp, ADEID_NAME ));
+    }
     ad_flush( adp, ADFLAGS_DF|ADFLAGS_HF );
     ad_close( adp, ADFLAGS_DF|ADFLAGS_HF );
 
@@ -799,7 +800,7 @@ int setfilparams(struct vol *vol,
             return vol_noadouble(vol) ? AFP_OK : AFPERR_ACCESS;
         }
         isad = 0;
-    } else if ((ad_get_HF_flags( adp ) & O_CREAT) ) {
+    } else if (ad_getentryoff(adp, ADEID_NAME) && (ad_get_HF_flags( adp ) & O_CREAT) ) {
         ad_setentrylen( adp, ADEID_NAME, strlen( path->m_name ));
         memcpy(ad_entry( adp, ADEID_NAME ), path->m_name,
                ad_getentrylen( adp, ADEID_NAME ));
@@ -876,7 +877,7 @@ int setfilparams(struct vol *vol,
             buf += sizeof( aint );
             aint = ntohl (aint);
 
-            setfilemode(path, aint);
+            setfilunixmode(vol, path, aint);
             break;
             /* Client needs to set the ProDOS file info for this file.
                Use a defined string for TEXT to support crlf
@@ -951,9 +952,9 @@ setfilparam_done:
  * adp         adouble struct of src file, if open, or & zeroed one
  *
  */
-int renamefile(src, dst, newname, noadouble, adp )
+int renamefile(vol, src, dst, newname, adp )
+const struct vol *vol;
 char   *src, *dst, *newname;
-const int         noadouble;
 struct adouble    *adp;
 {
     char       adsrc[ MAXPATHLEN + 1];
@@ -982,19 +983,19 @@ struct adouble    *adp;
                /* FIXME  warning in syslog so admin'd know there's a conflict ?*/
                return AFPERR_OLOCK; /* little lie */
            }
-            if (AFP_OK != ( rc = copyfile(src, dst, newname, noadouble )) ) {
+            if (AFP_OK != ( rc = copyfile(vol, vol, src, dst, newname )) ) {
                 /* on error copyfile delete dest */
                 return( rc );
             }
-            return deletefile(NULL, src, 0);
+            return deletefile(vol, src, 0);
         default :
             return( AFPERR_PARAM );
         }
     }
 
-    strcpy( adsrc, ad_path( src, 0 ));
+    strcpy( adsrc, vol->ad_path( src, 0 ));
 
-    if (unix_rename( adsrc, ad_path( dst, 0 )) < 0 ) {
+    if (unix_rename( adsrc, vol->ad_path( dst, 0 )) < 0 ) {
         struct stat st;
         int err;
         
@@ -1012,10 +1013,10 @@ struct adouble    *adp;
              * 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, AD_VERSION); /* FIXME */
+            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, ad_path( dst, 0 )) ) 
+               if (!unix_rename( adsrc, vol->ad_path( dst, 0 )) ) 
                    err = 0;
                 else 
                    err = errno;
@@ -1046,10 +1047,12 @@ struct adouble    *adp;
 
     /* don't care if we can't open the newly renamed ressource fork
      */
-    if ( !ad_open( dst, ADFLAGS_HF, O_RDWR, 0666, adp)) {
-        len = strlen( newname );
-        ad_setentrylen( adp, ADEID_NAME, len );
-        memcpy(ad_entry( adp, ADEID_NAME ), newname, len );
+    if (!ad_open( dst, ADFLAGS_HF, O_RDWR, 0666, adp)) {
+        if (ad_getentryoff(adp, ADEID_NAME) ) {
+            len = strlen( newname );
+            ad_setentrylen( adp, ADEID_NAME, len );
+            memcpy(ad_entry( adp, ADEID_NAME ), newname, len );
+        }
         ad_flush( adp, ADFLAGS_HF );
         ad_close( adp, ADFLAGS_HF );
     }
@@ -1114,7 +1117,7 @@ AFPObj      *obj;
 char   *ibuf, *rbuf;
 int            ibuflen, *rbuflen;
 {
-    struct vol *vol;
+    struct vol *s_vol, *d_vol;
     struct dir *dir;
     char       *newname, *p, *upath;
     struct path *s_path;
@@ -1131,13 +1134,13 @@ int             ibuflen, *rbuflen;
 
     memcpy(&svid, ibuf, sizeof( svid ));
     ibuf += sizeof( svid );
-    if (NULL == ( vol = getvolbyvid( svid )) ) {
+    if (NULL == ( s_vol = getvolbyvid( svid )) ) {
         return( AFPERR_PARAM );
     }
 
     memcpy(&sdid, ibuf, sizeof( sdid ));
     ibuf += sizeof( sdid );
-    if (NULL == ( dir = dirlookup( vol, sdid )) ) {
+    if (NULL == ( dir = dirlookup( s_vol, sdid )) ) {
         return afp_errno;
     }
 
@@ -1146,7 +1149,7 @@ int               ibuflen, *rbuflen;
     memcpy(&ddid, ibuf, sizeof( ddid ));
     ibuf += sizeof( ddid );
 
-    if (NULL == ( s_path = cname( vol, dir, &ibuf )) ) {
+    if (NULL == ( s_path = cname( s_vol, dir, &ibuf )) ) {
         return get_afp_errno(AFPERR_PARAM);
     }
     if ( path_isadir(s_path) ) {
@@ -1165,7 +1168,7 @@ int               ibuflen, *rbuflen;
     if (of_findname(s_path))
         return AFPERR_DENYCONF;
 
-    p = ctoupath( vol, curdir, newname );
+    p = ctoupath( s_vol, curdir, newname );
     if (!p) {
         return AFPERR_PARAM;
     
@@ -1173,18 +1176,18 @@ int             ibuflen, *rbuflen;
 #ifdef FORCE_UIDGID
     /* FIXME svid != dvid && dvid's user can't read svid */
 #endif
-    if (NULL == ( vol = getvolbyvid( dvid )) ) {
+    if (NULL == ( d_vol = getvolbyvid( dvid )) ) {
         return( AFPERR_PARAM );
     }
 
-    if (vol->v_flags & AFPVOL_RO)
+    if (d_vol->v_flags & AFPVOL_RO)
         return AFPERR_VLOCK;
 
-    if (NULL == ( dir = dirlookup( vol, ddid )) ) {
+    if (NULL == ( dir = dirlookup( d_vol, ddid )) ) {
         return afp_errno;
     }
 
-    if (( s_path = cname( vol, dir, &ibuf )) == NULL ) {
+    if (( s_path = cname( d_vol, dir, &ibuf )) == NULL ) {
         return get_afp_errno(AFPERR_NOOBJ); 
     }
     if ( *s_path->m_name != '\0' ) {
@@ -1201,10 +1204,10 @@ int             ibuflen, *rbuflen;
     /* newname is always only a filename so curdir *is* its
      * parent folder
     */
-    if (NULL == (upath = mtoupath(vol, newname, curdir->d_did, utf8_encoding()))) {
+    if (NULL == (upath = mtoupath(d_vol, newname, curdir->d_did, utf8_encoding()))) {
         return( AFPERR_PARAM );
     }
-    if ( (err = copyfile(p, upath , newname, vol_noadouble(vol))) < 0 ) {
+    if ( (err = copyfile(s_vol, d_vol, p, upath , newname)) < 0 ) {
         return err;
     }
     curdir->offcnt++;
@@ -1215,7 +1218,7 @@ int               ibuflen, *rbuflen;
     }
 #endif /* DROPKLUDGE */
 
-    setvoltime(obj, vol );
+    setvoltime(obj, d_vol );
 
 #ifdef DEBUG
     LOG(log_info, logtype_afpd, "end afp_copyfile:");
@@ -1224,7 +1227,7 @@ int               ibuflen, *rbuflen;
     return( retvalue );
 }
 
-
+/* ----------------------- */
 static __inline__ int copy_all(const int dfd, const void *buf,
                                size_t buflen)
 {
@@ -1239,14 +1242,8 @@ static __inline__ int copy_all(const int dfd, const void *buf,
             switch (errno) {
             case EINTR:
                 continue;
-            case EDQUOT:
-            case EFBIG:
-            case ENOSPC:
-                return AFPERR_DFULL;
-            case EROFS:
-                return AFPERR_VLOCK;
             default:
-                return AFPERR_PARAM;
+                return -1;
             }
         }
         buflen -= cc;
@@ -1256,14 +1253,14 @@ static __inline__ int copy_all(const int dfd, const void *buf,
     LOG(log_info, logtype_afpd, "end copy_all:");
 #endif /* DEBUG */
 
-    return AFP_OK;
+    return 0;
 }
 
 /* -------------------------- */
 static int copy_fd(int dfd, int sfd)
 {
     ssize_t cc;
-    int     err = AFP_OK;
+    int     err = 0;
     char    filebuf[8192];
     
 #ifdef SENDFILE_FLAVOR_LINUX
@@ -1276,7 +1273,7 @@ static int copy_fd(int dfd, int sfd)
         
         while (1) {
             if ( offset >= st.st_size) {
-               return AFP_OK;
+               return 0;
             }
             size = (st.st_size -offset > BUF)?BUF:st.st_size -offset;
             if ((cc = sys_sendfile(dfd, sfd, &offset, size)) < 0) {
@@ -1284,14 +1281,8 @@ static int copy_fd(int dfd, int sfd)
                 case ENOSYS:
                 case EINVAL:  /* there's no guarantee that all fs support sendfile */
                     goto no_sendfile;
-                case EDQUOT:
-                case EFBIG:
-                case ENOSPC:
-                    return AFPERR_DFULL;
-                case EROFS:
-                    return AFPERR_VLOCK;
                 default:
-                    return AFPERR_PARAM;
+                    return -1;
                 }
             }
         }
@@ -1304,12 +1295,13 @@ static int copy_fd(int dfd, int sfd)
         if ((cc = read(sfd, filebuf, sizeof(filebuf))) < 0) {
             if (errno == EINTR)
                 continue;
-            err = AFPERR_PARAM;
+            err = -1;
             break;
         }
 
-        if (!cc || ((err = copy_all(dfd, filebuf, cc)) < 0))
+        if (!cc || ((err = copy_all(dfd, filebuf, cc)) < 0)) {
             break;
+        }
     }
     return err;
 }
@@ -1318,103 +1310,77 @@ static int copy_fd(int dfd, int sfd)
  * if newname is NULL (from directory.c) we don't want to copy ressource fork.
  * because we are doing it elsewhere.
  */
-int copyfile(src, dst, newname, noadouble )
+int copyfile(s_vol, d_vol, src, dst, newname )
+const struct vol *s_vol, *d_vol;
 char   *src, *dst, *newname;
-const int   noadouble;
 {
     struct adouble     ads, add;
-    int                        len, err = AFP_OK;
+    int                        len, err = 0;
+    int                 ret_err = 0;
     int                 adflags;
+    int                 noadouble = vol_noadouble(d_vol);
     struct stat         st;
     
 #ifdef DEBUG
     LOG(log_info, logtype_afpd, "begin copyfile:");
 #endif /* DEBUG */
 
-    ad_init(&ads, 0); /* OK */
-    ad_init(&add, 0); /* FIXME */
+    ad_init(&ads, s_vol->v_adouble); 
+    ad_init(&add, d_vol->v_adouble);
     adflags = ADFLAGS_DF;
     if (newname) {
         adflags |= ADFLAGS_HF;
     }
 
     if (ad_open(src , adflags | ADFLAGS_NOHF, O_RDONLY, 0, &ads) < 0) {
-        switch ( errno ) {
-        case ENOENT :
-            return( AFPERR_NOOBJ );
-        case EACCES :
-            return( AFPERR_ACCESS );
-        default :
-            return( AFPERR_PARAM );
-        }
+        ret_err = errno;
+        goto done;
     }
+
     if (ad_open(dst , adflags | noadouble, O_RDWR|O_CREAT|O_EXCL, 0666, &add) < 0) {
+        ret_err = errno;
         ad_close( &ads, adflags );
-        if (EEXIST != (err = errno)) {
-            deletefile(NULL, dst, 0);
-        }
-        switch ( err ) {
-        case EEXIST :
-            return AFPERR_EXIST;
-        case ENOENT :
-            return( AFPERR_NOOBJ );
-        case EACCES :
-            return( AFPERR_ACCESS );
-        case EROFS:
-            return AFPERR_VLOCK;
-        default :
-            return( AFPERR_PARAM );
+        if (EEXIST != ret_err) {
+            deletefile(d_vol, dst, 0);
+            goto done;
         }
+        return AFPERR_EXIST;
     }
-    if (ad_hfileno(&ads) == -1 || AFP_OK == (err = copy_fd(ad_hfileno(&add), ad_hfileno(&ads)))){
+    if (ad_hfileno(&ads) == -1 || 0 == (err = copy_fd(ad_hfileno(&add), ad_hfileno(&ads)))){
         /* copy the data fork */
        err = copy_fd(ad_dfileno(&add), ad_dfileno(&ads));
     }
 
     /* Now, reopen destination file */
-    err = AFP_OK;
+    if (err < 0) {
+       ret_err = errno;
+    }
+    ad_close( &ads, adflags );
+
     if (ad_close( &add, adflags ) <0) {
-       deletefile(NULL, dst, 0);
-        return AFPERR_PARAM;  /* FIXME */
-    } else {
-       ad_init(&add, 0);
+        deletefile(d_vol, dst, 0);
+        ret_err = errno;
+        goto done;
+    } 
+    else {
+       ad_init(&add, d_vol->v_adouble);
        if (ad_open(dst , adflags | noadouble, O_RDWR, 0666, &add) < 0) {
-           ad_close( &ads, adflags );
-           deletefile(NULL, dst, 0);
-           switch ( err ) {
-           case ENOENT :
-               return( AFPERR_NOOBJ );
-           case EACCES :
-               return( AFPERR_ACCESS );
-           case EROFS:
-               return AFPERR_VLOCK;
-           default :
-               return( AFPERR_PARAM );
-           }
+           ret_err = errno;
        }
     }
 
-    if (newname) {
+    if (!ret_err && newname && ad_getentryoff(&add, ADEID_NAME)) {
         len = strlen( newname );
         ad_setentrylen( &add, ADEID_NAME, len );
         memcpy(ad_entry( &add, ADEID_NAME ), newname, len );
     }
 
-    ad_close( &ads, adflags );
     ad_flush( &add, adflags );
     if (ad_close( &add, adflags ) <0) {
-       err = errno;
+       ret_err = errno;
     }
-    if (err != AFP_OK) {
-        deletefile(NULL, dst, 0);
-        switch ( err ) {
-        case ENOENT :
-            return( AFPERR_NOOBJ );
-        case EACCES :
-            return( AFPERR_ACCESS );
-        default :
-            return( AFPERR_PARAM );
-        }
+    if (ret_err) {
+        deletefile(d_vol, dst, 0);
     }
 
     /* set dest modification date to src date */
@@ -1429,7 +1395,22 @@ const int   noadouble;
     LOG(log_info, logtype_afpd, "end copyfile:");
 #endif /* DEBUG */
 
-    return( AFP_OK );
+done:
+    switch ( ret_err ) {
+    case 0:
+        return AFP_OK;
+    case EDQUOT:
+    case EFBIG:
+    case ENOSPC:
+        return AFPERR_DFULL;
+    case ENOENT:
+        return AFPERR_NOOBJ;
+    case EACCES:
+        return AFPERR_ACCESS;
+    case EROFS:
+        return AFPERR_VLOCK;
+    }
+    return AFPERR_PARAM;
 }
 
 
@@ -1444,7 +1425,7 @@ const int   noadouble;
    WRITE lock on read only file.
 */
 int deletefile( vol, file, checkAttrib )
-struct vol      *vol;
+const struct vol      *vol;
 char           *file;
 int         checkAttrib;
 {
@@ -1458,7 +1439,7 @@ int         checkAttrib;
     /* try to open both forks at once */
     adflags = ADFLAGS_DF|ADFLAGS_HF;
     while(1) {
-        ad_init(&ad, 0);  /* OK */
+        ad_init(&ad, vol->v_adouble);  /* OK */
         if ( ad_open( file, adflags, O_RDONLY, 0, &ad ) < 0 ) {
             switch (errno) {
             case ENOENT:
@@ -1511,10 +1492,10 @@ int         checkAttrib;
     if (ad_tmplock( &ad, ADEID_DFORK, ADLOCK_WR, 0, 0, 0 ) < 0) {
         err = AFPERR_BUSY;
     }
-    else if (!(err = netatalk_unlink( ad_path( file, ADFLAGS_HF)) ) &&
+    else if (!(err = netatalk_unlink( vol->ad_path( file, ADFLAGS_HF)) ) &&
              !(err = netatalk_unlink( file )) ) {
         cnid_t id;
-        if (vol && (id = cnid_get(vol->v_cdb, curdir->d_did, file, strlen(file)))) 
+        if (checkAttrib && (id = cnid_get(vol->v_cdb, curdir->d_did, file, strlen(file)))) 
         {
             cnid_delete(vol->v_cdb, id);
         }
@@ -2002,17 +1983,17 @@ int             ibuflen, *rbuflen;
         return AFPERR_MISC;
 
     /* now, quickly rename the file. we error if we can't. */
-    if ((err = renamefile(p, temp, temp, vol_noadouble(vol), adsp)) < 0)
+    if ((err = renamefile(vol, p, temp, temp, adsp)) < 0)
         goto err_exchangefile;
     of_rename(vol, s_of, sdir, spath, curdir, temp);
 
     /* rename destination to source */
-    if ((err = renamefile(upath, p, spath, vol_noadouble(vol), addp)) < 0)
+    if ((err = renamefile(vol, upath, p, spath, addp)) < 0)
         goto err_src_to_tmp;
     of_rename(vol, d_of, curdir, path->m_name, sdir, spath);
 
     /* rename temp to destination */
-    if ((err = renamefile(temp, upath, path->m_name, vol_noadouble(vol), adsp)) < 0)
+    if ((err = renamefile(vol, temp, upath, path->m_name, adsp)) < 0)
         goto err_dest_to_src;
     of_rename(vol, s_of, curdir, temp, curdir, path->m_name);
 
@@ -2053,17 +2034,17 @@ int             ibuflen, *rbuflen;
      * properly. */
 err_temp_to_dest:
     /* rename dest to temp */
-    renamefile(upath, temp, temp, vol_noadouble(vol), adsp);
+    renamefile(vol, upath, temp, temp, adsp);
     of_rename(vol, s_of, curdir, upath, curdir, temp);
 
 err_dest_to_src:
     /* rename source back to dest */
-    renamefile(p, upath, path->m_name, vol_noadouble(vol), addp);
+    renamefile(vol, p, upath, path->m_name, addp);
     of_rename(vol, d_of, sdir, spath, curdir, path->m_name);
 
 err_src_to_tmp:
     /* rename temp back to source */
-    renamefile(temp, p, spath, vol_noadouble(vol), adsp);
+    renamefile(vol, temp, p, spath, adsp);
     of_rename(vol, s_of, curdir, temp, sdir, spath);
 
 err_exchangefile:
index 6d6e62d8267f4af8f6574c3cf6652f49d16f802b..1e66e70b49830ede032865840de009f1f0e59349 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: file.h,v 1.16.2.2.2.2 2003-09-28 13:58:57 didg Exp $
+ * $Id: file.h,v 1.16.2.2.2.3 2004-03-11 02:02:01 didg Exp $
  *
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
  * All Rights Reserved.
@@ -129,9 +129,9 @@ extern int getfilparams __P((struct vol *, u_int16_t, struct path *,
                                  struct dir *, char *buf, int *));
 
 extern int setfilparams __P((struct vol *, struct path *, u_int16_t, char *));
-extern int renamefile   __P((char *, char *, char *, const int, struct adouble *));
-extern int copyfile     __P((char *, char *, char *, const int));
-extern int deletefile   __P((struct vol *, char *, int));
+extern int renamefile   __P((const struct vol *, char *, char *, char *, struct adouble *));
+extern int copyfile     __P((const struct vol *, const struct vol *, char *, char *, char *));
+extern int deletefile   __P((const struct vol *, char *, int));
 
 extern void *get_finderinfo __P((const char *, struct adouble *, void *));
 extern int  copy_path_name __P((char *, char *i));
index d2c849b7e8a2ab310d7c21cdaaa60b291562597b..fb39c1f14fd63395cd2570bc6efe3c6b77752dfe 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: filedir.c,v 1.45.2.2.2.8 2004-03-02 13:27:07 didg Exp $
+ * $Id: filedir.c,v 1.45.2.2.2.9 2004-03-11 02:02:01 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -73,7 +73,7 @@ more information */
         return AFPERR_NOOBJ ;
     }
 
-    adpath = ad_path( upath, ADFLAGS_HF );
+    adpath = vol->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.");
@@ -302,7 +302,7 @@ int         ibuflen, *rbuflen;
 }
 
 /* -------------------------------------------- 
-   Factorise some check on a pathname
+   Factorise some checks on a pathname
 */
 int check_name(const struct vol *vol, char *name)
 {
@@ -313,7 +313,7 @@ int check_name(const struct vol *vol, char *name)
     if ((vol->v_flags & AFPVOL_NOHEX) && strchr(name, '/'))
         return AFPERR_PARAM;
 
-    if (!validupath(vol, name))
+    if (!vol->validupath(vol, name))
         return AFPERR_EXIST;
 
     /* check for vetoed filenames */
@@ -432,12 +432,12 @@ int         isdir;
         if (of_findname(&path)) {
             rc = AFPERR_EXIST; /* was AFPERR_BUSY; */
         } else {
-            rc = renamefile( p, upath, newname,vol_noadouble(vol), adp );
+            rc = renamefile(vol, p, upath, newname, adp );
             if (rc == AFP_OK)
                 of_rename(vol, opened, sdir, oldname, curdir, newname);
         }
     } else {
-        rc = renamedir(p, upath, sdir, curdir, newname, vol_noadouble(vol));
+        rc = renamedir(vol, p, upath, sdir, curdir, newname);
     }
     if ( rc == AFP_OK && id ) {
         /* renaming may have moved the file/dir across a filesystem */
@@ -764,7 +764,7 @@ int         ibuflen, *rbuflen;
                 int  admode = ad_mode("", 0777);
 
                 setfilmode(upath, admode, NULL);
-                setfilmode(ad_path( upath, ADFLAGS_HF ), ad_hf_mode(admode), NULL);
+                setfilmode(vol->ad_path( upath, ADFLAGS_HF ), ad_hf_mode(admode), NULL);
             }
         setvoltime(obj, vol );
     }
index d569d66e2c81d8daa693d5287ec6fbd84d6f25bc..c066e67f0bb4c92aab5fd501b6eb940c5e27f495 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: fork.c,v 1.51.2.2.2.6 2004-02-20 21:23:13 didg Exp $
+ * $Id: fork.c,v 1.51.2.2.2.7 2004-03-11 02:02:01 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -459,10 +459,12 @@ int               ibuflen, *rbuflen;
     }
 
     if ((adflags & ADFLAGS_HF) && (ad_get_HF_flags( ofork->of_ad) & O_CREAT)) {
-        ad_setentrylen( ofork->of_ad, ADEID_NAME, strlen( path ));
-        memcpy(ad_entry( ofork->of_ad, ADEID_NAME ), path,
+        if (ad_getentryoff(ofork->of_ad, ADEID_NAME)) {
+            ad_setentrylen( ofork->of_ad, ADEID_NAME, strlen( path ));
+            memcpy(ad_entry( ofork->of_ad, ADEID_NAME ), path,
                ad_getentrylen( ofork->of_ad, ADEID_NAME ));
-        ad_flush( ofork->of_ad, adflags );
+            ad_flush( ofork->of_ad, adflags );
+        }
     }
 
     if (( ret = getforkparams(ofork, bitmap, rbuf + 2 * sizeof( u_int16_t ),
index 50bccc0a5704fd193c56c0ad69875d198e8bf6d0..e07b305b327a3e708b08f9b1bf82b7a5137442ca 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: unix.c,v 1.43.2.1.2.3 2004-02-20 21:23:13 didg Exp $
+ * $Id: unix.c,v 1.43.2.1.2.4 2004-03-11 02:02:03 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -364,7 +364,8 @@ const mode_t        mode;
 }
 
 /* --------------------- */
-int setfilemode (path, mode)
+int setfilunixmode (vol, path, mode)
+const struct vol *vol;
 struct path* path;
 mode_t mode;
 {
@@ -379,7 +380,7 @@ mode_t mode;
     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(ad_path( path->u_name, ADFLAGS_HF ), ad_hf_mode(mode), &path->st);
+    return setfilmode(vol->ad_path( path->u_name, ADFLAGS_HF ), ad_hf_mode(mode), &path->st);
 }
 
 /* --------------------- */
@@ -405,13 +406,16 @@ mode_t mask = S_IRUSR |S_IWUSR | S_IRGRP | S_IWGRP |S_IROTH | S_IWOTH;
 }
 
 /* --------------------- */
-int setdirunixmode( mode, noadouble, dropbox )
-const mode_t mode;
-const int noadouble;
-const int dropbox;
+int setdirunixmode( vol, mode )
+const struct vol *vol;
+const mode_t     mode;
 {
-    if ( stickydirmode(".AppleDouble", DIRBITS | mode, dropbox) < 0 && !noadouble)
-        return  -1 ;
+    int dropbox = (vol->v_flags & AFPVOL_DROPBOX);
+
+    if (vol->v_adouble != AD_VERSION2_OSX) {
+        if (stickydirmode(".AppleDouble", DIRBITS | mode, dropbox) < 0 && !vol_noadouble(vol))
+            return  -1 ;
+    }
 
     if ( stickydirmode(".", DIRBITS | mode, dropbox) < 0 )
         return -1;
@@ -419,16 +423,18 @@ const int dropbox;
 }
 
 /* --------------------- */
-int setdirmode( mode, noadouble, dropbox )
+int setdirmode( vol, mode )
+const struct vol *vol;
 const mode_t mode;
-const int noadouble;
-const int dropbox;
 {
     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);
     
     if (( dir = opendir( "." )) == NULL ) {
         LOG(log_error, logtype_afpd, "setdirmode: opendir .: %s", strerror(errno) );
@@ -436,7 +442,8 @@ const int dropbox;
     }
 
     for ( dirp = readdir( dir ); dirp != NULL; dirp = readdir( dir )) {
-        if ( *dirp->d_name == '.' ) {
+        /* FIXME */
+        if ( *dirp->d_name == '.' && (!osx || dirp->d_name[1] != '_')) {
             continue;
         }
         if ( stat( dirp->d_name, &st ) < 0 ) {
@@ -446,7 +453,9 @@ const int dropbox;
         }
 
         if (!S_ISDIR(st.st_mode)) {
-           if (setfilmode(dirp->d_name, mode, &st) < 0) {
+           int setmode = (osx && *dirp->d_name == '.')?hf_mode:mode;
+
+           if (setfilmode(dirp->d_name, setmode, &st) < 0) {
                 LOG(log_error, logtype_afpd, "setdirmode: chmod %s: %s",
                     dirp->d_name, strerror(errno) );
                 return -1;
@@ -463,11 +472,15 @@ const int dropbox;
 #endif
     }
     closedir( dir );
-
+    
+    if (osx) {
+        goto setdirmode_noadouble;
+    }
+    
     /* change perm of .AppleDouble's files
     */
     if (( dir = opendir( ".AppleDouble" )) == NULL ) {
-        if (noadouble)
+        if (vol_noadouble(vol))
             goto setdirmode_noadouble;
         LOG(log_error, logtype_afpd, "setdirmode: opendir .AppleDouble: %s", strerror(errno) );
         return( -1 );
@@ -488,7 +501,7 @@ const int dropbox;
             continue;
         }
         if (!S_ISDIR(st.st_mode)) {
-           if (setfilmode(buf, ad_hf_mode(mode), &st) < 0) {
+           if (setfilmode(buf, hf_mode , &st) < 0) {
                /* FIXME what do we do then? */
            }
         }
@@ -574,28 +587,31 @@ const gid_t       gid;
 }
 
 
-/* uid/gid == 0 need to be handled as special cases. they really mean
+/* --------------------------------- 
+ * 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
  * into the unix permission scheme. we can get around this by
  * co-opting some bits. */
-int setdirowner( uid, gid, noadouble )
+int setdirowner(vol, uid, gid )
+const struct vol *vol;
 const uid_t    uid;
 const gid_t    gid;
-const int   noadouble;
 {
     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);
 
     if (( dir = opendir( "." )) == NULL ) {
         return( -1 );
     }
     for ( dirp = readdir( dir ); dirp != NULL; dirp = readdir( dir )) {
-        if ( *dirp->d_name == '.' ) {
+        if ( *dirp->d_name == '.' && (!osx || dirp->d_name[1] != '_')) {
             continue;
-        };
+        }
         if ( stat( dirp->d_name, &st ) < 0 ) {
             LOG(log_error, logtype_afpd, "setdirowner: stat %s: %s",
                 dirp->d_name, strerror(errno) );
@@ -610,6 +626,11 @@ const int   noadouble;
         }
     }
     closedir( dir );
+    
+    if (osx) {
+       goto setdirowner_noadouble;
+    }
+
     if (( dir = opendir( ".AppleDouble" )) == NULL ) {
         if (noadouble)
             goto setdirowner_noadouble;
index 70d82cd4f0b0572ad5c5b538deb49839cbd31fa7..25ed2da2f7dd2d176a87c9004fb889cc80625e43 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: unix.h,v 1.12.2.1.2.2 2004-01-07 13:33:03 lenneis Exp $
+ * $Id: unix.h,v 1.12.2.1.2.3 2004-03-11 02:02:03 didg Exp $
  */
 
 #ifndef AFPD_UNIX_H
@@ -217,12 +217,12 @@ extern struct afp_options default_options;
 
 extern int gmem            __P((const gid_t));
 extern int setdeskmode      __P((const mode_t));
-extern int setdirunixmode   __P((const mode_t, const int, const int));
-extern int setdirmode       __P((const mode_t, const int, const int));
+extern int setdirunixmode   __P((const struct vol *, const mode_t));
+extern int setdirmode       __P((const struct vol *, const mode_t));
 extern int setdeskowner     __P((const uid_t, const gid_t));
-extern int setdirowner      __P((const uid_t, const gid_t, const int));
+extern int setdirowner      __P((const struct vol *, const uid_t, const gid_t));
 extern int setfilmode       __P((char *, mode_t , struct stat *));
-extern int setfilemode      __P((struct path*, const mode_t));
+extern int setfilunixmode   __P((const struct vol *, struct path*, const mode_t));
 extern int unix_rename      __P((const char *oldpath, const char *newpath));
 
 extern void accessmode      __P((char *, struct maccess *, struct dir *, struct stat *));
index 4b03f06b9916d09f4407e9ebc854c3335e2af878..f42076aaef4b6ca92b3e8776492883bd2cfe0045 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: volume.c,v 1.51.2.7.2.24 2004-03-02 13:27:08 didg Exp $
+ * $Id: volume.c,v 1.51.2.7.2.25 2004-03-11 02:02:03 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -391,6 +391,8 @@ static void volset(struct vol_option *options, struct vol_option *save,
 #if AD_VERSION == AD_VERSION2            
         else if (strcasecmp(val + 1, "v2") == 0)
             options[VOLOPT_ADOUBLE].i_value = AD_VERSION2;
+        else if (strcasecmp(val + 1, "osx") == 0)
+            options[VOLOPT_ADOUBLE].i_value = AD_VERSION2_OSX;
 #endif
     } else if (optionok(tmp, "options:", val)) {
         char *p;
@@ -487,6 +489,34 @@ static void showvol(const ucs2_t *name)
     }
 }
 
+/* ----------------- 
+ * 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, 
@@ -589,6 +619,7 @@ static int creatvol(AFPObj *obj, struct passwd *pwd,
            volume->v_adouble = options[VOLOPT_ADOUBLE].i_value;
        else 
            volume->v_adouble = AD_VERSION;
+       initvoladouble(volume);
 #ifdef FORCE_UIDGID
         if (options[VOLOPT_FORCEUID].c_value) {
             volume->v_forceuid = strdup(options[VOLOPT_FORCEUID].c_value);
@@ -1170,10 +1201,11 @@ int             *buflen;
             slash++;
         else
             slash = vol->v_path;
-
-        ad_setentrylen( &ad, ADEID_NAME, strlen( slash ));
-        memcpy(ad_entry( &ad, ADEID_NAME ), slash,
+        if (ad_getentryoff(&ad, ADEID_NAME)) {
+            ad_setentrylen( &ad, ADEID_NAME, strlen( slash ));
+            memcpy(ad_entry( &ad, ADEID_NAME ), slash,
                ad_getentrylen( &ad, ADEID_NAME ));
+        }
         vol_setdate(vol->v_vid, &ad, st->st_mtime);
         ad_flush(&ad, ADFLAGS_HF);
     }
@@ -2066,9 +2098,11 @@ static int create_special_folder (const struct vol *vol, const struct _special_f
                        return (-1);
                }
                if ((ad_get_HF_flags( &ad ) & O_CREAT) ) {
-                       ad_setentrylen( &ad, ADEID_NAME, strlen(folder->name));
-                       memcpy(ad_entry( &ad, ADEID_NAME ), folder->name,
-                       ad_getentrylen( &ad, ADEID_NAME ));
+                   if (ad_getentryoff(&ad, ADEID_NAME)) {
+                       ad_setentrylen( &ad, ADEID_NAME, strlen(folder->name));
+                       memcpy(ad_entry( &ad, ADEID_NAME ), folder->name,
+                              ad_getentrylen( &ad, ADEID_NAME ));
+                   }
                }
  
                ad_getattr(&ad, &attr);
index e82d535277966883b702435ab6c3c6736eccb5ea..46fb94e0c294c21030bac1dc9eea9a19fab336cb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: volume.h,v 1.19.2.5.2.5 2004-01-03 22:21:09 didg Exp $
+ * $Id: volume.h,v 1.19.2.5.2.6 2004-03-11 02:02:04 didg Exp $
  *
  * Copyright (c) 1990,1994 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -77,6 +77,10 @@ struct vol {
 
     int                 v_root_preexec_close;
     int                 v_preexec_close;
+    
+    /* adouble indirection */
+    int                 (*validupath)(const struct vol *, const char *);
+    char                *(*ad_path)(const char *, int);
 };
 
 #ifdef NO_LARGE_VOL_SUPPORT
index 8f137032187299f2d13e6705a4ca1d4d0518fa98..bace1fddc5f9d346bf40a711e3e18d8f2a96a116 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: adouble.h,v 1.21.6.12 2004-02-20 20:53:14 bfernhomberg Exp $
+ * $Id: adouble.h,v 1.21.6.13 2004-03-11 02:02:04 didg Exp $
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
  * All Rights Reserved.
  *
@@ -77,6 +77,7 @@
 /* version info */
 #define AD_VERSION1    0x00010000
 #define AD_VERSION2    0x00020000
+#define AD_VERSION2_OSX        0x00020001
 #define AD_VERSION     AD_VERSION2
 
 /*
@@ -246,6 +247,8 @@ struct adouble {
     off_t               ad_rlen;     /* ressource fork len with AFP 3.0
                                         the header parameter size is too small.
                                      */
+    char                *(*ad_path)(const char *, int);
+                           
 #ifdef USE_MMAPPED_HEADERS
     char                *ad_data;
 #else
@@ -350,18 +353,20 @@ extern int ad_excl_lock     __P((struct adouble * /*adp*/, const u_int32_t /*eid
 #define ad_unlock ad_fcntl_unlock
 
 /* ad_open.c */
-extern int ad_setfuid __P((const uid_t ));
-extern uid_t ad_getfuid __P((void ));
-
-extern char *ad_dir   __P((const char *));
-extern char *ad_path  __P((const char *, int));
-extern int ad_mode    __P((const char *, int));
-extern int ad_mkdir   __P((const char *, int));
-extern void ad_init   __P((struct adouble *, int ));
-
-extern int ad_open    __P((const char *, int, int, int, struct adouble *)); 
-extern int ad_refresh __P((struct adouble *));
-extern int ad_stat    __P((const char *, struct stat *));
+extern int ad_setfuid     __P((const uid_t ));
+extern uid_t ad_getfuid   __P((void ));
+
+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 int ad_mode        __P((const char *, int));
+extern int ad_mkdir       __P((const char *, int));
+extern void ad_init       __P((struct adouble *, int ));
+
+extern int ad_open        __P((const char *, int, int, int, struct adouble *)); 
+extern int ad_refresh     __P((struct adouble *));
+extern int ad_stat        __P((const char *, struct stat *));
 
 /* extend header to RW if R or W (W if R for locking),
  */ 
index 49c8ff8e21bdcf44d667bbe9f174d83bf5fe0372..5282485bc2b7be47d6b17b8aaf213d1bcfd25a03 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: ad_attr.c,v 1.4.8.3 2004-02-06 13:39:52 bfernhomberg Exp $
+ * $Id: ad_attr.c,v 1.4.8.4 2004-03-11 02:02:05 didg Exp $
  */
 
 #ifdef HAVE_CONFIG_H
 
 int ad_getattr(const struct adouble *ad, u_int16_t *attr)
 {
-  if (ad->ad_version == AD_VERSION1)
-    memcpy(attr, ad_entry(ad, ADEID_FILEI) + FILEIOFF_ATTR,
-          sizeof(u_int16_t));
+   *attr = 0;
+        
+   if (ad->ad_version == AD_VERSION1) {
+       if (ad_getentryoff(ad, ADEID_FILEI)) {
+           memcpy(attr, ad_entry(ad, ADEID_FILEI) + FILEIOFF_ATTR,
+                 sizeof(u_int16_t));
+       }
+   }
 #if AD_VERSION == AD_VERSION2
-  else if (ad->ad_version == AD_VERSION2)
-    memcpy(attr, ad_entry(ad, ADEID_AFPFILEI) + AFPFILEIOFF_ATTR,
-          sizeof(u_int16_t));
+   else if (ad->ad_version == AD_VERSION2) {
+       if (ad_getentryoff(ad, ADEID_AFPFILEI)) {
+           memcpy(attr, ad_entry(ad, ADEID_AFPFILEI) + AFPFILEIOFF_ATTR,
+                 sizeof(u_int16_t));
+       }
+   }      
 #endif
-  else 
-    return -1;
+   else 
+      return -1;
 
-  return 0;
+   return 0;
 }
 
+/* ----------------- */
 int ad_setattr(const struct adouble *ad, const u_int16_t attr)
 {
-  if (ad->ad_version == AD_VERSION1)
-    memcpy(ad_entry(ad, ADEID_FILEI) + FILEIOFF_ATTR, &attr,
-          sizeof(attr));
+   if (ad->ad_version == AD_VERSION1) {
+       if (ad_getentryoff(ad, ADEID_FILEI)) {
+           memcpy(ad_entry(ad, ADEID_FILEI) + FILEIOFF_ATTR, &attr,
+                  sizeof(attr));
+       }
+   }      
 #if AD_VERSION == AD_VERSION2
-  else if (ad->ad_version == AD_VERSION2)
-    memcpy(ad_entry(ad, ADEID_AFPFILEI) + AFPFILEIOFF_ATTR, &attr,
-          sizeof(attr));
+   else if (ad->ad_version == AD_VERSION2) {
+       if (ad_getentryoff(ad, ADEID_AFPFILEI)) {
+            memcpy(ad_entry(ad, ADEID_AFPFILEI) + AFPFILEIOFF_ATTR, &attr,
+                   sizeof(attr));
+       }
+   }      
 #endif
-  else 
-    return -1;
+   else 
+      return -1;
 
-  return 0;
+   return 0;
 }
 
 /* -------------- 
@@ -50,7 +65,8 @@ int ad_setattr(const struct adouble *ad, const u_int16_t attr)
 #if AD_VERSION == AD_VERSION2
 int ad_setid (struct adouble *adp, const dev_t dev, const ino_t ino , const u_int32_t id, const cnid_t did, const void *stamp)
 {
-    if (adp->ad_flags == AD_VERSION2 && sizeof(dev_t) == ADEDLEN_PRIVDEV && sizeof(ino_t) == ADEDLEN_PRIVINO) 
+    if (adp->ad_flags == AD_VERSION2  && ad_getentryoff(adp, ADEID_PRIVDEV) &&
+                sizeof(dev_t) == ADEDLEN_PRIVDEV && sizeof(ino_t) == ADEDLEN_PRIVINO) 
     {
         ad_setentrylen( adp, ADEID_PRIVDEV, sizeof(dev_t));
         memcpy(ad_entry( adp, ADEID_PRIVDEV ), &dev, sizeof(dev_t));
index 5ec1bebadd1a225933e287d738e6c82cbae02456..1742af8437c345f164e6f229c5eda8a2e1e2cff0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: ad_date.c,v 1.3.14.2 2004-02-20 20:18:33 didg Exp $
+ * $Id: ad_date.c,v 1.3.14.3 2004-03-11 02:02:05 didg Exp $
  */
 
 #ifdef HAVE_CONFIG_H
@@ -24,8 +24,11 @@ int ad_setdate(const struct adouble *ad,
     memcpy(ad_entry(ad, ADEID_FILEI) + dateoff, &date, sizeof(date));
 
   } else if (ad->ad_version == AD_VERSION2) {
+    if (!ad_getentryoff(ad, ADEID_FILEDATESI))
+        return -1;
+        
     if (dateoff > AD_DATE_ACCESS)
-      return -1;
+        return -1;
     memcpy(ad_entry(ad, ADEID_FILEDATESI) + dateoff, &date, sizeof(date));
 
   } else 
@@ -46,6 +49,9 @@ int ad_getdate(const struct adouble *ad,
     memcpy(date, ad_entry(ad, ADEID_FILEI) + dateoff, sizeof(u_int32_t));
 
   } else if (ad->ad_version == AD_VERSION2) {
+    if (!ad_getentryoff(ad, ADEID_FILEDATESI))
+        return -1;
+
     if (dateoff > AD_DATE_ACCESS)
       return -1;
     memcpy(date, ad_entry(ad, ADEID_FILEDATESI) + dateoff, sizeof(u_int32_t));
index 09741757216ce8d364c0e7a016bce11f407629ed..6e14a715ab59a783f5e88fa41d57d32f984f4471 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: ad_open.c,v 1.30.6.8 2004-02-20 19:57:14 didg Exp $
+ * $Id: ad_open.c,v 1.30.6.9 2004-03-11 02:02:05 didg Exp $
  *
  * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu)
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
 
 #define ADEDOFF_RFORK_V2     (ADEDOFF_PRIVID + ADEDLEN_PRIVID)
 
+#define ADEID_NUM_OSX        2
+#define ADEDOFF_FINDERI_OSX  (AD_HEADER_LEN + ADEID_NUM_OSX*AD_ENTRY_LEN)
+#define ADEDOFF_RFORK_OSX    (ADEDOFF_FINDERI_OSX + ADEDLEN_FINDERI)
+
 /* we keep local copies of a bunch of stuff so that we can initialize things 
  * correctly. */
 
@@ -191,6 +195,16 @@ static const struct entry entry_order2[ADEID_NUM_V2 +1] = {
 
   {0, 0, 0}
 };
+
+/* OS X adouble finder info and resource fork only
+*/
+static const struct entry entry_order_osx[ADEID_NUM_OSX +1] = {
+  {ADEID_FINDERI, ADEDOFF_FINDERI_OSX, ADEDLEN_FINDERI},
+  {ADEID_RFORK, ADEDOFF_RFORK_OSX, ADEDLEN_INIT},
+
+  {0, 0, 0}
+};
+
 #endif /* AD_VERSION == AD_VERSION2 */
 
 #if AD_VERSION == AD_VERSION2
@@ -206,7 +220,7 @@ static int ad_update(struct adouble *ad, const char *path)
   int fd;
 
   /* check to see if we should convert this header. */
-  if (!path || (ad->ad_version != AD_VERSION2))
+  if (!path || (ad->ad_flags != AD_VERSION2))
     return 0;
   
   if (ad->ad_eid[ADEID_RFORK].ade_off)  
@@ -315,7 +329,7 @@ static int ad_v1tov2(struct adouble *ad, const char *path)
     return 0;
 
   /* we want version1 anyway */
-  if (ad->ad_flags == AD_VERSION1)
+  if (ad->ad_flags != AD_VERSION2)
       return 0;
 
 
@@ -622,8 +636,7 @@ static int ad_header_read(struct adouble *ad, struct stat *hst)
     return 0;
 }
 
-
-/*
+/* ---------------------------------------
  * Put the .AppleDouble where it needs to be:
  *
  *         /   a/.AppleDouble/b
@@ -666,6 +679,39 @@ ad_path( path, adflags )
     return( pathbuf );
 }
 
+/* ---------------------------------------
+ * Put the resource fork where it needs to be:
+ * ._name
+ */
+char *
+ad_path_osx( path, adflags )
+    const char *path;
+    int                adflags;
+{
+    static char        pathbuf[ MAXPATHLEN + 1];
+    char       c, *slash, buf[MAXPATHLEN + 1];
+    
+    if (!strcmp(path,".")) {
+            /* fixme */
+        getcwd(buf, MAXPATHLEN);
+    }
+    else {
+        strncpy(buf, path, MAXPATHLEN);
+    }
+    if (NULL != ( slash = strrchr( buf, '/' )) ) {
+       c = *++slash;
+       *slash = '\0';
+       strncpy( pathbuf, buf, MAXPATHLEN);
+       *slash = c;
+    } else {
+       pathbuf[ 0 ] = '\0';
+       slash = buf;
+    }
+    strncat( pathbuf, "._", MAXPATHLEN - strlen(pathbuf));  
+    strncat( pathbuf, slash, MAXPATHLEN - strlen(pathbuf));
+    return pathbuf;
+}
+
 /*
  * Support inherited protection modes for AppleDouble files.  The supplied
  * mode is ANDed with the parent directory's mask value in lieu of "umask",
@@ -847,6 +893,12 @@ void ad_init(struct adouble *ad, int flags)
 {
     memset( ad, 0, sizeof( struct adouble ) );
     ad->ad_flags = flags;
+    if (flags == AD_VERSION2_OSX) {
+        ad->ad_path     = ad_path_osx;
+    }
+    else {
+        ad->ad_path     = ad_path;
+    }
 }
 
 /* -------------------
@@ -933,7 +985,7 @@ int ad_open( path, adflags, oflags, mode, ad )
        return 0;
     }
 
-    ad_p = ad_path( path, adflags );
+    ad_p = ad->ad_path( path, adflags );
 
     hoflags = oflags & ~O_CREAT;
     hoflags = (hoflags & ~(O_RDONLY | O_WRONLY)) | O_RDWR;
@@ -957,7 +1009,7 @@ int ad_open( path, adflags, oflags, mode, ad )
            admode = ad_hf_mode(admode); 
            errno = 0;
            ad->ad_hf.adf_fd = open( ad_p, oflags,admode );
-           if ( ad->ad_hf.adf_fd < 0 ) {
+           if ( ad->ad_hf.adf_fd < 0 && ad->ad_flags != AD_VERSION2_OSX) {
                /*
                 * Probably .AppleDouble doesn't exist, try to
                 * mkdir it.
@@ -976,13 +1028,11 @@ int ad_open( path, adflags, oflags, mode, ad )
                    st_invalid = ad_mode_st(ad_p, &admode, &st);
                    admode = ad_hf_mode(admode); 
                    ad->ad_hf.adf_fd = open( ad_p, oflags, admode);
-                   if ( ad->ad_hf.adf_fd < 0 ) {
-                       return ad_error(ad, adflags);
-                   }
-               } else {
-                    return ad_error(ad, adflags);
                }
            }
+           if ( ad->ad_hf.adf_fd < 0 ) {
+               return ad_error(ad, adflags);
+           }
            ad->ad_hf.adf_flags = oflags;
            /* just created, set owner if admin owner (root) */
            if (!st_invalid) {
@@ -1029,24 +1079,24 @@ int ad_open( path, adflags, oflags, mode, ad )
 /* ----------------------------------- */
 static int new_rfork(const char *path, struct adouble *ad, int adflags)
 {
-#if 0
-    struct timeval      tv;
-#endif    
     const struct entry  *eid;
     u_int16_t           ashort;
     struct stat         st;
 
     ad->ad_magic = AD_MAGIC;
-    ad->ad_version = ad->ad_flags;
-    if (!ad->ad_version)
-    ad->ad_version = AD_VERSION;
+    ad->ad_version = ad->ad_flags & 0x0f0000;
+    if (!ad->ad_version) {
+        ad->ad_version = AD_VERSION;
+    }
 
     memset(ad->ad_filler, 0, sizeof( ad->ad_filler ));
     memset(ad->ad_data, 0, sizeof(ad->ad_data));
 
 #if AD_VERSION == AD_VERSION2
-    if (ad->ad_version == AD_VERSION2)
+    if (ad->ad_flags == AD_VERSION2)
        eid = entry_order2;
+    else if (ad->ad_flags == AD_VERSION2_OSX)
+       eid = entry_order_osx;
     else
 #endif
        eid = entry_order1;
@@ -1078,12 +1128,6 @@ static int new_rfork(const char *path, struct adouble *ad, int adflags)
                     &ashort, sizeof(ashort));
     }
 
-#if 0
-    if (gettimeofday(&tv, NULL) < 0) {
-       return -1;
-    } 
-#endif
-    
     if (stat(path, &st) < 0) {
        return -1;
     }