diff options
-rw-r--r-- | qarsh_packet.c | 235 | ||||
-rw-r--r-- | qarsh_packet.h | 2 | ||||
-rw-r--r-- | sockutil.c | 22 |
3 files changed, 122 insertions, 137 deletions
diff --git a/qarsh_packet.c b/qarsh_packet.c index 0000a31..fea4435 100644 --- a/qarsh_packet.c +++ b/qarsh_packet.c @@ -30,6 +30,7 @@ #include <string.h> #include <assert.h> #include <sys/wait.h> +#include <endian.h> #include <libxml/parser.h> #include <libxml/xpath.h> @@ -50,16 +51,16 @@ int parse_qp_recvfile(xmlXPathContextPtr ctxt, struct qa_packet *qp); int parse_qp_sendfile(xmlXPathContextPtr ctxt, struct qa_packet *qp); int parse_qp_rstat(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); -void string_qp_runcmd(xmlNodePtr node, struct qa_packet *qp); -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 string_qp_rstat(xmlNodePtr node, struct qa_packet *qp); +char *store_qp_hello(char *buf, struct qa_packet *qp); +char *store_qp_returncode(char *buf, struct qa_packet *qp); +char *store_qp_runcmd(char *buf, struct qa_packet *qp); +char *store_qp_ack(char *buf, struct qa_packet *qp); +char *store_qp_cmdexit(char *buf, struct qa_packet *qp); +char *store_qp_setuser(char *buf, struct qa_packet *qp); +char *store_qp_kill(char *buf, struct qa_packet *qp); +char *store_qp_recvfile(char *buf, struct qa_packet *qp); +char *store_qp_sendfile(char *buf, struct qa_packet *qp); +char *store_qp_rstat(char *buf, struct qa_packet *qp); void free_qp_hello(struct qa_packet *qp); void free_qp_returncode(struct qa_packet *qp); @@ -83,74 +84,74 @@ void dump_qp_rstat(struct qa_packet *qp); struct packet_internals { char *pi_name; int (*pi_parse)(xmlXPathContextPtr ctxt, struct qa_packet *qp); - void (*pi_string)(xmlNodePtr node, struct qa_packet *qp); + char *(*pi_store)(char *buf, struct qa_packet *qp); void (*pi_free)(struct qa_packet *qp); void (*pi_dump)(struct qa_packet *qp); } qa_pi[] = { { .pi_name = "", .pi_parse = NULL, - .pi_string = NULL, + .pi_store = NULL, .pi_free = NULL, .pi_dump = NULL }, { .pi_name = "hello", .pi_parse = parse_qp_hello, - .pi_string = string_qp_hello, + .pi_store = store_qp_hello, .pi_free = free_qp_hello }, { .pi_name = "returncode", .pi_parse = parse_qp_returncode, - .pi_string = string_qp_returncode, + .pi_store = store_qp_returncode, .pi_free = free_qp_returncode, .pi_dump = dump_qp_returncode }, { .pi_name = "runcmd", .pi_parse = parse_qp_runcmd, - .pi_string = string_qp_runcmd, + .pi_store = store_qp_runcmd, .pi_free = free_qp_runcmd, .pi_dump = dump_qp_runcmd }, { .pi_name = "ack", .pi_parse = parse_qp_ack, - .pi_string = string_qp_ack, + .pi_store = store_qp_ack, .pi_free = NULL, .pi_dump = dump_qp_ack }, { .pi_name = "cmdexit", .pi_parse = parse_qp_cmdexit, - .pi_string = string_qp_cmdexit, + .pi_store = store_qp_cmdexit, .pi_free = NULL, .pi_dump = dump_qp_cmdexit }, { .pi_name = "setuser", .pi_parse = parse_qp_setuser, - .pi_string = string_qp_setuser, + .pi_store = store_qp_setuser, .pi_free = free_qp_setuser, .pi_dump = dump_qp_setuser }, { .pi_name = "kill", .pi_parse = parse_qp_kill, - .pi_string = string_qp_kill, + .pi_store = store_qp_kill, .pi_free = NULL, .pi_dump = dump_qp_kill }, { .pi_name = "recvfile", .pi_parse = parse_qp_recvfile, - .pi_string = string_qp_recvfile, + .pi_store = store_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_store = store_qp_sendfile, .pi_free = free_qp_sendfile, .pi_dump = dump_qp_sendfile }, { .pi_name = "rstat", .pi_parse = parse_qp_rstat, - .pi_string = string_qp_rstat, + .pi_store = store_qp_rstat, .pi_free = free_qp_rstat, .pi_dump = dump_qp_rstat } @@ -424,150 +425,134 @@ get_xpath_string(xmlXPathContextPtr ctxt, const char *xpath_query) /* * Packet serialization functions * - * for converting structs to XML */ -xmlNodePtr -make_param(char *name, char *value) +static char * +store_int(char *buf, int i) { - xmlChar *xstr; - - xmlNodePtr param = xmlNewNode(NULL, QP_PARAM_XML); - xmlNewProp(param, QP_NAME_XML, (xmlChar *)name); - xstr = xmlEncodeSpecialChars(NULL, (xmlChar *)value); - xmlNodeSetContent(param, xstr); - xmlFree(xstr); - return param; + i = htobe32(i); + memcpy(buf, &i, sizeof i); + return buf + sizeof i; } -void string_qp_hello(xmlNodePtr node, struct qa_packet *qp) +static char * +store_string(char *buf, char *s) { - xmlAddChild(node, make_param("greeting", qp->qp_hello.qp_greeting)); + char *cp; + cp = store_int(buf, strlen(s)); + memcpy(cp, s, strlen(s)); + return cp+strlen(s); } -void string_qp_returncode(xmlNodePtr node, struct qa_packet *qp) -{ - char tmpstr[32]; - snprintf(tmpstr, 32, "%d", qp->qp_returncode.qp_rc); - xmlAddChild(node, make_param("rc", tmpstr)); - snprintf(tmpstr, 32, "%d", qp->qp_returncode.qp_errno); - xmlAddChild(node, make_param("errno", tmpstr)); - xmlAddChild(node, make_param("strerror", qp->qp_returncode.qp_strerror)); +static char * +store_off_t(char *buf, off_t o) +{ + o = htobe64(o); + memcpy(buf, &o, sizeof o); + return buf + sizeof o; } -void string_qp_runcmd(xmlNodePtr node, struct qa_packet *qp) + +char * +store_qp_hello(char *buf, struct qa_packet *qp) { - char tmpstr[32]; - xmlAddChild(node, make_param("cmdline", qp->qp_runcmd.qp_cmdline)); - snprintf(tmpstr, 32, "%d", qp->qp_runcmd.qp_stdin_port); - xmlAddChild(node, make_param("stdin", tmpstr)); - snprintf(tmpstr, 32, "%d", qp->qp_runcmd.qp_stdout_port); - xmlAddChild(node, make_param("stdout", tmpstr)); - snprintf(tmpstr, 32, "%d", qp->qp_runcmd.qp_stderr_port); - xmlAddChild(node, make_param("stderr", tmpstr)); + return store_string(buf, qp->qp_hello.qp_greeting); } -void string_qp_ack(xmlNodePtr node, struct qa_packet *qp) + +char * +store_qp_returncode(char *buf, struct qa_packet *qp) { - char tmpstr[32]; + buf = store_int(buf, qp->qp_returncode.qp_rc); + buf = store_int(buf, qp->qp_returncode.qp_errno); + buf = store_string(buf, qp->qp_returncode.qp_strerror); + return buf; +} - xmlAddChild(node, make_param("type", - QP_NAME(qp->qp_ack.qp_ack_type))); - snprintf(tmpstr, 32, "%d", qp->qp_ack.qp_ack_seq); - xmlAddChild(node, make_param("seq", tmpstr)); +char * +store_qp_runcmd(char *buf, struct qa_packet *qp) +{ + buf = store_string(buf, qp->qp_runcmd.qp_cmdline); + buf = store_int(buf, qp->qp_runcmd.qp_stdin_port); + buf = store_int(buf, qp->qp_runcmd.qp_stdout_port); + buf = store_int(buf, qp->qp_runcmd.qp_stderr_port); + return buf; } -void string_qp_cmdexit(xmlNodePtr node, struct qa_packet *qp) +char * +store_qp_ack(char *buf, struct qa_packet *qp) { - char tmpstr[32]; + buf = store_int(buf, qp->qp_ack.qp_ack_type); + buf = store_int(buf, qp->qp_ack.qp_ack_seq); + return buf; +} - snprintf(tmpstr, 32, "%d", qp->qp_cmdexit.qp_pid); - xmlAddChild(node, make_param("pid", tmpstr)); - snprintf(tmpstr, 32, "%d", qp->qp_cmdexit.qp_status); - xmlAddChild(node, make_param("status", tmpstr)); +char * +store_qp_cmdexit(char *buf, struct qa_packet *qp) +{ + buf = store_int(buf, qp->qp_cmdexit.qp_pid); + buf = store_int(buf, qp->qp_cmdexit.qp_status); + return buf; } -void string_qp_setuser(xmlNodePtr node, struct qa_packet *qp) +char * +store_qp_setuser(char *buf, struct qa_packet *qp) { - xmlAddChild(node, make_param("user", qp->qp_setuser.qp_user)); + buf = store_string(buf, qp->qp_setuser.qp_user); if (qp->qp_setuser.qp_group) { - xmlAddChild(node, make_param("group", qp->qp_setuser.qp_group)); + buf = store_string(buf, qp->qp_setuser.qp_group); } + return buf; } -void string_qp_kill(xmlNodePtr node, struct qa_packet *qp) +char * +store_qp_kill(char *buf, struct qa_packet *qp) { - char tmpstr[32]; - - snprintf(tmpstr, 32, "%d", qp->qp_kill.qp_sig); - xmlAddChild(node, make_param("signal", tmpstr)); + return store_int(buf, qp->qp_kill.qp_sig); } -void string_qp_recvfile(xmlNodePtr node, struct qa_packet *qp) +char * +store_qp_recvfile(char *buf, 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, "%lld", (long long int)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)); + buf = store_string(buf, qp->qp_recvfile.qp_path); + buf = store_int(buf, qp->qp_recvfile.qp_if_port); + buf = store_off_t(buf, qp->qp_recvfile.qp_count); + buf = store_int(buf, qp->qp_recvfile.qp_mode); + return buf; } -void string_qp_sendfile(xmlNodePtr node, struct qa_packet *qp) +char * +store_qp_sendfile(char *buf, 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)); + buf = store_string(buf, qp->qp_sendfile.qp_path); + buf = store_int(buf, qp->qp_sendfile.qp_of_port); + return buf; } -void string_qp_rstat(xmlNodePtr node, struct qa_packet *qp) +char * +store_qp_rstat(char *buf, struct qa_packet *qp) { - char tmpstr[32]; - - xmlAddChild(node, make_param("path", qp->qp_rstat.qp_path)); - snprintf(tmpstr, 32, "%d", qp->qp_rstat.qp_st_mode); - xmlAddChild(node, make_param("st_mode", tmpstr)); - snprintf(tmpstr, 32, "%d", qp->qp_rstat.qp_st_uid); - xmlAddChild(node, make_param("st_uid", tmpstr)); - snprintf(tmpstr, 32, "%d", qp->qp_rstat.qp_st_gid); - xmlAddChild(node, make_param("st_gid", tmpstr)); - snprintf(tmpstr, 32, "%lld", (long long int)qp->qp_rstat.qp_st_size); - xmlAddChild(node, make_param("st_size", tmpstr)); + buf = store_string(buf, qp->qp_rstat.qp_path); + buf = store_int(buf, qp->qp_rstat.qp_st_mode); + buf = store_int(buf, qp->qp_rstat.qp_st_uid); + buf = store_int(buf, qp->qp_rstat.qp_st_gid); + buf = store_off_t(buf, qp->qp_rstat.qp_st_size); + return buf; } -/* Must pass in a pointer, but not a malloc'ed pointer */ -char * -qptostr(struct qa_packet *qp, char **qpstr, int *qpsize) +int +qptostr(struct qa_packet *qp, char *qpstr, int maxsize) { - xmlDocPtr doc; - xmlNodePtr node; - char tmpstr[32]; + char *cp; - if (qp->qp_type == QP_INVALID) return NULL; + if (qp->qp_type == QP_INVALID) return 0; - doc = xmlNewDoc((xmlChar *)XML_DEFAULT_VERSION); + cp = qpstr; - /* Add <qarsh> */ - node = xmlNewDocNode(doc, NULL, QP_QARSH_XML, NULL); - xmlDocSetRootElement(doc, node); + cp = store_int(cp, qp->qp_seq); + cp = store_int(cp, qp->qp_type); - /* Add <packet type="foo"> */ - node = xmlNewChild(node, NULL, QP_PACKET_XML, NULL); - xmlNewProp(node, QP_TYPE_XML, (xmlChar *)QP_NAME(qp->qp_type)); - snprintf(tmpstr, 32, "%d", qp->qp_seq); - xmlNewProp(node, QP_SEQ_XML, (xmlChar *)tmpstr); - - if (qa_pi[qp->qp_type].pi_string) { - qa_pi[qp->qp_type].pi_string(node, qp); + if (qa_pi[qp->qp_type].pi_store) { + cp = qa_pi[qp->qp_type].pi_store(cp, qp); } - xmlDocDumpMemory(doc, (xmlChar **)qpstr, qpsize); - xmlFreeDoc(doc); - return *qpstr; + return cp - qpstr; } /* diff --git a/qarsh_packet.h b/qarsh_packet.h index 2ed50f4..516c4fd 100644 --- a/qarsh_packet.h +++ b/qarsh_packet.h @@ -140,7 +140,7 @@ struct qa_packet *make_qp_kill(int sig); struct qa_packet *make_qp_recvfile(const char *path, int if_port, off_t count, mode_t mode); struct qa_packet *make_qp_sendfile(const char *path, int of_port); struct qa_packet *make_qp_rstat(const char *path, const struct stat *sb); -char *qptostr(struct qa_packet *qp, char **qpstr, int *qpsize); +int qptostr(struct qa_packet *qp, char *qpstr, int maxsize); void qpfree(struct qa_packet *qp); void dump_qp(struct qa_packet *qp); @@ -255,21 +255,21 @@ recv_read: int send_packet(int fd, struct qa_packet *qp) { - char *packetbuf; - int packetsize; + Buffer pb = { "", 0, 0}; uint32_t netsize; - ssize_t ret; + ssize_t ret = -1; struct iovec iovs[2]; - packetbuf = qptostr(qp, &packetbuf, &packetsize); + pb.end = qptostr(qp, pb.buf, QARSH_MAX_PACKET_SIZE - sizeof netsize); - netsize = htonl(packetsize); - iovs[0].iov_base = &netsize; - iovs[0].iov_len = sizeof netsize; - iovs[1].iov_base = packetbuf; - iovs[1].iov_len = packetsize; + if (pb.end > 0) { + netsize = htonl(pb.end); + iovs[0].iov_base = &netsize; + iovs[0].iov_len = sizeof netsize; + iovs[1].iov_base = pb.buf; + iovs[1].iov_len = pb.end; - ret = writev(fd, iovs, 2); - free(packetbuf); + ret = writev(fd, iovs, 2); + } return ret; } |