diff options
Diffstat (limited to 'qacp.c')
-rw-r--r-- | qacp.c | 88 |
1 files changed, 41 insertions, 47 deletions
@@ -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); } |