X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Ffork.c;h=57b3268ea8726d0d8cb7bb1d80ad8ead3d73693f;hb=f758a8c097b044293fa2fe58f8a7fcc2d8909b55;hp=34ef99c3d92f442a9812289917d071128ea421ea;hpb=aa6d367eb990d47117b688b7eca825e4c5f2bb8d;p=netatalk.git diff --git a/etc/afpd/fork.c b/etc/afpd/fork.c index 34ef99c3..57b3268e 100644 --- a/etc/afpd/fork.c +++ b/etc/afpd/fork.c @@ -1,5 +1,5 @@ /* - * $Id: fork.c,v 1.41 2003-01-08 15:01:35 didg Exp $ + * $Id: fork.c,v 1.67 2009-10-22 12:35:38 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -10,35 +10,26 @@ #endif /* HAVE_CONFIG_H */ #include -#ifdef HAVE_UNISTD_H -#include -#endif /* HAVE_UNISTD_H */ -#ifdef HAVE_FCNTL_H -#include -#endif /* HAVE_FCNTL_H */ + #include #include #include + +#include #include #include -#include -#include -#include #include -#include #include #include #include #include #include -#include + #include -#ifdef CNID_DB #include -#endif #include "fork.h" #include "file.h" @@ -47,24 +38,20 @@ #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; @@ -80,7 +67,7 @@ const u_int16_t attrbits; 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; @@ -89,64 +76,113 @@ const u_int16_t attrbits; vol = ofork->of_vol; dir = ofork->of_dir; + if (NULL == (path.u_name = mtoupath(vol, of_name(ofork), dir->d_did, utf8_encoding()))) { + return( AFPERR_MISC ); + } + path.m_name = of_name(ofork); + st = &path.st; if ( bitmap & ( (1<of_ad ) == -1 ) { - upath = mtoupath(vol, ofork->of_name); + if ( ad_data_fileno( ofork->of_ad ) == -1 ) { if (movecwd(vol, dir) < 0) return( AFPERR_NOOBJ ); - if ( stat( upath, &st ) < 0 ) + 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, 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))) { @@ -166,14 +202,13 @@ static int afp_setmode(struct adouble *adp, int eid, int access, int ofrefnum) /* 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; } @@ -193,34 +228,34 @@ static int afp_setmode(struct adouble *adp, int eid, int access, int ofrefnum) 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; @@ -232,14 +267,14 @@ int ibuflen, *rbuflen; 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; } @@ -254,8 +289,8 @@ int ibuflen, *rbuflen; 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') { @@ -272,13 +307,20 @@ int ibuflen, *rbuflen; 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; @@ -290,9 +332,6 @@ int ibuflen, *rbuflen; 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; } @@ -322,15 +361,18 @@ int ibuflen, *rbuflen; 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 : @@ -343,12 +385,16 @@ int ibuflen, *rbuflen; 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; @@ -357,21 +403,24 @@ int ibuflen, *rbuflen; 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 : @@ -383,23 +432,25 @@ int ibuflen, *rbuflen; 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) ); 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; } @@ -409,14 +460,18 @@ int ibuflen, *rbuflen; 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); + } } /* @@ -424,9 +479,9 @@ int ibuflen, *rbuflen; */ /* 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; @@ -442,15 +497,16 @@ int ibuflen, *rbuflen; 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 ); @@ -462,28 +518,28 @@ openfork_err: 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 ); } @@ -493,31 +549,76 @@ int ibuflen, *rbuflen; 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<of_flags & AFPFORK_DATA)) { + if ( ( (bitmap & ( (1<= 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<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<of_flags & AFPFORK_RSRC)) { + } else if (bitmap == (1<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 */ @@ -552,62 +653,17 @@ afp_setfork_err: #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 */ @@ -617,8 +673,8 @@ int is64; 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 ); } @@ -632,39 +688,29 @@ int is64; 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: @@ -688,19 +734,13 @@ int is64; } /* --------------------------- */ -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); } @@ -708,35 +748,29 @@ int ibuflen, *rbuflen; #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; @@ -744,11 +778,11 @@ static __inline__ ssize_t read_file(struct ofork *ofork, int eid, 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; } @@ -801,16 +835,12 @@ static __inline__ ssize_t read_file(struct ofork *ofork, int eid, * * 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; @@ -818,8 +848,8 @@ int is64; 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; } @@ -862,38 +892,29 @@ int is64; 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; + int non_blocking = 0; + + /* 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) { @@ -906,19 +927,19 @@ int is64; /* 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) +#if 0 /* ifdef WITH_SENDFILE */ + /* FIXME with OS X deadlock partial workaround we can't use sendfile */ + if (!(xlate || Debug(obj) )) { + if (ad_readfile(ofork->of_ad, eid, dsi->socket, 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; } } @@ -928,39 +949,49 @@ int is64; } afp_read_loop: -#endif /* HAVE_SENDFILE_READ */ +#endif + /* fill up our buffer. */ + if (*rbuflen) { + /* set to non blocking mode */ + non_blocking = 1; + dsi_block(dsi, 1); + } /* 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_exit; *rbuflen = cc; } + if (non_blocking) { + /* set back to blocking mode */ + dsi_block(dsi, 0); + } dsi_readdone(dsi); 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: @@ -969,28 +1000,19 @@ 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; @@ -999,7 +1021,7 @@ int ibuflen, *rbuflen; ibuf += 2; memcpy(&vid, ibuf, sizeof(vid)); - if (( vol = getvolbyvid( vid )) == NULL ) { + if (NULL == ( vol = getvolbyvid( vid )) ) { return( AFPERR_PARAM ); } @@ -1007,10 +1029,7 @@ int ibuflen, *rbuflen; 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; @@ -1019,35 +1038,64 @@ int ibuflen, *rbuflen; 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): %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, "afp_flushfork: %s", strerror(errno) ); + 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); @@ -1060,74 +1108,43 @@ struct ofork *ofork; } /* 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) { @@ -1155,7 +1172,7 @@ static __inline__ ssize_t write_file(struct ofork *ofork, int eid, case ENOSPC : return( AFPERR_DFULL ); 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 ); } } @@ -1163,14 +1180,11 @@ static __inline__ ssize_t write_file(struct ofork *ofork, int eid, 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; @@ -1188,8 +1202,8 @@ int is64; 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; } @@ -1224,7 +1238,7 @@ int is64; /* 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; } @@ -1237,7 +1251,7 @@ int is64; 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; } @@ -1252,15 +1266,16 @@ int is64; 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; @@ -1273,11 +1288,10 @@ int is64; /* 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; @@ -1299,7 +1313,7 @@ int is64; dsi_writeflush(dsi); *rbuflen = 0; ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, - reqcount); + reqcount, ofork->of_refnum); return cc; } @@ -1311,16 +1325,11 @@ int is64; /* 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; @@ -1329,8 +1338,8 @@ int is64; 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); @@ -1341,16 +1350,14 @@ afp_write_err: 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); } @@ -1358,25 +1365,18 @@ int ibuflen, *rbuflen; /* ---------------------------- * 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 ); @@ -1385,22 +1385,20 @@ int ibuflen, *rbuflen; 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 ); }