/*
+ * $Id: fork.c,v 1.9 2001-10-24 04:13:22 jmarcus Exp $
+ *
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
#include <stdio.h>
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#ifdef HAVE_FCNTL_H
#include <fcntl.h>
+#endif /* HAVE_FCNTL_H */
#include <dirent.h>
#include <string.h>
#include <errno.h>
#include <atalk/afp.h>
#include <atalk/adouble.h>
#include <atalk/util.h>
+#ifdef CNID_DB
#include <atalk/cnid.h>
+#endif
#include "fork.h"
#include "file.h"
} else {
aint = ad_getentrylen( ofork->of_ad, ADEID_RFORK );
if ( ad_refresh( ofork->of_ad ) < 0 ) {
- syslog( LOG_ERR, "getforkparams: ad_refresh: %m");
+ syslog( LOG_ERR, "getforkparams: ad_refresh: %s", strerror(errno) );
return( AFPERR_PARAM );
}
/* See afp_closefork() for why this is bad */
memcpy(data, ufinderi, 8 );
if (( em = getextmap( ofork->of_name )) != NULL ) {
memcpy(data, em->em_type, sizeof( em->em_type ));
- memcpy(data + 4, em->em_creator,
+ memcpy(data + 4, em->em_creator,
sizeof( em->em_creator ));
}
}
break;
case FILPBIT_FNUM :
- /*
- * See file.c getfilparams() for why this is done this
- * way.
- */
+ aint = 0;
#if AD_VERSION > AD_VERSION1
- if (isad)
- memcpy(&aint, ad_entry(ofork->of_ad, ADEID_DID), sizeof(aint));
- else
- aint = 0;
-
- if (!(aint = cnid_add(ofork->of_vol->v_db, &st,
- ofork->of_dir->d_did,
- upath, strlen(upath), aint))) {
-#endif
+ /* look in AD v2 header */
+ if (isad)
+ memcpy(&aint, ad_entry(ofork->of_ad, ADEID_DID), sizeof(aint));
+#endif /* AD_VERSION > AD_VERSION1 */
+
+#ifdef CNID_DB
+ aint = cnid_add(ofork->of_vol->v_db, &st,
+ ofork->of_dir->d_did,
+ upath, strlen(upath), aint);
+#endif /* CNID_DB */
+
+ if (aint == 0) {
#ifdef AFS
aint = st.st_ino;
-#else AFS
+#else /* AFS */
aint = ( st.st_dev << 16 ) | ( st.st_ino & 0x0000ffff );
-#endif AFS
-#if AD_VERSION > AD_VERSION1
+#endif /* AFS */
}
-#endif
- memcpy(data, &aint, sizeof( aint ));
+
+ memcpy(data, &aint, sizeof( aint ));
data += sizeof( aint );
break;
adsame)) == NULL ) {
return( AFPERR_NFILE );
}
+ if (access & OPENACC_WR) {
+ /* try opening in read-write mode */
+ upath = mtoupath(vol, path);
+ ret = AFPERR_NOOBJ;
+ if (ad_open(upath, adflags, O_RDWR, 0, ofork->of_ad) < 0) {
+ switch ( errno ) {
+ case EROFS:
+ ret = AFPERR_VLOCK;
+ case EACCES:
+ goto openfork_err;
- /* try opening in read-write mode with a fallback to read-only
- * if we don't need write access. */
- upath = mtoupath(vol, path);
- ret = AFPERR_NOOBJ;
- if (ad_open(upath, adflags, O_RDWR, 0, ofork->of_ad) < 0) {
- switch ( errno ) {
- case EROFS:
- ret = AFPERR_VLOCK;
- case EACCES:
- if (access & OPENACC_WR)
- goto openfork_err;
-
- if (ad_open(upath, adflags, O_RDONLY, 0, ofork->of_ad) < 0) {
+ break;
+ case ENOENT:
+ {
+ struct stat st;
+
+ /* see if client asked for the data fork */
+ if (fork == OPENFORK_DATA) {
+ if (ad_open(upath, ADFLAGS_DF, O_RDWR, 0, ofork->of_ad) < 0) {
+ goto openfork_err;
+ }
+ adflags = ADFLAGS_DF;
+
+ } else if (stat(upath, &st) == 0) {
+ /* here's the deal. we only try to create the resource
+ * fork if the user wants to open it for write acess. */
+ if (ad_open(upath, adflags, O_RDWR | O_CREAT, 0666, ofork->of_ad) < 0)
+ goto openfork_err;
+ } else
+ goto openfork_err;
+ }
+ break;
+ case EMFILE :
+ case ENFILE :
+ ret = AFPERR_NFILE;
+ goto openfork_err;
+ break;
+ case EISDIR :
+ ret = AFPERR_BADTYPE;
+ goto openfork_err;
+ break;
+ default:
+ syslog( LOG_ERR, "afp_openfork: ad_open: %s", strerror(errno) );
+ ret = AFPERR_PARAM;
+ goto openfork_err;
+ break;
+ }
+ }
+ } else {
+ /* try opening in read-only mode */
+ upath = mtoupath(vol, path);
+ ret = AFPERR_NOOBJ;
+ if (ad_open(upath, adflags, O_RDONLY, 0, ofork->of_ad) < 0) {
+ switch ( errno ) {
+ case EROFS:
+ ret = AFPERR_VLOCK;
+ case EACCES:
/* check for a read-only data fork */
if ((adflags != ADFLAGS_HF) &&
- (ad_open(upath, ADFLAGS_DF, O_RDONLY, 0, ofork->of_ad) < 0))
- goto openfork_err;
-
- adflags = ADFLAGS_DF;
- }
- break;
- case ENOENT:
- {
- struct stat st;
-
- /* see if client asked for the data fork */
- if (fork == OPENFORK_DATA) {
- if (((access & OPENACC_WR) &&
- (ad_open(upath, ADFLAGS_DF, O_RDWR, 0, ofork->of_ad) < 0))
- || (ad_open(upath, ADFLAGS_DF, O_RDONLY, 0,
- ofork->of_ad) < 0)) {
- goto openfork_err;
- }
- adflags = ADFLAGS_DF;
-
- } else if (stat(upath, &st) == 0) {
- /* here's the deal. we only try to create the resource
- * fork if the user wants to open it for write access. */
- if ((access & OPENACC_WR) &&
- (ad_open(upath, adflags, O_RDWR | O_CREAT,
- 0666, ofork->of_ad) < 0))
- goto openfork_err;
- } else
+ (ad_open(upath, ADFLAGS_DF, O_RDONLY, 0, ofork->of_ad) < 0))
+ goto openfork_err;
+
+ adflags = ADFLAGS_DF;
+ break;
+ case ENOENT:
+ {
+ struct stat st;
+
+ /* see if client asked for the data fork */
+ if (fork == OPENFORK_DATA) {
+ if (ad_open(upath, ADFLAGS_DF, O_RDONLY, 0, ofork->of_ad) < 0) {
goto openfork_err;
+ }
+ adflags = ADFLAGS_DF;
+
+ } else if (stat(upath, &st) != 0) {
+ goto openfork_err;
+ }
+ }
+ break;
+ case EMFILE :
+ case ENFILE :
+ ret = AFPERR_NFILE;
+ goto openfork_err;
+ break;
+ case EISDIR :
+ ret = AFPERR_BADTYPE;
+ goto openfork_err;
+ break;
+ default:
+ syslog( LOG_ERR, "afp_openfork: ad_open: %s", strerror(errno) );
+ goto openfork_err;
+ break;
}
- break;
- case EMFILE :
- case ENFILE :
- ret = AFPERR_NFILE;
- goto openfork_err;
- break;
- case EISDIR :
- ret = AFPERR_BADTYPE;
- goto openfork_err;
- break;
- default:
- syslog( LOG_ERR, "afp_openfork: ad_open: %m" );
- ret = AFPERR_PARAM;
- goto openfork_err;
- break;
- }
+ }
}
if ((adflags & ADFLAGS_HF) &&
if (!ret && (access & OPENACC_RD)) {
ofork->of_flags |= AFPFORK_ACCRD;
ret = ad_lock(ofork->of_ad, eid, ADLOCK_RD | ADLOCK_FILELOCK,
- AD_FILELOCK_RD, 1, ofrefnum);
+ AD_FILELOCK_RD, 1, ofrefnum);
}
/* can we access the fork? */
break;
default:
*rbuflen = 0;
- syslog( LOG_ERR, "afp_openfork: ad_lock: %m" );
+ syslog( LOG_ERR, "afp_openfork: ad_lock: %s", strerror(errno) );
return( AFPERR_PARAM );
}
}
*rbuflen = 0;
if (( ofork = of_find( ofrefnum )) == NULL ) {
- syslog( LOG_ERR, "afp_setforkparams: of_find: %m" );
+ syslog( LOG_ERR, "afp_setforkparams: of_find: %s", strerror(errno) );
return( AFPERR_PARAM );
}
goto afp_setfork_err;
if (ad_flush( ofork->of_ad, ADFLAGS_HF ) < 0) {
- syslog( LOG_ERR, "afp_setforkparams: ad_flush: %m" );
+ syslog( LOG_ERR, "afp_setforkparams: ad_flush: %s",
+ strerror(errno) );
return( AFPERR_PARAM );
}
} else
if ( flushfork( ofork ) < 0 ) {
syslog( LOG_ERR, "afp_setforkparams: flushfork: %m" );
}
-#endif AFS
+#endif /* AFS */
return( AFP_OK );
ibuf += sizeof(ofrefnum);
if (( ofork = of_find( ofrefnum )) == NULL ) {
- syslog( LOG_ERR, "afp_bytelock: of_find: %m" );
+ syslog( LOG_ERR, "afp_bytelock: of_find: %s", strerror(errno) );
return( AFPERR_PARAM );
}
cc = ad_read(ofork->of_ad, eid, offset, rbuf, *rbuflen);
if ( cc < 0 ) {
- syslog( LOG_ERR, "afp_read: ad_read: %m" );
+ syslog( LOG_ERR, "afp_read: ad_read: %s", strerror(errno) );
*rbuflen = 0;
return( AFPERR_PARAM );
}
ibuf += sizeof( u_short );
if (( ofork = of_find( ofrefnum )) == NULL ) {
- syslog( LOG_ERR, "afp_read: of_find: %m" );
+ syslog( LOG_ERR, "afp_read: of_find: %s", strerror(errno) );
err = AFPERR_PARAM;
goto afp_read_err;
}
if (errno == EINVAL)
goto afp_read_loop;
else {
- syslog(LOG_ERR, "afp_read: ad_readfile: %m");
+ syslog(LOG_ERR, "afp_read: ad_readfile: %s", strerror(errno));
goto afp_read_exit;
}
}
}
afp_read_loop:
-#endif
+#endif /* HAVE_SENDFILE_READ */
/* fill up our buffer. */
while (*rbuflen > 0) {
goto afp_read_done;
afp_read_exit:
- syslog(LOG_ERR, "afp_read: %m");
+ syslog(LOG_ERR, "afp_read: %s", strerror(errno));
dsi_readdone(dsi);
ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount);
obj->exit(1);
memcpy(&ofrefnum, ibuf, sizeof( ofrefnum ));
if (( ofork = of_find( ofrefnum )) == NULL ) {
- syslog( LOG_ERR, "afp_flushfork: of_find: %m" );
+ syslog( LOG_ERR, "afp_flushfork: of_find: %s", strerror(errno) );
return( AFPERR_PARAM );
}
if ( flushfork( ofork ) < 0 ) {
- syslog( LOG_ERR, "afp_flushfork: %m" );
+ syslog( LOG_ERR, "afp_flushfork: %s", strerror(errno) );
}
return( AFP_OK );
if ( ad_dfileno( ofork->of_ad ) != -1 &&
fsync( ad_dfileno( ofork->of_ad )) < 0 ) {
- syslog( LOG_ERR, "flushfork: dfile(%d) %m",
- ad_dfileno(ofork->of_ad) );
+ syslog( LOG_ERR, "flushfork: dfile(%d) %s",
+ ad_dfileno(ofork->of_ad), strerror(errno) );
err = -1;
}
if ( ad_hfileno( ofork->of_ad ) != -1 ) {
- if (ofork->of_flags & AFPFORK_RSRC) {
- len = ad_getentrylen(ofork->of_ad, ADEID_RFORK);
- ad_refresh(ofork->of_ad);
- if (len != ad_getentrylen(ofork->of_ad, ADEID_RFORK)) {
- ad_setentrylen(ofork->of_ad, ADEID_RFORK, len);
- doflush++;
- }
- }
+ /* read in the rfork length */
+ len = ad_getentrylen(ofork->of_ad, ADEID_RFORK);
+ ad_refresh(ofork->of_ad);
+
+ /* set the date if we're dirty */
if ((ofork->of_flags & AFPFORK_DIRTY) &&
(gettimeofday(&tv, NULL) == 0)) {
ad_setdate(ofork->of_ad, AD_DATE_MODIFY|AD_DATE_UNIX, tv.tv_sec);
doflush++;
}
- /* flush the header. */
- if (doflush && (ad_flush(ofork->of_ad, ADFLAGS_HF) < 0))
- err = -1;
+ /* if we're actually flushing this fork, make sure to set the
+ * length. otherwise, just use the stored length */
+ if ((ofork->of_flags & AFPFORK_RSRC) &&
+ (len != ad_getentrylen(ofork->of_ad, ADEID_RFORK))) {
+ ad_setentrylen(ofork->of_ad, ADEID_RFORK, len);
+ doflush++;
+ }
+
+
+ /* flush the header (if it is a resource fork) */
+ if (ofork->of_flags & AFPFORK_RSRC)
+ if (doflush && (ad_flush(ofork->of_ad, ADFLAGS_HF) < 0))
+ err = -1;
if (fsync( ad_hfileno( ofork->of_ad )) < 0)
err = -1;
#ifdef AFS
writtenfork = ofork;
-#endif AFS
+#endif /* AFS */
if ( ofork->of_flags & AFPFORK_DATA) {
eid = ADEID_DFORK;
offset += cc;
goto afp_write_done;
}
-#endif
+#endif /* 0, was HAVE_SENDFILE_WRITE */
/* loop until everything gets written. currently
* dsi_write handles the end case by itself. */
offset = htonl( offset );
#if defined(__GNUC__) && defined(HAVE_GCC_MEMCPY_BUG)
bcopy(&offset, rbuf, sizeof(offset));
-#else
+#else /* __GNUC__ && HAVE_GCC_MEMCPY_BUG */
memcpy(rbuf, &offset, sizeof(offset));
-#endif
+#endif /* __GNUC__ && HAVE_GCC_MEMCPY_BUG */
*rbuflen = sizeof(offset);
return( AFP_OK );