X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Ffork.c;h=3c1e8756b82c1f7b3bd98207804aa8c39623ebb3;hb=d81ea56449b54aaeccf8bba1dc7ae88773268c33;hp=32008c1db55d02f16a899e7a4c224be9a82077f1;hpb=d5fe0508bed28ef27f5d3c98315d84f96dd357c4;p=netatalk.git diff --git a/etc/afpd/fork.c b/etc/afpd/fork.c index 32008c1d..3c1e8756 100644 --- a/etc/afpd/fork.c +++ b/etc/afpd/fork.c @@ -1,5 +1,5 @@ /* - * $Id: fork.c,v 1.43 2003-01-12 14:40:01 didg Exp $ + * $Id: fork.c,v 1.69 2009-10-25 09:47:04 didg 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; @@ -255,7 +290,7 @@ int ibuflen, *rbuflen; } if (NULL == ( s_path = cname( vol, dir, &ibuf ))) { - return afp_errno; + 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 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; } @@ -333,6 +372,7 @@ int ibuflen, *rbuflen; * 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 : @@ -345,14 +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; } } - /* the fork is open */ - ofork->of_flags |= AFPFORK_OPEN; + else { + /* the ressource fork is open too */ + ofork->of_flags |= AFPFORK_OPEN; + } } else { /* try opening in read-only mode */ ret = AFPERR_NOOBJ; @@ -370,11 +412,14 @@ int ibuflen, *rbuflen; goto openfork_err; } adflags = ADFLAGS_DF; - ofork->of_flags |= AFPFORK_OPEN; } /* 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 : @@ -387,27 +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 fork is open */ + /* 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; } @@ -420,7 +463,7 @@ int ibuflen, *rbuflen; /* 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 ); @@ -436,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; @@ -454,7 +497,7 @@ 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 ); } } @@ -475,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 ); } @@ -506,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 */ @@ -565,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 */ @@ -630,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 ); } @@ -645,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: @@ -701,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); } @@ -721,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; @@ -757,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; } @@ -814,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; @@ -832,7 +849,7 @@ int is64; ibuf += sizeof( u_short ); if (NULL == ( ofork = of_find( ofrefnum )) ) { - LOG(log_error, logtype_afpd, "afp_read: of_find"); + LOG(log_error, logtype_afpd, "afp_read: of_find(%d) could not locate fork", ofrefnum ); err = AFPERR_PARAM; goto afp_read_err; } @@ -875,38 +892,28 @@ 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; + + /* 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) { @@ -919,19 +926,21 @@ 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) +#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; } } @@ -941,21 +950,21 @@ int is64; } 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) @@ -966,14 +975,14 @@ afp_read_loop: 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: @@ -982,28 +991,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; @@ -1020,10 +1020,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; @@ -1032,35 +1029,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", 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); @@ -1073,73 +1099,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_OPEN)) { - 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) ); - return( AFPERR_PARAM ); - } + 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) { @@ -1167,7 +1163,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 ); } } @@ -1175,14 +1171,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; @@ -1200,8 +1193,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; } @@ -1236,7 +1229,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; } @@ -1249,7 +1242,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; } @@ -1264,15 +1257,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; @@ -1285,11 +1279,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; @@ -1311,7 +1304,7 @@ int is64; dsi_writeflush(dsi); *rbuflen = 0; ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, - reqcount); + reqcount, ofork->of_refnum); return cc; } @@ -1323,16 +1316,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; @@ -1341,8 +1329,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); @@ -1353,16 +1341,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); } @@ -1370,25 +1356,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 ); @@ -1397,22 +1376,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 (AFP_OK != ( ret = getforkparams( ofork, bitmap, - rbuf + sizeof( u_short ), &buflen, attrbits ))) { + rbuf + sizeof( u_short ), &buflen ))) { return( ret ); }