summaryrefslogtreecommitdiffstats
path: root/qacp.c
diff options
context:
space:
mode:
Diffstat (limited to 'qacp.c')
-rw-r--r--qacp.c88
1 files changed, 41 insertions, 47 deletions
diff --git a/qacp.c b/qacp.c
index 734f42b..63cedf9 100644
--- a/qacp.c
+++ b/qacp.c
@@ -123,17 +123,13 @@ void
qacp_sendonefile(const char *host, const char *srcfile, const char *destfile)
{
struct qa_packet *qp;
- struct sockaddr_in daddr;
- socklen_t dlen;
int fd;
- int sd;
- int outsd;
- int port;
+ int remfd;
ssize_t nbytes;
- off_t offset = 0;
+ off_t offset;
struct stat sb;
- char *fallbackbuf;
- int bufsize;
+ const int bufsize = 16384;
+ char buf[bufsize];
if ((fd = open(srcfile, O_RDONLY)) <0) {
@@ -148,56 +144,51 @@ qacp_sendonefile(const char *host, const char *srcfile, const char *destfile)
exit(errno);
}
- sd = bind_any(QARSH_MINPORT, qarsh_ss_family);
- port = getsockport(sd);
+ if (S_ISDIR(sb.st_mode)) {
+ fprintf(stderr, "Skipping directory %s, recursive not supported, use rsync.\n", srcfile);
+ return;
+ }
- /* Recall that the packet types are qarshd-centric, so if we want
- * to send a file to the host running qarshd we have to tell
- * qarshd to recv a file. */
+ /* Packet types are qarshd-centric, so if we want to send a file to the
+ * host running qarshd we have to tell qarshd to recv a file. */
- qp = make_qp_recvfile(destfile, port, sb.st_size, sb.st_mode);
- qp->qp_seq = packet_seq++;
+ qp = make_qp_recvfile(destfile, sb.st_size, sb.st_mode);
send_packet(qacp_fd, qp);
qpfree(qp);
- dlen = sizeof daddr;
- outsd = accept(sd, (struct sockaddr *) &daddr, &dlen);
+ /* Await our return code from qarshd */
+ qp = recv_packet(qacp_fd);
+ if (qp && qp->qp_type == QP_RETURNCODE) {
+ if (qp->qp_returncode.qp_rc == 0) {
+ remfd = qp->qp_returncode.qp_errno;
+ } else if (qp->qp_returncode.qp_rc == -1) {
+ fprintf(stderr, "Remote side failed: %s\n",
+ qp->qp_returncode.qp_strerror);
+ goto sendone_error;
+ } else {
+ fprintf(stderr, "Unexpected return code %d\n",
+ qp->qp_returncode.qp_rc);
+ goto sendone_error;
+ }
+ } else {
+ fprintf(stderr, "Did not receive response to recvfile\n");
+ goto sendone_failure;
+ }
+ offset = 0;
do {
- nbytes = sendfile(outsd, fd, &offset, sb.st_size);
- } while (nbytes >= 0 && offset < sb.st_size);
-
- if (nbytes == -1 && errno == EINVAL) {
- fprintf(stderr, "Falling back to reads\n");
-
- if (sb.st_size < 1024000) {
- bufsize = 8192;
+ nbytes = read(fd, buf, bufsize);
+ if (nbytes < 0) {
+ fprintf(stderr, "read() error: %s\n", strerror(errno));
+ qp = make_qp_returncode(-1, errno, strerror(errno));
} else {
- bufsize = 1024000;
- }
- fallbackbuf = malloc(bufsize);
- if (fallbackbuf == NULL) {
- fprintf(stderr, "Could not allocate transfer buffer\n");
- goto sendone_failure;
+ qp = make_qp_data(remfd, offset, nbytes, buf);
}
-
- do {
- nbytes = read(fd, fallbackbuf, bufsize);
- if (nbytes < 0) {
- fprintf(stderr, "read() error: %s\n", strerror(errno));
- goto sendone_failure;
- } else if (nbytes == 0) { /* EOF */
- break;
- }
- write(outsd, fallbackbuf, nbytes);
- } while (nbytes > 0);
- } else if (nbytes == -1) {
- fprintf(stderr, "error: %s\n", strerror(errno));
- }
+ send_packet(qacp_fd, qp);
+ offset += nbytes;
+ } while (nbytes > 0);
sendone_failure:
- close(sd);
- close(outsd);
close(fd);
/* Await our return code from qarshd */
@@ -218,6 +209,9 @@ sendone_failure:
}
return;
+sendone_error:
+ close(qacp_fd);
+ exit(125);
}