summaryrefslogtreecommitdiffstats
path: root/qacp.c
diff options
context:
space:
mode:
Diffstat (limited to 'qacp.c')
-rw-r--r--qacp.c114
1 files changed, 70 insertions, 44 deletions
diff --git a/qacp.c b/qacp.c
index 3afc35e..295c2d9 100644
--- a/qacp.c
+++ b/qacp.c
@@ -148,6 +148,11 @@ qacp_sendonefile(const char *host, const char *srcfile, const char *destfile)
struct stat sb;
const int bufsize = QARSH_MAX_PACKET_SIZE/2;
char buf[bufsize];
+ fd_set rfds, wfds;
+ int nfd;
+ struct timeval timeout;
+ int dallow;
+ int complete;
if ((fd = open(srcfile, O_RDONLY)) <0) {
@@ -174,59 +179,80 @@ qacp_sendonefile(const char *host, const char *srcfile, const char *destfile)
send_packet(qacp_fd, qp);
qpfree(qp);
- /* 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) {
- fprintf(stderr, "Remote side failed: %s\n",
- qp->qp_returncode.qp_strerror);
- qpfree(qp);
- goto sendone_error;
- }
- qpfree(qp);
- } else {
- fprintf(stderr, "Did not receive response to recvfile\n");
- goto sendone_failure;
- }
-
offset = 0;
- do {
- 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 {
- qp = make_qp_data(0, offset, nbytes, buf);
+ dallow = 0;
+ complete = 0;
+ for (;;) {
+ FD_ZERO(&rfds);
+ FD_SET(qacp_fd, &rfds);
+ FD_ZERO(&wfds);
+ if (!complete && dallow > 0) FD_SET(qacp_fd, &wfds);
+ timeout.tv_sec = 10;
+ timeout.tv_usec = 0;
+
+ nfd = select(qacp_fd+1, &rfds, &wfds, NULL, &timeout);
+ if (nfd < 0) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ fprintf(stderr, "select errno %d, %s\n", errno, strerror(errno));
+ }
+ } else if (nfd > 0) {
+ if (nfd && FD_ISSET(qacp_fd, &rfds)) {
+ qp = recv_packet(qacp_fd);
+ if (qp == NULL) {
+ fprintf(stderr, "No packet\n");
+ break;
+ }
+ if (qp->qp_type == QP_DALLOW) {
+ if (qp->qp_dallow.qp_count > 0) {
+ dallow += qp->qp_dallow.qp_count;
+ } else {
+ dallow = 0;
+ }
+ } else if (qp->qp_type == QP_RETURNCODE) {
+ if (qp->qp_returncode.qp_rc == 0) { /* success */
+ break;
+ } else if (qp->qp_returncode.qp_rc == -1) {
+ fprintf(stderr, "Transfer failed: %s\n",
+ qp->qp_returncode.qp_strerror);
+ exit(125);
+ }
+ } else {
+ fprintf(stderr, "Received unexpected packet\n");
+ dump_qp(qp);
+ break;
+ }
+ qpfree(qp);
+ }
+ if (nfd && FD_ISSET(qacp_fd, &wfds)) {
+ /* Create a data packet to send */
+ nbytes = read(fd, buf, dallow);
+ if (nbytes < 0) {
+ fprintf(stderr, "read() error: %s\n",
+ strerror(errno));
+ qp = make_qp_returncode(-1, errno, strerror(errno));
+ } else {
+ qp = make_qp_data(0, offset, nbytes, buf);
+ if (nbytes == 0) { /* Transfer is complete */
+ complete = 1;
+ } else {
+ offset += nbytes;
+ dallow -= nbytes;
+ }
+ }
+ send_packet(qacp_fd, qp);
+ qpfree(qp);
+ }
}
- send_packet(qacp_fd, qp);
- offset += nbytes;
- qpfree(qp);
- } while (nbytes > 0);
-sendone_failure:
-
- close(fd);
-
- /* Await our return code from qarshd */
- qp = recv_packet(qacp_fd);
- if (qp && qp->qp_type == QP_RETURNCODE
- && qp->qp_returncode.qp_rc == -1) {
- fprintf(stderr, "Remote side failed, %s\n",
- qp->qp_returncode.qp_strerror);
- close(qacp_fd);
- qpfree(qp);
- exit(125);
}
-
- qpfree(qp);
+ close(fd);
if (!quiet) {
printf("%-30.30s -> %s:%s\n", srcfile, host, destfile);
}
return;
-sendone_error:
- close(qacp_fd);
- exit(125);
}