AC_SEARCH_LIBS(sendfile, sendfile)
AC_CHECK_FUNC([sendfile], [netatalk_cv_HAVE_SENDFILE=yes])
dnl -- there's a bug somewhere, disable for now
- netatalk_cv_HAVE_SENDFILE=no
+# netatalk_cv_HAVE_SENDFILE=no
;;
*freebsd*)
continue;
/* Blocking read on the network socket */
- cmd = dsi_receive(dsi);
+ cmd = dsi_stream_receive(dsi);
if (cmd == 0) {
/* cmd == 0 is the error condition */
/* AFP replay cache */
rc_idx = dsi->clientID % REPLAYCACHE_SIZE;
- LOG(log_debug, logtype_afpd, "DSI request ID: %u", dsi->clientID);
+ LOG(log_debug, logtype_dsi, "DSI request ID: %u", dsi->clientID);
if (replaycache[rc_idx].DSIreqID == dsi->clientID
&& replaycache[rc_idx].AFPcommand == function) {
if (dsi->flags & DSI_NOREPLY) {
dsi->flags &= ~DSI_NOREPLY;
break;
- }
-
- if (!dsi_cmdreply(dsi, err)) {
+ } else if (!dsi_cmdreply(dsi, err)) {
LOG(log_error, logtype_afpd, "dsi_cmdreply(%d): %s", dsi->socket, strerror(errno) );
if (dsi_disconnect(dsi) != 0)
afp_dsi_die(EXITERR_CLNT);
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) {
}
*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, xlate);
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. */
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;
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)
extern ssize_t dsi_stream_write (DSI *, void *, const size_t, const int mode);
extern size_t dsi_stream_read (DSI *, void *, const size_t);
extern int dsi_stream_send (DSI *, void *, size_t);
-extern int dsi_stream_receive (DSI *, void *, const size_t, size_t *);
+extern int dsi_stream_receive (DSI *);
extern int dsi_disconnect(DSI *dsi);
#ifdef WITH_SENDFILE
(x)->header.dsi_len = htonl((x)->cmdlen); \
dsi_stream_send((x), (x)->commands, (x)->cmdlen); \
} while (0)
-#define dsi_receive(x) (dsi_stream_receive((x), (x)->commands, \
- DSI_CMDSIZ, &(x)->cmdlen))
+
#endif /* atalk/dsi.h */
/*
- * $Id: dsi_cmdreply.c,v 1.5 2009-10-25 06:13:11 didg Exp $
- *
* Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
* All rights reserved. See COPYRIGHT.
*/
#include <stdio.h>
#include <atalk/dsi.h>
+#include <atalk/logger.h>
#include <netatalk/endian.h>
/* this assumes that the reply follows right after the command, saving
* reserved field are assumed to already be set. */
int dsi_cmdreply(DSI *dsi, const int err)
{
-int ret;
- dsi->header.dsi_flags = DSIFL_REPLY;
- /*dsi->header.dsi_command = DSIFUNC_CMD;*/
- dsi->header.dsi_len = htonl(dsi->datalen);
- dsi->header.dsi_code = htonl(err);
-
- ret = dsi_stream_send(dsi, dsi->data, dsi->datalen);
- return ret;
+ int ret;
+
+ LOG(log_debug, logtype_dsi, "dsi_cmdreply(DSI ID: %u, len: %jd): START",
+ dsi->clientID, (intmax_t)dsi->datalen);
+
+ dsi->header.dsi_flags = DSIFL_REPLY;
+ dsi->header.dsi_len = htonl(dsi->datalen);
+ dsi->header.dsi_code = htonl(err);
+
+ ret = dsi_stream_send(dsi, dsi->data, dsi->datalen);
+
+ LOG(log_debug, logtype_dsi, "dsi_cmdreply(DSI ID: %u, len: %jd): END",
+ dsi->clientID, (intmax_t)dsi->datalen);
+
+ return ret;
}
#include <atalk/dsi.h>
#include <atalk/util.h>
+#include <atalk/logger.h>
/* streaming i/o for afp_read. this is all from the perspective of the
* client. it basically does the reverse of dsi_write. on first entry,
* buffer. it returns the amount of stuff still to be read
* (constrained by the buffer size). */
ssize_t dsi_readinit(DSI *dsi, void *buf, const size_t buflen,
- const size_t size, const int err)
+ const size_t size, const int err)
{
+ LOG(log_maxdebug, logtype_dsi, "dsi_readinit: sending %zd bytes from buffer, total size: %zd",
+ buflen, size);
- dsi->flags |= DSI_NOREPLY; /* we will handle our own replies */
- dsi->header.dsi_flags = DSIFL_REPLY;
- /*dsi->header.dsi_command = DSIFUNC_CMD;*/
- dsi->header.dsi_len = htonl(size);
- dsi->header.dsi_code = htonl(err);
+ dsi->flags |= DSI_NOREPLY; /* we will handle our own replies */
+ dsi->header.dsi_flags = DSIFL_REPLY;
+ dsi->header.dsi_len = htonl(size);
+ dsi->header.dsi_code = htonl(err);
- dsi->in_write++;
- if (dsi_stream_send(dsi, buf, buflen)) {
- dsi->datasize = size - buflen;
- return MIN(dsi->datasize, buflen);
- }
+ dsi->in_write++;
+ if (dsi_stream_send(dsi, buf, buflen)) {
+ dsi->datasize = size - buflen;
+ LOG(log_maxdebug, logtype_dsi, "dsi_readinit: remaining data for sendfile: %zd", dsi->datasize);
+ return MIN(dsi->datasize, buflen);
+ }
- return -1; /* error */
+ return -1; /* error */
}
void dsi_readdone(DSI *dsi)
{
- dsi->in_write--;
+ dsi->in_write--;
}
/* send off the data */
ssize_t dsi_read(DSI *dsi, void *buf, const size_t buflen)
{
- size_t len;
-
- len = dsi_stream_write(dsi, buf, buflen, 0);
+ size_t len;
- if (len == buflen) {
- dsi->datasize -= len;
- return MIN(dsi->datasize, buflen);
- }
+ len = dsi_stream_write(dsi, buf, buflen, 0);
- return -1;
+ if (len == buflen) {
+ dsi->datasize -= len;
+ return MIN(dsi->datasize, buflen);
+ }
+
+ return -1;
}
dsi->in_write++;
written = 0;
- LOG(log_maxdebug, logtype_dsi, "dsi_stream_write: sending %u bytes", length);
+ LOG(log_maxdebug, logtype_dsi, "dsi_stream_write(send: %zd bytes): START", length);
if (dsi->flags & DSI_DISCONNECTED)
return -1;
}
dsi->write_count += written;
+ LOG(log_maxdebug, logtype_dsi, "dsi_stream_write(send: %zd bytes): END", length);
exit:
dsi->in_write--;
#ifdef WITH_SENDFILE
ssize_t dsi_stream_read_file(DSI *dsi, int fromfd, off_t offset, const size_t length)
{
+ int ret = 0;
size_t written;
ssize_t len;
+ off_t pos = offset;
- LOG(log_maxdebug, logtype_dsi, "dsi_stream_read_file: sending %u bytes", length);
+ LOG(log_maxdebug, logtype_dsi, "dsi_stream_read_file(send %zd bytes): START", length);
if (dsi->flags & DSI_DISCONNECTED)
return -1;
written = 0;
while (written < length) {
- len = sys_sendfile(dsi->socket, fromfd, &offset, length - written);
+ len = sys_sendfile(dsi->socket, fromfd, &pos, length - written);
if (len < 0) {
if (errno == EINTR)
continue;
- if (errno == EINVAL || errno == ENOSYS)
- return -1;
-
+ if (errno == EINVAL || errno == ENOSYS) {
+ ret = -1;
+ goto exit;
+ }
if (errno == EAGAIN || errno == EWOULDBLOCK) {
if (dsi_peek(dsi)) {
/* can't go back to blocking mode, exit, the next read
}
else if (!len) {
/* afpd is going to exit */
- errno = EIO;
- return -1; /* I think we're at EOF here... */
+ ret = -1;
+ goto exit;
}
else
written += len;
}
dsi->write_count += written;
+
+exit:
dsi->in_write--;
+ LOG(log_maxdebug, logtype_dsi, "dsi_stream_read_file: sent: %zd", written);
+ if (ret != 0)
+ return -1;
return written;
}
#endif
size_t towrite;
ssize_t len;
- LOG(log_maxdebug, logtype_dsi, "dsi_stream_send: %u bytes",
- length ? length : sizeof(block));
+ LOG(log_maxdebug, logtype_dsi, "dsi_stream_send(%u bytes): START", length);
if (dsi->flags & DSI_DISCONNECTED)
return 0;
sizeof(dsi->header.dsi_reserved));
if (!length) { /* just write the header */
+ LOG(log_maxdebug, logtype_dsi, "dsi_stream_send(%u bytes): DSI header, no data", sizeof(block));
length = (dsi_stream_write(dsi, block, sizeof(block), 0) == sizeof(block));
return length; /* really 0 on failure, 1 on success */
}
iov[1].iov_len -= len;
}
}
+
+ LOG(log_maxdebug, logtype_dsi, "dsi_stream_send(%u bytes): END", length);
unblock_sig(dsi);
return 1;
}
-/* ---------------------------------------
- * read data. function on success. 0 on failure. data length gets
- * stored in length variable. this should really use size_t's, but
- * that would require changes elsewhere. */
-int dsi_stream_receive(DSI *dsi, void *buf, const size_t ilength,
- size_t *rlength)
+/*!
+ * Read DSI command and data
+ *
+ * @param dsi (rw) DSI handle
+ *
+ * @return DSI function on success, 0 on failure
+ */
+int dsi_stream_receive(DSI *dsi)
{
char block[DSI_BLOCKSIZ];
- LOG(log_maxdebug, logtype_dsi, "dsi_stream_receive: %u bytes", ilength);
+ LOG(log_maxdebug, logtype_dsi, "dsi_stream_receive: START");
if (dsi->flags & DSI_DISCONNECTED)
return 0;
dsi->header.dsi_flags = block[0];
dsi->header.dsi_command = block[1];
- /* FIXME, not the right place,
- but we get a server disconnect without reason in the log
- */
- if (!block[1]) {
- LOG(log_error, logtype_dsi, "dsi_stream_receive: invalid packet, fatal");
+
+ if (dsi->header.dsi_command == 0)
return 0;
- }
- memcpy(&dsi->header.dsi_requestID, block + 2,
- sizeof(dsi->header.dsi_requestID));
+ memcpy(&dsi->header.dsi_requestID, block + 2, sizeof(dsi->header.dsi_requestID));
memcpy(&dsi->header.dsi_code, block + 4, sizeof(dsi->header.dsi_code));
memcpy(&dsi->header.dsi_len, block + 8, sizeof(dsi->header.dsi_len));
- memcpy(&dsi->header.dsi_reserved, block + 12,
- sizeof(dsi->header.dsi_reserved));
+ memcpy(&dsi->header.dsi_reserved, block + 12, sizeof(dsi->header.dsi_reserved));
dsi->clientID = ntohs(dsi->header.dsi_requestID);
/* make sure we don't over-write our buffers. */
- *rlength = min(ntohl(dsi->header.dsi_len), ilength);
- if (dsi_stream_read(dsi, buf, *rlength) != *rlength)
+ dsi->cmdlen = min(ntohl(dsi->header.dsi_len), DSI_CMDSIZ);
+ if (dsi_stream_read(dsi, dsi->commands, dsi->cmdlen) != dsi->cmdlen)
return 0;
+ LOG(log_debug, logtype_dsi, "dsi_stream_receive: DSI cmdlen: %zd", dsi->cmdlen);
+
return block[1];
}