/*
- * $Id: nad.c,v 1.14 2006-09-19 01:35:45 didg Exp $
+ * $Id: nad.c,v 1.15 2006-09-29 09:39:16 didg Exp $
*/
#ifdef HAVE_CONFIG_H
initvol(path);
strcpy( nad.adpath[0], path );
strcpy( nad.adpath[1],
- nad.ad.ad_path( nad.adpath[0], ADFLAGS_DF|ADFLAGS_HF ));
+ nad.ad.ad_ops->ad_path( nad.adpath[0], ADFLAGS_HF ));
for ( fork = 0 ; fork < NUMFORKS ; fork++ ) {
if ( stat( nad.adpath[ fork ], &st ) < 0 ) {
if ( errno == ENOENT ) {
strcpy( nad.macname, fh->name );
strcpy( nad.adpath[0], mtoupath( nad.macname ));
strcpy( nad.adpath[1],
- nad.ad.ad_path( nad.adpath[0], ADFLAGS_DF|ADFLAGS_HF ));
+ nad.ad.ad_ops->ad_path( nad.adpath[0], ADFLAGS_HF ));
#if DEBUG
fprintf(stderr, "%s\n", nad.macname);
fprintf(stderr, "%s is adpath[0]\n", nad.adpath[0]);
#endif /* HEXOUTPUT */
nad.offset[ DATA ] = nad.offset[ RESOURCE ] = 0;
- ad_flush( &nad.ad, ADFLAGS_DF|ADFLAGS_HF );
+ ad_flush( &nad.ad );
return( 0 );
}
{
int rv;
if ( status == KEEP ) {
- if (( rv = ad_flush( &nad.ad, ADFLAGS_DF|ADFLAGS_HF )) < 0 ) {
+ if (( rv = ad_flush( &nad.ad )) < 0 ) {
fprintf( stderr, "nad_close rv for flush %d\n", rv );
return( rv );
}
/*
- * $Id: desktop.c,v 1.36 2006-09-19 01:35:45 didg Exp $
+ * $Id: desktop.c,v 1.37 2006-09-29 09:39:16 didg Exp $
*
* See COPYRIGHT.
*
}
if (ad_getentryoff(adp, ADEID_COMMENT)) {
- if ( (ad_getoflags( adp, ADFLAGS_HF ) & O_CREAT) ) {
+ if ( (ad_get_MD_flags( adp ) & O_CREAT) ) {
if ( *path->m_name == '\0' ) {
name = curdir->d_m_name;
} else {
}
ad_setentrylen( adp, ADEID_COMMENT, clen );
memcpy( ad_entry( adp, ADEID_COMMENT ), ibuf, clen );
- ad_flush_metadata( adp );
+ ad_flush( adp );
}
ad_close_metadata( adp);
return( AFP_OK );
if (ad_getentryoff(adp, ADEID_COMMENT)) {
ad_setentrylen( adp, ADEID_COMMENT, 0 );
- ad_flush_metadata( adp );
+ ad_flush( adp );
}
ad_close_metadata( adp);
return( AFP_OK );
/*
- * $Id: directory.c,v 1.83 2006-09-19 23:00:49 didg Exp $
+ * $Id: directory.c,v 1.84 2006-09-29 09:39:16 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
ad_setid(&ad, st->st_dev, st->st_ino, dir->d_did, dir->d_parent->d_did, vol->v_stamp);
}
}
- ad_flush_metadata( &ad);
+ ad_flush( &ad);
ad_close_metadata( &ad);
}
ad_setname(&ad, s_path->m_name);
ad_setid( &ad, s_path->st.st_dev, s_path->st.st_ino, dir->d_did, did, vol->v_stamp);
- ad_flush_metadata( &ad);
+ ad_flush( &ad);
ad_close_metadata( &ad);
createdir_done:
if (!ad_open_metadata( dst, ADFLAGS_DIR, 0, &ad)) {
ad_setname(&ad, newname);
- ad_flush_metadata( &ad);
+ ad_flush( &ad);
ad_close_metadata( &ad);
}
/*
- * $Id: file.c,v 1.102 2006-09-19 23:00:49 didg Exp $
+ * $Id: file.c,v 1.103 2006-09-29 09:39:16 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
* for a folder adp is always null
*/
if (ad_setid(adp, st->st_dev, st->st_ino, aint, did, vol->v_stamp)) {
- ad_flush(adp, ADFLAGS_HF);
+ ad_flush(adp);
}
}
#endif
int getmetadata(struct vol *vol,
u_int16_t bitmap,
struct path *path, struct dir *dir,
- char *buf, int *buflen, struct adouble *adp, int attrbits )
+ char *buf, int *buflen, struct adouble *adp)
{
char *data, *l_nameoff = NULL, *upath;
char *utf_nameoff = NULL;
if ((ma.ma_user & AR_UWRITE)) {
accessmode( upath, &ma, dir , st);
if (!(ma.ma_user & AR_UWRITE)) {
- attrbits |= ATTRBIT_NOWRITE;
+ ashort |= htons(ATTRBIT_NOWRITE);
}
}
#endif
- if (attrbits)
- ashort = htons(ntohs(ashort) | attrbits);
memcpy(data, &ashort, sizeof( ashort ));
data += sizeof( ashort );
break;
struct adouble ad, *adp;
struct ofork *of;
char *upath;
- u_int16_t attrbits = 0;
int opened = 0;
int rc;
opened = PARAM_NEED_ADP(bitmap);
adp = NULL;
+
if (opened) {
+ int flags = (bitmap & (1 << FILPBIT_ATTR))?ADFLAGS_OPENFORKS:0;
upath = path->u_name;
if ((of = of_findname(path))) {
adp = of->of_ad;
- attrbits = ((of->of_ad->ad_df.adf_refcount > 0) ? ATTRBIT_DOPEN : 0);
- attrbits |= ((of->of_ad->ad_hf.adf_refcount > of->of_ad->ad_df.adf_refcount)? ATTRBIT_ROPEN : 0);
} else {
ad_init(&ad, vol->v_adouble, vol->v_ad_options);
adp = &ad;
}
- if ( ad_metadata( upath, 0, adp) < 0 ) {
+ if ( ad_metadata( upath, flags, adp) < 0 ) {
switch (errno) {
case EACCES:
LOG(log_error, logtype_afpd, "getfilparams(%s): %s: check resource fork permission?",
break;
}
}
- if (adp) {
- /* FIXME
- we need to check if the file is open by another process.
- it's slow so we only do it if we have to:
- - bitmap is requested.
- - we don't already have the answer!
- */
- if ((bitmap & (1 << FILPBIT_ATTR))) {
- if (!(attrbits & ATTRBIT_ROPEN)) {
- attrbits |= ad_testlock(adp, ADEID_RFORK, AD_FILELOCK_OPEN_RD) > 0? ATTRBIT_ROPEN : 0;
- attrbits |= ad_testlock(adp, ADEID_RFORK, AD_FILELOCK_OPEN_WR) > 0? ATTRBIT_ROPEN : 0;
- }
- if (!(attrbits & ATTRBIT_DOPEN)) {
- attrbits |= ad_testlock(adp, ADEID_DFORK, AD_FILELOCK_OPEN_RD) > 0? ATTRBIT_DOPEN : 0;
- attrbits |= ad_testlock(adp, ADEID_DFORK, AD_FILELOCK_OPEN_WR) > 0? ATTRBIT_DOPEN : 0;
- }
- }
- }
}
- rc = getmetadata(vol, bitmap, path, dir, buf, buflen, adp, attrbits);
+ rc = getmetadata(vol, bitmap, path, dir, buf, buflen, adp);
if ( adp ) {
ad_close_metadata( adp);
}
return( AFPERR_PARAM );
}
}
- if ( ad_hfileno( adp ) == -1 ) {
+ if ( ad_reso_fileno( adp ) == -1 ) { /* Hard META / HF */
/* on noadouble volumes, just creating the data fork is ok */
if (vol_noadouble(vol)) {
ad_close( adp, ADFLAGS_DF );
path = s_path->m_name;
ad_setname(adp, path);
- ad_flush( adp, ADFLAGS_DF|ADFLAGS_HF );
+ ad_flush( adp);
ad_close( adp, ADFLAGS_DF|ADFLAGS_HF );
createfile_done:
}
if (isad) {
- ad_flush_metadata( adp);
+ ad_flush( adp);
ad_close_metadata( adp);
}
* get two files, it's fixable for our process (eg reopen the new file, get the
* locks, and so on. But it doesn't solve the case with a second process
*/
- if (adp->ad_df.adf_refcount || adp->ad_hf.adf_refcount) {
+ if (adp->ad_open_forks) {
/* FIXME warning in syslog so admin'd know there's a conflict ?*/
return AFPERR_OLOCK; /* little lie */
}
*/
if (!ad_open( dst, ADFLAGS_HF, O_RDWR, 0666, adp)) {
ad_setname(adp, newname);
- ad_flush( adp, ADFLAGS_HF );
+ ad_flush( adp );
ad_close( adp, ADFLAGS_HF );
}
#ifdef DEBUG
return 0;
}
-/* -------------------------- */
-static int copy_fd(int dfd, int sfd)
+/* --------------------------
+ * copy only the fork data stream
+*/
+static int copy_fork(int eid, struct adouble *add, struct adouble *ads)
{
ssize_t cc;
int err = 0;
char filebuf[8192];
+ int sfd, dfd;
+ if (eid == ADEID_DFORK) {
+ sfd = ad_data_fileno(ads);
+ dfd = ad_data_fileno(add);
+ }
+ else {
+ sfd = ad_reso_fileno(ads);
+ dfd = ad_reso_fileno(add);
+ }
+
+ if ((off_t)-1 == lseek(sfd, ad_getentryoff(ads, eid), SEEK_SET))
+ return -1;
+
+ if ((off_t)-1 == lseek(dfd, ad_getentryoff(add, eid), SEEK_SET))
+ return -1;
+
#if 0 /* ifdef SENDFILE_FLAVOR_LINUX */
/* doesn't work With 2.6 FIXME, only check for EBADFD ? */
off_t offset = 0;
}
/* ----------------------------------
- * if newname is NULL (from directory.c) we don't want to copy ressource fork.
+ * if newname is NULL (from directory.c) we don't want to copy the resource fork.
* because we are doing it elsewhere.
* currently if newname is NULL then adp is NULL.
*/
goto done;
}
- if (ad_hfileno(adp) == -1) {
+ if (ad_meta_fileno(adp) == -1 && ad_reso_fileno(adp) == -1) { /* META / HF */
/* no resource fork, don't create one for dst file */
adflags &= ~ADFLAGS_HF;
}
- stat_result = fstat(ad_dfileno(adp), &st); /* saving stat exit code, thus saving us on one more stat later on */
+ stat_result = fstat(ad_data_fileno(adp), &st); /* saving stat exit code, thus saving us on one more stat later on */
if (stat_result < 0) {
/* unlikely but if fstat fails, the default file mode will be 0666. */
}
/* XXX if the source and the dest don't use the same resource type it's broken
*/
- if (ad_hfileno(adp) == -1 || 0 == (err = copy_fd(ad_hfileno(&add), ad_hfileno(adp)))){
+ if (ad_reso_fileno(adp) == -1 || 0 == (err = copy_fork(ADEID_RFORK, &add, adp))){
/* copy the data fork */
- err = copy_fd(ad_dfileno(&add), ad_dfileno(adp));
+ err = copy_fork(ADEID_DFORK, &add, adp);
}
- /* Now, reopen destination file */
if (err < 0) {
ret_err = errno;
}
- ad_close( adp, adflags );
-
- if (ad_close( &add, adflags ) <0) {
- if (!ret_err) {
- ret_err = errno;
- }
- deletefile(d_vol, dst, 0);
- goto done;
- }
if (!ret_err && newname && (adflags & ADFLAGS_HF)) {
/* set the new name in the resource fork */
- ad_init(&add, d_vol->v_adouble, d_vol->v_ad_options);
- if (ad_open_metadata(dst , noadouble, 0, &add) < 0) {
- ret_err = errno;
- }
- else {
- ad_setname(&add, newname);
- ad_flush_metadata( &add);
- if (ad_close_metadata( &add)) {
- ret_err = errno;
- }
- }
+ ad_copy_header(&add, adp);
+ ad_setname(&add, newname);
+ ad_flush( &add );
}
+ ad_close( adp, adflags );
+
+ if (ad_close( &add, adflags ) <0) {
+ ret_err = errno;
+ }
if (ret_err) {
deletefile(d_vol, dst, 0);
ad_open always try to open file RDWR first and ad_lock takes care of
WRITE lock on read only file.
*/
+
+static int check_attrib(struct adouble *adp)
+{
+u_int16_t bshort = 0;
+
+ ad_getattr(adp, &bshort);
+ /*
+ * Does kFPDeleteInhibitBit (bit 8) set?
+ */
+ if ((bshort & htons(ATTRBIT_NODELETE))) {
+ return AFPERR_OLOCK;
+ }
+ if ((bshort & htons(ATTRBIT_DOPEN | ATTRBIT_ROPEN))) {
+ return AFPERR_BUSY;
+ }
+ return 0;
+}
+
int deletefile( vol, file, checkAttrib )
const struct vol *vol;
char *file;
/* try to open both forks at once */
adflags = ADFLAGS_DF|ADFLAGS_HF;
- ad_init(&ad, vol->v_adouble, vol->v_ad_options); /* OK */
+ if (checkAttrib) {
+ /* was EACCESS error try to get only metadata */
+ ad_init(&ad, vol->v_adouble, vol->v_ad_options);
+ if ( ad_metadata( file , ADFLAGS_OPENFORKS, &ad) == 0 ) {
+ ad_close( &ad, adflags );
+ if ((err = check_attrib(&ad))) {
+ return err;
+ }
+ }
+ }
+
while(1) {
+ ad_init(&ad, vol->v_adouble, vol->v_ad_options); /* OK */
if ( ad_open( file, adflags, O_RDONLY, 0, &ad ) < 0 ) {
switch (errno) {
case ENOENT:
}
break; /* from the while */
}
- /*
- * Does kFPDeleteInhibitBit (bit 8) set?
- */
- if (checkAttrib) {
- u_int16_t bshort;
-
- if ( ad_metadata( file , 0, &ad) == 0 ) {
- ad_getattr(&ad, &bshort);
- ad_close_metadata( &ad);
- if ((bshort & htons(ATTRBIT_NODELETE))) {
- return AFPERR_OLOCK;
- }
- }
- }
-
+
if (adp && (adflags & ADFLAGS_HF) ) {
/* FIXME we have a pb here because we want to know if a file is open
* there's a 'priority inversion' if you can't open the ressource fork RW
return 0;
}
if (ad_setid(adp, path.st.st_dev, path.st.st_ino, aint, did, vol->v_stamp)) {
- ad_flush_metadata(adp);
+ ad_flush(adp);
}
ad_close_metadata(adp);
}
}
else {
ret = ad_open( path->u_name, ADFLAGS_HF, O_RDONLY, 0, adp);
- if ( !ret && ad_hfileno(adp) != -1 && !(adp->ad_hf.adf_flags & ( O_RDWR | O_WRONLY))) {
+ /* META and HF */
+ if ( !ret && ad_reso_fileno(adp) != -1 && !(adp->ad_resource_fork.adf_flags & ( O_RDWR | O_WRONLY))) {
/* from AFP spec.
* The user must have the Read & Write privilege for both files in order to use this command.
*/
/* here we need to reopen if crossdev */
if (sid && ad_setid(addp, destst.st_dev, destst.st_ino, sid, sdir->d_did, vol->v_stamp))
{
- ad_flush( addp, ADFLAGS_HF );
+ ad_flush( addp );
}
if (did && ad_setid(adsp, srcst.st_dev, srcst.st_ino, did, curdir->d_did, vol->v_stamp))
{
- ad_flush( adsp, ADFLAGS_HF );
+ ad_flush( adsp );
}
/* change perms, src gets dest perm and vice versa */
of_rename(vol, s_of, curdir, temp, sdir, spath);
err_exchangefile:
- if ( !s_of && adsp && ad_hfileno(adsp) != -1 ) {
+ if ( !s_of && adsp && ad_meta_fileno(adsp) != -1 ) { /* META */
ad_close(adsp, ADFLAGS_HF);
}
- if ( !d_of && addp && ad_hfileno(addp) != -1 ) {
+ if ( !d_of && addp && ad_meta_fileno(addp) != -1 ) {/* META */
ad_close(addp, ADFLAGS_HF);
}
/*
- * $Id: file.h,v 1.19 2006-09-19 23:00:50 didg Exp $
+ * $Id: file.h,v 1.20 2006-09-29 09:39:16 didg Exp $
*
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
#define ATTRBIT_INVISIBLE (1<<0) /* invisible (d) */
#define ATTRBIT_MULTIUSER (1<<1) /* multiuser */
#define ATTRBIT_SYSTEM (1<<2) /* system (d) */
+
+#if 0
+/* define in adouble.h */
#define ATTRBIT_DOPEN (1<<3) /* data fork already open */
#define ATTRBIT_ROPEN (1<<4) /* resource fork already open */
+#endif
+
#define ATTRBIT_SHARED (1<<4) /* shared area (d) */
#define ATTRBIT_NOWRITE (1<<5) /* write inhibit(v2)/read-only(v1) bit */
#define ATTRBIT_BACKUP (1<<6) /* backup needed (d) */
/*
- * $Id: fork.c,v 1.55 2005-09-28 09:46:37 didg Exp $
+ * $Id: fork.c,v 1.56 2006-09-29 09:39:16 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
extern int getmetadata(struct vol *vol,
u_int16_t bitmap,
struct path *path, struct dir *dir, char *buf,
- int *buflen, struct adouble *adp, int attrbits );
+ int *buflen, struct adouble *adp);
-static int getforkparams(ofork, bitmap, buf, buflen, attrbits )
+static int getforkparams(ofork, bitmap, buf, buflen )
struct ofork *ofork;
u_int16_t bitmap;
char *buf;
int *buflen;
-const u_int16_t attrbits;
{
struct path path;
struct stat *st;
return( AFPERR_BITMAP );
}
- if ( ad_hfileno( ofork->of_ad ) == -1 ) {
+ if ( ad_reso_fileno( ofork->of_ad ) == -1 ) { /* META ? */
adp = NULL;
} else {
adp = ofork->of_ad;
if ( bitmap & ( (1<<FILPBIT_DFLEN) | (1<<FILPBIT_EXTDFLEN) |
(1<<FILPBIT_FNUM) | (1 << FILPBIT_CDATE) |
(1 << FILPBIT_MDATE) | (1 << FILPBIT_BDATE))) {
- if ( ad_dfileno( ofork->of_ad ) == -1 ) {
+ if ( ad_data_fileno( ofork->of_ad ) == -1 ) {
if (movecwd(vol, dir) < 0)
return( AFPERR_NOOBJ );
if ( stat( path.u_name, st ) < 0 )
return( AFPERR_NOOBJ );
} else {
- if ( fstat( ad_dfileno( ofork->of_ad ), st ) < 0 ) {
+ if ( fstat( ad_data_fileno( ofork->of_ad ), st ) < 0 ) {
return( AFPERR_BITMAP );
}
}
}
- return getmetadata(vol, bitmap, &path, dir, buf, buflen, adp, attrbits );
+ return getmetadata(vol, bitmap, &path, dir, buf, buflen, adp );
}
/* ---------------------------- */
struct adouble *adsame = NULL;
int buflen, ret, adflags, eid;
u_int32_t did;
- u_int16_t vid, bitmap, access, ofrefnum, attrbits = 0;
+ u_int16_t vid, bitmap, access, ofrefnum;
char fork, *path, *upath;
struct stat *st;
u_int16_t bshort;
FIXME: add the fork we are opening?
*/
if ((opened = of_findname(s_path))) {
- attrbits = ((opened->of_ad->ad_df.adf_refcount > 0) ? ATTRBIT_DOPEN : 0);
- attrbits |= ((opened->of_ad->ad_hf.adf_refcount > opened->of_ad->ad_df.adf_refcount)? ATTRBIT_ROPEN : 0);
-
adsame = opened->of_ad;
}
if ((adflags & ADFLAGS_HF) && (ad_get_HF_flags( ofork->of_ad) & O_CREAT)) {
if (ad_setname(ofork->of_ad, path)) {
- ad_flush( ofork->of_ad, adflags );
+ ad_flush( ofork->of_ad );
}
}
if (( ret = getforkparams(ofork, bitmap, rbuf + 2 * sizeof( u_int16_t ),
- &buflen, attrbits )) != AFP_OK ) {
+ &buflen )) != AFP_OK ) {
ad_close( ofork->of_ad, adflags );
goto openfork_err;
}
/* check WriteInhibit bit if we have a ressource fork
* the test is done here, after some Mac trafic capture
*/
- if (ad_hfileno(ofork->of_ad) != -1) {
+ if (ad_meta_fileno(ofork->of_ad) != -1) { /* META */
ad_getattr(ofork->of_ad, &bshort);
if ((bshort & htons(ATTRBIT_NOWRITE)) && (access & OPENACC_WR)) {
ad_close( ofork->of_ad, adflags );
*/
/* don't try to lock non-existent rforks. */
- if ((eid == ADEID_DFORK) || (ad_hfileno(ofork->of_ad) != -1)) {
+ if ((eid == ADEID_DFORK) || (ad_meta_fileno(ofork->of_ad) != -1)) { /* META */
ret = fork_setmode(ofork->of_ad, eid, access, ofrefnum);
/* can we access the fork? */
if (err < 0)
goto afp_setfork_err;
- if (ad_flush( ofork->of_ad, ADFLAGS_HF ) < 0) {
+ if (ad_flush( ofork->of_ad ) < 0) {
LOG(log_error, logtype_afpd, "afp_setforkparams(%s): ad_flush: %s", of_name(ofork), strerror(errno) );
return AFPERR_PARAM;
}
length = BYTELOCK_MAX;
else if (!length || is_neg(is64, length)) {
return AFPERR_PARAM;
- } else if ((length >= AD_FILELOCK_BASE) && -1 == (ad_hfileno(ofork->of_ad))) {
+ } else if ((length >= AD_FILELOCK_BASE) && -1 == (ad_reso_fileno(ofork->of_ad))) { /* HF ?*/
return AFPERR_LOCK;
}
{
struct extmap *em;
- if ( ad_hfileno( of->of_ad ) == -1 || !memcmp( ufinderi, ad_entry( of->of_ad, ADEID_FINDERI),8)) {
+ if ( ad_meta_fileno( of->of_ad ) == -1 || !memcmp( ufinderi, ad_entry( of->of_ad, ADEID_FINDERI),8)) { /* META */
/* no resource fork or no finderinfo, use our files extension mapping */
if (!( em = getextmap( of_name(of) )) || memcmp( "TEXT", em->em_type, sizeof( em->em_type ))) {
return 0;
int err = 0, doflush = 0;
- if ( ad_dfileno( ofork->of_ad ) != -1 &&
- fsync( ad_dfileno( ofork->of_ad )) < 0 ) {
+ if ( ad_data_fileno( ofork->of_ad ) != -1 &&
+ fsync( ad_data_fileno( ofork->of_ad )) < 0 ) {
LOG(log_error, logtype_afpd, "flushfork(%s): dfile(%d) %s",
- of_name(ofork), ad_dfileno(ofork->of_ad), strerror(errno) );
+ of_name(ofork), ad_data_fileno(ofork->of_ad), strerror(errno) );
err = -1;
}
- if ( ad_hfileno( ofork->of_ad ) != -1 &&
+ if ( ad_reso_fileno( ofork->of_ad ) != -1 && /* HF */
(ofork->of_flags & AFPFORK_RSRC)) {
/* read in the rfork length */
}
/* flush the header */
- if (doflush && ad_flush(ofork->of_ad, ADFLAGS_HF) < 0)
+ if (doflush && ad_flush(ofork->of_ad) < 0)
err = -1;
- if (fsync( ad_hfileno( ofork->of_ad )) < 0)
+ if (fsync( ad_reso_fileno( ofork->of_ad )) < 0)
err = -1;
if (err < 0)
LOG(log_error, logtype_afpd, "flushfork(%s): hfile(%d) %s",
- of_name(ofork), ad_hfileno(ofork->of_ad), strerror(errno) );
+ of_name(ofork), ad_reso_fileno(ofork->of_ad), strerror(errno) );
}
return( err );
}
ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount, ofork->of_refnum);
- if ( ad_hfileno( ofork->of_ad ) != -1 )
+ if ( ad_meta_fileno( ofork->of_ad ) != -1 ) /* META */
ofork->of_flags |= AFPFORK_DIRTY;
*rbuflen = set_off_t (offset, rbuf, is64);
struct ofork *ofork;
int buflen, ret;
u_int16_t ofrefnum, bitmap;
- u_int16_t attrbits = 0;
ibuf += 2;
memcpy(&ofrefnum, ibuf, sizeof( ofrefnum ));
LOG(log_error, logtype_afpd, "afp_getforkparams: of_find(%d) could not locate fork", ofrefnum );
return( AFPERR_PARAM );
}
- attrbits = ((ofork->of_ad->ad_df.adf_refcount > 0) ? ATTRBIT_DOPEN : 0);
- attrbits |= ((ofork->of_ad->ad_hf.adf_refcount > ofork->of_ad->ad_df.adf_refcount) ? ATTRBIT_ROPEN : 0);
- if ( ad_hfileno( ofork->of_ad ) != -1 ) {
+ if ( ad_meta_fileno( ofork->of_ad ) != -1 ) { /* META */
if ( ad_refresh( ofork->of_ad ) < 0 ) {
LOG(log_error, logtype_afpd, "getforkparams(%s): ad_refresh: %s", of_name(ofork), strerror(errno) );
return( AFPERR_PARAM );
}
if (AFP_OK != ( ret = getforkparams( ofork, bitmap,
- rbuf + sizeof( u_short ), &buflen, attrbits ))) {
+ rbuf + sizeof( u_short ), &buflen ))) {
return( ret );
}
/*
- * $Id: ofork.c,v 1.24 2005-09-28 09:46:37 didg Exp $
+ * $Id: ofork.c,v 1.25 2006-09-29 09:39:16 didg Exp $
*
* Copyright (c) 1996 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
int ret;
adflags = 0;
- if ((ofork->of_flags & AFPFORK_DATA) && (ad_dfileno( ofork->of_ad ) != -1)) {
+ if ((ofork->of_flags & AFPFORK_DATA) && (ad_data_fileno( ofork->of_ad ) != -1)) {
adflags |= ADFLAGS_DF;
}
- if ( (ofork->of_flags & AFPFORK_OPEN) && ad_hfileno( ofork->of_ad ) != -1 ) {
+ if ( (ofork->of_flags & AFPFORK_OPEN) && ad_reso_fileno( ofork->of_ad ) != -1 ) {
adflags |= ADFLAGS_HF;
/*
* Only set the rfork's length if we're closing the rfork.
doflush++;
}
if ( doflush ) {
- ad_flush( ofork->of_ad, adflags );
+ ad_flush( ofork->of_ad );
}
}
}
/* rf_renamefile: */ RF_renamefile_ads,
};
+/* =======================================
+ samba sfm format
+ ad_path shouldn't be set here
+ */
+struct vfs_ops netatalk_adouble_sfm = {
+ /* ad_path: */ ad_path_sfm,
+ /* validupath: */ validupath_adouble,
+ /* rf_chown: */ RF_chown_ads,
+ /* rf_renamedir: */ RF_renamedir_adouble,
+ /* rf_deletecurdir: */ RF_deletecurdir_ads,
+ /* rf_setfilmode: */ RF_setfilmode_ads,
+ /* rf_setdirmode: */ RF_setdirmode_ads,
+ /* rf_setdirunixmode:*/ RF_setdirunixmode_ads,
+ /* rf_setdirowner: */ RF_setdirowner_ads,
+ /* rf_deletefile: */ RF_deletefile_ads,
+ /* rf_renamefile: */ RF_renamefile_ads,
+};
+
/* ---------------- */
void initvol_vfs(struct vol *vol)
{
else if (vol->v_adouble == AD_VERSION1_ADS) {
vol->vfs = &netatalk_adouble_ads;
}
+ else if (vol->v_adouble == AD_VERSION1_SFM) {
+ vol->vfs = &netatalk_adouble_sfm;
+ }
else {
vol->vfs = &netatalk_adouble;
}
/*
- * $Id: volume.c,v 1.67 2006-09-19 23:00:50 didg Exp $
+ * $Id: volume.c,v 1.68 2006-09-29 09:39:16 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
options[VOLOPT_ADOUBLE].i_value = AD_VERSION2_OSX;
else if (strcasecmp(val + 1, "ads") == 0)
options[VOLOPT_ADOUBLE].i_value = AD_VERSION1_ADS;
+ else if (strcasecmp(val + 1, "sfm") == 0)
+ options[VOLOPT_ADOUBLE].i_value = AD_VERSION1_SFM;
#endif
} else if (optionok(tmp, "options:", val)) {
char *p;
isad = 0;
vol->v_ctime = AD_DATE_FROM_UNIX(st->st_mtime);
- } else if (ad_get_HF_flags( &ad ) & O_CREAT) {
+ } else if (ad_get_MD_flags( &ad ) & O_CREAT) {
slash = strrchr( vol->v_path, '/' );
if(slash)
slash++;
ad_getentrylen( &ad, ADEID_NAME ));
}
vol_setdate(vol->v_vid, &ad, st->st_mtime);
- ad_flush_metadata(&ad);
+ ad_flush(&ad);
}
else {
if (ad_getdate(&ad, AD_DATE_CREATE, &aint) < 0)
memcpy(&aint, ibuf, sizeof(aint));
ad_setdate(&ad, AD_DATE_BACKUP, aint);
- ad_flush(&ad, ADFLAGS_HF);
+ ad_flush(&ad);
ad_close(&ad, ADFLAGS_HF);
return( AFP_OK );
}
memcpy(ad_entry(&ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF,&attr, sizeof(attr));
}
- ad_flush( &ad, ADFLAGS_HF );
+ ad_flush( &ad );
ad_close( &ad, ADFLAGS_HF );
}
free(p);
case AD_VERSION1_ADS:
strlcat(buf, "ADOUBLE_VER:ads\n", sizeof(buf));
break;
+ case AD_VERSION1_SFM:
+ strlcat(buf, "ADOUBLE_VER:sfm\n", sizeof(buf));
+ break;
}
strlcat(buf, "CNIDBACKEND:", sizeof(buf));
/*
- * $Id: adouble.h,v 1.30 2006-09-19 23:00:50 didg Exp $
+ * $Id: adouble.h,v 1.31 2006-09-29 09:39:16 didg Exp $
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
*
/* version info */
#define AD_VERSION1 0x00010000
+#define SFM_VERSION AD_VERSION1
+
#define AD_VERSION2 0x00020000
#define AD_VERSION2_OSX 0x00020001
#define AD_VERSION1_ADS 0x00010002
+#define AD_VERSION1_SFM 0x00010003
#define AD_VERSION AD_VERSION2
/*
#define ADEID_PRIVINO 17
#define ADEID_PRIVSYN 18 /* in synch with database */
#define ADEID_PRIVID 19
+#define ADEID_SFMRESERVE1 20
+#define ADEID_SFMRESERVE2 21
#define AD_DEV 0x80444556
#define AD_INO 0x80494E4F
#define AD_SYN 0x8053594E
#define AD_ID 0x8053567E
-#define ADEID_MAX 20
+#define ADEID_MAX 22
#endif
/* magic */
#define AD_APPLEDOUBLE_MAGIC 0x00051607
#define AD_MAGIC AD_APPLEDOUBLE_MAGIC
+#define SFM_MAGIC 0x00504641
/* sizes of relevant entry bits */
#define ADEDLEN_MAGIC 4
#define ADEID_NUM_V1 5
#define ADEID_NUM_V2 13
+// #define ADEID_NUM_SFM 5
+/* sizeof SFM meta data */
+#define AD_SFM_LEN 60
+
/* 589 */
#define AD_DATASZ1 (AD_HEADER_LEN + ADEDLEN_NAME + ADEDLEN_COMMENT +ADEDLEN_FILEI +ADEDLEN_FINDERI+\
ADEID_NUM_V1*AD_ENTRY_LEN)
int adf_refcount, adf_lockcount, adf_lockmax;
};
+/* fork attribute */
+#define ATTRBIT_DOPEN (1<<3) /* data fork already open */
+#define ATTRBIT_ROPEN (1<<4) /* resource fork already open */
+
/* some header protection */
#define AD_INITED 0xad494e54 /* ad"INT" */
+struct adouble_fops;
+
struct adouble {
u_int32_t ad_magic;
u_int32_t ad_version;
char ad_filler[ 16 ];
struct ad_entry ad_eid[ ADEID_MAX ];
- struct ad_fd ad_df, ad_hf;
+ struct ad_fd ad_data_fork, ad_resource_fork, ad_metadata_fork;
+ struct ad_fd *ad_md; /* either ad_resource or ad_metadata */
+
int ad_flags;
unsigned int ad_inited;
int ad_options;
*/
char *ad_m_name; /* mac name for open fork */
int ad_m_namelen;
+ struct adouble_fops *ad_ops;
- char *(*ad_path)(const char *, int);
- int (*ad_mkrf)(char *);
+
+ u_int16_t ad_open_forks; /* open forks (by others) */
#ifdef USE_MMAPPED_HEADERS
char *ad_data;
#endif
};
+struct adouble_fops {
+ char *(*ad_path)(const char *, int);
+ int (*ad_mkrf)(char *);
+
+ int (*ad_rebuild_header)(struct adouble *);
+ int (*ad_check_header)(struct adouble *, struct stat *);
+ int (*ad_header_read)(struct adouble *, struct stat *);
+
+ int (*ad_header_upgrade)(struct adouble *, char *);
+
+};
+
#define ADFLAGS_DF (1<<0)
-#define ADFLAGS_HF (1<<1)
+#define ADFLAGS_HF (1<<1)
#define ADFLAGS_DIR (1<<2)
#define ADFLAGS_NOADOUBLE (1<<3)
#define ADFLAGS_V1COMPAT (1<<4)
#define ADFLAGS_NOHF (1<<5) /* not an error if no ressource fork */
#define ADFLAGS_RDONLY (1<<6) /* don't try readwrite */
+#define ADFLAGS_OPENFORKS (1<<7) /* check for open fork in ad_metadata function */
+#define ADFLAGS_RF (1<<8)
+#define ADFLAGS_MD ADFLAGS_HF /* (1<<9) */
/* adouble v2 cnid cache */
#define ADVOL_NODEV (1 << 0)
#define AD_AFPFILEI_GROUP (1 << 1) /* ignore group */
#define AD_AFPFILEI_BLANKACCESS (1 << 2) /* blank access permissions */
-#define ad_dfileno(ad) ((ad)->ad_df.adf_fd)
-#define ad_hfileno(ad) ((ad)->ad_hf.adf_fd)
+#define ad_data_fileno(ad) ((ad)->ad_data_fork.adf_fd)
+#define ad_reso_fileno(ad) ((ad)->ad_resource_fork.adf_fd)
+#define ad_meta_fileno(ad) ((ad)->ad_md->adf_fd)
+
#define ad_getversion(ad) ((ad)->ad_version)
#define ad_getentrylen(ad,eid) ((ad)->ad_eid[(eid)].ade_len)
#define ad_getentryoff(ad,eid) ((ad)->ad_eid[(eid)].ade_off)
#define ad_entry(ad,eid) ((caddr_t)(ad)->ad_data + \
(ad)->ad_eid[(eid)].ade_off)
-#define ad_getoflags(ad,adf) (((adf)&ADFLAGS_HF) ? \
- (ad)->ad_hf.adf_flags : (ad)->ad_df.adf_flags)
-#define ad_get_HF_flags(ad) ((ad)->ad_hf.adf_flags)
+#define ad_get_HF_flags(ad) ((ad)->ad_resource_fork.adf_flags)
+#define ad_get_MD_flags(ad) ((ad)->ad_md->adf_flags)
+
+/* ad_flush.c
+
+*/
+extern int ad_rebuild_adouble_header __P((struct adouble *));
+extern int ad_rebuild_sfm_header __P((struct adouble *));
-/* ad_flush.c */
-extern void ad_rebuild_header __P((struct adouble *));
-extern int ad_flush __P((struct adouble *, int));
+extern int ad_flush __P((struct adouble *));
extern int ad_close __P((struct adouble *, int));
/* ad_lock.c */
extern char *ad_path __P((const char *, int));
extern char *ad_path_osx __P((const char *, int));
extern char *ad_path_ads __P((const char *, int));
+extern char *ad_path_sfm __P((const char *, int));
extern int ad_mode __P((const char *, int));
extern int ad_mkdir __P((const char *, int));
extern int ad_metadata __P((const char *, int, struct adouble *));
#define ad_open_metadata(name, flags, mode, adp)\
- ad_open(name, ADFLAGS_HF|(flags), O_RDWR |(mode), 0666, (adp))
+ ad_open(name, ADFLAGS_MD|(flags), O_RDWR |(mode), 0666, (adp))
-#define ad_flush_metadata(adp) ad_flush( (adp), ADFLAGS_HF)
-#define ad_close_metadata(adp) ad_close( (adp), ADFLAGS_HF)
+#define ad_close_metadata(adp) ad_close( (adp), ADFLAGS_MD)
/* build a resource fork mode from the data fork mode:
* remove X mode and extend header to RW if R or W (W if R for locking),
/*
- * $Id: ad_attr.c,v 1.5 2005-04-28 20:49:51 bfernhomberg Exp $
+ * $Id: ad_attr.c,v 1.6 2006-09-29 09:39:16 didg Exp $
*/
#ifdef HAVE_CONFIG_H
else
return -1;
+ *attr |= htons(ad->ad_open_forks);
+
return 0;
}
/* ----------------- */
-int ad_setattr(const struct adouble *ad, const u_int16_t attr)
+int ad_setattr(const struct adouble *ad, const u_int16_t attribute)
{
+ /* we don't save open forks indicator */
+ u_int16_t attr = attribute & ~htons(ATTRBIT_DOPEN | ATTRBIT_ROPEN);
+
if (ad->ad_version == AD_VERSION1) {
if (ad_getentryoff(ad, ADEID_FILEI)) {
memcpy(ad_entry(ad, ADEID_FILEI) + FILEIOFF_ATTR, &attr,
* note inode and device are opaques and not in network order
* only use the ID if adouble is writable for us.
*/
- if (adp && ( adp->ad_options & ADVOL_CACHE) && ( adp->ad_hf.adf_flags & O_RDWR )
+ if (adp && ( adp->ad_options & ADVOL_CACHE) && ( adp->ad_md->adf_flags & O_RDWR )
&& sizeof(dev_t) == ad_getentrylen(adp, ADEID_PRIVDEV)
&& sizeof(ino_t) == ad_getentrylen(adp,ADEID_PRIVINO)
&& sizeof(temp) == ad_getentrylen(adp,ADEID_PRIVSYN)
/*
- * $Id: ad_date.c,v 1.4 2005-04-28 20:49:51 bfernhomberg Exp $
+ * $Id: ad_date.c,v 1.5 2006-09-29 09:39:16 didg Exp $
*/
#ifdef HAVE_CONFIG_H
date = AD_DATE_FROM_UNIX(date);
if (ad->ad_version == AD_VERSION1) {
+
+ if (!ad_getentryoff(ad, ADEID_FILEI))
+ return -1;
+
if (dateoff > AD_DATE_BACKUP)
return -1;
memcpy(ad_entry(ad, ADEID_FILEI) + dateoff, &date, sizeof(date));
if (ad->ad_version == AD_VERSION1) {
if (dateoff > AD_DATE_BACKUP)
return -1;
+ if (!ad_getentryoff(ad, ADEID_FILEI))
+ return -1;
memcpy(date, ad_entry(ad, ADEID_FILEI) + dateoff, sizeof(u_int32_t));
} else if (ad->ad_version == AD_VERSION2) {
/*
- * $Id: ad_flush.c,v 1.7 2005-04-28 20:49:52 bfernhomberg Exp $
+ * $Id: ad_flush.c,v 1.8 2006-09-29 09:39:16 didg Exp $
*
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
#include <config.h>
#endif /* HAVE_CONFIG_H */
+#include <string.h>
#include <atalk/adouble.h>
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
#include <errno.h>
#include "ad_private.h"
#define EID_DISK(a) (set_eid[a])
#endif
-/* rebuild the header */
-void ad_rebuild_header(struct adouble *ad)
+/* rebuild the adouble header
+ * XXX should be in a separate file ?
+*/
+int ad_rebuild_adouble_header(struct adouble *ad)
{
u_int32_t eid;
u_int32_t temp;
}
nent = htons( nent );
memcpy(nentp, &nent, sizeof( nent ));
+ return ad_getentryoff(ad, ADEID_RFORK);
+}
+
+/* -------------------
+ * XXX copy only header with same size or comment
+ * doesn't work well for adouble with different version.
+ *
+*/
+int ad_copy_header(struct adouble *add, struct adouble *ads)
+{
+ u_int32_t eid;
+ int len;
+
+ for ( eid = 0; eid < ADEID_MAX; eid++ ) {
+ if ( ads->ad_eid[ eid ].ade_off == 0 ) {
+ continue;
+ }
+
+ if ( add->ad_eid[ eid ].ade_off == 0 ) {
+ continue;
+ }
+
+ len = ads->ad_eid[ eid ].ade_len;
+ if (!len) {
+ continue;
+ }
+
+ if (eid != ADEID_COMMENT && add->ad_eid[ eid ].ade_len != len ) {
+ continue;
+ }
+
+ ad_setentrylen( add, eid, len );
+ memcpy( ad_entry( add, eid ), ad_entry( ads, eid ), len );
+ }
+ add->ad_rlen = ads->ad_rlen;
+ return 0;
}
+/* ------------------- */
+int ad_rebuild_sfm_header(struct adouble *ad)
+{
+ u_int32_t eid;
+ u_int32_t temp;
+
+ u_int16_t attr;
+ char *buf, *nentp;
-int ad_flush( ad, adflags )
+ /*
+ * Rebuild any header information that might have changed.
+ */
+ buf = ad->ad_data;
+ /* FIXME */
+// temp = htonl( ad->ad_magic );
+ temp = ad->ad_magic;
+ memcpy(buf, &temp, sizeof( temp ));
+
+// temp = htonl( ad->ad_version );
+ temp = ad->ad_version;
+ memcpy(buf +4, &temp, sizeof( temp ));
+
+ /* need to save attrib */
+ if (!ad_getattr(ad, &attr)) {
+ attr &= ~htons(ATTRBIT_DOPEN | ATTRBIT_ROPEN);
+
+ memcpy(buf +48 +4, &attr, sizeof(attr));
+
+ }
+ return AD_SFM_LEN;
+}
+
+
+int ad_flush( ad )
struct adouble *ad;
- int adflags;
{
int len;
- if (( adflags & ADFLAGS_HF ) && ( ad->ad_hf.adf_flags & O_RDWR )) {
+ if (( ad->ad_md->adf_flags & O_RDWR )) {
/* sync our header */
if (ad->ad_rlen > 0xffffffff) {
ad_setentrylen(ad, ADEID_RFORK, 0xffffffff);
else {
ad_setentrylen(ad, ADEID_RFORK, ad->ad_rlen);
}
- ad_rebuild_header(ad);
- len = ad_getentryoff(ad, ADEID_RFORK);
- /* now flush it out */
- if (adf_pwrite(&ad->ad_hf, ad->ad_data, len, 0) != len) {
+ len = ad->ad_ops->ad_rebuild_header(ad);
+
+ if (adf_pwrite(ad->ad_md, ad->ad_data, len, 0) != len) {
if ( errno == 0 ) {
errno = EIO;
}
{
int err = 0;
- if (( adflags & ADFLAGS_DF ) && ad->ad_df.adf_fd != -1 &&
- !(--ad->ad_df.adf_refcount)) {
- if ( close( ad->ad_df.adf_fd ) < 0 ) {
+ if (( adflags & ADFLAGS_DF ) && ad_data_fileno(ad) != -1 &&
+ !(--ad->ad_data_fork.adf_refcount)) {
+ if ( close( ad_data_fileno(ad) ) < 0 ) {
err = -1;
}
- ad->ad_df.adf_fd = -1;
- adf_lock_free(&ad->ad_df);
+ ad_data_fileno(ad) = -1;
+ adf_lock_free(&ad->ad_data_fork);
}
- if (( adflags & ADFLAGS_HF ) && ad->ad_hf.adf_fd != -1 &&
- !(--ad->ad_hf.adf_refcount)) {
- if ( close( ad->ad_hf.adf_fd ) < 0 ) {
+ if (!( adflags & ADFLAGS_HF )) {
+ return err;
+ }
+
+ /* meta /resource fork */
+
+ if ( ad_meta_fileno(ad) != -1 && !(--ad->ad_md->adf_refcount)) {
+ if ( close( ad_meta_fileno(ad) ) < 0 ) {
err = -1;
}
- ad->ad_hf.adf_fd = -1;
- adf_lock_free(&ad->ad_hf);
+ ad_meta_fileno(ad) = -1;
+ adf_lock_free(ad->ad_md);
}
- return( err );
+ if (ad->ad_flags != AD_VERSION1_SFM) {
+ return err;
+ }
+
+ if ((adflags & ADFLAGS_DIR)) {
+ return err;
+ }
+
+ if ( ad_reso_fileno(ad) != -1 && !(--ad->ad_resource_fork.adf_refcount)) {
+ if ( close( ad_reso_fileno(ad) ) < 0 ) {
+ err = -1;
+ }
+ ad_reso_fileno(ad) = -1;
+ adf_lock_free(&ad->ad_resource_fork);
+ }
+
+ return err;
}
/*
- * $Id: ad_lock.c,v 1.12 2005-04-28 20:49:52 bfernhomberg Exp $
+ * $Id: ad_lock.c,v 1.13 2006-09-29 09:39:16 didg Exp $
*
* Copyright (c) 1998,1999 Adrian Sun (asun@zoology.washington.edu)
* All Rights Reserved. See COPYRIGHT for more information.
lock.l_start = off;
type = locktype;
if (eid == ADEID_DFORK) {
- adf = &ad->ad_df;
+ adf = &ad->ad_data_fork;
if ((type & ADLOCK_FILELOCK)) {
- if (ad_hfileno(ad) != -1) {
+ if (ad_meta_fileno(ad) != -1) { /* META */
+ adf = ad->ad_md;
lock.l_start = df2off(off);
- adf = &ad->ad_hf;
}
}
} else { /* rfork */
- adf = &ad->ad_hf;
- if (adf->adf_fd == -1) {
- /* there's no resource fork. return a lock error
+ if (ad_meta_fileno(ad) == -1 || ad_reso_fileno(ad) == -1) {
+ /* there's no meta data. return a lock error
* otherwise if a second process is able to create it
* locks are a mess.
*/
errno = EACCES;
return -1;
}
- if (type & ADLOCK_FILELOCK)
+ if (type & ADLOCK_FILELOCK) {
+ adf = ad->ad_md; /* either resource or meta data (set in ad_open) */
lock.l_start = hf2off(off);
- else
+ }
+ else {
+ /* we really want the resource fork it's a byte lock */
+ adf = &ad->ad_resource_fork;
lock.l_start += ad_getentryoff(ad, eid);
+ }
}
/* NOTE: we can't write lock a read-only file. on those, we just
* make sure that we have a read lock set. that way, we at least prevent
lock.l_start = off;
if (eid == ADEID_DFORK) {
- adf = &ad->ad_df;
- if ((ad_hfileno(ad) != -1)) {
- adf = &ad->ad_hf;
+ adf = &ad->ad_data_fork;
+ if ((ad_meta_fileno(ad) != -1)) {
+ adf = ad->ad_md;
lock.l_start = df2off(off);
}
}
else { /* rfork */
- if ((ad_hfileno(ad) == -1)) {
+ if ((ad_meta_fileno(ad) == -1)) {
/* there's no resource fork. return no lock */
return 0;
}
- adf = &ad->ad_hf;
+ adf = ad->ad_md;
lock.l_start = hf2off(off);
}
lock.l_start = off;
type = locktype;
if (eid == ADEID_DFORK) {
- adf = &ad->ad_df;
+ adf = &ad->ad_data_fork;
} else {
- adf = &ad->ad_hf;
+ /* FIXME META */
+ adf = &ad->ad_resource_fork;
if (adf->adf_fd == -1) {
/* there's no resource fork. return success */
return 0;
lock.l_len = 0;
if (eid == ADEID_DFORK) {
- adf = &ad->ad_df;
+ adf = &ad->ad_data_fork;
} else {
- adf = &ad->ad_hf;
+ adf = &ad->ad_resource_fork;
lock.l_start = ad_getentryoff(ad, eid);
}
/* --------------------- */
void ad_fcntl_unlock(struct adouble *ad, const int user)
{
- if (ad->ad_df.adf_fd != -1) {
- adf_unlock(&ad->ad_df, user);
+ if (ad_data_fileno(ad) != -1) {
+ adf_unlock(&ad->ad_data_fork, user);
}
- if (ad->ad_hf.adf_fd != -1) {
- adf_unlock(&ad->ad_hf, user);
+ if (ad_reso_fileno(ad) != -1) {
+ adf_unlock(&ad->ad_resource_fork, user);
}
+
+ if (ad->ad_flags != AD_VERSION1_SFM) {
+ return;
+ }
+ if (ad_meta_fileno(ad) != -1) {
+ adf_unlock(&ad->ad_metadata_fork, user);
+ }
+
}
/*
- * $Id: ad_open.c,v 1.36 2006-09-19 23:00:50 didg Exp $
+ * $Id: ad_open.c,v 1.37 2006-09-29 09:39:16 didg Exp $
*
* Copyright (c) 1999 Adrian Sun (asun@u.washington.edu)
* Copyright (c) 1990,1991 Regents of The University of Michigan.
{0, 0, 0}
};
+#define ADEID_NUM_SFM 3
+static const struct entry entry_order_sfm[ADEID_NUM_SFM +1] = {
+ {ADEID_FINDERI, 16, ADEDLEN_FINDERI}, /* 9 */
+ {ADEID_SFMRESERVE2, 16+32, 6}, /* 21 */
+ {ADEID_FILEI, 60, ADEDLEN_FILEI}, /* 7 */
+
+ {0, 0, 0}
+};
+
#endif /* AD_VERSION == AD_VERSION2 */
#if AD_VERSION == AD_VERSION2
if (!path || ad->ad_flags != AD_VERSION2)
return 0;
- if (!(ad->ad_hf.adf_flags & O_RDWR)) {
+ if (!(ad->ad_md->adf_flags & O_RDWR)) {
/* we were unable to open the file read write the last time */
return 0;
}
if (ad_tmplock(ad, ADEID_RFORK, ADLOCK_WR, 0, 0, 0) < 0)
goto bail_err;
- fd = ad->ad_hf.adf_fd;
+ fd = ad->ad_md->adf_fd;
if (fstat(fd, &st)) {
goto bail_lock;
/* rebuild the header and cleanup */
LOG(log_debug, logtype_default, "updated AD2 header %s", path);
- ad_flush(ad, ADFLAGS_HF );
+ ad_flush(ad );
ret = 0;
bail_lock:
return 0;
}
- if (!(ad->ad_hf.adf_flags & ( O_RDWR))) {
+ if (!(ad->ad_md->adf_flags & ( O_RDWR))) {
/* we were unable to open the file read write the last time */
return 0;
}
goto bail_err;
/* we reuse fd from the resource fork */
- fd = ad->ad_hf.adf_fd;
+ fd = ad->ad_md->adf_fd;
if (ad->ad_eid[ADEID_RFORK].ade_off) {
shiftdata = ADEDOFF_RFORK_V2 -ad->ad_eid[ADEID_RFORK].ade_off;
memset(ad_entry(ad, ADEID_PRODOSFILEI), 0, ADEDLEN_PRODOSFILEI);
/* rebuild the header and cleanup */
- ad_flush(ad, ADFLAGS_HF );
+ ad_flush(ad );
ret = 0;
bail_lock:
struct stat st;
/* read the header */
- if ((header_len = adf_pread( &ad->ad_hf, buf, sizeof(ad->ad_data), 0)) < 0) {
+ if ((header_len = adf_pread( ad->ad_md, buf, sizeof(ad->ad_data), 0)) < 0) {
return -1;
}
if (header_len < AD_HEADER_LEN) {
if (hst == NULL) {
hst = &st;
- if (fstat(ad->ad_hf.adf_fd, &st) < 0) {
+ if (fstat(ad->ad_md->adf_fd, &st) < 0) {
return 1; /* fail silently */
}
}
return 0;
}
+/* ---------------------------
+ SFM structure
+ */
+#if 0
+typedef struct {
+ byte afpi_Signature[4]; /* Must be 0x00504641 */
+ byte afpi_Version[4]; /* Must be 0x00010000 */
+ byte afpi_Reserved1[4];
+ byte afpi_BackupTime[4]; /* Backup time for the file/dir */
+ byte finderinfo[32]; /* Finder info */
+ byte afpi_ProDosInfo[6]; /* ProDos Info */
+ byte afpi_Reserved2[6];
+} sfm_info;
+#endif
+
+static int ad_header_sfm_read(struct adouble *ad, struct stat *hst)
+{
+ char *buf = ad->ad_data;
+ const struct entry *eid;
+ u_int16_t nentries;
+ int len;
+ ssize_t header_len;
+ static int warning = 0;
+ struct stat st;
+
+ /* read the header */
+ if ((header_len = adf_pread( ad->ad_md, buf, sizeof(ad->ad_data), 0)) < 0) {
+ return -1;
+ }
+ if (header_len != AD_SFM_LEN) {
+ errno = EIO;
+ return -1;
+ }
+
+ memcpy(&ad->ad_magic, buf, sizeof( ad->ad_magic ));
+ memcpy(&ad->ad_version, buf + 4, sizeof( ad->ad_version ));
+
+ /* FIXME in the the great Microsoft tradition they aren't in network order */
+#if 0
+ if (ad->ad_magic == SFM_MAGIC && ad->ad_version == AD_VERSION1) {
+ if (!warning) {
+ LOG(log_debug, logtype_default, "notice: fixing up byte-swapped v1 magic/version.");
+ warning++;
+ }
+
+ } else {
+ ad->ad_magic = ntohl( ad->ad_magic );
+ ad->ad_version = ntohl( ad->ad_version );
+ }
+#endif
+ if ((ad->ad_magic != SFM_MAGIC) || ((ad->ad_version != AD_VERSION1) )) {
+ errno = EIO;
+ LOG(log_debug, logtype_default, "ad_header_sfm_read: can't parse AppleDouble header.");
+ return -1;
+ }
+
+ /* reinit adouble table */
+ eid = entry_order_sfm;
+ while (eid->id) {
+ ad->ad_eid[eid->id].ade_off = eid->offset;
+ ad->ad_eid[eid->id].ade_len = eid->len;
+ eid++;
+ }
+
+ /* steal some prodos for attribute */
+ {
+
+ u_int16_t attribute;
+ memcpy(&attribute, buf + 48 +4, sizeof(attribute));
+ ad_setattr(ad, attribute );
+ }
+
+ if (ad->ad_resource_fork.adf_fd != -1) {
+ /* we have a resource fork use it rather than the metadata */
+ if (fstat(ad->ad_resource_fork.adf_fd, &st) < 0) {
+ /* XXX set to zero ?
+ ad->ad_rlen = 0;
+ */
+ return 1;
+ }
+ ad->ad_rlen = st.st_size;
+ hst = &st;
+ }
+ else if (hst == NULL) {
+ hst = &st;
+ if (fstat(ad->ad_md->adf_fd, &st) < 0) {
+ return 1; /* fail silently */
+ }
+ }
+
+ /* fix up broken dates */
+ if (ad->ad_version == AD_VERSION1) {
+ u_int32_t aint;
+
+ /* check to see if the ad date is wrong. just see if we have
+ * a modification date in the future. */
+ if (((ad_getdate(ad, AD_DATE_MODIFY | AD_DATE_UNIX, &aint)) == 0) &&
+ (aint > TIMEWARP_DELTA + hst->st_mtime)) {
+ ad_setdate(ad, AD_DATE_MODIFY | AD_DATE_UNIX, aint - AD_DATE_DELTA);
+ ad_getdate(ad, AD_DATE_CREATE | AD_DATE_UNIX, &aint);
+ ad_setdate(ad, AD_DATE_CREATE | AD_DATE_UNIX, aint - AD_DATE_DELTA);
+ ad_getdate(ad, AD_DATE_BACKUP | AD_DATE_UNIX, &aint);
+ ad_setdate(ad, AD_DATE_BACKUP | AD_DATE_UNIX, aint - AD_DATE_DELTA);
+ }
+ }
+
+ return 0;
+}
+
/* ---------------------------------------
* Put the .AppleDouble where it needs to be:
*
strlcat( pathbuf, slash, MAXPATHLEN +1);
strlcat( pathbuf, "/Afp_AfpInfo", MAXPATHLEN +1);
+ return( pathbuf );
+}
-#if 0
- if ((adflags & ADFLAGS_HF)) {
- strlcat( pathbuf, "Afp_AfpInfo", MAXPATHLEN +1);
+/* ----------------------
+ * mostly the same as ads, only case change Afp --> AFP and AFP_Resoure
+*/
+char *
+ad_path_sfm( path, adflags )
+ const char *path;
+ int adflags;
+{
+ static char pathbuf[ MAXPATHLEN + 1];
+ char c, *slash, buf[MAXPATHLEN + 1];
+ size_t l;
+
+ l = strlcpy(buf, path, MAXPATHLEN +1);
+ if ( adflags & ADFLAGS_DIR ) {
+ strcpy( pathbuf, buf);
+ if ( *buf != '\0' && l < MAXPATHLEN) {
+ pathbuf[l++] = '/';
+ pathbuf[l] = 0;
+ }
+ slash = ".Parent";
+ } else {
+ if (NULL != ( slash = strrchr( buf, '/' )) ) {
+ c = *++slash;
+ *slash = '\0';
+ strcpy( pathbuf, buf);
+ *slash = c;
+ } else {
+ pathbuf[ 0 ] = '\0';
+ slash = buf;
+ }
+ }
+ strlcat( pathbuf, ".AppleDouble/", MAXPATHLEN +1);
+ strlcat( pathbuf, slash, MAXPATHLEN +1);
+
+ if ((adflags == ADFLAGS_RF)) {
+ strlcat( pathbuf, "/AFP_Resource", MAXPATHLEN +1);
+ }
else {
- strlcat( pathbuf, "Afp_Resource", MAXPATHLEN +1);
+ strlcat( pathbuf, "/AFP_AfpInfo", MAXPATHLEN +1);
}
-#endif
return( pathbuf );
}
#define AD_SET(a) a = 0
#endif
+/* --------------------------- */
+static int ad_check_size(struct adouble *ad, struct stat *st)
+{
+ if (st->st_size > 0 && st->st_size < AD_DATASZ1)
+ return 1;
+ return 0;
+}
+
+/* --------------------------- */
+static int ad_check_size_sfm(struct adouble *ad, struct stat *st)
+{
+ if (st->st_size > 0 && st->st_size < AD_SFM_LEN)
+ return 1;
+ return 0;
+}
+
+/* --------------------------- */
+static int ad_header_upgrade(struct adouble *ad, char *name)
+{
+#if AD_VERSION == AD_VERSION2
+ int ret;
+ if ( (ret = ad_convert(ad, name)) < 0 || (ret = ad_update(ad, name) < 0)) {
+ return ret;
+ }
+#endif
+ return 0;
+}
+
+/* --------------------------- */
+static int ad_header_upgrade_none(struct adouble *ad, char *name)
+{
+ return 0;
+}
+
+/* --------------------------- */
+static struct adouble_fops ad_osx = {
+ &ad_path_osx,
+ &ad_mkrf_osx,
+ &ad_rebuild_adouble_header,
+ &ad_check_size,
+
+ &ad_header_read,
+ &ad_header_upgrade,
+};
+
+static struct adouble_fops ad_ads = {
+ &ad_path_ads,
+ &ad_mkrf_ads,
+ &ad_rebuild_adouble_header,
+ &ad_check_size,
+
+ &ad_header_read,
+ &ad_header_upgrade,
+};
+
+static struct adouble_fops ad_sfm = {
+ &ad_path_sfm,
+ &ad_mkrf_ads,
+ &ad_rebuild_sfm_header,
+ &ad_check_size_sfm,
+
+ &ad_header_sfm_read,
+ &ad_header_upgrade_none,
+};
+
+static struct adouble_fops ad_adouble = {
+ &ad_path,
+ &ad_mkrf,
+ &ad_rebuild_adouble_header,
+ &ad_check_size,
+
+ &ad_header_read,
+ &ad_header_upgrade,
+};
+
+
void ad_init(struct adouble *ad, int flags, int options)
{
memset( ad, 0, sizeof( struct adouble ) );
ad->ad_flags = flags;
if (flags == AD_VERSION2_OSX) {
- ad->ad_path = ad_path_osx;
- ad->ad_mkrf = ad_mkrf_osx;
+ ad->ad_ops = &ad_osx;
}
else if (flags == AD_VERSION1_ADS) {
- ad->ad_path = ad_path_ads;
- ad->ad_mkrf = ad_mkrf_ads;
+ ad->ad_ops = &ad_ads;
+ }
+ else if (flags == AD_VERSION1_SFM) {
+ ad->ad_ops = &ad_sfm;
}
else {
- ad->ad_path = ad_path;
- ad->ad_mkrf = ad_mkrf;
+ ad->ad_ops = &ad_adouble;
}
ad->ad_options = options;
}
int adflags, oflags, mode;
struct adouble *ad;
{
- struct stat st;
+ struct stat st_dir;
+ struct stat st_meta;
+ struct stat *pst = NULL;
char *ad_p;
int hoflags, admode;
int st_invalid = -1;
int open_df = 0;
if (ad->ad_inited != AD_INITED) {
- ad_dfileno(ad) = -1;
- ad_hfileno(ad) = -1;
- adf_lock_init(&ad->ad_df);
- adf_lock_init(&ad->ad_hf);
+ ad_data_fileno(ad) = -1;
+ ad_reso_fileno(ad) = -1;
+ adf_lock_init(&ad->ad_data_fork);
+ adf_lock_init(&ad->ad_resource_fork);
+ if (ad->ad_flags != AD_VERSION1_SFM) {
+ ad->ad_md = &ad->ad_resource_fork;
+ }
+ else {
+ adf_lock_init(&ad->ad_metadata_fork);
+ ad->ad_md = &ad->ad_metadata_fork;
+ ad_meta_fileno(ad) = -1;
+ }
ad->ad_inited = AD_INITED;
ad->ad_refcount = 1;
+ ad->ad_open_forks = 0;
+ }
+ else {
+ ad->ad_open_forks = ((ad->ad_data_fork.adf_refcount > 0) ? ATTRBIT_DOPEN : 0);
+ /* XXX not true if we have a meta data fork ? */
+ if ((ad->ad_resource_fork.adf_refcount > ad->ad_data_fork.adf_refcount))
+ ad->ad_open_forks |= ATTRBIT_ROPEN;
}
if ((adflags & ADFLAGS_DF)) {
- if (ad_dfileno(ad) == -1) {
+ if (ad_data_fileno(ad) == -1) {
hoflags = (oflags & ~(O_RDONLY | O_WRONLY)) | O_RDWR;
admode = mode;
if ((oflags & O_CREAT)) {
- st_invalid = ad_mode_st(path, &admode, &st);
+ st_invalid = ad_mode_st(path, &admode, &st_dir);
if ((ad->ad_options & ADVOL_UNIXPRIV)) {
admode = mode;
}
}
- ad->ad_df.adf_fd =open( path, hoflags, admode );
- if (ad->ad_df.adf_fd < 0 ) {
+ ad->ad_data_fork.adf_fd =open( path, hoflags, admode );
+ if (ad->ad_data_fork.adf_fd < 0 ) {
if ((errno == EACCES || errno == EROFS) && !(oflags & O_RDWR)) {
hoflags = oflags;
- ad->ad_df.adf_fd = open( path, hoflags, admode );
+ ad->ad_data_fork.adf_fd = open( path, hoflags, admode );
}
}
- if ( ad->ad_df.adf_fd < 0)
+ if ( ad->ad_data_fork.adf_fd < 0)
return -1;
- AD_SET(ad->ad_df.adf_off);
- ad->ad_df.adf_flags = hoflags;
+ AD_SET(ad->ad_data_fork.adf_off);
+ ad->ad_data_fork.adf_flags = hoflags;
if (!st_invalid) {
/* just created, set owner if admin (root) */
- ad_chown(path, &st);
+ ad_chown(path, &st_dir);
}
}
else {
/* the file is already open... but */
if ((oflags & ( O_RDWR | O_WRONLY)) && /* we want write access */
- !(ad->ad_df.adf_flags & ( O_RDWR | O_WRONLY))) /* and it was denied the first time */
+ !(ad->ad_data_fork.adf_flags & ( O_RDWR | O_WRONLY))) /* and it was denied the first time */
{
errno = EACCES;
return -1;
*/
}
open_df = ADFLAGS_DF;
- ad->ad_df.adf_refcount++;
+ ad->ad_data_fork.adf_refcount++;
}
if (!(adflags & ADFLAGS_HF))
return 0;
+
+ /* ****************************************** */
- if (ad_hfileno(ad) != -1) { /* the file is already open */
+ if (ad_meta_fileno(ad) != -1) { /* the file is already open */
if ((oflags & ( O_RDWR | O_WRONLY)) &&
- !(ad->ad_hf.adf_flags & ( O_RDWR | O_WRONLY))) {
+ !(ad->ad_md->adf_flags & ( O_RDWR | O_WRONLY))) {
if (open_df) {
/* don't call with ADFLAGS_HF because we didn't open ressource fork */
ad_close( ad, open_df );
return -1;
}
ad_refresh(ad);
- ad->ad_hf.adf_refcount++;
- return 0;
+ ad->ad_md->adf_refcount++;
+ goto sfm;
}
- ad_p = ad->ad_path( path, adflags );
+ ad_p = ad->ad_ops->ad_path( path, adflags );
hoflags = oflags & ~O_CREAT;
if (!(adflags & ADFLAGS_RDONLY)) {
hoflags = (hoflags & ~(O_RDONLY | O_WRONLY)) | O_RDWR;
}
- ad->ad_hf.adf_fd = open( ad_p, hoflags, 0 );
- if (ad->ad_hf.adf_fd < 0 ) {
+ ad->ad_md->adf_fd = open( ad_p, hoflags, 0 );
+ if (ad->ad_md->adf_fd < 0 ) {
if ((errno == EACCES || errno == EROFS) && !(oflags & O_RDWR)) {
hoflags = oflags & ~O_CREAT;
- ad->ad_hf.adf_fd = open( ad_p, hoflags, 0 );
+ ad->ad_md->adf_fd = open( ad_p, hoflags, 0 );
}
}
- if ( ad->ad_hf.adf_fd < 0 ) {
+ if ( ad->ad_md->adf_fd < 0 ) {
if (errno == ENOENT && (oflags & O_CREAT) ) {
/*
* We're expecting to create a new adouble header file,
*/
admode = mode;
errno = 0;
- st_invalid = ad_mode_st(ad_p, &admode, &st);
+ st_invalid = ad_mode_st(ad_p, &admode, &st_dir);
if ((ad->ad_options & ADVOL_UNIXPRIV)) {
admode = mode;
}
admode = ad_hf_mode(admode);
if ( errno == ENOENT && !(adflags & ADFLAGS_NOADOUBLE) && ad->ad_flags != AD_VERSION2_OSX) {
- if (ad->ad_mkrf( ad_p) < 0) {
+ if (ad->ad_ops->ad_mkrf( ad_p) < 0) {
return ad_error(ad, adflags);
}
admode = mode;
- st_invalid = ad_mode_st(ad_p, &admode, &st);
+ st_invalid = ad_mode_st(ad_p, &admode, &st_dir);
if ((ad->ad_options & ADVOL_UNIXPRIV)) {
admode = mode;
}
admode = ad_hf_mode(admode);
}
/* retry with O_CREAT */
- ad->ad_hf.adf_fd = open( ad_p, oflags,admode );
- if ( ad->ad_hf.adf_fd < 0 ) {
+ ad->ad_md->adf_fd = open( ad_p, oflags,admode );
+ if ( ad->ad_md->adf_fd < 0 ) {
return ad_error(ad, adflags);
}
- ad->ad_hf.adf_flags = oflags;
+ ad->ad_md->adf_flags = oflags;
/* just created, set owner if admin owner (root) */
if (!st_invalid) {
- ad_chown(ad_p, &st);
+ ad_chown(ad_p, &st_dir);
}
}
else {
return ad_error(ad, adflags);
}
- } else if (fstat(ad->ad_hf.adf_fd, &st) == 0 && st.st_size == 0) {
+ } else if (fstat(ad->ad_md->adf_fd, &st_meta) == 0 && st_meta.st_size == 0) {
/* for 0 length files, treat them as new. */
- ad->ad_hf.adf_flags = hoflags| O_TRUNC;
+ ad->ad_md->adf_flags = hoflags| O_TRUNC;
} else {
- ad->ad_hf.adf_flags = hoflags;
+ ad->ad_md->adf_flags = hoflags;
}
- AD_SET(ad->ad_hf.adf_off);
+ AD_SET(ad->ad_md->adf_off);
memset(ad->ad_eid, 0, sizeof( ad->ad_eid ));
- ad->ad_hf.adf_refcount++;
- if ((ad->ad_hf.adf_flags & ( O_TRUNC | O_CREAT ))) {
+ ad->ad_md->adf_refcount++;
+ if ((ad->ad_md->adf_flags & ( O_TRUNC | O_CREAT ))) {
/*
* This is a new adouble header file. Initialize the structure,
* instead of reading it.
return -1;
}
} else {
- /* Read the adouble header in and parse it.*/
- if ((ad_header_read( ad , &st) < 0)
-#if AD_VERSION == AD_VERSION2
- || (ad_convert(ad, ad_p) < 0) || (ad_update(ad, ad_p) < 0)
-#endif /* AD_VERSION == AD_VERSION2 */
- ) {
+ /* Read the adouble header in and parse it.*/
+ if (ad->ad_ops->ad_header_read( ad , pst) < 0
+ || ad->ad_ops->ad_header_upgrade(ad, ad_p) < 0)
+ {
int err = errno;
ad_close( ad, adflags );
return -1;
}
}
+
+ /* ****************************************** */
+ /* open the resource fork if SFM */
+sfm:
+ if (ad->ad_flags != AD_VERSION1_SFM) {
+ return 0;
+ }
+
+ if ((adflags & ADFLAGS_DIR)) {
+ /* no resource fork for directories / volumes XXX it's false! */
+ return 0;
+ }
+
+ /* untrue yet but ad_close will decremente it*/
+ ad->ad_resource_fork.adf_refcount++;
+
+ if (ad_reso_fileno(ad) != -1) { /* the file is already open */
+ if ((oflags & ( O_RDWR | O_WRONLY)) &&
+ !(ad->ad_resource_fork.adf_flags & ( O_RDWR | O_WRONLY))) {
+
+ ad_close( ad, open_df | ADFLAGS_HF);
+ errno = EACCES;
+ return -1;
+ }
+ return 0;
+ }
+
+ ad_p = ad->ad_ops->ad_path( path, ADFLAGS_RF );
+
+ hoflags = (oflags & ~(O_RDONLY | O_WRONLY)) | O_RDWR;
+ ad->ad_resource_fork.adf_fd = open( ad_p, hoflags, admode );
+ admode = mode;
+ st_invalid = ad_mode_st(ad_p, &admode, &st_dir);
+
+ if ((ad->ad_options & ADVOL_UNIXPRIV)) {
+ admode = mode;
+ }
+
+ if (ad->ad_resource_fork.adf_fd < 0 ) {
+ if ((errno == EACCES || errno == EROFS) && !(oflags & O_RDWR)) {
+ hoflags = oflags;
+ ad->ad_resource_fork.adf_fd =open( ad_p, hoflags, admode );
+ }
+ }
+
+ if ( ad->ad_resource_fork.adf_fd < 0) {
+ int err = errno;
+
+ ad_close( ad, adflags );
+ errno = err;
+ return -1;
+ }
+
+ AD_SET(ad->ad_resource_fork.adf_off);
+ ad->ad_resource_fork.adf_flags = hoflags;
+ if ((oflags & O_CREAT) && !st_invalid) {
+ /* just created, set owner if admin (root) */
+ ad_chown(ad_p, &st_dir);
+ }
+ else if (!fstat(ad->ad_resource_fork.adf_fd, &st_meta)) {
+ ad->ad_rlen = st_meta.st_size;
+ }
return 0 ;
}
{
uid_t uid;
int ret, err;
+ int dir = flags & ADFLAGS_DIR;
- if ((ret = ad_open(name, ADFLAGS_HF | flags, O_RDONLY, 0, adp)) < 0 && errno == EACCES) {
+ if ((ret = ad_open(name, ADFLAGS_HF | dir, O_RDONLY, 0, adp)) < 0 && errno == EACCES) {
uid = geteuid();
if (seteuid(0)) {
LOG(log_error, logtype_default, "ad_metadata(%s): seteuid failed %s", name, strerror(errno));
return -1;
}
/* we are root open read only */
- ret = ad_open(name, ADFLAGS_HF|ADFLAGS_RDONLY|flags, O_RDONLY, 0, adp);
+ ret = ad_open(name, ADFLAGS_HF|ADFLAGS_RDONLY| dir, O_RDONLY, 0, adp);
err = errno;
if ( seteuid(uid) < 0) {
LOG(log_error, logtype_default, "ad_metadata: can't seteuid back");
}
errno = err;
}
+
+ if (!ret && (ADFLAGS_OPENFORKS & flags)) {
+ u_int16_t attrbits = adp->ad_open_forks;
+
+ /*
+ we need to check if the file is open by another process.
+ it's slow so we only do it if we have to:
+ - it's requested.
+ - we don't already have the answer!
+ */
+
+ if (!(attrbits & ATTRBIT_ROPEN)) {
+ attrbits |= ad_testlock(adp, ADEID_RFORK, AD_FILELOCK_OPEN_RD) > 0? ATTRBIT_ROPEN : 0;
+ attrbits |= ad_testlock(adp, ADEID_RFORK, AD_FILELOCK_OPEN_WR) > 0? ATTRBIT_ROPEN : 0;
+ }
+
+ if (!(attrbits & ATTRBIT_DOPEN)) {
+ attrbits |= ad_testlock(adp, ADEID_DFORK, AD_FILELOCK_OPEN_RD) > 0? ATTRBIT_DOPEN : 0;
+ attrbits |= ad_testlock(adp, ADEID_DFORK, AD_FILELOCK_OPEN_WR) > 0? ATTRBIT_DOPEN : 0;
+ }
+ adp->ad_open_forks = attrbits;
+ }
return ret;
}
eid = entry_order2;
else if (ad->ad_flags == AD_VERSION2_OSX)
eid = entry_order_osx;
+ else if (ad->ad_flags == AD_VERSION1_SFM) {
+ ad->ad_magic = SFM_MAGIC;
+ eid = entry_order_sfm;
+ }
else
#endif
eid = entry_order1;
int ad_refresh(struct adouble *ad)
{
- if (ad->ad_hf.adf_fd < 0)
+ if (ad_meta_fileno(ad) < 0)
return -1;
- return ad_header_read(ad, NULL);
+ return ad->ad_ops->ad_header_read(ad, NULL);
}
/*
- * $Id: ad_read.c,v 1.6 2005-04-28 20:49:52 bfernhomberg Exp $
+ * $Id: ad_read.c,v 1.7 2006-09-29 09:39:16 didg Exp $
*
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
/* We're either reading the data fork (and thus the data file)
* or we're reading anything else (and thus the header file). */
if ( eid == ADEID_DFORK ) {
- cc = adf_pread(&ad->ad_df, buf, buflen, off);
+ cc = adf_pread(&ad->ad_data_fork, buf, buflen, off);
} else {
off_t r_off;
- if ( ad_hfileno( ad ) == -1 ) {
+ if ( ad_reso_fileno( ad ) == -1 ) {
/* resource fork is not open ( cf etc/afp/fork.c) */
return 0;
}
r_off = ad_getentryoff(ad, eid) + off;
- if (( cc = adf_pread( &ad->ad_hf, buf, buflen, r_off )) < 0 ) {
+ if (( cc = adf_pread( &ad->ad_resource_fork, buf, buflen, r_off )) < 0 ) {
return( -1 );
}
/*
* FIXME : always false?
*/
if (r_off < ad_getentryoff(ad, ADEID_RFORK)) {
- if ( ad->ad_hf.adf_flags & O_RDWR ) {
+ if ( ad->ad_resource_fork.adf_flags & O_RDWR ) {
memcpy(buf, ad->ad_data + r_off,
MIN(sizeof( ad->ad_data ) - r_off, cc));
} else {
/*
- * $Id: ad_size.c,v 1.6 2005-04-28 20:49:52 bfernhomberg Exp $
+ * $Id: ad_size.c,v 1.7 2006-09-29 09:39:16 didg Exp $
*
* Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
* All rights reserved. See COPYRIGHT.
if (eid == ADEID_DFORK) {
struct stat st;
- if (fstat(ad_dfileno(ad), &st) < 0)
+ if (fstat(ad_data_fileno(ad), &st) < 0)
return 0;
return st.st_size;
}
/*
- * $Id: ad_write.c,v 1.8 2005-04-28 20:49:52 bfernhomberg Exp $
+ * $Id: ad_write.c,v 1.9 2006-09-29 09:39:16 didg Exp $
*
* Copyright (c) 1990,1995 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
if ( eid == ADEID_DFORK ) {
if ( end ) {
- if ( fstat( ad->ad_df.adf_fd, &st ) < 0 ) {
+ if ( fstat( ad_data_fileno(ad), &st ) < 0 ) {
return( -1 );
}
off = st.st_size - off;
}
- cc = adf_pwrite(&ad->ad_df, buf, buflen, off);
+ cc = adf_pwrite(&ad->ad_data_fork, buf, buflen, off);
} else if ( eid == ADEID_RFORK ) {
off_t r_off;
if ( end ) {
- if ( fstat( ad->ad_df.adf_fd, &st ) < 0 ) {
+ if ( fstat( ad_data_fileno(ad), &st ) < 0 ) {
return( -1 );
}
off = st.st_size - off -ad_getentryoff(ad, eid);
}
r_off = ad_getentryoff(ad, eid) + off;
- cc = adf_pwrite(&ad->ad_hf, buf, buflen, r_off);
+ cc = adf_pwrite(&ad->ad_resource_fork, buf, buflen, r_off);
/* sync up our internal buffer FIXME always false? */
if (r_off < ad_getentryoff(ad, ADEID_RFORK)) {
struct adouble *ad;
const off_t size;
{
- if ( sys_ftruncate( ad->ad_hf.adf_fd,
+ if ( sys_ftruncate( ad_reso_fileno(ad),
size + ad->ad_eid[ ADEID_RFORK ].ade_off ) < 0 ) {
return -1;
}
struct adouble *ad;
const off_t size;
{
- if (sys_ftruncate(ad->ad_df.adf_fd, size) < 0) {
+ if (sys_ftruncate(ad_data_fileno(ad), size) < 0) {
return -1;
}
return 0;