diff options
Diffstat (limited to 'qarsh/qarshd.c')
-rw-r--r-- | qarsh/qarshd.c | 90 |
1 files changed, 89 insertions, 1 deletions
diff --git a/qarsh/qarshd.c b/qarsh/qarshd.c index 3eb9182..70ed09d 100644 --- a/qarsh/qarshd.c +++ b/qarsh/qarshd.c @@ -8,7 +8,9 @@ #include <sys/time.h> #include <assert.h> #include <syslog.h> +#include <fcntl.h> #include <sys/types.h> +#include <sys/stat.h> #include <sys/wait.h> #include <sys/socket.h> #include <arpa/inet.h> @@ -91,6 +93,59 @@ run_cmd(const char *cmd, int p_in, int p_out, int p_err) return pid; } +ssize_t +recvfile(const char *path, int if_port, size_t count, mode_t mode) +{ + int sd; + int ofd; + char buf[BUFSIZ]; + ssize_t nread; + ssize_t nwrote; + ssize_t nleft; + + /* Read count bytes from ifd (sd after we connect), + * write into file @ path + */ + + sd = connect_to_peer(&peername, if_port); + if (sd == -1) { + syslog(LOG_WARNING, "connect to if_port failed\n"); + return -1; + } + + if ((ofd = open(path, O_TRUNC|O_CREAT|O_WRONLY, mode)) < 0) { + syslog(LOG_WARNING, "Could not open %s to recv file: %s\n", + path, strerror(errno)); + return -1; + } + + fchmod(ofd, mode); + + nleft = count; + while (nleft > 0) { + nread = read(sd, buf, BUFSIZ); + if (nread < 0) { + return nread; + } else if (nread == 0) { /* EOF */ + break; + } + + nwrote = write(ofd, buf, nread); + nleft -= nread; + } + + if (nleft != 0) { + unlink(path); + syslog(LOG_WARNING, "Short file transfer in recvfile(), " + "%d bytes lost, wanted %d\n", nleft, count); + } + + close(sd); + close(ofd); + + return count - nleft; +} + void handle_packets(int infd) { @@ -98,11 +153,13 @@ handle_packets(int infd) int nfd; struct timespec timeout; struct qa_packet *qp = NULL, *rp = NULL; - sigset_t sigmask, orig_sigmask; + sigset_t sigmask, orig_sigmask; struct sigaction sa; pid_t child_pid = 0; int child_status; + ssize_t nbytes; + int i=0; sigemptyset(&sigmask); sigaddset(&sigmask, SIGCHLD); @@ -116,6 +173,7 @@ handle_packets(int infd) FD_SET(infd, &rfds); timeout.tv_sec = 3; + syslog(LOG_INFO, "Iteration: %d\n", i++); nfd = pselect(infd+1, &rfds, NULL, NULL, &timeout, &orig_sigmask); if (child_exitted) { @@ -165,6 +223,36 @@ handle_packets(int infd) qp->qp_runcmd.qp_stdout_port, qp->qp_runcmd.qp_stderr_port); break; + case QP_RECVFILE: + syslog(LOG_INFO, "Got a QP_GETFILE with path = %s, " + "ifd = %d, count = %d, mode = %o\n", + qp->qp_recvfile.qp_path, + qp->qp_recvfile.qp_if_port, + qp->qp_recvfile.qp_count, + qp->qp_recvfile.qp_mode); + nbytes = recvfile(qp->qp_recvfile.qp_path, + qp->qp_recvfile.qp_if_port, + qp->qp_recvfile.qp_count, + qp->qp_recvfile.qp_mode); + if (nbytes < 0) { + rp = make_qp_returncode(-1, errno, strerror(errno)); + } else if (nbytes < qp->qp_recvfile.qp_count) { + char tmpstr[512]; + sprintf(tmpstr, "Excpected %d, wrote %d\n", + qp->qp_recvfile.qp_count, nbytes); + rp = make_qp_returncode(-1, 0, tmpstr); + } else { + rp = make_qp_returncode(0, 0, "Tranfer Complete"); + } + send_packet(fileno(stdout), rp); + break; + case QP_SENDFILE: + syslog(LOG_INFO, "Got a QP_SENDFILE with path = %s, " + "ofd = %d, count = %d\n", + qp->qp_sendfile.qp_path, + qp->qp_sendfile.qp_of_port, + qp->qp_sendfile.qp_count); + break; default: syslog(LOG_WARNING, "Packet type %s unimplemented", |