summaryrefslogtreecommitdiffstats
path: root/qarsh/qarshd.c
diff options
context:
space:
mode:
Diffstat (limited to 'qarsh/qarshd.c')
-rw-r--r--qarsh/qarshd.c90
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",