summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: e268294)
raw | patch | inline | side by side (parent: e268294)
author | Sebastian Harl <sh@teamix.net> | |
Wed, 12 Sep 2012 13:44:07 +0000 (15:44 +0200) | ||
committer | Sebastian Harl <sh@teamix.net> | |
Wed, 12 Sep 2012 13:44:07 +0000 (15:44 +0200) |
This function may be used to call an arbitrary JUNOScript method with any
number and type of attributes and arguments. Attributes and arguments are
specified using a variable argument list using tuples <type>, <name>[,
<value>] where type is any of a list of constants defined in junos.h. The type
of <value> is determined from the specified type. The list has to be
terminated by the constant JUNOS_NO_ARGS.
junos_simple_method() has been "degraded" to a define calling
junos_invoke_method().
number and type of attributes and arguments. Attributes and arguments are
specified using a variable argument list using tuples <type>, <name>[,
<value>] where type is any of a list of constants defined in junos.h. The type
of <value> is determined from the specified type. The list has to be
terminated by the constant JUNOS_NO_ARGS.
junos_simple_method() has been "degraded" to a define calling
junos_invoke_method().
src/junos.c | patch | blob | history | |
src/junos.h | patch | blob | history |
diff --git a/src/junos.c b/src/junos.c
index d254992cb6f1e886edeed264ba124eda5199bb3b..8608551f41593c2787712165ac64545dda26edd7 100644 (file)
--- a/src/junos.c
+++ b/src/junos.c
#include <errno.h>
+#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
* private helper functions
*/
+static int
+meth_append_arg(junos_strbuf_t *body, junos_strbuf_t *attrs,
+ int arg_type, va_list *ap)
+{
+ char *name = va_arg(*ap, char *);
+ ssize_t status;
+
+ if (! name) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ switch (arg_type) {
+ case JUNOS_ARG_TOGGLE: /* fall thru */
+ case JUNOS_ARG_TOGGLE_NO:
+ {
+ int value = va_arg(*ap, int);
+ if (value)
+ status = junos_strbuf_sprintf(body,
+ " <%s/>\n", name);
+ else if (arg_type == JUNOS_ARG_TOGGLE_NO)
+ status = junos_strbuf_sprintf(body,
+ " <no-%s/>\n", name);
+ }
+ break;
+ case JUNOS_ARG_STRING:
+ {
+ char *value = va_arg(*ap, char *);
+ status = junos_strbuf_sprintf(body,
+ " <%s>%s</%s>\n", name,
+ value ? value : "", name);
+ }
+ break;
+ case JUNOS_ARG_INTEGER:
+ {
+ int value = va_arg(*ap, int);
+ status = junos_strbuf_sprintf(body,
+ " <%s>%i</%s>\n",
+ name, value, name);
+ }
+ break;
+ case JUNOS_ARG_DOUBLE:
+ {
+ double value = va_arg(*ap, double);
+ status = junos_strbuf_sprintf(body,
+ " <%s>%lf</%s>\n",
+ name, value, name);
+ }
+ break;
+ case JUNOS_ARG_DOM:
+ {
+ status = junos_strbuf_sprintf(body,
+ " %s\n", name);
+ }
+ break;
+ case JUNOS_ATTR_STRING:
+ {
+ char *value = va_arg(*ap, char *);
+ status = junos_strbuf_sprintf(attrs,
+ " %s=\"%s\"",
+ name, value ? value : "");
+ }
+ break;
+ case JUNOS_ATTR_INTEGER:
+ {
+ int value = va_arg(*ap, int);
+ status = junos_strbuf_sprintf(attrs,
+ " %s=\"%s\"", name, value);
+ }
+ break;
+ case JUNOS_ATTR_DOUBLE:
+ {
+ double value = va_arg(*ap, double);
+ status = junos_strbuf_sprintf(attrs,
+ " %s=\"%s\"", name, value);
+ }
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ break;
+ }
+ if (status < 0)
+ return -1;
+ return 0;
+} /* meth_append_arg */
+
static ssize_t
read_lines(junos_t *junos, char *buf, size_t buf_len)
{
} /* junos_disconnect */
xmlDocPtr
-junos_simple_method(junos_t *junos, const char *name)
+junos_invoke_method(junos_t *junos, const char *name, ...)
{
- char method_string[1024];
+ junos_strbuf_t *method_buf;
+ junos_strbuf_t *body_buf;
+ junos_strbuf_t *attr_buf;
+
+ char *method_string;
+ size_t method_len;
+ char *body_string;
+ char *attr_string;
+
char recv_buf[4096];
ssize_t status;
int xml_status;
-
xmlDocPtr doc;
+ va_list ap;
+ int arg_type;
+
if ((! junos) || (! name)) {
junos_set_error(junos, JUNOS_SYS_ERROR, EINVAL,
- "junos_simple_method() requires the "
+ "junos_invoke_method() requires the "
"'junos' and 'name' arguments");
return NULL;
}
return NULL;
}
- snprintf(method_string, sizeof(method_string),
- "<rpc><%s/></rpc>", name);
- status = junos_ssh_send(junos->access,
- method_string, strlen(method_string));
- if (status != (ssize_t)strlen(method_string)) {
+ errno = 0;
+ method_buf = junos_strbuf_new(1024);
+ body_buf = junos_strbuf_new(1024);
+ attr_buf = junos_strbuf_new(1024);
+
+#define BUF_FREE() \
+ do { \
+ junos_strbuf_free(method_buf); \
+ method_buf = NULL; \
+ method_string = NULL; \
+ method_len = 0; \
+ junos_strbuf_free(body_buf); \
+ body_buf = NULL; \
+ body_string = NULL; \
+ junos_strbuf_free(attr_buf); \
+ attr_buf = NULL; \
+ attr_string = NULL; \
+ } while (0)
+
+ if ((! method_buf) || (! body_buf) || (! attr_buf)) {
+ junos_set_error(junos, JUNOS_SYS_ERROR, errno,
+ "Failed to allocate string buffers");
+ BUF_FREE();
+ return NULL;
+ }
+
+ va_start(ap, name);
+ while ((arg_type = va_arg(ap, int)) != JUNOS_NO_ARGS) {
+ if (meth_append_arg(body_buf, attr_buf, arg_type, &ap)) {
+ BUF_FREE();
+ junos_set_error(junos, JUNOS_SYS_ERROR, errno,
+ "Failed to append argument (type %d) to method '%s'",
+ arg_type, name);
+ return NULL;
+ }
+ }
+ va_end(ap);
+
+ body_string = junos_strbuf_string(body_buf);
+ attr_string = junos_strbuf_string(attr_buf);
+
+ if (body_string[0])
+ junos_strbuf_sprintf(method_buf,
+ "<rpc>\n"
+ " <%s%s>\n%s"
+ " </%s>\n"
+ "</rpc>",
+ name, attr_string, body_string, name);
+ else
+ junos_strbuf_sprintf(method_buf,
+ "<rpc>\n"
+ " <%s%s/>\n"
+ "</rpc>",
+ name, attr_string);
+
+ method_string = junos_strbuf_string(method_buf);
+ method_len = junos_strbuf_len(method_buf);
+
+ dprintf(" -> %s\n", method_string);
+ status = junos_ssh_send(junos->access, method_string, method_len);
+
+ if (status != (ssize_t)method_len) {
dprintf("Failed to send method '%s' (status %d)\n",
method_string, (int)status);
+ BUF_FREE();
return NULL;
}
+ BUF_FREE();
+
errno = 0;
junos->xml_ctx = xmlCreatePushParserCtxt(/* sax = */ NULL,
/* user_data = */ NULL,
}
return doc;
-} /* junos_simple_method */
+} /* junos_invoke_method */
/* error handling */
diff --git a/src/junos.h b/src/junos.h
index 055cd03204a472ae53c4b13c21ee5bf58f5694c8..a122330022b14feeec748c16cf200aa17c7a5377 100644 (file)
--- a/src/junos.h
+++ b/src/junos.h
typedef struct junos junos_t;
+/* method invocation */
+
+enum {
+ JUNOS_NO_ARGS = 0,
+ JUNOS_ARG_TOGGLE,
+ JUNOS_ARG_TOGGLE_NO,
+ JUNOS_ARG_STRING,
+ JUNOS_ARG_INTEGER,
+ JUNOS_ARG_DOUBLE,
+ JUNOS_ARG_DOM,
+ JUNOS_ATTR_STRING,
+ JUNOS_ATTR_INTEGER,
+ JUNOS_ATTR_DOUBLE,
+};
+
/* string buffer */
typedef struct junos_strbuf junos_strbuf_t;
junos_connect(junos_t *junos);
xmlDocPtr
-junos_simple_method(junos_t *junos, const char *name);
+junos_invoke_method(junos_t *junos, const char *name, ...);
+
+#define junos_simple_method(junos, name) \
+ junos_invoke_method((junos), (name), JUNOS_NO_ARGS)
int
junos_disconnect(junos_t *junos);