summaryrefslogtreecommitdiffstats
path: root/qarshd.c
diff options
context:
space:
mode:
authorNathan Straz <nstraz@redhat.com>2013-09-27 11:32:53 -0400
committerNathan Straz <nstraz@redhat.com>2013-10-02 14:11:33 -0400
commitdb70c6e59af1634d3734019e6e2e17c95f6c6d97 (patch)
tree70e419c16889221d58e2c3949ac0e54c5787bc16 /qarshd.c
parent1aa4bac6bceb8bd1ce0914134d91f59ed46d4a90 (diff)
downloadqarsh-db70c6e59af1634d3734019e6e2e17c95f6c6d97.tar.gz
qarsh-db70c6e59af1634d3734019e6e2e17c95f6c6d97.tar.xz
qarsh-db70c6e59af1634d3734019e6e2e17c95f6c6d97.zip
Rewrite qacp receive file to handle all packets
Diffstat (limited to 'qarshd.c')
-rw-r--r--qarshd.c55
1 files changed, 44 insertions, 11 deletions
diff --git a/qarshd.c b/qarshd.c
index 78b9dda..e8a5ec7 100644
--- a/qarshd.c
+++ b/qarshd.c
@@ -58,6 +58,7 @@ pid_t child_pid;
sigset_t orig_sigmask;
int childfds[3] = { -1, -1, -1 }; /* pipes to child for stdin/stdout/stderr */
int receivefd = -1;
+int sendfd = -1;
off_t recvsize = 0;
off_t received = 0;
@@ -193,6 +194,7 @@ receive_data(struct qa_packet *qp)
if (qp->qp_data.qp_count == 0) { /* EOF */
close(receivefd);
+ receivefd = -1;
if (debug) syslog(LOG_DEBUG, "Transfer complete\n");
return make_qp_returncode(0, 0, "Transfer complete");
}
@@ -210,6 +212,23 @@ receive_data(struct qa_packet *qp)
return make_qp_data_allow(0, nwrote);
}
+struct qa_packet *
+prepare_sendfile(struct qa_packet *qp)
+{
+ int fd;
+
+ syslog(LOG_INFO, "Sending file %s\n", qp->qp_sendfile.qp_path);
+
+ if ((fd = open(qp->qp_sendfile.qp_path, O_RDONLY)) == -1) {
+ syslog(LOG_WARNING, "Could not open %s to send file: %s\n",
+ qp->qp_sendfile.qp_path, strerror(errno));
+ return make_qp_returncode(-1, errno, strerror(errno));
+ }
+
+ sendfd = fd;
+ return NULL;
+}
+
ssize_t
pushfile(const char *path)
{
@@ -485,7 +504,8 @@ handle_packets()
int nfd;
struct timeval timeout;
struct qa_packet *qp = NULL, *rp = NULL;
-
+ const int bufsize = QARSH_MAX_PACKET_SIZE/2;
+ char buf[bufsize];
off_t nbytes;
if (dopause) {
@@ -537,7 +557,7 @@ handle_packets()
send_packet(qoutfd, rp);
qpfree(rp);
break;
- case QP_DATA:
+ case QP_DATA: /* qacp sent some data */
rp = receive_data(qp);
if (rp) {
send_packet(qoutfd, rp);
@@ -545,16 +565,29 @@ handle_packets()
}
break;
case QP_SENDFILE:
- syslog(LOG_INFO, "Sending file %s\n",
- qp->qp_sendfile.qp_path);
- nbytes = pushfile(qp->qp_sendfile.qp_path);
- if (nbytes < 0) {
- rp = make_qp_returncode(-1, errno, strerror(errno));
- } else {
- rp = make_qp_returncode(0, 0, "Transfer Complete");
+ rp = prepare_sendfile(qp);
+ if (rp) {
+ send_packet(qoutfd, rp);
+ qpfree(rp);
}
- send_packet(qoutfd, rp);
- qpfree(rp);
+ break;
+ case QP_DALLOW: /* qacp is ready to receive some data */
+ if (sendfd != -1) {
+ nbytes = read(sendfd, buf, bufsize < qp->qp_dallow.qp_count ? bufsize : qp->qp_dallow.qp_count);
+ if (nbytes == -1) {
+ qp = make_qp_returncode(-1, errno, strerror(errno));
+ } else {
+ rp = make_qp_data(0, 0, nbytes, buf);
+ if (nbytes == 0) {
+ close(sendfd);
+ sendfd = -1;
+ }
+ }
+ send_packet(qoutfd, rp);
+ qpfree(rp);
+ }
+ break;
+ case QP_RETURNCODE: /* qacp either completed or hit an error */
break;
case QP_RSTAT:
if (debug) syslog(LOG_DEBUG, "Got a QP_RSTAT with path = %s\n",