/*
- * $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.
*
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 );
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);
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;
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;
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.
*/
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;
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
}
}
+ 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);
+}
/*
- * $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.
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 *));
/*
- * $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.
}
/* 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;
struct utimbuf ut;
size_t slen, dlen;
size_t srem, drem;
-
int err;
/* doesn't exist or the path is too long. */
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 {
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;
ret.u_name = path +tp;
}
+ /* FIXME should we set :
+ ret.st_valid = 1;
+ ret.st_errno = ENOENT;
+ */
+
dir_invalidate(vol, dir);
return &ret;
}
* 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 ));
break;
}
}
- if ( setdirowner( ntohl(aint), -1, vol_noadouble(vol) ) < 0 ) {
+ if ( setdirowner(vol, ntohl(aint), -1 ) < 0 ) {
switch ( errno ) {
case EPERM :
case EACCES :
}
#endif /* 0 */
- if ( setdirowner( -1, ntohl(aint), vol_noadouble(vol) ) < 0 ) {
+ if ( setdirowner(vol, -1, ntohl(aint) ) < 0 ) {
switch ( errno ) {
case EPERM :
case EACCES :
}
#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 :
}
#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 :
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);
* 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;
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;
}
}
}
- 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;
}
}
- /* 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 */
/*
- * $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.
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 *);
/*
- * $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.
if (!strcmp(name, "..") || !strcmp(name, "."))
return NULL;
- if (!(validupath(vol, name)))
+ if (!vol->validupath(vol, name))
return NULL;
/* check for vetoed filenames */
/*
- * $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.
}
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 );
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 ));
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
* 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];
/* 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;
* 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;
/* 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 );
}
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;
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;
}
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) ) {
if (of_findname(s_path))
return AFPERR_DENYCONF;
- p = ctoupath( vol, curdir, newname );
+ p = ctoupath( s_vol, curdir, newname );
if (!p) {
return AFPERR_PARAM;
#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' ) {
/* 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++;
}
#endif /* DROPKLUDGE */
- setvoltime(obj, vol );
+ setvoltime(obj, d_vol );
#ifdef DEBUG
LOG(log_info, logtype_afpd, "end afp_copyfile:");
return( retvalue );
}
-
+/* ----------------------- */
static __inline__ int copy_all(const int dfd, const void *buf,
size_t buflen)
{
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;
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
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) {
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;
}
}
}
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;
}
* 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 */
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;
}
WRITE lock on read only file.
*/
int deletefile( vol, file, checkAttrib )
-struct vol *vol;
+const struct vol *vol;
char *file;
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:
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);
}
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);
* 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:
/*
- * $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.
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));
/*
- * $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.
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.");
}
/* --------------------------------------------
- Factorise some check on a pathname
+ Factorise some checks on a pathname
*/
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 */
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 */
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 );
}
/*
- * $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.
}
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 ),
/*
- * $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.
}
/* --------------------- */
-int setfilemode (path, mode)
+int setfilunixmode (vol, path, mode)
+const struct vol *vol;
struct path* path;
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);
}
/* --------------------- */
}
/* --------------------- */
-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;
}
/* --------------------- */
-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) );
}
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 ) {
}
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;
#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 );
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? */
}
}
}
-/* 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) );
}
}
closedir( dir );
+
+ if (osx) {
+ goto setdirowner_noadouble;
+ }
+
if (( dir = opendir( ".AppleDouble" )) == NULL ) {
if (noadouble)
goto setdirowner_noadouble;
/*
- * $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
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 *));
/*
- * $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.
#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;
}
}
+/* -----------------
+ * 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,
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);
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);
}
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);
/*
- * $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.
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
/*
- * $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.
*
/* version info */
#define AD_VERSION1 0x00010000
#define AD_VERSION2 0x00020000
+#define AD_VERSION2_OSX 0x00020001
#define AD_VERSION AD_VERSION2
/*
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
#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),
*/
/*
- * $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;
}
/* --------------
#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));
/*
- * $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
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
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));
/*
- * $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. */
{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
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)
return 0;
/* we want version1 anyway */
- if (ad->ad_flags == AD_VERSION1)
+ if (ad->ad_flags != AD_VERSION2)
return 0;
return 0;
}
-
-/*
+/* ---------------------------------------
* Put the .AppleDouble where it needs to be:
*
* / a/.AppleDouble/b
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",
{
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;
+ }
}
/* -------------------
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;
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.
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) {
/* ----------------------------------- */
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;
&ashort, sizeof(ashort));
}
-#if 0
- if (gettimeofday(&tv, NULL) < 0) {
- return -1;
- }
-#endif
-
if (stat(path, &st) < 0) {
return -1;
}