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<<FILPBIT_DFLEN) | (1<<FILPBIT_EXTDFLEN) |
int afp_setforkparams(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf _U_, size_t *rbuflen)
{
struct ofork *ofork;
+ struct vol *vol;
+ struct dir *dir;
off_t size;
uint16_t ofrefnum, bitmap;
int err;
return( AFPERR_PARAM );
}
+ vol = ofork->of_vol;
+ if ((dir = dirlookup(vol, ofork->of_did)) == NULL) {
+ LOG(log_error, logtype_afpd, "%s: bad fork did", of_name(ofork));
+ return AFPERR_MISC;
+ }
+ if (movecwd(vol, dir) != 0) {
+ LOG(log_error, logtype_afpd, "%s: bad fork directory", dir->d_fullpath);
+ return AFPERR_MISC;
+ }
+
if (ofork->of_vol->v_flags & AFPVOL_RO)
return AFPERR_VLOCK;
}
/* find out what we have already */
- cc = dsi_writeinit(dsi, rcvbuf, rcvbuflen);
-
- if (!cc || (cc = write_file(ofork, eid, offset, rcvbuf, cc)) < 0) {
- 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;
+ 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))) {
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 */