summaryrefslogtreecommitdiffstats
path: root/qarsh_packet.c
diff options
context:
space:
mode:
authorNathan Straz <nstraz@redhat.com>2013-08-01 01:58:09 -0400
committerNathan Straz <nstraz@redhat.com>2013-09-11 17:33:17 -0400
commitbbceec6030f8501ce129a93980c0f2e045cce562 (patch)
tree025006d9d7dbc7808065dc2f78671eda725a2042 /qarsh_packet.c
parent063f117b1dbe3868bcfe1933967d2a665b3de0db (diff)
downloadqarsh-bbceec6030f8501ce129a93980c0f2e045cce562.tar.gz
qarsh-bbceec6030f8501ce129a93980c0f2e045cce562.tar.xz
qarsh-bbceec6030f8501ce129a93980c0f2e045cce562.zip
Rewrite qptostr to store binary bits into an existing buffer
Diffstat (limited to 'qarsh_packet.c')
-rw-r--r--qarsh_packet.c235
1 files changed, 110 insertions, 125 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;
}
/*