summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDean Jansa <djansa@redhat.com>2005-09-01 21:11:41 +0000
committerDean Jansa <djansa@redhat.com>2005-09-01 21:11:41 +0000
commitb3c4810fcd272e113797f6e2119b8102f53b8d58 (patch)
treeaa4061914f0fa2bf4fb6a9ebee7fe674e1deebd4
parent4ac88fc3498eca53a4c419412cf18a8d102daa41 (diff)
downloadqarsh-b3c4810fcd272e113797f6e2119b8102f53b8d58.tar.gz
qarsh-b3c4810fcd272e113797f6e2119b8102f53b8d58.tar.xz
qarsh-b3c4810fcd272e113797f6e2119b8102f53b8d58.zip
Added qacp, the scp replacement using qarshd. Currently can only
transver files *to* the remote host. No recursive copies and the srcfile can not be a dir. These features are underway. New packet types were added and handlers for those packets in qarshd.
-rw-r--r--qarsh/Makefile3
-rw-r--r--qarsh/qacp.c334
-rw-r--r--qarsh/qarsh_packet.c147
-rw-r--r--qarsh/qarsh_packet.h24
-rw-r--r--qarsh/qarshd.c90
5 files changed, 595 insertions, 3 deletions
diff --git a/qarsh/Makefile b/qarsh/Makefile
index 0402db7..a742e12 100644
--- a/qarsh/Makefile
+++ b/qarsh/Makefile
@@ -7,10 +7,11 @@ LOADLIBES := -lxml2
COMMON := qarsh_packet.c sockutil.c
-all: qarshd qarsh
+all: qarshd qarsh qacp
qarshd: qarshd.c $(COMMON)
qarsh: qarsh.c $(COMMON)
+qacp: qacp.c $(COMMON)
install: qarsh qarshd
@echo Installing qarsh daemon and client
diff --git a/qarsh/qacp.c b/qarsh/qacp.c
new file mode 100644
index 0000000..b404482
--- /dev/null
+++ b/qarsh/qacp.c
@@ -0,0 +1,334 @@
+/*
+ * QA Remote Copy - client side
+ *
+ * Copy a file to, or from, server.
+ *
+ *
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <sys/sendfile.h>
+#include <libgen.h>
+
+
+#include "sockutil.h"
+#include "qarsh_packet.h"
+
+#define QARSHD_CONTROL_PORT 5008
+#define QARSH_MINPORT 5010
+
+/* Globals */
+int qacp_fd = -1; /* The control connection to qacpd */
+
+void
+usage()
+{
+/* printf("usage: qacp: [-r] [[user@]host1:]file1 [...] " */
+ /* "[[user@]host2:]file2\n"); */
+
+ /* For now, only simple cmdlines */
+ fprintf(stderr, "usage:\n\t%s\n\t%s\n",
+ "qacp <localpath> [<loacalpath> ...] [user@]host:<rmtpath>",
+ "qacp [user@]host:<rmtpath> [[user@]host:<rmtpath> ...] <localpath> ");
+}
+
+char *
+copyargs(char **argv)
+{
+ int cc;
+ char **ap, *p;
+ char *args;
+
+ cc = 0;
+ for (ap = argv; *ap; ++ap)
+ cc += strlen(*ap) + 1;
+ if (cc == 0) return NULL;
+ args = malloc(cc);
+ if (!args) {
+ perror("qacp: malloc failed in copyargs");
+ exit(1);
+ }
+ for (p = args, ap = argv; *ap; ++ap) {
+ for (p = strcpy(p, *ap); *p; ++p);
+ if (ap[1])
+ *p++ = ' ';
+ }
+ return args;
+}
+
+void
+set_remote_user(char *user, char *group)
+{
+ struct qa_packet *qp;
+
+ qp = make_qp_setuser(user, group);
+ qp->qp_seq = 1;
+ send_packet(qacp_fd, qp);
+ qpfree(qp);
+ qp = recv_packet(qacp_fd);
+ if (qp && qp->qp_type == QP_RETURNCODE
+ && qp->qp_returncode.qp_rc == -1) {
+
+ fprintf(stderr, "Remote side failed, %s\n",
+ qp->qp_returncode.qp_strerror);
+ close(qacp_fd);
+ exit(125);
+ }
+}
+
+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;
+ ssize_t nbytes;
+ off_t offset = 0;
+ struct stat sb;
+
+ /* 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. */
+
+ if ((fd = open(srcfile, O_RDONLY)) <0) {
+ fprintf(stderr, "Could not open %s: %s\n", srcfile, strerror(errno));
+ close(qacp_fd);
+ exit(errno);
+ }
+
+ if (fstat(fd, &sb) < 0) {
+ fprintf(stderr, "Could not stat %s: %s\n", srcfile, strerror(errno));
+ close(qacp_fd);
+ exit(errno);
+ }
+
+ sd = bind_any(QARSH_MINPORT);
+ port = getsockport(sd);
+
+ qp = make_qp_recvfile(destfile, port, sb.st_size, sb.st_mode);
+ qp->qp_seq = 1;
+ send_packet(qacp_fd, qp);
+ qpfree(qp);
+
+ dlen = sizeof daddr;
+ outsd = accept(sd, (struct sockaddr *) &daddr, &dlen);
+
+ nbytes = sendfile(outsd, fd, &offset, sb.st_size);
+
+ close(sd);
+ close(outsd);
+ close(fd);
+
+ /* Await our return code from qarshd */
+ qp = recv_packet(qacp_fd);
+ if (qp && qp->qp_type == QP_RETURNCODE
+ && qp->qp_returncode.qp_rc == -1) {
+ fprintf(stderr, "Remote side failed, %s\n",
+ qp->qp_returncode.qp_strerror);
+ close(qacp_fd);
+ exit(125);
+ }
+
+ return;
+}
+
+void
+qacp_recvonefile(const char *host, const char *srcfile, const char *destfile)
+{
+ struct qa_packet *qp;
+
+ /* Recall that the packet types are qarshd-centric, so if we want
+ * to recv a file from the host running qarshd we have to tell
+ * qarshd to send a file. */
+
+ qp = make_qp_sendfile(srcfile, 88, 8888);
+ qp->qp_seq = 1;
+ send_packet(qacp_fd, qp);
+ qpfree(qp);
+
+ return;
+}
+
+int
+recvfiles(char **argv, int argc, short recursive, short quiet)
+{
+ puts("recvfiles() NA");
+ return 0;
+}
+
+
+int
+sendfiles(char **argv, int argc, short recursive, short quiet)
+{
+ char *cp;
+ char *rhost = NULL;
+ char *ruser = NULL;
+ char *rgrp = NULL;
+ struct passwd *pw;
+ int file;
+ char *rmtpath;
+ char *destpath;
+ char *tmpstr;
+ char *lbnp; /* local file basename */
+ char *ldnp; /* local file dirname */
+ char *rbnp; /* remote file basename */
+ char *rdnp; /* remote file dirname */
+
+ if (strchr(argv[argc-1], ':') == NULL) {
+ fprintf(stderr, "%s is not a valid remote host:file string\n",
+ argv[argc-1]);
+ return -1;
+ }
+
+ rhost = strdup(argv[argc-1]);
+ cp = strchr(rhost, ':');
+ *cp = '\0';
+
+ /* Grab any user/group info */
+ if ((cp = strchr(rhost, '@'))) {
+ ruser = rhost;
+ rhost = cp+1;
+ *cp = '\0';
+ }
+
+ if (ruser && (cp = strchr(ruser, '.'))) {
+ rgrp = cp+1;
+ *cp = '\0';
+ }
+
+ if (!(pw = getpwuid(getuid()))) {
+ fprintf(stderr, "qacp: unknown user id.\n");
+ return -1;
+ }
+
+ if (ruser == NULL) {
+ ruser = strdup(pw->pw_name);
+ }
+
+ qacp_fd = connect_to_host(rhost, QARSHD_CONTROL_PORT);
+ if (qacp_fd == -1) {
+ if (errno == 0) {
+ fprintf(stderr, "Could not connect to %s:%d, %d: %s\n",
+ rhost, QARSHD_CONTROL_PORT, h_errno, hstrerror(h_errno));
+ } else {
+ fprintf(stderr, "Could not connect to %s:%d, %d: %s\n",
+ rhost, QARSHD_CONTROL_PORT, errno, strerror(errno));
+ }
+ return -1;
+ }
+
+ set_remote_user(ruser, rgrp);
+
+ cp = strdup(argv[argc-1]);
+ cp = strchr(argv[argc-1], ':');
+ cp++;
+ rmtpath = strdup(cp);
+
+ tmpstr = strdup(rmtpath);
+ rdnp = strdup(dirname(tmpstr));
+ free(tmpstr);
+
+ tmpstr = strdup(rmtpath);
+ rbnp = strdup(basename(tmpstr));
+ free(tmpstr);
+
+
+ for (file = optind; file < (argc - 1); file++) {
+ tmpstr = strdup(argv[file]);
+ lbnp = strdup(basename(tmpstr));
+ free(tmpstr);
+
+ tmpstr = strdup(argv[file]);
+ ldnp = strdup(dirname(tmpstr));
+ free(tmpstr);
+
+ if (strcmp(lbnp, rbnp)) {
+ /* Tack on our lbnp to rmtpath */
+ destpath = malloc(strlen(rmtpath) + strlen(lbnp) + 2);
+ memset(destpath, 0, strlen(destpath));
+ strcpy(destpath, rmtpath);
+ strcat(destpath, "/");
+ strcat(destpath, lbnp);
+ } else {
+ destpath = strdup(rmtpath);
+ }
+
+ if (!quiet) {
+ printf("%-20.20s -> %s:%s\n", file[argv], rhost, destpath);
+ }
+
+ qacp_sendonefile(rhost, file[argv], destpath);
+
+ free(destpath);
+ }
+
+ return 0;
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ int c;
+ short recursive=0;
+ short quiet=0;
+ int eflag;
+
+ while ((c = getopt(argc, argv, "+rq")) != -1) {
+ switch (c) {
+ case 'r':
+ recursive = 1;
+ break;
+ case 'q':
+ quiet = 1;
+ break;
+ case '?':
+ default:
+ printf("Unknown option %c\n", (char)optopt);
+ usage();
+ exit(1);
+ }
+ }
+
+ if (argv[optind + 1] == NULL) {
+ usage();
+ exit(2);
+ }
+
+ eflag = 0;
+ /* If last arg has a ':' then we are sending files */
+ if (strchr(argv[argc-1], ':') != NULL) {
+ if (sendfiles(argv, argc, recursive, quiet) < 0) {
+ eflag++;
+ }
+ } else {
+ if (recvfiles(argv, argc, recursive, quiet) < 0) {
+ eflag++;
+ }
+ }
+
+ close(qacp_fd);
+
+ if (eflag) {
+ exit(1);
+ }
+
+ exit(0);
+}
diff --git a/qarsh/qarsh_packet.c b/qarsh/qarsh_packet.c
index bad614f..f3f5559 100644
--- a/qarsh/qarsh_packet.c
+++ b/qarsh/qarsh_packet.c
@@ -18,6 +18,8 @@ int parse_qp_runcmd(xmlXPathContextPtr ctxt, struct qa_packet *qp);
int parse_qp_cmdexit(xmlXPathContextPtr ctxt, struct qa_packet *qp);
int parse_qp_setuser(xmlXPathContextPtr ctxt, struct qa_packet *qp);
int parse_qp_kill(xmlXPathContextPtr ctxt, struct qa_packet *qp);
+int parse_qp_recvfile(xmlXPathContextPtr ctxt, struct qa_packet *qp);
+int parse_qp_sendfile(xmlXPathContextPtr ctxt, struct qa_packet *qp);
void string_qp_hello(xmlNodePtr node, struct qa_packet *qp);
void string_qp_returncode(xmlNodePtr node, struct qa_packet *qp);
@@ -26,11 +28,15 @@ void string_qp_ack(xmlNodePtr node, struct qa_packet *qp);
void string_qp_cmdexit(xmlNodePtr node, struct qa_packet *qp);
void string_qp_setuser(xmlNodePtr node, struct qa_packet *qp);
void string_qp_kill(xmlNodePtr node, struct qa_packet *qp);
+void string_qp_recvfile(xmlNodePtr node, struct qa_packet *qp);
+void string_qp_sendfile(xmlNodePtr node, struct qa_packet *qp);
void free_qp_hello(struct qa_packet *qp);
void free_qp_returncode(struct qa_packet *qp);
void free_qp_runcmd(struct qa_packet *qp);
void free_qp_setuser(struct qa_packet *qp);
+void free_qp_recvfile(struct qa_packet *qp);
+void free_qp_sendfile(struct qa_packet *qp);
void dump_qp_ack(struct qa_packet *qp);
void dump_qp_runcmd(struct qa_packet *qp);
@@ -38,6 +44,8 @@ void dump_qp_returncode(struct qa_packet *qp);
void dump_qp_cmdexit(struct qa_packet *qp);
void dump_qp_setuser(struct qa_packet *qp);
void dump_qp_kill(struct qa_packet *qp);
+void dump_qp_recvfile(struct qa_packet *qp);
+void dump_qp_sendfile(struct qa_packet *qp);
struct packet_internals {
@@ -95,6 +103,18 @@ struct packet_internals {
.pi_string = string_qp_kill,
.pi_free = NULL,
.pi_dump = dump_qp_kill
+ }, {
+ .pi_name = "recvfile",
+ .pi_parse = parse_qp_recvfile,
+ .pi_string = string_qp_recvfile,
+ .pi_free = free_qp_recvfile,
+ .pi_dump = dump_qp_recvfile
+ }, {
+ .pi_name = "sendfile",
+ .pi_parse = parse_qp_sendfile,
+ .pi_string = string_qp_sendfile,
+ .pi_free = free_qp_sendfile,
+ .pi_dump = dump_qp_sendfile
}
};
@@ -216,6 +236,44 @@ parse_qp_kill(xmlXPathContextPtr ctxt, struct qa_packet *qp)
return 0;
}
+int
+parse_qp_recvfile(xmlXPathContextPtr ctxt, struct qa_packet *qp)
+{
+ char *s;
+
+ qp->qp_recvfile.qp_path = get_xpath_string(ctxt, "param[@name='path']");
+
+ s = get_xpath_string(ctxt, "param[@name='if_port']");
+ qp->qp_recvfile.qp_if_port = atoi(s);
+ free(s);
+
+ s = get_xpath_string(ctxt, "param[@name='count']");
+ qp->qp_recvfile.qp_count = atoi(s);
+ free(s);
+
+ s = get_xpath_string(ctxt, "param[@name='mode']");
+ qp->qp_recvfile.qp_mode = atoi(s);
+ free(s);
+
+ return 0;
+}
+
+int
+parse_qp_sendfile(xmlXPathContextPtr ctxt, struct qa_packet *qp)
+{
+ char *s;
+
+ qp->qp_sendfile.qp_path = get_xpath_string(ctxt, "param[@name='path']");
+ s = get_xpath_string(ctxt, "param[@name='of_port']");
+ qp->qp_sendfile.qp_of_port = atoi(s);
+ free(s);
+ s = get_xpath_string(ctxt, "param[@name='count']");
+ qp->qp_sendfile.qp_count = atoi(s);
+ free(s);
+ return 0;
+}
+
+
struct qa_packet *
parse_packet(xmlXPathContextPtr ctxt)
{
@@ -377,6 +435,33 @@ void string_qp_kill(xmlNodePtr node, struct qa_packet *qp)
xmlAddChild(node, make_param("signal", tmpstr));
}
+void string_qp_recvfile(xmlNodePtr node, struct qa_packet *qp)
+{
+ char tmpstr[32];
+
+ xmlAddChild(node, make_param("path", qp->qp_recvfile.qp_path));
+
+ snprintf(tmpstr, 32, "%d", qp->qp_recvfile.qp_if_port);
+ xmlAddChild(node, make_param("if_port", tmpstr));
+
+ snprintf(tmpstr, 32, "%d", qp->qp_recvfile.qp_count);
+ xmlAddChild(node, make_param("count", tmpstr));
+
+ snprintf(tmpstr, 32, "%d", qp->qp_recvfile.qp_mode);
+ xmlAddChild(node, make_param("mode", tmpstr));
+}
+
+void string_qp_sendfile(xmlNodePtr node, struct qa_packet *qp)
+{
+ char tmpstr[32];
+
+ xmlAddChild(node, make_param("path", qp->qp_sendfile.qp_path));
+ snprintf(tmpstr, 32, "%d", qp->qp_sendfile.qp_of_port);
+ xmlAddChild(node, make_param("of_port", tmpstr));
+ snprintf(tmpstr, 32, "%d", qp->qp_sendfile.qp_count);
+ xmlAddChild(node, make_param("count", tmpstr));
+}
+
/* Must pass in a pointer, but not a malloc'ed pointer */
char *
qptostr(struct qa_packet *qp, char **qpstr, int *qpsize)
@@ -518,6 +603,38 @@ make_qp_kill(int sig)
return qp;
}
+struct qa_packet *
+make_qp_recvfile(const char *path, int if_port, size_t count, mode_t mode)
+{
+ struct qa_packet *qp;
+ qp = malloc(sizeof *qp);
+ assert(qp);
+ memset(qp, 0, sizeof *qp);
+
+ qp->qp_type = QP_RECVFILE;
+ qp->qp_recvfile.qp_path = strdup(path);
+ qp->qp_recvfile.qp_if_port = if_port;
+ qp->qp_recvfile.qp_count = count;
+ qp->qp_recvfile.qp_mode = mode;
+
+ return qp;
+}
+
+struct qa_packet *
+make_qp_sendfile(const char *path, int of_port, size_t count)
+{
+ struct qa_packet *qp;
+ qp = malloc(sizeof *qp);
+ assert(qp);
+ memset(qp, 0, sizeof *qp);
+
+ qp->qp_type = QP_SENDFILE;
+ qp->qp_sendfile.qp_path = strdup(path);
+ qp->qp_sendfile.qp_of_port = of_port;
+ qp->qp_sendfile.qp_count = count;
+ return qp;
+}
+
/*
* Packet deallocation functions
*/
@@ -547,6 +664,19 @@ free_qp_setuser(struct qa_packet *qp)
}
void
+free_qp_recvfile(struct qa_packet *qp)
+{
+ condfree(qp->qp_recvfile.qp_path);
+}
+
+void
+free_qp_sendfile(struct qa_packet *qp)
+{
+ condfree(qp->qp_sendfile.qp_path);
+}
+
+
+void
qpfree(struct qa_packet *qp)
{
if (qp) {
@@ -608,6 +738,23 @@ dump_qp_kill(struct qa_packet *qp)
}
void
+dump_qp_recvfile(struct qa_packet *qp)
+{
+ printf("\tpath: %s\n", qp->qp_recvfile.qp_path);
+ printf("\tif_port: %d\n", qp->qp_recvfile.qp_if_port);
+ printf("\tcount: %d\n", qp->qp_recvfile.qp_count);
+ printf("\tmode: %o\n", qp->qp_recvfile.qp_mode);
+}
+
+void
+dump_qp_sendfile(struct qa_packet *qp)
+{
+ printf("\tpath: %s\n", qp->qp_sendfile.qp_path);
+ printf("\tof_port: %d\n", qp->qp_sendfile.qp_of_port);
+ printf("\tcount: %d\n", qp->qp_sendfile.qp_count);
+}
+
+void
dump_qp(struct qa_packet *qp)
{
printf("%s #%d\n", QP_NAME(qp->qp_type), qp->qp_seq);
diff --git a/qarsh/qarsh_packet.h b/qarsh/qarsh_packet.h
index 64b2b2a..b858631 100644
--- a/qarsh/qarsh_packet.h
+++ b/qarsh/qarsh_packet.h
@@ -13,7 +13,9 @@ enum qa_packet_type {
QP_ACK = 4,
QP_CMDEXIT = 5,
QP_SETUSER = 6,
- QP_KILL = 7
+ QP_KILL = 7,
+ QP_RECVFILE = 8,
+ QP_SENDFILE = 9
};
struct qp_hello_pkt {
@@ -53,6 +55,20 @@ struct qp_kill_pkt {
int qp_sig;
};
+struct qp_recvfile_pkt {
+ char *qp_path;
+ mode_t qp_mode;
+ int qp_if_port;
+ size_t qp_count;
+};
+
+struct qp_sendfile_pkt {
+ char *qp_path;
+ int qp_of_port;
+ size_t qp_count;
+};
+
+
#define QP_VERSION 1
struct qa_packet {
@@ -66,6 +82,8 @@ struct qa_packet {
struct qp_cmdexit_pkt cmdexit;
struct qp_setuser_pkt setuser;
struct qp_kill_pkt kill;
+ struct qp_recvfile_pkt recvfile;
+ struct qp_sendfile_pkt sendfile;
} qp_u;
};
@@ -76,6 +94,8 @@ struct qa_packet {
#define qp_cmdexit qp_u.cmdexit
#define qp_setuser qp_u.setuser
#define qp_kill qp_u.kill
+#define qp_recvfile qp_u.recvfile
+#define qp_sendfile qp_u.sendfile
/* Prototypes */
char *qp_packet_type(enum qa_packet_type t);
@@ -87,6 +107,8 @@ struct qa_packet *make_qp_runcmd(char *cmdline, int p_in, int p_out, int p_err);
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, int if_port, size_t count, mode_t mode);
+struct qa_packet *make_qp_sendfile(const char *path, int of_port, size_t count);
char *qptostr(struct qa_packet *qp, char **qpstr, int *qpsize);
void qpfree(struct qa_packet *qp);
void dump_qp(struct qa_packet *qp);
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",