From bf489daffc4902db3a9eb95d485fd867ac1ea524 Mon Sep 17 00:00:00 2001 From: Nate Straz Date: Tue, 13 Sep 2005 16:01:28 +0000 Subject: Flatten the qarsh tree. --- qarsh_packet.c | 850 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 850 insertions(+) create mode 100644 qarsh_packet.c (limited to 'qarsh_packet.c') diff --git a/qarsh_packet.c b/qarsh_packet.c new file mode 100644 index 0000000..76fadf1 --- /dev/null +++ b/qarsh_packet.c @@ -0,0 +1,850 @@ + +#include +#include +#include + +#include +#include + +#include "qarsh_packet.h" + +/* Prototypes */ +static char *get_xpath_string(xmlXPathContextPtr ctxt, const char *xpath_query); + +int parse_qp_hello(xmlXPathContextPtr ctxt, struct qa_packet *qp); +int parse_qp_returncode(xmlXPathContextPtr ctxt, struct qa_packet *qp); +int parse_qp_ack(xmlXPathContextPtr ctxt, struct qa_packet *qp); +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); +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); + +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 free_qp_rstat(struct qa_packet *qp); + +void dump_qp_ack(struct qa_packet *qp); +void dump_qp_runcmd(struct qa_packet *qp); +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); +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); + 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_free = NULL, + .pi_dump = NULL + + }, { + .pi_name = "hello", + .pi_parse = parse_qp_hello, + .pi_string = string_qp_hello, + .pi_free = free_qp_hello + }, { + .pi_name = "returncode", + .pi_parse = parse_qp_returncode, + .pi_string = string_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_free = free_qp_runcmd, + .pi_dump = dump_qp_runcmd + }, { + .pi_name = "ack", + .pi_parse = parse_qp_ack, + .pi_string = string_qp_ack, + .pi_free = NULL, + .pi_dump = dump_qp_ack + }, { + .pi_name = "cmdexit", + .pi_parse = parse_qp_cmdexit, + .pi_string = string_qp_cmdexit, + .pi_free = NULL, + .pi_dump = dump_qp_cmdexit + }, { + .pi_name = "setuser", + .pi_parse = parse_qp_setuser, + .pi_string = string_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_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 + }, { + .pi_name = "rstat", + .pi_parse = parse_qp_rstat, + .pi_string = string_qp_rstat, + .pi_free = free_qp_rstat, + .pi_dump = dump_qp_rstat + } +}; + +#define QP_TYPES (sizeof qa_pi / sizeof *qa_pi) +#define QP_NAME(n) qa_pi[n].pi_name + + +/* XML Strings */ +const xmlChar *QP_QARSH_XML = (xmlChar *)"qarsh"; +const xmlChar *QP_PACKET_XML = (xmlChar *)"packet"; +const xmlChar *QP_TYPE_XML = (xmlChar *)"type"; +const xmlChar *QP_PARAM_XML = (xmlChar *)"param"; +const xmlChar *QP_NAME_XML = (xmlChar *)"name"; +const xmlChar *QP_SEQ_XML = (xmlChar *)"seq"; + +enum qa_packet_type +parse_packet_type(char *s) +{ + int i; + for (i = 0; i < QP_TYPES; i++) { + if (strcasecmp(s, QP_NAME(i)) == 0) { + return (enum qa_packet_type)i; + } + } + return QP_INVALID; +} + +char * +qp_packet_type(enum qa_packet_type t) +{ + return QP_NAME(t); +} + + +/* + * Packet parsing functions + */ +int +parse_qp_hello(xmlXPathContextPtr ctxt, struct qa_packet *qp) +{ + qp->qp_hello.qp_greeting = get_xpath_string(ctxt, + "param[@name='greeting']"); + return 0; +} + +int +parse_qp_returncode(xmlXPathContextPtr ctxt, struct qa_packet *qp) +{ + char *s; + s = get_xpath_string(ctxt, "param[@name='rc']"); + qp->qp_returncode.qp_rc = atoi(s); + free(s); + s = get_xpath_string(ctxt, "param[@name='errno']"); + qp->qp_returncode.qp_errno = atoi(s); + free(s); + qp->qp_returncode.qp_strerror = get_xpath_string(ctxt, + "param[@name='strerror']"); + return 0; +} + +int +parse_qp_runcmd(xmlXPathContextPtr ctxt, struct qa_packet *qp) +{ + char *s; + qp->qp_runcmd.qp_cmdline = get_xpath_string(ctxt, + "param[@name='cmdline']"); + s = get_xpath_string(ctxt, "param[@name='stdin']"); + qp->qp_runcmd.qp_stdin_port = atoi(s); + free(s); + s = get_xpath_string(ctxt, "param[@name='stdout']"); + qp->qp_runcmd.qp_stdout_port = atoi(s); + free(s); + s = get_xpath_string(ctxt, "param[@name='stderr']"); + qp->qp_runcmd.qp_stderr_port = atoi(s); + free(s); + return 0; +} + +int +parse_qp_ack(xmlXPathContextPtr ctxt, struct qa_packet *qp) +{ + char *s; + s = get_xpath_string(ctxt, "param[@name='type']"); + qp->qp_ack.qp_ack_type = parse_packet_type(s); + free(s); + s = get_xpath_string(ctxt, "param[@name='seq']"); + qp->qp_ack.qp_ack_seq = atoi(s); + free(s); + return 0; +} + +int +parse_qp_cmdexit(xmlXPathContextPtr ctxt, struct qa_packet *qp) +{ + char *s; + + s = get_xpath_string(ctxt, "param[@name='status']"); + qp->qp_cmdexit.qp_status = atoi(s); + free(s); + return 0; +} + +int +parse_qp_setuser(xmlXPathContextPtr ctxt, struct qa_packet *qp) +{ + qp->qp_setuser.qp_user = get_xpath_string(ctxt, "param[@name='user']"); + qp->qp_setuser.qp_group = get_xpath_string(ctxt, "param[@name='group']"); + return 0; +} + +int +parse_qp_kill(xmlXPathContextPtr ctxt, struct qa_packet *qp) +{ + char *s; + + s = get_xpath_string(ctxt, "param[@name='signal']"); + qp->qp_kill.qp_sig = atoi(s); + free(s); + 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; +} + +int +parse_qp_rstat(xmlXPathContextPtr ctxt, struct qa_packet *qp) +{ + char *s; + + qp->qp_rstat.qp_path = get_xpath_string(ctxt, "param[@name='path']"); + + s = get_xpath_string(ctxt, "param[@name='st_mode']"); + qp->qp_rstat.qp_st_mode = atoi(s); + free(s); + + s = get_xpath_string(ctxt, "param[@name='st_uid']"); + qp->qp_rstat.qp_st_uid = atoi(s); + free(s); + + s = get_xpath_string(ctxt, "param[@name='st_gid']"); + qp->qp_rstat.qp_st_gid = atoi(s); + free(s); + + s = get_xpath_string(ctxt, "param[@name='st_size']"); + qp->qp_rstat.qp_st_size = atol(s); + free(s); + + return 0; +} + + +struct qa_packet * +parse_packet(xmlXPathContextPtr ctxt) +{ + struct qa_packet *qp = NULL; + char *s; + + qp = malloc(sizeof *qp); + assert(qp); + memset(qp, 0, sizeof *qp); + + s = get_xpath_string(ctxt, "@type"); + qp->qp_type = parse_packet_type(s); + free(s); + s = get_xpath_string(ctxt, "@seq"); + qp->qp_seq = atoi(s); + free(s); + + if (qa_pi[qp->qp_type].pi_parse) + qa_pi[qp->qp_type].pi_parse(ctxt, qp); + else { + printf("Packet type %s not implemented yet\n", s); + free(qp); + qp = NULL; + } + return qp; +} + +struct qa_packet * +parse_packets(char *buf, int n) +{ + xmlDocPtr doc; + xmlXPathContextPtr context; + xmlXPathObjectPtr obj = NULL; + struct qa_packet *qp = NULL; + + doc = xmlParseMemory(buf, n); + + /* If we can't parse the packet, we don't care about it */ + if (doc == NULL) return NULL; + + context = xmlXPathNewContext(doc); + obj = xmlXPathEvalExpression((xmlChar *)"//packet", context); + if (obj == NULL) { + printf("didn't find anything\n"); + goto free_context; + } + if (obj->type != XPATH_NODESET || obj->nodesetval->nodeNr == 0) { + printf("didn't find anything\n"); + goto free_obj; + } + if (obj->nodesetval->nodeNr > 1) { + printf("One packet at a time please!\n"); + } + context->node = xmlXPathNodeSetItem(obj->nodesetval, 0); + qp = parse_packet(context); + +free_obj: + xmlXPathFreeObject(obj); +free_context: + xmlXPathFreeContext(context); + xmlFreeDoc(doc); + return qp; +} + + +static char * +get_xpath_string(xmlXPathContextPtr ctxt, const char *xpath_query) +{ + xmlXPathObjectPtr obj = NULL; + char querystr[512]; + char *ret; + + snprintf(querystr, 512, "string(%s)", xpath_query); + obj = xmlXPathEvalExpression((xmlChar *)querystr, ctxt); + + if (obj == NULL) return NULL; + if (obj->type != XPATH_STRING) { + xmlXPathFreeObject(obj); + return NULL; + } + + ret = strdup((char *)obj->stringval); + xmlXPathFreeObject(obj); + return ret; +} + +/* + * Packet serialization functions + * + * for converting structs to XML + */ +xmlNodePtr +make_param(char *name, char *value) +{ + xmlNodePtr param = xmlNewNode(NULL, QP_PARAM_XML); + xmlNewProp(param, QP_NAME_XML, (xmlChar *)name); + xmlNodeSetContent(param, xmlEncodeSpecialChars(NULL, (xmlChar *)value)); + return param; +} + +void string_qp_hello(xmlNodePtr node, struct qa_packet *qp) +{ + xmlAddChild(node, make_param("greeting", qp->qp_hello.qp_greeting)); +} +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)); +} +void string_qp_runcmd(xmlNodePtr node, 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)); +} +void string_qp_ack(xmlNodePtr node, struct qa_packet *qp) +{ + char tmpstr[32]; + + 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)); +} + +void string_qp_cmdexit(xmlNodePtr node, struct qa_packet *qp) +{ + char tmpstr[32]; + + 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)); +} + +void string_qp_setuser(xmlNodePtr node, struct qa_packet *qp) +{ + xmlAddChild(node, make_param("user", qp->qp_setuser.qp_user)); + if (qp->qp_setuser.qp_group) { + xmlAddChild(node, make_param("group", qp->qp_setuser.qp_group)); + } +} + +void string_qp_kill(xmlNodePtr node, struct qa_packet *qp) +{ + char tmpstr[32]; + + snprintf(tmpstr, 32, "%d", qp->qp_kill.qp_sig); + 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)); +} + +void string_qp_rstat(xmlNodePtr node, 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, "%ld", qp->qp_rstat.qp_st_size); + xmlAddChild(node, make_param("st_size", tmpstr)); +} + +/* Must pass in a pointer, but not a malloc'ed pointer */ +char * +qptostr(struct qa_packet *qp, char **qpstr, int *qpsize) +{ + xmlDocPtr doc; + xmlNodePtr node; + char tmpstr[32]; + + if (qp->qp_type == QP_INVALID) return NULL; + + doc = xmlNewDoc((xmlChar *)XML_DEFAULT_VERSION); + + /* Add */ + node = xmlNewDocNode(doc, NULL, QP_QARSH_XML, NULL); + xmlDocSetRootElement(doc, node); + + /* Add */ + 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); + } + xmlDocDumpMemory(doc, (xmlChar **)qpstr, qpsize); + xmlFreeDoc(doc); + return *qpstr; +} + +/* + * Packet construction functions + */ +struct qa_packet * +make_qp_hello(char *greeting) +{ + struct qa_packet *qp; + + qp = malloc(sizeof *qp); + assert(qp); + memset(qp, 0, sizeof *qp); + + qp->qp_type = QP_HELLO; + qp->qp_hello.qp_greeting = strdup(greeting); + + return qp; +} + +struct qa_packet * +make_qp_returncode(int rc, int eno, char *strerr) +{ + struct qa_packet *qp; + + qp = malloc(sizeof *qp); + assert(qp); + memset(qp, 0, sizeof *qp); + + qp->qp_type = QP_RETURNCODE; + qp->qp_returncode.qp_rc = rc; + qp->qp_returncode.qp_errno = eno; + qp->qp_returncode.qp_strerror = strdup(strerr); + + return qp; +} + +struct qa_packet * +make_qp_ack(enum qa_packet_type t, int i) +{ + struct qa_packet *qp; + qp = malloc(sizeof *qp); + assert(qp); + memset(qp, 0, sizeof *qp); + + qp->qp_type = QP_ACK; + qp->qp_ack.qp_ack_type = t; + qp->qp_ack.qp_ack_seq = i; + + return qp; +} + +struct qa_packet * +make_qp_runcmd(char *cmdline, int p_in, int p_out, int p_err) +{ + struct qa_packet *qp; + qp = malloc(sizeof *qp); + assert(qp); + memset(qp, 0, sizeof *qp); + + qp->qp_type = QP_RUNCMD; + qp->qp_runcmd.qp_cmdline = strdup(cmdline); + qp->qp_runcmd.qp_stdin_port = p_in; + qp->qp_runcmd.qp_stdout_port = p_out; + qp->qp_runcmd.qp_stderr_port = p_err; + + return qp; +} + +struct qa_packet * +make_qp_cmdexit(pid_t pid, int status) +{ + struct qa_packet *qp; + qp = malloc(sizeof *qp); + assert(qp); + memset(qp, 0, sizeof *qp); + + qp->qp_type = QP_CMDEXIT; + qp->qp_cmdexit.qp_pid = pid; + qp->qp_cmdexit.qp_status = status; + + return qp; +} + +struct qa_packet * +make_qp_setuser(char *user, char *group) +{ + struct qa_packet *qp; + qp = malloc(sizeof *qp); + assert(qp); + memset(qp, 0, sizeof *qp); + + qp->qp_type = QP_SETUSER; + qp->qp_setuser.qp_user = strdup(user); + if (group) qp->qp_setuser.qp_group = strdup(group); + + return qp; +} + +struct qa_packet * +make_qp_kill(int sig) +{ + struct qa_packet *qp; + qp = malloc(sizeof *qp); + assert(qp); + memset(qp, 0, sizeof *qp); + + qp->qp_type = QP_KILL; + qp->qp_kill.qp_sig = 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; +} + +struct qa_packet * +make_qp_rstat(const char *path, const struct stat *sb) +{ + struct qa_packet *qp; + qp = malloc(sizeof *qp); + assert(qp); + memset(qp, 0, sizeof *qp); + + qp->qp_type = QP_RSTAT; + qp->qp_rstat.qp_path = strdup(path); + if (sb) { + qp->qp_rstat.qp_st_mode = sb->st_mode; + qp->qp_rstat.qp_st_uid = sb->st_uid; + qp->qp_rstat.qp_st_gid = sb->st_gid; + qp->qp_rstat.qp_st_size = sb->st_size; + } + return qp; +} + +/* + * Packet deallocation functions + */ +#define condfree(x) if (x) { free(x); } +void +free_qp_hello(struct qa_packet *qp) +{ + condfree(qp->qp_hello.qp_greeting); +} + +void +free_qp_returncode(struct qa_packet *qp) +{ + condfree(qp->qp_returncode.qp_strerror); +} +void +free_qp_runcmd(struct qa_packet *qp) +{ + condfree(qp->qp_runcmd.qp_cmdline); +} + +void +free_qp_setuser(struct qa_packet *qp) +{ + condfree(qp->qp_setuser.qp_user); + condfree(qp->qp_setuser.qp_group); +} + +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 +free_qp_rstat(struct qa_packet *qp) +{ + condfree(qp->qp_rstat.qp_path); +} + + +void +qpfree(struct qa_packet *qp) +{ + if (qp) { + if (qa_pi[qp->qp_type].pi_free) { + qa_pi[qp->qp_type].pi_free(qp); + } + free(qp); + } +} +#undef condfree + +/* + * Packet printing functions + * + * For printing out packets for debugging purposes + */ +void +dump_qp_ack(struct qa_packet *qp) +{ + printf("\t%s #%d\n", QP_NAME(qp->qp_ack.qp_ack_type), + qp->qp_ack.qp_ack_seq); +} + +void +dump_qp_runcmd(struct qa_packet *qp) +{ + printf("\tcmdline: %s\n", qp->qp_runcmd.qp_cmdline); +} + +void +dump_qp_returncode(struct qa_packet *qp) +{ + printf("\trc: %d\n", qp->qp_returncode.qp_rc); +} + +void +dump_qp_cmdexit(struct qa_packet *qp) +{ + if (WIFEXITED(qp->qp_cmdexit.qp_status)) { + printf("\texited: %d\n", WEXITSTATUS(qp->qp_cmdexit.qp_status)); + } else if (WIFSIGNALED(qp->qp_cmdexit.qp_status)) { + printf("\tsignaled: %d\n", WTERMSIG(qp->qp_cmdexit.qp_status)); + } else { + printf("\tstatus: %d\n", qp->qp_cmdexit.qp_status); + } +} + +void +dump_qp_setuser(struct qa_packet *qp) +{ + printf("\tuser: %s\n", qp->qp_setuser.qp_user); + printf("\tgroup: %s\n", qp->qp_setuser.qp_group); +} + +void +dump_qp_kill(struct qa_packet *qp) +{ + printf("\tsig: %d\n", qp->qp_kill.qp_sig); +} + +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_rstat(struct qa_packet *qp) +{ + printf("\tpath: %s\n", qp->qp_rstat.qp_path); + printf("\tst_mode: %o\n", qp->qp_rstat.qp_st_mode); + printf("\tst_uid: %d\n", qp->qp_rstat.qp_st_uid); + printf("\tst_gid: %d\n", qp->qp_rstat.qp_st_gid); + printf("\tst_size: %ld\n", qp->qp_rstat.qp_st_size); +} + +void +dump_qp(struct qa_packet *qp) +{ + printf("%s #%d\n", QP_NAME(qp->qp_type), qp->qp_seq); + if (qa_pi[qp->qp_type].pi_dump) { + qa_pi[qp->qp_type].pi_dump(qp); + } +} -- cgit