summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Straz <nstraz@redhat.com>2013-08-29 16:47:14 -0400
committerNathan Straz <nstraz@redhat.com>2013-09-11 17:49:40 -0400
commit5a8fc22727bc20624dd915f1e6fd805ba5e0f85f (patch)
treef514e667e0c114b89988a57d41daf5d408abd181
parentceaf5360d969f2507018f51876f64aaae767e367 (diff)
downloadqarsh-5a8fc22727bc20624dd915f1e6fd805ba5e0f85f.tar.gz
qarsh-5a8fc22727bc20624dd915f1e6fd805ba5e0f85f.tar.xz
qarsh-5a8fc22727bc20624dd915f1e6fd805ba5e0f85f.zip
Remove complicated remote file descriptor code
Only handle one file transfer at a time so we don't need an array to track multiple transfers or know the remote's fd number. Loop in recv_packet until we read a whole packet.
-rw-r--r--qacp.c4
-rw-r--r--qarsh_packet.c9
-rw-r--r--qarsh_packet.h3
-rw-r--r--qarshd.c46
-rw-r--r--sockutil.c22
5 files changed, 37 insertions, 47 deletions
diff --git a/qacp.c b/qacp.c
index db6fb90..54474cf 100644
--- a/qacp.c
+++ b/qacp.c
@@ -245,7 +245,7 @@ qacp_recvonefile(const char *host, const char *srcfile, const char *destfile)
* to recv a file from the host running qarshd we have to tell
* qarshd to send a file. */
- qp = make_qp_sendfile(srcfile, outfd);
+ qp = make_qp_sendfile(srcfile);
send_packet(qacp_fd, qp);
qpfree(qp);
@@ -255,7 +255,7 @@ qacp_recvonefile(const char *host, const char *srcfile, const char *destfile)
qp = recv_packet(qacp_fd);
if (qp) {
assert(qp->qp_type == QP_DATA);
- assert(qp->qp_data.qp_remfd == outfd);
+ 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) {
diff --git a/qarsh_packet.c b/qarsh_packet.c
index 945db6b..d6a45a1 100644
--- a/qarsh_packet.c
+++ b/qarsh_packet.c
@@ -319,7 +319,6 @@ void
parse_qp_sendfile(char *buf, int *buflen, struct qa_packet *qp)
{
buf = fetch_string(buf, buflen, &(qp->qp_sendfile.qp_path));
- buf = fetch_int(buf, buflen, &(qp->qp_sendfile.qp_remfd));
}
void
@@ -485,7 +484,6 @@ char *
store_qp_sendfile(char *buf, struct qa_packet *qp)
{
buf = store_string(buf, qp->qp_sendfile.qp_path);
- buf = store_int(buf, qp->qp_sendfile.qp_remfd);
return buf;
}
@@ -660,7 +658,7 @@ make_qp_recvfile(const char *path, off_t count, mode_t mode)
}
struct qa_packet *
-make_qp_sendfile(const char *path, int remfd)
+make_qp_sendfile(const char *path)
{
struct qa_packet *qp;
qp = malloc(sizeof *qp);
@@ -669,7 +667,6 @@ make_qp_sendfile(const char *path, int remfd)
qp->qp_type = QP_SENDFILE;
qp->qp_sendfile.qp_path = strdup(path);
- qp->qp_sendfile.qp_remfd = remfd;
return qp;
}
@@ -852,8 +849,8 @@ dump_qp_recvfile(struct qa_packet *qp)
void
dump_qp_sendfile(struct qa_packet *qp)
{
- fprintf(stderr, "path: %s remfd: %d",
- qp->qp_sendfile.qp_path, qp->qp_sendfile.qp_remfd);
+ fprintf(stderr, "path: %s",
+ qp->qp_sendfile.qp_path);
}
void
diff --git a/qarsh_packet.h b/qarsh_packet.h
index 8a74791..578fccb 100644
--- a/qarsh_packet.h
+++ b/qarsh_packet.h
@@ -83,7 +83,6 @@ struct qp_recvfile_pkt {
struct qp_sendfile_pkt {
char *qp_path;
- int qp_remfd; /* file descriptor on client side */
};
struct qp_rstat_pkt {
@@ -150,7 +149,7 @@ struct qa_packet *make_qp_cmdexit(pid_t pid, int status);
struct qa_packet *make_qp_setuser(char *user, char *group);
struct qa_packet *make_qp_kill(int sig);
struct qa_packet *make_qp_recvfile(const char *path, off_t count, mode_t mode);
-struct qa_packet *make_qp_sendfile(const char *path, int remfd);
+struct qa_packet *make_qp_sendfile(const char *path);
struct qa_packet *make_qp_rstat(const char *path, const struct stat *sb);
struct qa_packet *make_qp_data(const int remfd, const off_t offset, const int count, void *blob);
struct qa_packet *make_qp_data_allow(const int remfd, const int count);
diff --git a/qarshd.c b/qarshd.c
index 6cb52e0..15cf1d6 100644
--- a/qarshd.c
+++ b/qarshd.c
@@ -56,18 +56,14 @@ int child_exitted = 0;
pid_t child_pid;
sigset_t orig_sigmask;
int childfds[3] = { -1, -1, -1 }; /* pipes to child for stdin/stdout/stderr */
+int receivefd = -1;
+off_t recvsize = 0;
+off_t received = 0;
/* A mini cache for rstat so we can check it in pushfile */
char *saved_path = NULL;
struct stat saved_stat;
-struct remotefd {
- int fd;
- int direction; /* 0 incoming, 1 outgoing */
- off_t expectedsize;
- off_t received;
-} remotefds[8];
-
int
setup_user(char *user, char *group)
{
@@ -166,36 +162,36 @@ prepare_recvfile(struct qa_packet *qp)
fchmod(fd, qp->qp_recvfile.qp_mode);
/* Store fd to check data packets against */
- remotefds[0].fd = fd;
- remotefds[0].direction = 0;
- remotefds[0].expectedsize = qp->qp_recvfile.qp_count;
- remotefds[0].received = 0;
+ receivefd = fd;
+ recvsize = qp->qp_recvfile.qp_count;
+ received = 0;
- return make_qp_returncode(0, fd, "Ready to receive");
+ return make_qp_returncode(0, 0, "Ready to receive");
}
struct qa_packet *
-receive_data(struct remotefd *rfd, struct qa_packet *qp)
+receive_data(struct qa_packet *qp)
{
ssize_t nwrote;
if (qp->qp_data.qp_count == 0) { /* EOF */
- close(rfd->fd);
+ close(receivefd);
syslog(LOG_DEBUG, "Transfer complete\n");
return make_qp_returncode(0, 0, "Transfer complete");
}
- /* syslog(LOG_DEBUG, "Data for %d, %d@%ld\n", rfd->fd, qp->qp_data.qp_count, qp->qp_data.qp_offset); */
- nwrote = write(rfd->fd, qp->qp_data.qp_blob, qp->qp_data.qp_count);
+ if (debug) syslog(LOG_DEBUG, "Data for %d, %d@%ld\n",
+ receivefd, qp->qp_data.qp_count, qp->qp_data.qp_offset);
+ nwrote = write(receivefd, qp->qp_data.qp_blob, qp->qp_data.qp_count);
if (nwrote < 0) {
return make_qp_returncode(-1, errno, strerror(errno));
}
- rfd->received += nwrote;
+ received += nwrote;
return NULL;
}
ssize_t
-pushfile(const char *path, int remfd)
+pushfile(const char *path)
{
int infd;
off_t offset;
@@ -236,7 +232,7 @@ pushfile(const char *path, int remfd)
fprintf(stderr, "read() error: %s\n", strerror(errno));
qp = make_qp_returncode(-1, errno, strerror(errno));
} else {
- qp = make_qp_data(remfd, offset, nbytes, buf);
+ qp = make_qp_data(0, offset, nbytes, buf);
}
send_packet(qoutfd, qp);
offset += nbytes;
@@ -498,19 +494,16 @@ handle_packets()
qpfree(rp);
break;
case QP_DATA:
- assert(qp->qp_data.qp_remfd == remotefds[0].fd);
- rp = receive_data(&remotefds[0], qp);
+ rp = receive_data(qp);
if (rp) {
send_packet(qoutfd, rp);
qpfree(rp);
}
break;
case QP_SENDFILE:
- syslog(LOG_INFO, "Sending file %s, remfd = %d\n",
- qp->qp_sendfile.qp_path,
- qp->qp_sendfile.qp_remfd);
- nbytes = pushfile(qp->qp_sendfile.qp_path,
- qp->qp_sendfile.qp_remfd);
+ 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 {
@@ -525,7 +518,6 @@ handle_packets()
rp = rstat(qp->qp_rstat.qp_path);
send_packet(qoutfd, rp);
qpfree(rp);
- qpfree(qp);
break;
default:
syslog(LOG_WARNING,
diff --git a/sockutil.c b/sockutil.c
index 1a53e62..9ff9210 100644
--- a/sockutil.c
+++ b/sockutil.c
@@ -207,10 +207,13 @@ recv_packet(int fd)
{
char buf[QARSH_MAX_PACKET_SIZE];
uint32_t packetsize;
+ int bufused = 0;
int ret = 0;
if ((ret = read(fd, &packetsize, sizeof packetsize)) < 0) {
- fprintf(stderr, "Read error while reading packet size: %s\n", strerror(errno));
+ if (errno != ECONNRESET) {
+ fprintf(stderr, "Read error while reading packet size: %s\n", strerror(errno));
+ }
return NULL;
} else if (ret == 0) {
return NULL;
@@ -223,15 +226,14 @@ recv_packet(int fd)
fprintf(stderr, "Packet size too large, %d > %d\n", packetsize, QARSH_MAX_PACKET_SIZE);
return NULL;
}
- if ((ret = read(fd, buf, packetsize)) < 0) {
- fprintf(stderr, "Read error while reading packet data: %s\n", strerror(errno));
- return NULL;
- }
- if (ret != packetsize) {
- fprintf(stderr, "Read something other than packetsize bytes, %d != %d\n",
- ret, packetsize);
- return NULL;
- }
+ /* Keep reading until we get the whole packet and nothing but the packet, so help me socket */
+ do {
+ if ((ret = read(fd, buf+bufused, packetsize-bufused)) < 0) {
+ fprintf(stderr, "Read error while reading packet data: %s\n", strerror(errno));
+ return NULL;
+ }
+ bufused += ret;
+ } while (bufused < packetsize);
return parse_packet(buf, packetsize);
}