/*
- * $Id: fork.c,v 1.41 2003-01-08 15:01:35 didg Exp $
+ * $Id: fork.c,v 1.73 2010-03-30 12:55:26 franklahm Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#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/adouble.h>
#include <atalk/logger.h>
#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/time.h>
#include <sys/socket.h>
-#include <netatalk/endian.h>
#include <netatalk/at.h>
#include <atalk/dsi.h>
#include <atalk/atp.h>
#include <atalk/asp.h>
#include <atalk/afp.h>
-#include <atalk/adouble.h>
#include <atalk/util.h>
-#ifdef CNID_DB
#include <atalk/cnid.h>
-#endif
+#include <atalk/globals.h>
#include "fork.h"
#include "file.h"
-#include "globals.h"
#include "directory.h"
#include "desktop.h"
#include "volume.h"
-#define BYTELOCK_MAX 0x7FFFFFFFU
-#define BYTELOCK_MAXL 0x7FFFFFFFFFFFFFFFULL
-
-struct ofork *writtenfork;
-extern int getmetadata(struct vol *vol,
- u_int16_t bitmap,
- char *path, struct dir *dir, struct stat *st,
- char *buf, int *buflen, struct adouble *adp, int attrbits );
-
-static int getforkparams(ofork, bitmap, buf, buflen, attrbits )
-struct ofork *ofork;
-u_int16_t bitmap;
-char *buf;
-int *buflen;
-const u_int16_t attrbits;
+#ifdef DEBUG1
+#define Debug(a) ((a)->options.flags & OPTION_DEBUG)
+#else
+#define Debug(a) (0)
+#endif
+
+#ifdef AFS
+struct ofork *writtenfork;
+#endif
+
+static int getforkparams(struct ofork *ofork, u_int16_t bitmap, char *buf, size_t *buflen)
{
- struct stat st;
- char *upath;
+ struct path path;
+ struct stat *st;
struct adouble *adp;
struct dir *dir;
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;
}
vol = ofork->of_vol;
- dir = ofork->of_dir;
+ dir = dirlookup(vol, ofork->of_did);
+ if (NULL == (path.u_name = mtoupath(vol, of_name(ofork), dir->d_did, utf8_encoding()))) {
+ return( AFPERR_MISC );
+ }
+ path.m_name = of_name(ofork);
+ path.id = 0;
+ st = &path.st;
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 ) {
- upath = mtoupath(vol, ofork->of_name);
+ if ( ad_data_fileno( ofork->of_ad ) <= 0 ) {
+ /* 0 is for symlink */
if (movecwd(vol, dir) < 0)
return( AFPERR_NOOBJ );
- if ( stat( upath, &st ) < 0 )
+ if ( lstat( 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, ofork->of_name, dir, &st, buf, buflen, adp, attrbits );
+ return getmetadata(vol, bitmap, &path, dir, buf, buflen, adp );
}
-/* -------------------------
+/* ---------------------------- */
+static off_t get_off_t(char **ibuf, int is64)
+{
+ u_int32_t temp;
+ off_t ret;
+
+ ret = 0;
+ memcpy(&temp, *ibuf, sizeof( temp ));
+ ret = ntohl(temp); /* ntohl is unsigned */
+ *ibuf += sizeof(temp);
+
+ if (is64) {
+ memcpy(&temp, *ibuf, sizeof( temp ));
+ *ibuf += sizeof(temp);
+ ret = ntohl(temp)| (ret << 32);
+ }
+ else {
+ ret = (int)ret; /* sign extend */
+ }
+ return ret;
+}
+
+/* ---------------------- */
+static int set_off_t(off_t offset, char *rbuf, int is64)
+{
+ u_int32_t temp;
+ int ret;
+
+ ret = 0;
+ if (is64) {
+ temp = htonl(offset >> 32);
+ memcpy(rbuf, &temp, sizeof( temp ));
+ rbuf += sizeof(temp);
+ ret = sizeof( temp );
+ offset &= 0xffffffff;
+ }
+ temp = htonl(offset);
+ memcpy(rbuf, &temp, sizeof( temp ));
+ ret += sizeof( temp );
+
+ return ret;
+}
+
+/* ------------------------
*/
-#define SHARE 0
-#define EXCL 1
-static int setforkmode(struct adouble *adp, int eid, int ofrefnum, int what, int mode)
+static int is_neg(int is64, off_t val)
{
- int lockmode;
- int lockop;
-
- /* 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
- * someone else from really setting a deny read/write on the file.
- */
- lockmode = (ad_getoflags(adp, eid) & O_RDWR) ?ADLOCK_WR : ADLOCK_RD;
- lockop = (mode == EXCL)?lockmode:ADLOCK_RD;
-
- return ad_lock(adp, eid, lockop | ADLOCK_FILELOCK | ADLOCK_UPGRADE,
- what, 1, ofrefnum);
+ if (val < 0 || (sizeof(off_t) == 8 && !is64 && (val & 0x80000000U)))
+ return 1;
+ return 0;
+}
+
+static int sum_neg(int is64, off_t offset, off_t reqcount)
+{
+ if (is_neg(is64, offset +reqcount) )
+ return 1;
+ return 0;
}
/* -------------------------
*/
-extern int ad_testlock(struct adouble *adp, int eid, int off);
+static int setforkmode(struct adouble *adp, int eid, int ofrefnum, int what)
+{
+ return ad_lock(adp, eid, ADLOCK_RD | ADLOCK_FILELOCK, what, 1, ofrefnum);
+}
-static int getforkmode(struct adouble *adp, int eid, int what)
+/* -------------------------
+*/
+int getforkmode(struct adouble *adp, int eid, int what)
{
return ad_testlock(adp, eid, what);
}
-static int afp_setmode(struct adouble *adp, int eid, int access, int ofrefnum)
+/* -------------------------
+*/
+static int fork_setmode(struct adouble *adp, int eid, int access, int ofrefnum)
{
int ret;
int readset;
int writeset;
int denyreadset;
int denywriteset;
- int mode;
if (! (access & (OPENACC_WR | OPENACC_RD | OPENACC_DWR | OPENACC_DRD))) {
- return setforkmode(adp, eid, ofrefnum, AD_FILELOCK_OPEN_NONE, SHARE);
+ return setforkmode(adp, eid, ofrefnum, AD_FILELOCK_OPEN_NONE);
}
if ((access & (OPENACC_RD | OPENACC_DRD))) {
/* boolean logic is not enough, because getforkmode is not always telling the
* true
*/
- mode = ((access & OPENACC_DRD))?EXCL: SHARE;
if ((access & OPENACC_RD)) {
- ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_OPEN_RD, mode);
+ ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_OPEN_RD);
if (ret)
return ret;
}
if ((access & OPENACC_DRD)) {
- ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_DENY_RD, SHARE);
+ ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_DENY_RD);
if (ret)
return ret;
}
errno = EACCES;
return -1;
}
- mode = ((access & OPENACC_DWR))?EXCL: SHARE;
if ((access & OPENACC_WR)) {
- ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_OPEN_WR, mode);
+ ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_OPEN_WR);
if (ret)
return ret;
}
if ((access & OPENACC_DWR)) {
- ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_DENY_WR, SHARE);
+ ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_DENY_WR);
if (ret)
return ret;
}
}
+ if ( access == (OPENACC_WR | OPENACC_RD | OPENACC_DWR | OPENACC_DRD)) {
+ return ad_excl_lock(adp, eid);
+ }
return 0;
}
-/* ----------------------- */
-int afp_openfork(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+/* ----------------------- */
+int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen)
{
struct vol *vol;
struct dir *dir;
struct ofork *ofork, *opened;
struct adouble *adsame = NULL;
- int buflen, ret, adflags, eid, lockop;
+ size_t buflen;
+ int 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;
ibuf += sizeof(vid);
*rbuflen = 0;
- if (( vol = getvolbyvid( vid )) == NULL ) {
+ if (NULL == ( vol = getvolbyvid( vid ))) {
return( AFPERR_PARAM );
}
memcpy(&did, ibuf, sizeof( did ));
ibuf += sizeof( int );
- if (( dir = dirlookup( vol, did )) == NULL ) {
+ if (NULL == ( dir = dirlookup( vol, did ))) {
return afp_errno;
}
return AFPERR_VLOCK;
}
- if (( s_path = cname( vol, dir, &ibuf )) == NULL ) {
- return afp_errno;
+ if (NULL == ( s_path = cname( vol, dir, &ibuf ))) {
+ return get_afp_errno(AFPERR_PARAM);
}
if (*s_path->m_name == '\0') {
case EACCES:
return (access & OPENACC_WR) ? AFPERR_LOCK : AFPERR_ACCESS;
default:
- LOG(log_error, logtype_afpd, "afp_openfork: ad_open: %s", strerror(errno) );
+ LOG(log_error, logtype_afpd, "afp_openfork(%s): ad_open: %s", s_path->m_name, strerror(errno) );
return AFPERR_PARAM;
}
- /* FIXME should we check first ? */
+ /* FIXME should we check it first ? */
upath = s_path->u_name;
- if (check_access(upath, access ) < 0) {
- return AFPERR_ACCESS;
+ if (!vol_unix_priv(vol)) {
+ if (check_access(upath, access ) < 0) {
+ return AFPERR_ACCESS;
+ }
+ }
+ else {
+ if (file_access(s_path, access ) < 0) {
+ return AFPERR_ACCESS;
+ }
}
st = &s_path->st;
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;
}
break;
case ENOENT:
if (fork == OPENFORK_DATA) {
+ /* try to open only the data fork */
if (ad_open(upath, ADFLAGS_DF, O_RDWR, 0, ofork->of_ad) < 0) {
goto openfork_err;
}
adflags = ADFLAGS_DF;
-
+ }
+ else {
/* 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;
+ ofork->of_flags |= AFPFORK_OPEN;
}
break;
case EMFILE :
goto openfork_err;
break;
default:
- LOG(log_error, logtype_afpd, "afp_openfork: ad_open: %s", strerror(errno) );
+ LOG(log_error, logtype_afpd, "afp_openfork(%s): ad_open: %s", s_path->m_name, strerror(errno) );
ret = AFPERR_PARAM;
goto openfork_err;
break;
}
}
+ else {
+ /* the ressource fork is open too */
+ ofork->of_flags |= AFPFORK_OPEN;
+ }
} else {
/* try opening in read-only mode */
ret = AFPERR_NOOBJ;
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;
+ goto openfork_err;
break;
case ENOENT:
- /* see if client asked for the data fork */
+ /* see if client asked for a read only 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 we don't set AFPFORK_OPEN because there's no ressource fork file
+ * We need to check AFPFORK_OPEN in afp_closefork(). eg fork open read-only
+ * then create in open read-write.
+ * FIXME , it doesn't play well with byte locking example:
+ * ressource fork open read only
+ * locking set on it (no effect, there's no file!)
+ * ressource fork open read write now
+ */
break;
case EMFILE :
case ENFILE :
goto openfork_err;
break;
default:
- LOG(log_error, logtype_afpd, "afp_openfork: ad_open: %s", strerror(errno) );
+ LOG(log_error, logtype_afpd, "afp_openfork('%s/%s'): ad_open: errno: %i (%s)",
+ getcwdpath, s_path->m_name, errno, strerror(errno) );
goto openfork_err;
break;
}
}
+ else {
+ /* the ressource fork is open too */
+ ofork->of_flags |= AFPFORK_OPEN;
+ }
}
- if ((adflags & ADFLAGS_HF) &&
- (ad_getoflags( ofork->of_ad, ADFLAGS_HF ) & O_CREAT)) {
- 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 );
+ 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 );
+ }
}
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;
}
memcpy(rbuf, &bitmap, sizeof( u_int16_t ));
rbuf += sizeof( u_int16_t );
- /* check WriteInhibit bit, the test is done here, after some Mac trafic capture */
- ad_getattr(ofork->of_ad, &bshort);
- if ((bshort & htons(ATTRBIT_NOWRITE)) && (access & OPENACC_WR)) {
- ad_close( ofork->of_ad, adflags );
- of_dealloc( ofork );
- ofrefnum = 0;
- memcpy(rbuf, &ofrefnum, sizeof(ofrefnum));
- return(AFPERR_OLOCK);
+ /* check WriteInhibit bit if we have a ressource fork
+ * the test is done here, after some Mac trafic capture
+ */
+ 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 );
+ of_dealloc( ofork );
+ ofrefnum = 0;
+ memcpy(rbuf, &ofrefnum, sizeof(ofrefnum));
+ return(AFPERR_OLOCK);
+ }
}
/*
*/
/* 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 = afp_setmode(ofork->of_ad, eid, access, ofrefnum);
+ ret = fork_setmode(ofork->of_ad, eid, access, ofrefnum);
/* can we access the fork? */
if (ret < 0) {
ret = errno;
break;
default:
*rbuflen = 0;
- LOG(log_error, logtype_afpd, "afp_openfork: ad_lock: %s", strerror(errno) );
+ LOG(log_error, logtype_afpd, "afp_openfork(%s): ad_lock: %s", s_path->m_name, strerror(ret) );
return( AFPERR_PARAM );
}
}
if ((access & OPENACC_WR))
ofork->of_flags |= AFPFORK_ACCWR;
- if ((access & OPENACC_RD))
- ofork->of_flags |= AFPFORK_ACCRD;
}
+ /* the file may be open read only without ressource fork */
+ if ((access & OPENACC_RD))
+ ofork->of_flags |= AFPFORK_ACCRD;
memcpy(rbuf, &ofrefnum, sizeof(ofrefnum));
return( AFP_OK );
return ret;
}
-int afp_setforkparams(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+int afp_setforkparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen, char *rbuf _U_, size_t *rbuflen)
{
struct ofork *ofork;
- int32_t size;
+ off_t size;
u_int16_t ofrefnum, bitmap;
int err;
-
+ int is64;
+ int eid;
+ off_t st_size;
+
ibuf += 2;
+
memcpy(&ofrefnum, ibuf, sizeof( ofrefnum ));
ibuf += sizeof( ofrefnum );
+
memcpy(&bitmap, ibuf, sizeof(bitmap));
bitmap = ntohs(bitmap);
ibuf += sizeof( bitmap );
- memcpy(&size, ibuf, sizeof( size ));
- size = ntohl( size );
*rbuflen = 0;
- if (( ofork = of_find( ofrefnum )) == NULL ) {
- LOG(log_error, logtype_afpd, "afp_setforkparams: of_find could not locate open fork refnum: %u", ofrefnum );
+ if (NULL == ( ofork = of_find( ofrefnum )) ) {
+ LOG(log_error, logtype_afpd, "afp_setforkparams: of_find(%d) could not locate fork", ofrefnum );
return( AFPERR_PARAM );
}
if ((ofork->of_flags & AFPFORK_ACCWR) == 0)
return AFPERR_ACCESS;
- if (size < 0)
+ if ( ofork->of_flags & AFPFORK_DATA) {
+ eid = ADEID_DFORK;
+ } else if (ofork->of_flags & AFPFORK_RSRC) {
+ eid = ADEID_RFORK;
+ } else
return AFPERR_PARAM;
- if ((bitmap == (1<<FILPBIT_DFLEN)) && (ofork->of_flags & AFPFORK_DATA)) {
+ if ( ( (bitmap & ( (1<<FILPBIT_DFLEN) | (1<<FILPBIT_EXTDFLEN) ))
+ && eid == ADEID_RFORK
+ ) ||
+ ( (bitmap & ( (1<<FILPBIT_RFLEN) | (1<<FILPBIT_EXTRFLEN) ))
+ && eid == ADEID_DFORK)) {
+ return AFPERR_BITMAP;
+ }
+
+ is64 = 0;
+ if ((bitmap & ( (1<<FILPBIT_EXTDFLEN) | (1<<FILPBIT_EXTRFLEN) ))) {
+ if (afp_version >= 30) {
+ is64 = 4;
+ }
+ else
+ return AFPERR_BITMAP;
+ }
+
+ if (ibuflen < 2+ sizeof(ofrefnum) + sizeof(bitmap) + is64 +4)
+ return AFPERR_PARAM ;
+
+ size = get_off_t(&ibuf, is64);
+
+ if (size < 0)
+ return AFPERR_PARAM; /* Some MacOS don't return an error they just don't change the size! */
+
+
+ if (bitmap == (1<<FILPBIT_DFLEN) || bitmap == (1<<FILPBIT_EXTDFLEN)) {
+ st_size = ad_size(ofork->of_ad, eid);
+ err = -2;
+ if (st_size > size &&
+ ad_tmplock(ofork->of_ad, eid, ADLOCK_WR, size, st_size -size, ofork->of_refnum) < 0)
+ goto afp_setfork_err;
+
err = ad_dtruncate( ofork->of_ad, size );
+ if (st_size > size)
+ ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, size, st_size -size, ofork->of_refnum);
if (err < 0)
goto afp_setfork_err;
- } else if ((bitmap == (1<<FILPBIT_RFLEN)) &&
- (ofork->of_flags & AFPFORK_RSRC)) {
+ } else if (bitmap == (1<<FILPBIT_RFLEN) || bitmap == (1<<FILPBIT_EXTRFLEN)) {
ad_refresh( ofork->of_ad );
+
+ st_size = ad_size(ofork->of_ad, eid);
+ err = -2;
+ if (st_size > size &&
+ ad_tmplock(ofork->of_ad, eid, ADLOCK_WR, size, st_size -size, ofork->of_refnum) < 0) {
+ goto afp_setfork_err;
+ }
err = ad_rtruncate(ofork->of_ad, size);
+ if (st_size > size)
+ ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, size, st_size -size, ofork->of_refnum);
if (err < 0)
goto afp_setfork_err;
- if (ad_flush( ofork->of_ad, ADFLAGS_HF ) < 0) {
- LOG(log_error, logtype_afpd, "afp_setforkparams: ad_flush: %s",
- strerror(errno) );
- return( AFPERR_PARAM );
+ 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;
}
} else
return AFPERR_BITMAP;
#ifdef AFS
if ( flushfork( ofork ) < 0 ) {
- LOG(log_error, logtype_afpd, "afp_setforkparams: flushfork: %s", strerror(errno) );
+ LOG(log_error, logtype_afpd, "afp_setforkparams(%s): flushfork: %s", of_name(ofork), strerror(errno) );
}
#endif /* AFS */
#define ENDBIT(a) ((a) & 0x80)
#define UNLOCKBIT(a) ((a) & 0x01)
-static off_t get_off_t(ibuf, is64)
-char **ibuf;
-int is64;
-{
- u_int32_t temp;
- off_t ret;
-
- memcpy(&temp, *ibuf, sizeof( temp ));
- ret = ntohl(temp); /* ntohl is unsigned */
- *ibuf += sizeof(temp);
-
- if (is64) {
- memcpy(&temp, *ibuf, sizeof( temp ));
- *ibuf += sizeof(temp);
- ret = ntohl(temp)| (ret << 32);
- }
- return ret;
-}
-
-/* ---------------------- */
-static int set_off_t(offset, rbuf, is64)
-off_t offset;
-char *rbuf;
-int is64;
-{
- u_int32_t temp;
- int ret;
-
- ret = 0;
- if (is64) {
- temp = htonl(offset >> 32);
- memcpy(rbuf, &temp, sizeof( temp ));
- rbuf += sizeof(temp);
- ret = sizeof( temp );
- offset &= 0xffffffff;
- }
- temp = htonl(offset);
- memcpy(rbuf, &temp, sizeof( temp ));
- ret += sizeof( temp );
-
- return ret;
-}
/* ---------------------- */
-static int byte_lock(obj, ibuf, ibuflen, rbuf, rbuflen, is64 )
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
-int is64;
+static int byte_lock(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen, int is64)
{
struct ofork *ofork;
off_t offset, length;
int eid;
u_int16_t ofrefnum;
u_int8_t flags;
-
+ int lockop;
+
*rbuflen = 0;
/* figure out parameters */
memcpy(&ofrefnum, ibuf, sizeof(ofrefnum));
ibuf += sizeof(ofrefnum);
- if (( ofork = of_find( ofrefnum )) == NULL ) {
- LOG(log_error, logtype_afpd, "afp_bytelock: of_find");
+ if (NULL == ( ofork = of_find( ofrefnum )) ) {
+ LOG(log_error, logtype_afpd, "afp_bytelock: of_find(%d) could not locate fork", ofrefnum );
return( AFPERR_PARAM );
}
offset = get_off_t(&ibuf, is64);
length = get_off_t(&ibuf, is64);
- if (is64) {
- if (length == -1)
- length = BYTELOCK_MAXL;
- else if (length <= 0) {
- return AFPERR_PARAM;
- } else if ((length >= AD_FILELOCK_BASE) &&
- (ad_hfileno(ofork->of_ad) == -1)) {
- return AFPERR_LOCK;
- }
- }
- else {
- if (length == 0xFFFFFFFF)
- length = BYTELOCK_MAX;
- else if (!length || (length & (1 << 31))) {
- return AFPERR_PARAM;
- } else if ((length >= AD_FILELOCK_BASE) &&
- (ad_hfileno(ofork->of_ad) == -1)) {
- return AFPERR_LOCK;
- }
+ /* FIXME AD_FILELOCK test is surely wrong */
+ if (length == -1)
+ length = BYTELOCK_MAX;
+ else if (!length || is_neg(is64, length)) {
+ return AFPERR_PARAM;
+ } else if ((length >= AD_FILELOCK_BASE) && -1 == (ad_reso_fileno(ofork->of_ad))) { /* HF ?*/
+ return AFPERR_LOCK;
}
-
- if (ENDBIT(flags))
- offset += ad_size(ofork->of_ad, eid);
+ if (ENDBIT(flags)) {
+ offset += ad_size(ofork->of_ad, eid);
+ /* FIXME what do we do if file size > 2 GB and
+ it's not byte_lock_ext?
+ */
+ }
if (offset < 0) /* error if we have a negative offset */
return AFPERR_PARAM;
/* if the file is a read-only file, we use read locks instead of
* write locks. that way, we can prevent anyone from initiating
* a write lock. */
- if (ad_lock(ofork->of_ad, eid, UNLOCKBIT(flags) ? ADLOCK_CLR :
- ((ad_getoflags(ofork->of_ad, eid) & O_RDWR) ?
- ADLOCK_WR : ADLOCK_RD), offset, length,
+ lockop = UNLOCKBIT(flags) ? ADLOCK_CLR : ADLOCK_WR;
+ if (ad_lock(ofork->of_ad, eid, lockop, offset, length,
ofork->of_refnum) < 0) {
switch (errno) {
case EACCES:
}
/* --------------------------- */
-int afp_bytelock(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+int afp_bytelock(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
{
return byte_lock ( obj, ibuf, ibuflen, rbuf, rbuflen , 0);
}
/* --------------------------- */
-int afp_bytelock_ext(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+int afp_bytelock_ext(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
{
return byte_lock ( obj, ibuf, ibuflen, rbuf, rbuflen , 1);
}
#undef UNLOCKBIT
/* --------------------------- */
-static __inline__ int crlf( of )
-struct ofork *of;
+static int crlf(struct ofork *of)
{
struct extmap *em;
- if ( ad_hfileno( of->of_ad ) == -1 ||
- memcmp( ufinderi, ad_entry( of->of_ad, ADEID_FINDERI ),
- 8) == 0 ) {
- if (( em = getextmap( of->of_name )) == NULL ||
- memcmp( "TEXT", em->em_type, sizeof( em->em_type )) == 0 ) {
- return( 1 );
- } else {
- return( 0 );
- }
- } else {
- if ( memcmp( ufinderi,
- ad_entry( of->of_ad, ADEID_FINDERI ), 4 ) == 0 ) {
- return( 1 );
- } else {
- return( 0 );
- }
+ 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;
+ }
+ /* file type is TEXT */
+ return 1;
+
+ } else if ( !memcmp( "TEXT", ad_entry( of->of_ad, ADEID_FINDERI ), 4 )) {
+ return 1;
}
+ return 0;
}
-static __inline__ ssize_t read_file(struct ofork *ofork, int eid,
- int offset, u_char nlmask,
+static ssize_t read_file(struct ofork *ofork, int eid,
+ off_t offset, u_char nlmask,
u_char nlchar, char *rbuf,
- int *rbuflen, const int xlate)
+ size_t *rbuflen, const int xlate)
{
ssize_t cc;
int eof = 0;
cc = ad_read(ofork->of_ad, eid, offset, rbuf, *rbuflen);
if ( cc < 0 ) {
- LOG(log_error, logtype_afpd, "afp_read: ad_read: %s", strerror(errno) );
+ LOG(log_error, logtype_afpd, "afp_read(%s): ad_read: %s", of_name(ofork), strerror(errno) );
*rbuflen = 0;
return( AFPERR_PARAM );
}
- if ( cc < *rbuflen ) {
+ if ( (size_t)cc < *rbuflen ) {
eof = 1;
}
*
* with dsi, should we check that reqcount < server quantum?
*/
-static int read_fork(obj, ibuf, ibuflen, rbuf, rbuflen, is64)
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
-int is64;
+static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen, int is64)
{
struct ofork *ofork;
- off_t size;
off_t offset, saveoff, reqcount, savereqcount;
- int cc, err, eid, xlate = 0;
+ ssize_t cc, err;
+ int eid, xlate = 0;
u_int16_t ofrefnum;
u_char nlmask, nlchar;
memcpy(&ofrefnum, ibuf, sizeof( ofrefnum ));
ibuf += sizeof( u_short );
- if (( ofork = of_find( ofrefnum )) == NULL ) {
- LOG(log_error, logtype_afpd, "afp_read: of_find");
+ if (NULL == ( ofork = of_find( ofrefnum )) ) {
+ LOG(log_error, logtype_afpd, "afp_read: of_find(%d) could not locate fork", ofrefnum );
err = AFPERR_PARAM;
goto afp_read_err;
}
goto afp_read_err;
}
- /* reqcount isn't always truthful. we need to deal with that. */
- size = ad_size(ofork->of_ad, eid);
-
- if (offset >= size) {
- err = AFPERR_EOF;
- goto afp_read_err;
- }
-
savereqcount = reqcount;
saveoff = offset;
- if (ad_tmplock(ofork->of_ad, eid, ADLOCK_RD, saveoff, savereqcount) < 0) {
+ if (ad_tmplock(ofork->of_ad, eid, ADLOCK_RD, saveoff, savereqcount,ofork->of_refnum) < 0) {
err = AFPERR_LOCK;
goto afp_read_err;
}
#define min(a,b) ((a)<(b)?(a):(b))
*rbuflen = min( reqcount, *rbuflen );
- err = read_file(ofork, eid, offset, nlmask, nlchar, rbuf, rbuflen,
- xlate);
+ err = read_file(ofork, eid, offset, nlmask, nlchar, rbuf, rbuflen, xlate);
if (err < 0)
goto afp_read_done;
/* dsi can stream requests. we can only do this if we're not checking
* for an end-of-line character. oh well. */
if ((obj->proto == AFPPROTO_DSI) && (*rbuflen < reqcount) && !nlmask) {
- DSI *dsi = obj->handle;
+ DSI *dsi = obj->handle;
+ off_t size;
+
+ /* reqcount isn't always truthful. we need to deal with that. */
+ size = ad_size(ofork->of_ad, eid);
- if (obj->options.flags & OPTION_DEBUG) {
- printf( "(read) reply: %d/%d, %d\n", *rbuflen,
- (int) reqcount, dsi->clientID);
- bprint(rbuf, *rbuflen);
- }
/* subtract off the offset */
size -= offset;
if (reqcount > size) {
/* dsi_readinit() returns size of next read buffer. by this point,
* we know that we're sending some data. if we fail, something
* horrible happened. */
- if ((*rbuflen = dsi_readinit(dsi, rbuf, *rbuflen, reqcount, err)) < 0)
+ if ((cc = dsi_readinit(dsi, rbuf, *rbuflen, reqcount, err)) < 0)
goto afp_read_exit;
-
+ *rbuflen = cc;
/* due to the nature of afp packets, we have to exit if we get
an error. we can't do this with translation on. */
-#ifdef HAVE_SENDFILE_READ
- if (!(xlate || (obj->options.flags & OPTION_DEBUG))) {
- if (ad_readfile(ofork->of_ad, eid, dsi->socket, offset,
- dsi->datasize) < 0) {
- if (errno == EINVAL)
+#ifdef WITH_SENDFILE
+ if (!(xlate || Debug(obj) )) {
+ int fd;
+
+ fd = ad_readfile_init(ofork->of_ad, eid, &offset, 0);
+ if (dsi_stream_read_file(dsi, fd, offset, dsi->datasize) < 0) {
+ if (errno == EINVAL || errno == ENOSYS)
goto afp_read_loop;
else {
- LOG(log_error, logtype_afpd, "afp_read: ad_readfile: %s", strerror(errno));
+ LOG(log_error, logtype_afpd, "afp_read(%s): ad_readfile: %s", of_name(ofork), strerror(errno));
goto afp_read_exit;
}
}
}
afp_read_loop:
-#endif /* HAVE_SENDFILE_READ */
+#endif
/* fill up our buffer. */
while (*rbuflen > 0) {
- cc = read_file(ofork, eid, offset, nlmask, nlchar, rbuf,
- rbuflen, xlate);
+ cc = read_file(ofork, eid, offset, nlmask, nlchar, rbuf,rbuflen, xlate);
if (cc < 0)
goto afp_read_exit;
offset += *rbuflen;
+#ifdef DEBUG1
if (obj->options.flags & OPTION_DEBUG) {
printf( "(read) reply: %d, %d\n", *rbuflen, dsi->clientID);
bprint(rbuf, *rbuflen);
}
-
+#endif
/* dsi_read() also returns buffer size of next allocation */
cc = dsi_read(dsi, rbuf, *rbuflen); /* send it off */
if (cc < 0)
goto afp_read_done;
afp_read_exit:
- LOG(log_error, logtype_afpd, "afp_read: %s", strerror(errno));
+ LOG(log_error, logtype_afpd, "afp_read(%s): %s", of_name(ofork), strerror(errno));
dsi_readdone(dsi);
- ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, savereqcount);
- obj->exit(1);
+ ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, savereqcount,ofork->of_refnum);
+ obj->exit(EXITERR_CLNT);
}
afp_read_done:
- ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, savereqcount);
+ ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, savereqcount,ofork->of_refnum);
return err;
afp_read_err:
}
/* ---------------------- */
-int afp_read(obj, ibuf, ibuflen, rbuf, rbuflen)
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+int afp_read(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
{
return read_fork(obj, ibuf, ibuflen, rbuf, rbuflen, 0);
}
/* ---------------------- */
-int afp_read_ext(obj, ibuf, ibuflen, rbuf, rbuflen)
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+int afp_read_ext(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
{
return read_fork(obj, ibuf, ibuflen, rbuf, rbuflen, 1);
}
/* ---------------------- */
-int afp_flush(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+int afp_flush(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
{
struct vol *vol;
u_int16_t vid;
ibuf += 2;
memcpy(&vid, ibuf, sizeof(vid));
- if (( vol = getvolbyvid( vid )) == NULL ) {
+ if (NULL == ( vol = getvolbyvid( vid )) ) {
return( AFPERR_PARAM );
}
return( AFP_OK );
}
-int afp_flushfork(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+int afp_flushfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
{
struct ofork *ofork;
u_int16_t ofrefnum;
ibuf += 2;
memcpy(&ofrefnum, ibuf, sizeof( ofrefnum ));
- if (( ofork = of_find( ofrefnum )) == NULL ) {
- LOG(log_error, logtype_afpd, "afp_flushfork: of_find");
+ if (NULL == ( ofork = of_find( ofrefnum )) ) {
+ LOG(log_error, logtype_afpd, "afp_flushfork: of_find(%d) could not locate fork", ofrefnum );
return( AFPERR_PARAM );
}
if ( flushfork( ofork ) < 0 ) {
- LOG(log_error, logtype_afpd, "afp_flushfork: %s", strerror(errno) );
+ LOG(log_error, logtype_afpd, "afp_flushfork(%s): %s", of_name(ofork), strerror(errno) );
+ }
+
+ return( AFP_OK );
+}
+
+/*
+ FIXME
+ There is a lot to tell about fsync, fdatasync, F_FULLFSYNC.
+ fsync(2) on OSX is implemented differently than on other platforms.
+ see: http://mirror.linux.org.au/pub/linux.conf.au/2007/video/talks/278.pdf.
+ */
+int afp_syncfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
+{
+ struct ofork *ofork;
+ u_int16_t ofrefnum;
+
+ *rbuflen = 0;
+ ibuf += 2;
+
+ memcpy(&ofrefnum, ibuf, sizeof(ofrefnum));
+ ibuf += sizeof( ofrefnum );
+
+ if (NULL == ( ofork = of_find( ofrefnum )) ) {
+ LOG(log_error, logtype_afpd, "afpd_syncfork: of_find(%d) could not locate fork", ofrefnum );
+ return( AFPERR_PARAM );
+ }
+
+ if ( flushfork( ofork ) < 0 ) {
+ LOG(log_error, logtype_afpd, "flushfork(%s): %s", of_name(ofork), strerror(errno) );
+ return AFPERR_MISC;
}
return( AFP_OK );
}
/* this is very similar to closefork */
-int flushfork( ofork )
-struct ofork *ofork;
+int flushfork(struct ofork *ofork)
{
struct timeval tv;
int err = 0, doflush = 0;
- if ( ad_dfileno( ofork->of_ad ) != -1 &&
- fsync( ad_dfileno( ofork->of_ad )) < 0 ) {
- LOG(log_error, logtype_afpd, "flushfork: dfile(%d) %s",
- ad_dfileno(ofork->of_ad), strerror(errno) );
+ 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_data_fileno(ofork->of_ad), strerror(errno) );
err = -1;
}
- if ( ad_hfileno( ofork->of_ad ) != -1 &&
- (ofork->of_flags & AFPFORK_RSRC)) {
+ if ( ad_reso_fileno( ofork->of_ad ) != -1 && /* HF */
+ (ofork->of_flags & AFPFORK_RSRC)) {
/* read in the rfork length */
ad_refresh(ofork->of_ad);
}
/* 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: hfile(%d) %s",
- ad_hfileno(ofork->of_ad), strerror(errno) );
+ LOG(log_error, logtype_afpd, "flushfork(%s): hfile(%d) %s",
+ of_name(ofork), ad_reso_fileno(ofork->of_ad), strerror(errno) );
}
return( err );
}
-int afp_closefork(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+int afp_closefork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
{
struct ofork *ofork;
- struct timeval tv;
- int adflags, doflush = 0;
u_int16_t ofrefnum;
*rbuflen = 0;
ibuf += 2;
memcpy(&ofrefnum, ibuf, sizeof( ofrefnum ));
- if (( ofork = of_find( ofrefnum )) == NULL ) {
- LOG(log_error, logtype_afpd, "afp_closefork: of_find");
+ if (NULL == ( ofork = of_find( ofrefnum )) ) {
+ LOG(log_error, logtype_afpd, "afp_closefork: of_find(%d) could not locate fork", ofrefnum );
return( AFPERR_PARAM );
}
-
- adflags = 0;
- if ((ofork->of_flags & AFPFORK_DATA) &&
- (ad_dfileno( ofork->of_ad ) != -1)) {
- adflags |= ADFLAGS_DF;
- }
-
- if ( ad_hfileno( ofork->of_ad ) != -1 ) {
- adflags |= ADFLAGS_HF;
- /*
- * Only set the rfork's length if we're closing the rfork.
- */
- if ((ofork->of_flags & AFPFORK_RSRC)) {
- ad_refresh( ofork->of_ad );
- if ((ofork->of_flags & AFPFORK_DIRTY) &&
- !gettimeofday(&tv, NULL)) {
- ad_setdate(ofork->of_ad, AD_DATE_MODIFY | AD_DATE_UNIX,tv.tv_sec);
- doflush++;
- }
- if ( doflush ) {
- ad_flush( ofork->of_ad, adflags );
- }
- }
- }
-
- if ( ad_close( ofork->of_ad, adflags ) < 0 ) {
- LOG(log_error, logtype_afpd, "afp_closefork: ad_close: %s", strerror(errno) );
+ if ( of_closefork( ofork ) < 0 ) {
+ LOG(log_error, logtype_afpd, "afp_closefork(%s): of_closefork: %s", of_name(ofork), strerror(errno) );
return( AFPERR_PARAM );
}
- of_dealloc( ofork );
return( AFP_OK );
}
-static __inline__ ssize_t write_file(struct ofork *ofork, int eid,
+static ssize_t write_file(struct ofork *ofork, int eid,
off_t offset, char *rbuf,
size_t rbuflen, const int xlate)
{
case EFBIG :
case ENOSPC :
return( AFPERR_DFULL );
+ case EACCES:
+ return AFPERR_ACCESS;
default :
- LOG(log_error, logtype_afpd, "afp_write: ad_write: %s", strerror(errno) );
+ LOG(log_error, logtype_afpd, "afp_write(%s): ad_write: %s", of_name(ofork), strerror(errno) );
return( AFPERR_PARAM );
}
}
return cc;
}
+
/* FPWrite. NOTE: on an error, we always use afp_write_err as
* the client may have sent us a bunch of data that's not reflected
* in reqcount et al. */
-static int write_fork(obj, ibuf, ibuflen, rbuf, rbuflen, is64)
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
-int is64;
+static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen, int is64)
{
struct ofork *ofork;
off_t offset, saveoff, reqcount;
offset = get_off_t(&ibuf, is64);
reqcount = get_off_t(&ibuf, is64);
- if (( ofork = of_find( ofrefnum )) == NULL ) {
- LOG(log_error, logtype_afpd, "afp_write: of_find");
+ if (NULL == ( ofork = of_find( ofrefnum )) ) {
+ LOG(log_error, logtype_afpd, "afp_write: of_find(%d) could not locate fork", ofrefnum );
err = AFPERR_PARAM;
goto afp_write_err;
}
/* offset can overflow on 64-bit capable filesystems.
* report disk full if that's going to happen. */
- if (offset + reqcount < 0) {
+ if (sum_neg(is64, offset, reqcount)) {
err = AFPERR_DFULL;
goto afp_write_err;
}
saveoff = offset;
if (ad_tmplock(ofork->of_ad, eid, ADLOCK_WR, saveoff,
- reqcount) < 0) {
+ reqcount, ofork->of_refnum) < 0) {
err = AFPERR_LOCK;
goto afp_write_err;
}
return( AFPERR_PARAM );
}
+#ifdef DEBUG1
if (obj->options.flags & OPTION_DEBUG) {
printf("(write) len: %d\n", *rbuflen);
bprint(rbuf, *rbuflen);
}
-
+#endif
if ((cc = write_file(ofork, eid, offset, rbuf, *rbuflen,
xlate)) < 0) {
*rbuflen = 0;
- ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount);
+ ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount, ofork->of_refnum);
return cc;
}
offset += cc;
/* find out what we have already and write it out. */
cc = dsi_writeinit(dsi, rbuf, *rbuflen);
- if (!cc ||
- (cc = write_file(ofork, eid, offset, rbuf, cc, xlate)) < 0) {
+ if (!cc || (cc = write_file(ofork, eid, offset, rbuf, cc, xlate)) < 0) {
dsi_writeflush(dsi);
*rbuflen = 0;
- ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount);
+ ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount, ofork->of_refnum);
return cc;
}
offset += cc;
dsi_writeflush(dsi);
*rbuflen = 0;
ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff,
- reqcount);
+ reqcount, ofork->of_refnum);
return cc;
}
/* loop until everything gets written. currently
* dsi_write handles the end case by itself. */
while ((cc = dsi_write(dsi, rbuf, *rbuflen))) {
- if ( obj->options.flags & OPTION_DEBUG ) {
- printf("(write) command cont'd: %d\n", cc);
- bprint(rbuf, cc);
- }
-
if ((cc = write_file(ofork, eid, offset, rbuf, cc, xlate)) < 0) {
dsi_writeflush(dsi);
*rbuflen = 0;
ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff,
- reqcount);
+ reqcount, ofork->of_refnum);
return cc;
}
offset += cc;
break;
}
- ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount);
- if ( ad_hfileno( ofork->of_ad ) != -1 )
+ ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount, ofork->of_refnum);
+ if ( ad_meta_fileno( ofork->of_ad ) != -1 ) /* META */
ofork->of_flags |= AFPFORK_DIRTY;
*rbuflen = set_off_t (offset, rbuf, is64);
dsi_writeinit(obj->handle, rbuf, *rbuflen);
dsi_writeflush(obj->handle);
}
-
- *rbuflen = (err == AFP_OK) ? sizeof(offset) : 0;
+ if (err != AFP_OK) {
+ *rbuflen = 0;
+ }
return err;
}
/* ---------------------------- */
-int afp_write(obj, ibuf, ibuflen, rbuf, rbuflen)
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+int afp_write(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
{
return write_fork(obj, ibuf, ibuflen, rbuf, rbuflen, 0);
}
/* ----------------------------
* FIXME need to deal with SIGXFSZ signal
*/
-int afp_write_ext(obj, ibuf, ibuflen, rbuf, rbuflen)
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+int afp_write_ext(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
{
return write_fork(obj, ibuf, ibuflen, rbuf, rbuflen, 1);
}
/* ---------------------------- */
-int afp_getforkparams(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+int afp_getforkparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen)
{
struct ofork *ofork;
- int buflen, ret;
+ int ret;
u_int16_t ofrefnum, bitmap;
- u_int16_t attrbits = 0;
-
+ size_t buflen;
ibuf += 2;
memcpy(&ofrefnum, ibuf, sizeof( ofrefnum ));
ibuf += sizeof( ofrefnum );
ibuf += sizeof( bitmap );
*rbuflen = 0;
- if (( ofork = of_find( ofrefnum )) == NULL ) {
- LOG(log_error, logtype_afpd, "afp_getforkparams: of_find");
+ if (NULL == ( ofork = of_find( 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: ad_refresh: %s", strerror(errno) );
+ LOG(log_error, logtype_afpd, "getforkparams(%s): ad_refresh: %s", of_name(ofork), strerror(errno) );
return( AFPERR_PARAM );
}
}
- if (( ret = getforkparams( ofork, bitmap,
- rbuf + sizeof( u_short ), &buflen, attrbits )) != AFP_OK ) {
+ if (AFP_OK != ( ret = getforkparams( ofork, bitmap,
+ rbuf + sizeof( u_short ), &buflen ))) {
return( ret );
}