diff options
author | Nathan Straz <nstraz@redhat.com> | 2013-09-27 11:32:53 -0400 |
---|---|---|
committer | Nathan Straz <nstraz@redhat.com> | 2013-10-02 14:11:33 -0400 |
commit | db70c6e59af1634d3734019e6e2e17c95f6c6d97 (patch) | |
tree | 70e419c16889221d58e2c3949ac0e54c5787bc16 /qacp.c | |
parent | 1aa4bac6bceb8bd1ce0914134d91f59ed46d4a90 (diff) | |
download | qarsh-db70c6e59af1634d3734019e6e2e17c95f6c6d97.tar.gz qarsh-db70c6e59af1634d3734019e6e2e17c95f6c6d97.tar.xz qarsh-db70c6e59af1634d3734019e6e2e17c95f6c6d97.zip |
Rewrite qacp receive file to handle all packets
Diffstat (limited to 'qacp.c')
-rw-r--r-- | qacp.c | 103 |
1 files changed, 62 insertions, 41 deletions
@@ -260,11 +260,14 @@ void qacp_recvonefile(const char *host, const char *srcfile, const char *destfile) { struct qa_packet *qp; + struct qa_packet *rp; int outfd; ssize_t nwrote; - off_t nleft; struct qp_rstat_pkt *rstatp; int rstaterrno; + fd_set rfds; + int nfd; + struct timeval timeout; rstatp = qacp_rstat(srcfile, &rstaterrno); if (!rstatp) { @@ -272,7 +275,7 @@ qacp_recvonefile(const char *host, const char *srcfile, const char *destfile) return; } - if ((outfd = open(destfile, O_TRUNC|O_CREAT|O_WRONLY)) <0) { + if ((outfd = open(destfile, O_TRUNC|O_CREAT|O_WRONLY)) < 0) { fprintf(stderr, "Could not open %s: %s\n", destfile, strerror(errno)); close(qacp_fd); exit(errno); @@ -288,49 +291,67 @@ qacp_recvonefile(const char *host, const char *srcfile, const char *destfile) send_packet(qacp_fd, qp); qpfree(qp); - /* Read/write file */ - nleft = rstatp->qp_st_size; - while (nleft > 0) { - qp = recv_packet(qacp_fd); - if (qp) { - assert(qp->qp_type == QP_DATA); - assert(qp->qp_data.qp_remfd == 0); - assert(rstatp->qp_st_size - nleft == qp->qp_data.qp_offset); - nwrote = write(outfd, qp->qp_data.qp_blob, qp->qp_data.qp_count); - if (nwrote < 0) { - fprintf(stderr, "write() error: %s\n", strerror(errno)); - break; + qp = make_qp_data_allow(0, QARSH_MAX_PACKET_SIZE/2); + send_packet(qacp_fd, qp); + qpfree(qp); + + for (;;) { + FD_ZERO(&rfds); + FD_SET(qacp_fd, &rfds); + + timeout.tv_sec = 10; + timeout.tv_usec = 0; + + nfd = select(qacp_fd+1, &rfds, NULL, 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_DATA) { + if (qp->qp_data.qp_count == 0) { + break; + } + if ((nwrote = write(outfd, qp->qp_data.qp_blob, qp->qp_data.qp_count)) == -1) { + fprintf(stderr, "write() error: %s\n", strerror(errno)); + rp = make_qp_returncode(-1, errno, strerror(errno)); + send_packet(qacp_fd, rp); + qpfree(rp); + break; + } else if (nwrote == qp->qp_data.qp_count) { + rp = make_qp_data_allow(0, nwrote); + send_packet(qacp_fd, rp); + qpfree(rp); + } else { + fprintf(stderr, "short write\n"); + break; + } + } 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); } - assert(nwrote == qp->qp_data.qp_count); - nleft -= qp->qp_data.qp_count; - qpfree(qp); - } else { - fprintf(stderr, "Did not receive a packet\n"); - break; } - - } - - if (nleft != 0) { - unlink(destfile); - fprintf(stderr, "Short file transfer of %s, " - "%lld bytes lost, wanted %lld\n", srcfile, - (long long int)nleft, - (long long int)rstatp->qp_st_size); } close(outfd); - free_rstat(rstatp); - - /* 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); - exit(125); - } - if (qp) qpfree(qp); if (!quiet) { printf("%s:%s -> %30.30s\n", host, srcfile, destfile); |