X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=blobdiff_plain;f=etc%2Fafpd%2Ffork.c;h=89f15e18ac23e9a60fae0333354d20b0bc8d7620;hp=889b7ac278287d1cf88ff517ef35869613d15f3f;hb=260c314546ffcfdbef47f2c7de82d5310b26df0a;hpb=cc8879f147f1411285e3a209b7eff4cdd2567d63 diff --git a/etc/afpd/fork.c b/etc/afpd/fork.c index 889b7ac2..89f15e18 100644 --- a/etc/afpd/fork.c +++ b/etc/afpd/fork.c @@ -16,35 +16,26 @@ #include #include -#include #include -#include -#include #include #include #include #include #include #include +#include #include "fork.h" #include "file.h" -#include "globals.h" #include "directory.h" #include "desktop.h" #include "volume.h" -#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) +static int getforkparams(struct ofork *ofork, uint16_t bitmap, char *buf, size_t *buflen) { struct path path; struct stat *st; @@ -63,7 +54,7 @@ static int getforkparams(struct ofork *ofork, u_int16_t bitmap, char *buf, size_ return( AFPERR_BITMAP ); } - if ( ad_reso_fileno( ofork->of_ad ) == -1 ) { /* META ? */ + if (! AD_META_OPEN(ofork->of_ad)) { adp = NULL; } else { adp = ofork->of_ad; @@ -96,10 +87,9 @@ static int getforkparams(struct ofork *ofork, u_int16_t bitmap, char *buf, size_ return getmetadata(vol, bitmap, &path, dir, buf, buflen, adp ); } -/* ---------------------------- */ static off_t get_off_t(char **ibuf, int is64) { - u_int32_t temp; + uint32_t temp; off_t ret; ret = 0; @@ -118,10 +108,9 @@ static off_t get_off_t(char **ibuf, int is64) return ret; } -/* ---------------------- */ static int set_off_t(off_t offset, char *rbuf, int is64) { - u_int32_t temp; + uint32_t temp; int ret; ret = 0; @@ -139,8 +128,6 @@ static int set_off_t(off_t offset, char *rbuf, int is64) return ret; } -/* ------------------------ - */ static int is_neg(int is64, off_t val) { if (val < 0 || (sizeof(off_t) == 8 && !is64 && (val & 0x80000000U))) @@ -155,22 +142,6 @@ static int sum_neg(int is64, off_t offset, off_t reqcount) 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); -} - -/* ------------------------- - */ -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; @@ -180,13 +151,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) { @@ -201,21 +172,21 @@ static int fork_setmode(struct adouble *adp, int eid, int access, int ofrefnum) * 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) { @@ -227,19 +198,17 @@ static int fork_setmode(struct adouble *adp, int eid, int access, int ofrefnum) 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; } @@ -258,6 +227,7 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si struct stat *st; uint16_t bshort; struct path *s_path; + struct stat xxx; ibuf++; fork = *ibuf++; @@ -296,11 +266,6 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si 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: @@ -339,10 +304,12 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si if ( fork == OPENFORK_DATA ) { eid = ADEID_DFORK; - adflags = ADFLAGS_DF | ADFLAGS_HF ; + adflags = ADFLAGS_DF | ADFLAGS_HF | ADFLAGS_NOHF; } else { eid = ADEID_RFORK; - adflags = ADFLAGS_RF | ADFLAGS_HF; + adflags = ADFLAGS_RF | ADFLAGS_HF | ADFLAGS_NOHF; + if (!(access & OPENACC_WR)) + adflags |= ADFLAGS_NORF; } path = s_path->m_name; @@ -351,71 +318,75 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si return( AFPERR_NFILE ); } + LOG(log_debug, logtype_afpd, "afp_openfork(\"%s\", %s, %s)", + fullpathname(s_path->u_name), + (fork == OPENFORK_DATA) ? "data" : "reso", + !(access & OPENACC_WR) ? "O_RDONLY" : "O_RDWR"); + ret = AFPERR_NOOBJ; if (access & OPENACC_WR) { /* try opening in read-write mode */ - if (ad_open(ofork->of_ad, upath, adflags, O_RDWR, O_RDWR) < 0) { + if (ad_open(ofork->of_ad, upath, + adflags | ADFLAGS_RDWR | ADFLAGS_SETSHRMD) < 0) { switch ( errno ) { case EROFS: ret = AFPERR_VLOCK; case EACCES: goto openfork_err; - break; case ENOENT: if (fork == OPENFORK_DATA) { /* try to open only the data fork */ - if (ad_open(ofork->of_ad, upath, ADFLAGS_DF, O_RDWR) < 0) { + if (ad_open(ofork->of_ad, upath, + ADFLAGS_DF | ADFLAGS_RDWR | ADFLAGS_SETSHRMD) < 0) { goto openfork_err; } adflags = ADFLAGS_DF; } else { /* here's the deal. we only try to create the resource * fork if the user wants to open it for write acess. */ - if (ad_open(ofork->of_ad, upath, adflags, O_RDWR | O_CREAT, 0666, O_RDWR | O_CREAT, 0666) < 0) + if (ad_open(ofork->of_ad, upath, + adflags | ADFLAGS_RDWR | ADFLAGS_SETSHRMD | ADFLAGS_CREATE, 0666) < 0) goto openfork_err; - ofork->of_flags |= AFPFORK_OPEN; + ofork->of_flags |= AFPFORK_META; } break; case EMFILE : case ENFILE : ret = AFPERR_NFILE; goto openfork_err; - break; case EISDIR : ret = AFPERR_BADTYPE; goto openfork_err; - break; default: LOG(log_error, logtype_afpd, "afp_openfork(%s): ad_open: %s", s_path->m_name, strerror(errno) ); ret = AFPERR_PARAM; goto openfork_err; - break; } } else { /* the ressource fork is open too */ - ofork->of_flags |= AFPFORK_OPEN; + ofork->of_flags |= AFPFORK_META; } } else { /* try opening in read-only mode */ ret = AFPERR_NOOBJ; - if (ad_open(ofork->of_ad, upath, adflags, O_RDONLY, O_RDONLY) < 0) { + if (ad_open(ofork->of_ad, upath, adflags | ADFLAGS_RDONLY | ADFLAGS_SETSHRMD) < 0) { switch ( errno ) { case EROFS: ret = AFPERR_VLOCK; + goto openfork_err; case EACCES: goto openfork_err; - break; case ENOENT: /* see if client asked for a read only data fork */ if (fork == OPENFORK_DATA) { - if (ad_open(ofork->of_ad, upath, ADFLAGS_DF, O_RDONLY) < 0) { + if (ad_open(ofork->of_ad, upath, ADFLAGS_DF | ADFLAGS_RDONLY | ADFLAGS_SETSHRMD) < 0) { goto openfork_err; } adflags = ADFLAGS_DF; } - /* else we don't set AFPFORK_OPEN because there's no ressource fork file - * We need to check AFPFORK_OPEN in afp_closefork(). eg fork open read-only + /* else we don't set AFPFORK_META because there's no ressource fork file + * We need to check AFPFORK_META 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 @@ -427,21 +398,16 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si case ENFILE : ret = AFPERR_NFILE; goto openfork_err; - break; case EISDIR : ret = AFPERR_BADTYPE; goto openfork_err; - break; default: LOG(log_error, logtype_afpd, "afp_openfork(\"%s\"): %s", - abspath(s_path->m_name), strerror(errno) ); + fullpathname(s_path->m_name), strerror(errno) ); goto openfork_err; - break; } - } - else { - /* the ressource fork is open too */ - ofork->of_flags |= AFPFORK_OPEN; + } else { + ofork->of_flags |= AFPFORK_META; } } @@ -452,14 +418,14 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si } if ((ret = getforkparams(ofork, bitmap, rbuf + 2 * sizeof(int16_t), &buflen)) != AFP_OK) { - ad_close( ofork->of_ad, adflags ); + ad_close( ofork->of_ad, adflags | ADFLAGS_SETSHRMD); goto openfork_err; } - *rbuflen = buflen + 2 * sizeof( u_int16_t ); + *rbuflen = buflen + 2 * sizeof( uint16_t ); bitmap = htons( bitmap ); - memcpy(rbuf, &bitmap, sizeof( u_int16_t )); - rbuf += sizeof( u_int16_t ); + memcpy(rbuf, &bitmap, sizeof( uint16_t )); + rbuf += sizeof( uint16_t ); /* check WriteInhibit bit if we have a ressource fork * the test is done here, after some Mac trafic capture @@ -467,7 +433,7 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si 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 ); + ad_close( ofork->of_ad, adflags | ADFLAGS_SETSHRMD); of_dealloc( ofork ); ofrefnum = 0; memcpy(rbuf, &ofrefnum, sizeof(ofrefnum)); @@ -480,13 +446,15 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si */ /* don't try to lock non-existent rforks. */ - if ((eid == ADEID_DFORK) || (ad_meta_fileno(ofork->of_ad) != -1)) { /* META */ - + if ((eid == ADEID_DFORK) + || (ad_reso_fileno(ofork->of_ad) != -1) + || (ofork->of_ad->ad_vers == AD_VERSION_EA)) { ret = fork_setmode(ofork->of_ad, eid, access, ofrefnum); /* can we access the fork? */ if (ret < 0) { + ofork->of_flags |= AFPFORK_ERROR; ret = errno; - ad_close( ofork->of_ad, adflags ); + ad_close( ofork->of_ad, adflags | ADFLAGS_SETSHRMD); of_dealloc( ofork ); switch (ret) { case EAGAIN: /* return data anyway */ @@ -523,7 +491,7 @@ int afp_setforkparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen, char *rbuf _U { struct ofork *ofork; off_t size; - u_int16_t ofrefnum, bitmap; + uint16_t ofrefnum, bitmap; int err; int is64; int eid; @@ -596,7 +564,7 @@ int afp_setforkparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen, char *rbuf _U if (err < 0) goto afp_setfork_err; } else if (bitmap == (1<of_ad ); + ad_refresh(NULL, ofork->of_ad ); st_size = ad_size(ofork->of_ad, eid); err = -2; @@ -661,8 +629,8 @@ static int byte_lock(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf struct ofork *ofork; off_t offset, length; int eid; - u_int16_t ofrefnum; - u_int8_t flags; + uint16_t ofrefnum; + uint8_t flags; int lockop; *rbuflen = 0; @@ -675,7 +643,7 @@ static int byte_lock(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf ibuf += sizeof(ofrefnum); if (NULL == ( ofork = of_find( ofrefnum )) ) { - LOG(log_error, logtype_afpd, "afp_bytelock: of_find(%d) could not locate fork", ofrefnum ); + LOG(log_error, logtype_afpd, "byte_lock: of_find(%d) could not locate fork", ofrefnum ); return( AFPERR_PARAM ); } @@ -689,7 +657,6 @@ static int byte_lock(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf offset = get_off_t(&ibuf, is64); length = get_off_t(&ibuf, is64); - /* FIXME AD_FILELOCK test is surely wrong */ if (length == -1) length = BYTELOCK_MAX; else if (!length || is_neg(is64, length)) { @@ -748,30 +715,10 @@ int afp_bytelock_ext(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t #undef UNLOCKBIT -/* --------------------------- */ -static int crlf(struct ofork *of) -{ - 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 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) + size_t *rbuflen) { ssize_t cc; int eof = 0; @@ -802,20 +749,6 @@ static ssize_t read_file(struct ofork *ofork, int eid, } } - /* - * If this file is of type TEXT, then swap \012 to \015. - */ - if (xlate) { - for ( p = rbuf, q = p + cc; p < q; p++ ) { - if ( *p == '\012' ) { - *p = '\015'; - } else if ( *p == '\015' ) { - *p = '\012'; - } - - } - } - *rbuflen = cc; if ( eof ) { return( AFPERR_EOF ); @@ -841,8 +774,8 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si struct ofork *ofork; off_t offset, saveoff, reqcount, savereqcount; ssize_t cc, err; - int eid, xlate = 0; - u_int16_t ofrefnum; + int eid; + uint16_t ofrefnum; u_char nlmask, nlchar; ibuf += 2; @@ -863,9 +796,8 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si 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"); + "afp_read(off: %" PRIu64 ", size: %" PRIu64 ", fork: %s)", offset, reqcount, + (ofork->of_flags & AFPFORK_DATA) ? "d" : "r"); if (is64) { nlmask = nlchar = 0; @@ -884,7 +816,6 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si if ( ofork->of_flags & AFPFORK_DATA) { eid = ADEID_DFORK; - xlate = (ofork->of_vol->v_flags & AFPVOL_CRLF) ? crlf(ofork) : 0; } else if (ofork->of_flags & AFPFORK_RSRC) { eid = ADEID_RFORK; } else { /* fork wasn't opened. this should never really happen. */ @@ -898,6 +829,9 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si goto afp_read_err; } + LOG(log_debug, logtype_afpd, "afp_read(name: \"%s\", offset: %jd, reqcount: %jd)", + of_name(ofork), (intmax_t)offset, (intmax_t)reqcount); + savereqcount = reqcount; saveoff = offset; if (ad_tmplock(ofork->of_ad, eid, ADLOCK_RD, saveoff, savereqcount,ofork->of_refnum) < 0) { @@ -905,16 +839,20 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si 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); + *rbuflen = MIN(reqcount, *rbuflen); + LOG(log_debug, logtype_afpd, "afp_read(name: \"%s\", offset: %jd, reqcount: %jd): reading %jd bytes from file", + of_name(ofork), (intmax_t)offset, (intmax_t)reqcount, (intmax_t)*rbuflen); + + err = read_file(ofork, eid, offset, nlmask, nlchar, rbuf, rbuflen); if (err < 0) goto afp_read_done; + LOG(log_debug, logtype_afpd, "afp_read(name: \"%s\", offset: %jd, reqcount: %jd): got %jd bytes from file", + of_name(ofork), (intmax_t)offset, (intmax_t)reqcount, (intmax_t)*rbuflen); /* 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; + if ((*rbuflen < reqcount) && !nlmask) { + DSI *dsi = obj->dsi; off_t size; /* reqcount isn't always truthful. we need to deal with that. */ @@ -938,39 +876,32 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si /* 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 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(%s): ad_readfile: %s", of_name(ofork), strerror(errno)); - goto afp_read_exit; - } - } + int fd; + + fd = ad_readfile_init(ofork->of_ad, eid, &offset, 0); - dsi_readdone(dsi); - goto afp_read_done; + 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(%s): ad_readfile: %s", of_name(ofork), strerror(errno)); + goto afp_read_exit; + } } + dsi_readdone(dsi); + goto afp_read_done; + 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); 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) @@ -1012,7 +943,7 @@ int afp_read_ext(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rb 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; + uint16_t vid; *rbuflen = 0; ibuf += 2; @@ -1029,7 +960,7 @@ int afp_flush(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, s 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; + uint16_t ofrefnum; *rbuflen = 0; ibuf += 2; @@ -1040,9 +971,7 @@ int afp_flushfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U return( AFPERR_PARAM ); } - LOG(log_debug, logtype_afpd, - "afp_flushfork(\"%s\", fork: %s)", - cfrombstr(ofork->of_ad->ad_fullpath), + LOG(log_debug, logtype_afpd, "afp_flushfork(fork: %s)", (ofork->of_flags & AFPFORK_DATA) ? "d" : "r"); if ( flushfork( ofork ) < 0 ) { @@ -1061,7 +990,7 @@ int afp_flushfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U 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; + uint16_t ofrefnum; *rbuflen = 0; ibuf += 2; @@ -1074,9 +1003,7 @@ int afp_syncfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_ return( AFPERR_PARAM ); } - LOG(log_debug, logtype_afpd, - "afp_syncfork(\"%s\", fork: %s)", - cfrombstr(ofork->of_ad->ad_fullpath), + LOG(log_debug, logtype_afpd, "afp_syncfork(fork: %s)", (ofork->of_flags & AFPFORK_DATA) ? "d" : "r"); if ( flushfork( ofork ) < 0 ) { @@ -1105,7 +1032,7 @@ int flushfork(struct ofork *ofork) (ofork->of_flags & AFPFORK_RSRC)) { /* read in the rfork length */ - ad_refresh(ofork->of_ad); + ad_refresh(NULL, ofork->of_ad); /* set the date if we're dirty */ if ((ofork->of_flags & AFPFORK_DIRTY) && !gettimeofday(&tv, NULL)) { @@ -1132,7 +1059,7 @@ int flushfork(struct ofork *ofork) int afp_closefork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen) { struct ofork *ofork; - u_int16_t ofrefnum; + uint16_t ofrefnum; *rbuflen = 0; ibuf += 2; @@ -1143,9 +1070,7 @@ int afp_closefork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U return( AFPERR_PARAM ); } - LOG(log_debug, logtype_afpd, - "afp_closefork(\"%s\", fork: %s)", - cfrombstr(ofork->of_ad->ad_fullpath), + LOG(log_debug, logtype_afpd, "afp_closefork(fork: %s)", (ofork->of_flags & AFPFORK_DATA) ? "d" : "r"); if ( of_closefork( ofork ) < 0 ) { @@ -1159,23 +1084,13 @@ int afp_closefork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U static ssize_t write_file(struct ofork *ofork, int eid, off_t offset, char *rbuf, - size_t rbuflen, const int xlate) + size_t rbuflen) { char *p, *q; ssize_t cc; - /* - * If this file is of type TEXT, swap \015 to \012. - */ - if (xlate) { - for ( p = rbuf, q = p + rbuflen; p < q; p++ ) { - if ( *p == '\015' ) { - *p = '\012'; - } else if ( *p == '\012' ) { - *p = '\015'; - } - } - } + LOG(log_debug, logtype_afpd, "write_file(off: %ju, size: %zu)", + (uintmax_t)offset, rbuflen); if (( cc = ad_write(ofork->of_ad, eid, offset, 0, rbuf, rbuflen)) < 0 ) { @@ -1202,9 +1117,9 @@ static ssize_t write_file(struct ofork *ofork, int eid, 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; + off_t offset, saveoff, reqcount, oldsize, newsize; + int endflag, eid, err = AFP_OK; + uint16_t ofrefnum; ssize_t cc; /* figure out parameters */ @@ -1223,10 +1138,8 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s 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"); + LOG(log_debug, logtype_afpd, "afp_write(off: %" PRIu64 ", size: %" PRIu64 ", fork: %s)", + offset, reqcount, (ofork->of_flags & AFPFORK_DATA) ? "d" : "r"); if ((ofork->of_flags & AFPFORK_ACCWR) == 0) { err = AFPERR_ACCESS; @@ -1239,7 +1152,6 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s if ( ofork->of_flags & AFPFORK_DATA) { eid = ADEID_DFORK; - xlate = (ofork->of_vol->v_flags & AFPVOL_CRLF) ? crlf(ofork) : 0; } else if (ofork->of_flags & AFPFORK_RSRC) { eid = ADEID_RFORK; } else { @@ -1247,8 +1159,9 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s goto afp_write_err; } + oldsize = ad_size(ofork->of_ad, eid); if (endflag) - offset += ad_size(ofork->of_ad, eid); + offset += oldsize; /* handle bogus parameters */ if (reqcount < 0 || offset < 0) { @@ -1256,6 +1169,8 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s goto afp_write_err; } + newsize = ((offset + reqcount) > oldsize) ? (offset + reqcount) : oldsize; + /* offset can overflow on 64-bit capable filesystems. * report disk full if that's going to happen. */ if (sum_neg(is64, offset, reqcount)) { @@ -1276,100 +1191,75 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s goto afp_write_err; } - /* this is yucky, but dsi can stream i/o and asp can't */ - switch (obj->proto) { -#ifndef NO_DDP - case AFPPROTO_ASP: - if (asp_wrtcont(obj->handle, rbuf, rbuflen) < 0) { - *rbuflen = 0; - LOG(log_error, logtype_afpd, "afp_write: asp_wrtcont: %s", strerror(errno) ); - return( AFPERR_PARAM ); - } + DSI *dsi = obj->dsi; + /* find out what we have already and write it out. */ + cc = dsi_writeinit(dsi, rbuf, *rbuflen); -#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, ofork->of_refnum); - return cc; - } - offset += cc; - break; -#endif /* no afp/asp */ + if (!cc || (cc = write_file(ofork, eid, offset, rbuf, cc)) < 0) { + dsi_writeflush(dsi); + *rbuflen = 0; + ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount, ofork->of_refnum); + return cc; + } - case AFPPROTO_DSI: - { - DSI *dsi = obj->handle; + 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 (!(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 ((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)) < 0) { + dsi_writeflush(dsi); + *rbuflen = 0; + ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, + reqcount, ofork->of_refnum); + return cc; } - } - break; + offset += cc; } 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; + /* we have modified any fork, remember until close_fork */ + ofork->of_flags |= AFPFORK_MODIFIED; + + /* update write count */ + ofork->of_vol->v_appended += (newsize > oldsize) ? (newsize - oldsize) : 0; + *rbuflen = set_off_t (offset, rbuf, is64); return( AFP_OK ); afp_write_err: - if (obj->proto == AFPPROTO_DSI) { - dsi_writeinit(obj->handle, rbuf, *rbuflen); - dsi_writeflush(obj->handle); - } + dsi_writeinit(obj->dsi, rbuf, *rbuflen); + dsi_writeflush(obj->dsi); + if (err != AFP_OK) { *rbuflen = 0; } @@ -1395,7 +1285,7 @@ int afp_getforkparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbu { struct ofork *ofork; int ret; - u_int16_t ofrefnum, bitmap; + uint16_t ofrefnum, bitmap; size_t buflen; ibuf += 2; memcpy(&ofrefnum, ibuf, sizeof( ofrefnum )); @@ -1410,15 +1300,14 @@ int afp_getforkparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbu return( AFPERR_PARAM ); } - if ( ad_meta_fileno( ofork->of_ad ) != -1 ) { /* META */ - if ( ad_refresh( ofork->of_ad ) < 0 ) { + if (AD_META_OPEN(ofork->of_ad)) { + if ( ad_refresh(NULL, ofork->of_ad ) < 0 ) { 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 ))) { + if (AFP_OK != (ret = getforkparams(ofork, bitmap, rbuf + sizeof( u_short ), &buflen ))) { return( ret ); }