busctl-introspect.c revision a1ad376761af16da46c9ad90fd8df41c8c5c0976
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2014 Lennart Poettering
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include "util.h"
#include "xml.h"
#include "sd-bus-vtable.h"
#include "busctl-introspect.h"
#define NODE_DEPTH_MAX 16
typedef struct Context {
const XMLIntrospectOps *ops;
void *userdata;
char *interface_name;
char *member_name;
char *member_signature;
char *member_result;
const char *current;
void *xml_state;
} Context;
enum {
} state = STATE_ANNOTATION;
for (;;) {
int t;
if (t < 0) {
log_error("XML parse error.");
return t;
}
if (t == XML_END) {
log_error("Premature end of XML data.");
return -EBADMSG;
}
switch (state) {
case STATE_ANNOTATION:
if (t == XML_ATTRIBUTE_NAME) {
state = STATE_NAME;
state = STATE_VALUE;
else {
return -EBADMSG;
}
} else if (t == XML_TAG_CLOSE_EMPTY ||
if (flags) {
}
}
return 0;
log_error("Unexpected token in <annotation>. (1)");
return -EINVAL;
}
break;
case STATE_NAME:
if (t == XML_ATTRIBUTE_VALUE) {
} else {
log_error("Unexpected token in <annotation>. (2)");
return -EINVAL;
}
break;
case STATE_VALUE:
if (t == XML_ATTRIBUTE_VALUE) {
} else {
log_error("Unexpected token in <annotation>. (3)");
return -EINVAL;
}
break;
default:
assert_not_reached("Bad state");
}
}
}
enum {
} state = STATE_NODE;
int r;
if (n_depth > NODE_DEPTH_MAX) {
log_error("<node> depth too high.");
return -EINVAL;
}
for (;;) {
int t;
if (t < 0) {
log_error("XML parse error.");
return t;
}
if (t == XML_END) {
log_error("Premature end of XML data.");
return -EBADMSG;
}
switch (state) {
case STATE_NODE:
if (t == XML_ATTRIBUTE_NAME) {
else {
return -EBADMSG;
}
} else if (t == XML_TAG_OPEN) {
if (r < 0)
return r;
} else {
return -EBADMSG;
}
} else if (t == XML_TAG_CLOSE_EMPTY ||
if (r < 0)
return r;
}
return 0;
log_error("Unexpected token in <node>. (1)");
return -EINVAL;
}
break;
case STATE_NODE_NAME:
if (t == XML_ATTRIBUTE_VALUE) {
if (name[0] == '/') {
} else {
else
if (!node_path)
return log_oom();
}
state = STATE_NODE;
} else {
log_error("Unexpected token in <node>. (2)");
return -EINVAL;
}
break;
case STATE_INTERFACE:
if (t == XML_ATTRIBUTE_NAME) {
else {
return -EBADMSG;
}
} else if (t == XML_TAG_OPEN) {
if (r < 0)
return r;
} else {
return -EINVAL;
}
} else if (t == XML_TAG_CLOSE_EMPTY ||
state = STATE_NODE;
log_error("Unexpected token in <interface>. (1)");
return -EINVAL;
}
break;
case STATE_INTERFACE_NAME:
if (t == XML_ATTRIBUTE_VALUE)
else {
log_error("Unexpected token in <interface>. (2)");
return -EINVAL;
}
break;
case STATE_METHOD:
if (t == XML_ATTRIBUTE_NAME) {
else {
return -EBADMSG;
}
} else if (t == XML_TAG_OPEN) {
if (r < 0)
return r;
} else {
return -EINVAL;
}
} else if (t == XML_TAG_CLOSE_EMPTY ||
log_error("Unexpected token in <method> (1).");
return -EINVAL;
}
break;
case STATE_METHOD_NAME:
if (t == XML_ATTRIBUTE_VALUE)
else {
log_error("Unexpected token in <method> (2).");
return -EINVAL;
}
break;
case STATE_METHOD_ARG:
if (t == XML_ATTRIBUTE_NAME) {
else {
return -EBADMSG;
}
} else if (t == XML_TAG_OPEN) {
if (r < 0)
return r;
} else {
return -EINVAL;
}
} else if (t == XML_TAG_CLOSE_EMPTY ||
log_error("Unexpected token in method <arg>. (1)");
return -EINVAL;
}
break;
case STATE_METHOD_ARG_NAME:
if (t == XML_ATTRIBUTE_VALUE)
else {
log_error("Unexpected token in method <arg>. (2)");
return -EINVAL;
}
break;
case STATE_METHOD_ARG_TYPE:
if (t == XML_ATTRIBUTE_VALUE)
else {
log_error("Unexpected token in method <arg>. (3)");
return -EINVAL;
}
break;
if (t == XML_ATTRIBUTE_VALUE)
else {
log_error("Unexpected token in method <arg>. (4)");
return -EINVAL;
}
break;
case STATE_SIGNAL:
if (t == XML_ATTRIBUTE_NAME) {
else {
return -EBADMSG;
}
} else if (t == XML_TAG_OPEN) {
if (r < 0)
return r;
} else {
return -EINVAL;
}
} else if (t == XML_TAG_CLOSE_EMPTY ||
log_error("Unexpected token in <signal>. (1)");
return -EINVAL;
}
break;
case STATE_SIGNAL_NAME:
if (t == XML_ATTRIBUTE_VALUE)
else {
log_error("Unexpected token in <signal>. (2)");
return -EINVAL;
}
break;
case STATE_SIGNAL_ARG:
if (t == XML_ATTRIBUTE_NAME) {
else {
return -EBADMSG;
}
} else if (t == XML_TAG_OPEN) {
if (r < 0)
return r;
} else {
return -EINVAL;
}
} else if (t == XML_TAG_CLOSE_EMPTY ||
log_error("Unexpected token in signal <arg> (1).");
return -EINVAL;
}
break;
case STATE_SIGNAL_ARG_NAME:
if (t == XML_ATTRIBUTE_VALUE)
else {
log_error("Unexpected token in signal <arg> (2).");
return -EINVAL;
}
break;
case STATE_SIGNAL_ARG_TYPE:
if (t == XML_ATTRIBUTE_VALUE)
else {
log_error("Unexpected token in signal <arg> (3).");
return -EINVAL;
}
break;
case STATE_PROPERTY:
if (t == XML_ATTRIBUTE_NAME) {
else {
return -EBADMSG;
}
} else if (t == XML_TAG_OPEN) {
if (r < 0)
return r;
} else {
return -EINVAL;
}
} else if (t == XML_TAG_CLOSE_EMPTY ||
log_error("Unexpected token in <property>. (1)");
return -EINVAL;
}
break;
case STATE_PROPERTY_NAME:
if (t == XML_ATTRIBUTE_VALUE)
else {
log_error("Unexpected token in <property>. (2)");
return -EINVAL;
}
break;
case STATE_PROPERTY_TYPE:
if (t == XML_ATTRIBUTE_VALUE)
else {
log_error("Unexpected token in <property>. (3)");
return -EINVAL;
}
break;
case STATE_PROPERTY_ACCESS:
if (t == XML_ATTRIBUTE_VALUE)
else {
log_error("Unexpected token in <property>. (4)");
return -EINVAL;
}
break;
}
}
}
int parse_xml_introspect(const char *prefix, const char *xml, const XMLIntrospectOps *ops, void *userdata) {
};
int r;
for (;;) {
if (r < 0) {
log_error("XML parse error");
return r;
}
if (r == XML_END)
break;
if (r == XML_TAG_OPEN) {
if (r < 0)
return r;
} else {
return -EBADMSG;
}
log_error("Unexpected token.");
return -EINVAL;
}
}
return 0;
}