X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Ffork.c;h=57b3268ea8726d0d8cb7bb1d80ad8ead3d73693f;hb=f758a8c097b044293fa2fe58f8a7fcc2d8909b55;hp=b9bc22a44d5448110b4b935936ca41eb2cda680f;hpb=ccaca461c5374341894f85fc56b17f3a3572948f;p=netatalk.git diff --git a/etc/afpd/fork.c b/etc/afpd/fork.c index b9bc22a4..57b3268e 100644 --- a/etc/afpd/fork.c +++ b/etc/afpd/fork.c @@ -1,5 +1,5 @@ /* - * $Id: fork.c,v 1.52 2003-06-05 09:17:11 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,18 +38,17 @@ #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 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 path path; struct stat *st; @@ -77,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; @@ -86,32 +76,30 @@ const u_int16_t attrbits; vol = ofork->of_vol; dir = ofork->of_dir; - 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); st = &path.st; if ( bitmap & ( (1<of_ad ) == -1 ) { + if ( ad_data_fileno( ofork->of_ad ) == -1 ) { if (movecwd(vol, dir) < 0) return( AFPERR_NOOBJ ); 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, &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; @@ -133,10 +121,7 @@ int is64; } /* ---------------------- */ -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; @@ -165,7 +150,7 @@ static int is_neg(int is64, off_t val) 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; @@ -181,11 +166,13 @@ static int setforkmode(struct adouble *adp, int eid, int ofrefnum, int what) /* ------------------------- */ -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 fork_setmode(struct adouble *adp, int eid, int access, int ofrefnum) { int ret; @@ -252,27 +239,23 @@ static int fork_setmode(struct adouble *adp, int eid, int access, int ofrefnum) 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; + 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; @@ -324,7 +307,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): ad_open: %s", s_path->m_name, strerror(errno) ); return AFPERR_PARAM; } /* FIXME should we check it first ? */ @@ -349,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; } @@ -405,7 +385,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; @@ -452,7 +432,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) ); goto openfork_err; break; } @@ -464,14 +444,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 (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; } @@ -484,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 ); @@ -500,7 +479,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 +497,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,10 +518,7 @@ 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; @@ -563,7 +539,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 ); } @@ -633,8 +609,8 @@ int ibuflen, *rbuflen; 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 +618,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 */ @@ -679,11 +655,7 @@ afp_setfork_err: /* ---------------------- */ -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; @@ -702,7 +674,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 ); } @@ -721,7 +693,7 @@ int is64; 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 >= AD_FILELOCK_BASE) && -1 == (ad_reso_fileno(ofork->of_ad))) { /* HF ?*/ return AFPERR_LOCK; } @@ -762,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); } @@ -782,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 (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 ); - } + 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, +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; @@ -818,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; } @@ -875,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; @@ -893,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; } @@ -936,14 +892,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) { @@ -953,21 +901,20 @@ int is64; #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) { @@ -980,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; } } @@ -1002,35 +949,45 @@ 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,ofork->of_refnum); - obj->exit(1); + obj->exit(EXITERR_CLNT); } afp_read_done: @@ -1043,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; @@ -1081,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; @@ -1094,34 +1039,63 @@ int ibuflen, *rbuflen; 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 ); } 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); @@ -1134,28 +1108,23 @@ 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; @@ -1163,42 +1132,19 @@ int ibuflen, *rbuflen; 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 ); - } - } - } - - 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) { @@ -1226,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 ); } } @@ -1238,11 +1184,7 @@ 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 * 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; @@ -1261,7 +1203,7 @@ 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; } @@ -1324,11 +1266,12 @@ 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; @@ -1345,8 +1288,7 @@ 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, ofork->of_refnum); @@ -1383,11 +1325,6 @@ 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; @@ -1402,7 +1339,7 @@ int is64; } 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,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); } @@ -1430,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 ); @@ -1458,21 +1386,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 ); }