X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Ffork.c;h=0c9ccef9c3c6f5e318532cce3f653c0cbd425276;hb=cb8de5b604041071f3454dd8df97295544caba59;hp=b9bc22a44d5448110b4b935936ca41eb2cda680f;hpb=ccaca461c5374341894f85fc56b17f3a3572948f;p=netatalk.git diff --git a/etc/afpd/fork.c b/etc/afpd/fork.c index b9bc22a4..0c9ccef9 100644 --- a/etc/afpd/fork.c +++ b/etc/afpd/fork.c @@ -1,7 +1,7 @@ /* - * $Id: fork.c,v 1.52 2003-06-05 09:17:11 didg Exp $ - * * Copyright (c) 1990,1993 Regents of The University of Michigan. + * Copyright (c) 2010 Frank Lahm + * * All Rights Reserved. See COPYRIGHT. */ @@ -10,35 +10,22 @@ #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 #include -#ifdef CNID_DB #include -#endif +#include #include "fork.h" #include "file.h" @@ -47,71 +34,63 @@ #include "desktop.h" #include "volume.h" -struct ofork *writtenfork; -extern int getmetadata(struct vol *vol, - u_int16_t bitmap, - struct path *path, struct dir *dir, char *buf, - int *buflen, struct adouble *adp, int attrbits ); - -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 AFS +struct ofork *writtenfork; +#endif + +static int getforkparams(struct ofork *ofork, u_int16_t bitmap, char *buf, size_t *buflen) { struct path path; - struct stat *st; + struct stat *st; + + struct adouble *adp; + struct dir *dir; + struct vol *vol; - struct adouble *adp; - struct dir *dir; - struct vol *vol; - /* can only get the length of the opened fork */ - if ( ( (bitmap & ((1<of_flags & AFPFORK_RSRC)) - || - ( (bitmap & ((1<of_flags & AFPFORK_DATA))) { + if ( ( (bitmap & ((1<of_flags & AFPFORK_RSRC)) + || + ( (bitmap & ((1<of_flags & AFPFORK_DATA))) { 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, ofork->of_name, utf8_encoding()))) { + if (NULL == (path.u_name = mtoupath(vol, of_name(ofork), dir->d_did, utf8_encoding()))) { return( AFPERR_MISC ); } - path.m_name = ofork->of_name; + path.m_name = of_name(ofork); + path.id = 0; st = &path.st; - if ( bitmap & ( (1<of_ad ) == -1 ) { + if ( ad_data_fileno( ofork->of_ad ) <= 0 ) { + /* 0 is for symlink */ if (movecwd(vol, dir) < 0) return( AFPERR_NOOBJ ); - if ( stat( path.u_name, 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, &path, dir, buf, buflen, adp, attrbits ); + return getmetadata(vol, bitmap, &path, dir, buf, buflen, adp ); } -/* ---------------------------- */ -static off_t get_off_t(ibuf, is64) -char **ibuf; -int is64; +static off_t get_off_t(char **ibuf, int is64) { u_int32_t temp; off_t ret; @@ -127,16 +106,12 @@ int is64; ret = ntohl(temp)| (ret << 32); } else { - ret = (int)ret; /* sign extend */ + ret = (int)ret; /* sign extend */ } return ret; } -/* ---------------------- */ -static int set_off_t(offset, rbuf, is64) -off_t offset; -char *rbuf; -int is64; +static int set_off_t(off_t offset, char *rbuf, int is64) { u_int32_t temp; int ret; @@ -156,36 +131,20 @@ int is64; return ret; } -/* ------------------------ -*/ static int is_neg(int is64, off_t val) { if (val < 0 || (sizeof(off_t) == 8 && !is64 && (val & 0x80000000U))) - return 1; + return 1; return 0; } -static __inline__ int sum_neg(int is64, off_t offset, off_t reqcount) +static int sum_neg(int is64, off_t offset, off_t reqcount) { - if (is_neg(is64, offset +reqcount) ) - return 1; + if (is_neg(is64, offset +reqcount) ) + return 1; return 0; } -/* ------------------------- -*/ -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) -{ - return ad_testlock(adp, eid, what); -} - static int fork_setmode(struct adouble *adp, int eid, int access, int ofrefnum) { int ret; @@ -195,13 +154,13 @@ static int fork_setmode(struct adouble *adp, int eid, int access, int ofrefnum) int denywriteset; if (! (access & (OPENACC_WR | OPENACC_RD | OPENACC_DWR | OPENACC_DRD))) { - return setforkmode(adp, eid, ofrefnum, AD_FILELOCK_OPEN_NONE); + return ad_lock(adp, eid, ADLOCK_RD | ADLOCK_FILELOCK, AD_FILELOCK_OPEN_NONE, 1, ofrefnum); } if ((access & (OPENACC_RD | OPENACC_DRD))) { - if ((readset = getforkmode(adp, eid, AD_FILELOCK_OPEN_RD)) <0) + if ((readset = ad_testlock(adp, eid, AD_FILELOCK_OPEN_RD)) <0) return readset; - if ((denyreadset = getforkmode(adp, eid, AD_FILELOCK_DENY_RD)) <0) + if ((denyreadset = ad_testlock(adp, eid, AD_FILELOCK_DENY_RD)) <0) return denyreadset; if ((access & OPENACC_RD) && denyreadset) { @@ -211,26 +170,26 @@ static int fork_setmode(struct adouble *adp, int eid, int access, int ofrefnum) if ((access & OPENACC_DRD) && readset) { errno = EACCES; return -1; - } + } /* boolean logic is not enough, because getforkmode is not always telling the - * true + * true */ if ((access & OPENACC_RD)) { - ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_OPEN_RD); + ret = ad_lock(adp, eid, ADLOCK_RD | ADLOCK_FILELOCK, AD_FILELOCK_OPEN_RD, 1, ofrefnum); if (ret) return ret; } if ((access & OPENACC_DRD)) { - ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_DENY_RD); + ret = ad_lock(adp, eid, ADLOCK_RD | ADLOCK_FILELOCK, AD_FILELOCK_DENY_RD, 1, ofrefnum); if (ret) return ret; } } /* ------------same for writing -------------- */ if ((access & (OPENACC_WR | OPENACC_DWR))) { - if ((writeset = getforkmode(adp, eid, AD_FILELOCK_OPEN_WR)) <0) + if ((writeset = ad_testlock(adp, eid, AD_FILELOCK_OPEN_WR)) <0) return writeset; - if ((denywriteset = getforkmode(adp, eid, AD_FILELOCK_DENY_WR)) <0) + if ((denywriteset = ad_testlock(adp, eid, AD_FILELOCK_DENY_WR)) <0) return denywriteset; if ((access & OPENACC_WR) && denywriteset) { @@ -240,44 +199,40 @@ static int fork_setmode(struct adouble *adp, int eid, int access, int ofrefnum) if ((access & OPENACC_DWR) && writeset) { errno = EACCES; return -1; - } + } if ((access & OPENACC_WR)) { - ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_OPEN_WR); + ret = ad_lock(adp, eid, ADLOCK_RD | ADLOCK_FILELOCK, AD_FILELOCK_OPEN_WR, 1, ofrefnum); if (ret) return ret; } if ((access & OPENACC_DWR)) { - ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_DENY_WR); + ret = ad_lock(adp, eid, ADLOCK_RD | ADLOCK_FILELOCK, AD_FILELOCK_DENY_WR, 1, ofrefnum); 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; - u_int32_t did; - u_int16_t vid, bitmap, access, ofrefnum, attrbits = 0; - char fork, *path, *upath; - struct stat *st; - u_int16_t bshort; - struct path *s_path; - + struct vol *vol; + struct dir *dir; + struct ofork *ofork, *opened; + struct adouble *adsame = NULL; + size_t buflen; + int ret, adflags, eid; + uint32_t did; + uint16_t vid, bitmap, access, ofrefnum; + char fork, *path, *upath; + struct stat *st; + uint16_t bshort; + struct path *s_path; + ibuf++; fork = *ibuf++; memcpy(&vid, ibuf, sizeof( vid )); @@ -292,7 +247,7 @@ int ibuflen, *rbuflen; ibuf += sizeof( int ); if (NULL == ( dir = dirlookup( vol, did ))) { - return afp_errno; + return afp_errno; } memcpy(&bitmap, ibuf, sizeof( bitmap )); @@ -307,14 +262,19 @@ int ibuflen, *rbuflen; } if (NULL == ( s_path = cname( vol, dir, &ibuf ))) { - return get_afp_errno(AFPERR_PARAM); + return get_afp_errno(AFPERR_PARAM); } if (*s_path->m_name == '\0') { - /* it's a dir ! */ - return AFPERR_BADTYPE; + /* it's a dir ! */ + return AFPERR_BADTYPE; } + LOG(log_debug, logtype_afpd, + "afp_openfork(\"%s\", %s)", + abspath(s_path->u_name), + (fork & OPENFORK_RSCS) ? "OPENFORK_RSCS" : "OPENFORK_DATA"); + /* stat() data fork st is set because it's not a dir */ switch ( s_path->st_errno ) { case 0: @@ -324,7 +284,7 @@ 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): %s", s_path->m_name, strerror(errno)); return AFPERR_PARAM; } /* FIXME should we check it first ? */ @@ -333,8 +293,7 @@ int ibuflen, *rbuflen; if (check_access(upath, access ) < 0) { return AFPERR_ACCESS; } - } - else { + } else { if (file_access(s_path, access ) < 0) { return AFPERR_ACCESS; } @@ -344,23 +303,20 @@ int ibuflen, *rbuflen; /* XXX: this probably isn't the best way to do this. the already open bits should really be set if the fork is opened by any program, not just this one. however, that's problematic to do - if we can't write lock files somewhere. opened is also passed to + if we can't write lock files somewhere. opened is also passed to ad_open so that we can keep file locks together. - FIXME: add the fork we are opening? + FIXME: add the fork we are opening? */ if ((opened = of_findname(s_path))) { - attrbits = ((opened->of_ad->ad_df.adf_refcount > 0) ? ATTRBIT_DOPEN : 0); - attrbits |= ((opened->of_ad->ad_hf.adf_refcount > opened->of_ad->ad_df.adf_refcount)? ATTRBIT_ROPEN : 0); - adsame = opened->of_ad; } if ( fork == OPENFORK_DATA ) { eid = ADEID_DFORK; - adflags = ADFLAGS_DF|ADFLAGS_HF; + adflags = ADFLAGS_DF | ADFLAGS_HF ; } else { eid = ADEID_RFORK; - adflags = ADFLAGS_HF; + adflags = ADFLAGS_RF | ADFLAGS_HF; } path = s_path->m_name; @@ -372,7 +328,7 @@ int ibuflen, *rbuflen; ret = AFPERR_NOOBJ; if (access & OPENACC_WR) { /* try opening in read-write mode */ - if (ad_open(upath, adflags, O_RDWR, 0, ofork->of_ad) < 0) { + if (ad_open(ofork->of_ad, upath, adflags, O_RDWR, O_RDWR) < 0) { switch ( errno ) { case EROFS: ret = AFPERR_VLOCK; @@ -382,15 +338,14 @@ int ibuflen, *rbuflen; 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) { + if (ad_open(ofork->of_ad, upath, ADFLAGS_DF, O_RDWR) < 0) { goto openfork_err; } adflags = ADFLAGS_DF; - } - else { + } 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) + * fork if the user wants to open it for write acess. */ + if (ad_open(ofork->of_ad, upath, adflags, O_RDWR | O_CREAT, 0666, O_RDWR | O_CREAT, 0666) < 0) goto openfork_err; ofork->of_flags |= AFPFORK_OPEN; } @@ -405,7 +360,7 @@ 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; @@ -418,7 +373,7 @@ int ibuflen, *rbuflen; } else { /* try opening in read-only mode */ ret = AFPERR_NOOBJ; - if (ad_open(upath, adflags, O_RDONLY, 0, ofork->of_ad) < 0) { + if (ad_open(ofork->of_ad, upath, adflags, O_RDONLY, O_RDONLY) < 0) { switch ( errno ) { case EROFS: ret = AFPERR_VLOCK; @@ -428,19 +383,19 @@ int ibuflen, *rbuflen; case ENOENT: /* 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) { + if (ad_open(ofork->of_ad, upath, ADFLAGS_DF, O_RDONLY) < 0) { goto openfork_err; } adflags = ADFLAGS_DF; } - /* else we don't set AFPFORK_OPEN because there's no ressource fork file + /* 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 : @@ -452,7 +407,8 @@ 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\"): %s", + abspath(s_path->m_name), strerror(errno) ); goto openfork_err; break; } @@ -463,15 +419,13 @@ int ibuflen, *rbuflen; } } - if ((adflags & ADFLAGS_HF) && (ad_get_HF_flags( ofork->of_ad) & 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_RF) && (ad_get_RF_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 ) { + if ((ret = getforkparams(ofork, bitmap, rbuf + 2 * sizeof(int16_t), &buflen)) != AFP_OK) { ad_close( ofork->of_ad, adflags ); goto openfork_err; } @@ -482,9 +436,9 @@ int ibuflen, *rbuflen; rbuf += sizeof( u_int16_t ); /* check WriteInhibit bit if we have a ressource fork - * the test is done here, after some Mac trafic capture + * 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 ); @@ -500,7 +454,7 @@ 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 = fork_setmode(ofork->of_ad, eid, access, ofrefnum); /* can we access the fork? */ @@ -518,7 +472,7 @@ int ibuflen, *rbuflen; break; default: *rbuflen = 0; - LOG(log_error, logtype_afpd, "afp_openfork: ad_lock: %s", strerror(ret) ); + LOG(log_error, logtype_afpd, "afp_openfork(%s): ad_lock: %s", s_path->m_name, strerror(ret) ); return( AFPERR_PARAM ); } } @@ -539,19 +493,16 @@ 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; - off_t size; - u_int16_t ofrefnum, bitmap; + struct ofork *ofork; + off_t size; + u_int16_t ofrefnum, bitmap; int err; int is64; int eid; - off_t st_size; - + off_t st_size; + ibuf += 2; memcpy(&ofrefnum, ibuf, sizeof( ofrefnum )); @@ -563,7 +514,7 @@ int ibuflen, *rbuflen; *rbuflen = 0; if (NULL == ( ofork = of_find( ofrefnum )) ) { - LOG(log_error, logtype_afpd, "afp_setforkparams: of_find could not locate open fork refnum: %u", ofrefnum ); + LOG(log_error, logtype_afpd, "afp_setforkparams: of_find(%d) could not locate fork", ofrefnum ); return( AFPERR_PARAM ); } @@ -580,26 +531,26 @@ int ibuflen, *rbuflen; } else return AFPERR_PARAM; - if ( ( (bitmap & ( (1<= 30) { is64 = 4; } - else - return AFPERR_BITMAP; + 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) @@ -607,34 +558,34 @@ int ibuflen, *rbuflen; 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) + 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); + 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_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) { + 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); + 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) ); + 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 @@ -642,7 +593,7 @@ int ibuflen, *rbuflen; #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 */ @@ -672,26 +623,22 @@ afp_setfork_err: * read and write. that's most easily handled by always doing an * appropriate check before each ad_read/ad_write. other things * that can change files like truncate are handled internally to those - * functions. + * functions. */ #define ENDBIT(a) ((a) & 0x80) #define UNLOCKBIT(a) ((a) & 0x01) /* ---------------------- */ -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; + struct ofork *ofork; off_t offset, length; int eid; - u_int16_t ofrefnum; + u_int16_t ofrefnum; u_int8_t flags; int lockop; - + *rbuflen = 0; /* figure out parameters */ @@ -702,7 +649,7 @@ int is64; ibuf += sizeof(ofrefnum); if (NULL == ( ofork = of_find( ofrefnum )) ) { - LOG(log_error, logtype_afpd, "afp_bytelock: of_find"); + LOG(log_error, logtype_afpd, "afp_bytelock: of_find(%d) could not locate fork", ofrefnum ); return( AFPERR_PARAM ); } @@ -719,15 +666,15 @@ int is64; /* 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_hfileno(ofork->of_ad))) { + 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); - /* FIXME what do we do if file size > 2 GB and + /* FIXME what do we do if file size > 2 GB and it's not byte_lock_ext? */ } @@ -762,55 +709,43 @@ 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); + 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); + 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 (NULL == ( em = getextmap( of->of_name )) || - 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 ); + struct extmap *em; + + 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, - off_t offset, u_char nlmask, - u_char nlchar, char *rbuf, - int *rbuflen, const int xlate) +static ssize_t read_file(struct ofork *ofork, int eid, + off_t offset, u_char nlmask, + u_char nlchar, char *rbuf, + size_t *rbuflen, const int xlate) { ssize_t cc; int eof = 0; @@ -818,11 +753,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; } @@ -863,7 +798,7 @@ static __inline__ ssize_t read_file(struct ofork *ofork, int eid, } /* ----------------------------- - * with ddp, afp_read can return fewer bytes than in reqcount + * with ddp, afp_read can return fewer bytes than in reqcount * so return EOF only if read actually past end of file not * if offset +reqcount > size of file * e.g.: @@ -871,29 +806,25 @@ static __inline__ ssize_t read_file(struct ofork *ofork, int eid, * read fork offset 0 size 10752 ???? ==> 4264 bytes (without EOF) * read fork offset 4264 size 6128 ==> 4264 (without EOF) * read fork offset 9248 size 1508 ==> 1182 (EOF) - * 10752 is a bug in Mac 7.5.x finder + * 10752 is a bug in Mac 7.5.x finder * - * 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; + * with dsi, should we check that reqcount < server quantum? + */ +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; - u_int16_t ofrefnum; - u_char nlmask, nlchar; - + struct ofork *ofork; + off_t offset, saveoff, reqcount, savereqcount; + ssize_t cc, err; + int eid, xlate = 0; + u_int16_t ofrefnum; + u_char nlmask, nlchar; + ibuf += 2; memcpy(&ofrefnum, ibuf, sizeof( ofrefnum )); 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; } @@ -905,6 +836,11 @@ int is64; offset = get_off_t(&ibuf, is64); reqcount = get_off_t(&ibuf, is64); + LOG(log_debug, logtype_afpd, + "afp_read(\"%s\", off: %" PRIu64 ", size: %" PRIu64 ", fork: %s)", + cfrombstr(ofork->of_ad->ad_fullpath), offset, reqcount, + (ofork->of_flags & AFPFORK_DATA) ? "d" : "r"); + if (is64) { nlmask = nlchar = 0; } @@ -936,14 +872,6 @@ 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,ofork->of_refnum) < 0) { @@ -951,28 +879,26 @@ int is64; goto afp_read_err; } -#define min(a,b) ((a)<(b)?(a):(b)) +#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) { - reqcount = size; - err = AFPERR_EOF; + reqcount = size; + err = AFPERR_EOF; } offset += *rbuflen; @@ -980,19 +906,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)) { + 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; } } @@ -1001,22 +929,16 @@ int is64; goto afp_read_done; } -afp_read_loop: -#endif /* HAVE_SENDFILE_READ */ + afp_read_loop: +#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; - if (obj->options.flags & OPTION_DEBUG) { - printf( "(read) reply: %d, %d\n", *rbuflen, dsi->clientID); - bprint(rbuf, *rbuflen); - } - /* dsi_read() also returns buffer size of next allocation */ cc = dsi_read(dsi, rbuf, *rbuflen); /* send it off */ if (cc < 0) @@ -1026,11 +948,11 @@ afp_read_loop: dsi_readdone(dsi); goto afp_read_done; -afp_read_exit: - LOG(log_error, logtype_afpd, "afp_read: %s", strerror(errno)); + afp_read_exit: + 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,ofork->of_refnum); - obj->exit(1); + obj->exit(EXITERR_CLNT); } afp_read_done: @@ -1043,28 +965,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; @@ -1081,47 +994,83 @@ 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; + struct ofork *ofork; + u_int16_t ofrefnum; *rbuflen = 0; ibuf += 2; memcpy(&ofrefnum, ibuf, sizeof( ofrefnum )); if (NULL == ( ofork = of_find( ofrefnum )) ) { - LOG(log_error, logtype_afpd, "afp_flushfork: of_find"); + LOG(log_error, logtype_afpd, "afp_flushfork: of_find(%d) could not locate fork", ofrefnum ); + return( AFPERR_PARAM ); + } + + LOG(log_debug, logtype_afpd, + "afp_flushfork(\"%s\", fork: %s)", + cfrombstr(ofork->of_ad->ad_fullpath), + (ofork->of_flags & AFPFORK_DATA) ? "d" : "r"); + + 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 ); } + LOG(log_debug, logtype_afpd, + "afp_syncfork(\"%s\", fork: %s)", + cfrombstr(ofork->of_ad->ad_fullpath), + (ofork->of_flags & AFPFORK_DATA) ? "d" : "r"); + 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); @@ -1134,73 +1083,51 @@ struct ofork *ofork; } /* flush the header */ - if (doflush && ad_flush(ofork->of_ad, ADFLAGS_HF) < 0) - err = -1; + 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; + struct ofork *ofork; + u_int16_t ofrefnum; *rbuflen = 0; ibuf += 2; memcpy(&ofrefnum, ibuf, sizeof( ofrefnum )); if (NULL == ( ofork = of_find( ofrefnum )) ) { - LOG(log_error, logtype_afpd, "afp_closefork: of_find"); + 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 ( (ofork->of_flags & AFPFORK_OPEN) && 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 ); - } - } - } + LOG(log_debug, logtype_afpd, + "afp_closefork(\"%s\", fork: %s)", + cfrombstr(ofork->of_ad->ad_fullpath), + (ofork->of_flags & AFPFORK_DATA) ? "d" : "r"); - 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, - off_t offset, char *rbuf, - size_t rbuflen, const int xlate) +static ssize_t write_file(struct ofork *ofork, int eid, + off_t offset, char *rbuf, + size_t rbuflen, const int xlate) { char *p, *q; ssize_t cc; @@ -1225,8 +1152,10 @@ static __inline__ ssize_t write_file(struct ofork *ofork, int eid, 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 ); } } @@ -1236,18 +1165,14 @@ static __inline__ ssize_t write_file(struct ofork *ofork, int eid, /* 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 + * 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; - int endflag, eid, xlate = 0, err = AFP_OK; - u_int16_t ofrefnum; + struct ofork *ofork; + off_t offset, saveoff, reqcount; + int endflag, eid, xlate = 0, err = AFP_OK; + u_int16_t ofrefnum; ssize_t cc; /* figure out parameters */ @@ -1261,11 +1186,16 @@ int is64; reqcount = get_off_t(&ibuf, is64); if (NULL == ( ofork = of_find( ofrefnum )) ) { - LOG(log_error, logtype_afpd, "afp_write: of_find"); + LOG(log_error, logtype_afpd, "afp_write: of_find(%d) could not locate fork", ofrefnum ); err = AFPERR_PARAM; goto afp_write_err; } + LOG(log_debug, logtype_afpd, + "afp_write(\"%s\", off: %" PRIu64 ", size: %" PRIu64 ", fork: %s)", + cfrombstr(ofork->of_ad->ad_fullpath), offset, reqcount, + (ofork->of_flags & AFPFORK_DATA) ? "d" : "r"); + if ((ofork->of_flags & AFPFORK_ACCWR) == 0) { err = AFPERR_ACCESS; goto afp_write_err; @@ -1296,7 +1226,7 @@ int is64; /* offset can overflow on 64-bit capable filesystems. * report disk full if that's going to happen. */ - if (sum_neg(is64, offset, reqcount)) { + if (sum_neg(is64, offset, reqcount)) { err = AFPERR_DFULL; goto afp_write_err; } @@ -1324,11 +1254,6 @@ int is64; return( AFPERR_PARAM ); } - if (obj->options.flags & OPTION_DEBUG) { - printf("(write) len: %d\n", *rbuflen); - bprint(rbuf, *rbuflen); - } - if ((cc = write_file(ofork, eid, offset, rbuf, *rbuflen, xlate)) < 0) { *rbuflen = 0; @@ -1340,69 +1265,63 @@ int is64; #endif /* no afp/asp */ case AFPPROTO_DSI: - { - DSI *dsi = obj->handle; + { + DSI *dsi = obj->handle; + + /* 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) { + dsi_writeflush(dsi); + *rbuflen = 0; + 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 0 /*def HAVE_SENDFILE_WRITE*/ + if (!(xlate || obj->options.flags & OPTION_DEBUG)) { + if ((cc = ad_writefile(ofork->of_ad, eid, dsi->socket, + offset, dsi->datasize)) < 0) { + switch (errno) { + case EDQUOT : + case EFBIG : + case ENOSPC : + cc = AFPERR_DFULL; + break; + default : + LOG(log_error, logtype_afpd, "afp_write: ad_writefile: %s", strerror(errno) ); + goto afp_write_loop; + } dsi_writeflush(dsi); *rbuflen = 0; - ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount, ofork->of_refnum); + ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, + reqcount, ofork->of_refnum); return cc; } - offset += cc; - -#if 0 /*def HAVE_SENDFILE_WRITE*/ - if (!(xlate || obj->options.flags & OPTION_DEBUG)) { - if ((cc = ad_writefile(ofork->of_ad, eid, dsi->socket, - offset, dsi->datasize)) < 0) { - switch (errno) { - case EDQUOT : - case EFBIG : - case ENOSPC : - cc = AFPERR_DFULL; - break; - default : - LOG(log_error, logtype_afpd, "afp_write: ad_writefile: %s", strerror(errno) ); - goto afp_write_loop; - } - dsi_writeflush(dsi); - *rbuflen = 0; - ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, - reqcount, ofork->of_refnum); - return cc; - } - offset += cc; - goto afp_write_done; - } + offset += cc; + goto afp_write_done; + } #endif /* 0, was HAVE_SENDFILE_WRITE */ - /* 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, ofork->of_refnum); - return cc; - } - offset += cc; + /* loop until everything gets written. currently + * dsi_write handles the end case by itself. */ + while ((cc = dsi_write(dsi, rbuf, *rbuflen))) { + 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, ofork->of_refnum); + return cc; } + offset += cc; } - break; + } + break; } ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount, ofork->of_refnum); - if ( ad_hfileno( ofork->of_ad ) != -1 ) + if ( ad_meta_fileno( ofork->of_ad ) != -1 ) /* META */ ofork->of_flags |= AFPFORK_DIRTY; *rbuflen = set_off_t (offset, rbuf, is64); @@ -1413,42 +1332,33 @@ 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); } -/* ---------------------------- +/* ---------------------------- * 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; - u_int16_t ofrefnum, bitmap; - u_int16_t attrbits = 0; - + struct ofork *ofork; + int ret; + u_int16_t ofrefnum, bitmap; + size_t buflen; ibuf += 2; memcpy(&ofrefnum, ibuf, sizeof( ofrefnum )); ibuf += sizeof( ofrefnum ); @@ -1458,21 +1368,19 @@ int ibuflen, *rbuflen; *rbuflen = 0; if (NULL == ( ofork = of_find( ofrefnum )) ) { - LOG(log_error, logtype_afpd, "afp_getforkparams: of_find"); + 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 ); }