X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=blobdiff_plain;f=etc%2Fafpd%2Ffork.c;h=73abb1e9a102e5a5143303a08011b976cdc982f8;hp=0c988828d609660bc096c8cf01c944f6f8e633dc;hb=42a0a094b72577aee3fee7f186da52dc83db001d;hpb=1e787cd52b5d7327d180af76ca7e4ab071683313 diff --git a/etc/afpd/fork.c b/etc/afpd/fork.c index 0c988828..73abb1e9 100644 --- a/etc/afpd/fork.c +++ b/etc/afpd/fork.c @@ -66,10 +66,10 @@ static int getforkparams(const AFPObj *obj, struct ofork *ofork, uint16_t bitmap vol = ofork->of_vol; dir = dirlookup(vol, ofork->of_did); - if (NULL == (path.m_name = utompath(vol, of_name(ofork), dir->d_did, utf8_encoding(obj)))) { + if (NULL == (path.u_name = mtoupath(vol, of_name(ofork), dir->d_did, utf8_encoding(obj)))) { return( AFPERR_MISC ); } - path.u_name = of_name(ofork); + path.m_name = of_name(ofork); path.id = 0; st = &path.st; if ( bitmap & ( (1<options.flags & OPTION_AFP_READ_LOCK) - ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount, ofork->of_refnum); - return cc; + if ((cc = dsi_writeinit(dsi, rcvbuf, rcvbuflen)) > 0) { + ssize_t written; + if ((written = write_file(ofork, eid, offset, rcvbuf, cc)) != cc) { + dsi_writeflush(dsi); + *rbuflen = 0; + if (obj->options.flags & OPTION_AFP_READ_LOCK) + ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount, ofork->of_refnum); + if (written > 0) + /* It's used for the read size and as error code in write_file(), ugh */ + written = AFPERR_MISC; + return written; + } } offset += cc; -#if 0 /*def HAVE_SENDFILE_WRITE*/ - 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; +#ifdef WITH_RECVFILE + if (obj->options.flags & OPTION_RECVFILE) { + LOG(log_maxdebug, logtype_afpd, "afp_write(fork: %" PRIu16 " [%s], off: %" PRIu64 ", size: %" PRIu32 ")", + ofork->of_refnum, (ofork->of_flags & AFPFORK_DATA) ? "data" : "reso", offset, dsi->datasize); + + if ((cc = ad_recvfile(ofork->of_ad, eid, dsi->socket, offset, dsi->datasize, obj->options.splice_size)) < dsi->datasize) { + switch (errno) { + case EDQUOT: + case EFBIG: + case ENOSPC: + cc = AFPERR_DFULL; + dsi_writeflush(dsi); + break; + case ENOSYS: + goto afp_write_loop; + default: + /* Low level error, can't do much to back up */ + cc = AFPERR_MISC; + LOG(log_error, logtype_afpd, "afp_write: ad_writefile: %s", strerror(errno)); + } + *rbuflen = 0; + if (obj->options.flags & OPTION_AFP_READ_LOCK) + ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount, ofork->of_refnum); + return cc; } - dsi_writeflush(dsi); - *rbuflen = 0; - if (obj->options.flags & OPTION_AFP_READ_LOCK) - ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount, ofork->of_refnum); - return cc; - } - offset += cc; - goto afp_write_done; -#endif /* 0, was HAVE_SENDFILE_WRITE */ + offset += cc; + goto afp_write_done; + } +#endif +afp_write_loop: /* loop until everything gets written. currently * dsi_write handles the end case by itself. */ while ((cc = dsi_write(dsi, rcvbuf, rcvbuflen))) { @@ -1235,6 +1248,7 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s offset += cc; } +afp_write_done: if (obj->options.flags & OPTION_AFP_READ_LOCK) ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount, ofork->of_refnum); if ( ad_meta_fileno( ofork->of_ad ) != -1 ) /* META */