a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering This file is part of systemd.
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering Copyright 2014 Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering systemd is free software; you can redistribute it and/or modify it
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering under the terms of the GNU Lesser General Public License as published by
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering (at your option) any later version.
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering systemd is distributed in the hope that it will be useful, but
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering Lesser General Public License for more details.
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering You should have received a copy of the GNU Lesser General Public License
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poetteringstatic void context_reset_member(Context *c) {
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering c->member_name = c->member_signature = c->member_result = NULL;
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poetteringstatic void context_reset_interface(Context *c) {
a1e58e8ee1c84b633d6d6d651d5328d4dd4eba5bLennart Poettering c->interface_name = mfree(c->interface_name);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poetteringstatic int parse_xml_annotation(Context *context, uint64_t *flags) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering _cleanup_free_ char *field = NULL, *value = NULL;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering t = xml_tokenize(&context->current, &name, &context->xml_state, NULL);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected <annotation> attribute %s.", name);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering } else if (t == XML_TAG_CLOSE_EMPTY ||
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering (t == XML_TAG_CLOSE && streq_ptr(name, "annotation"))) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (streq_ptr(field, "org.freedesktop.DBus.Deprecated")) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering } else if (streq_ptr(field, "org.freedesktop.DBus.Method.NoReply")) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering } else if (streq_ptr(field, "org.freedesktop.DBus.Property.EmitsChangedSignal")) {
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering *flags = (*flags & ~(SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION|SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE)) | SD_BUS_VTABLE_PROPERTY_CONST;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering else if (streq_ptr(value, "invalidates"))
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering *flags = (*flags & ~(SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE|SD_BUS_VTABLE_PROPERTY_CONST)) | SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION;
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering *flags = *flags & ~(SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE|SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected token in <annotation>. (1)");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected token in <annotation>. (2)");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected token in <annotation>. (3)");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poetteringstatic int parse_xml_node(Context *context, const char *prefix, unsigned n_depth) {
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering _cleanup_free_ char *node_path = NULL, *argument_type = NULL, *argument_direction = NULL;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering t = xml_tokenize(&context->current, &name, &context->xml_state, NULL);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected <node> attribute %s.", name);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering } else if (t == XML_TAG_OPEN) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = parse_xml_node(context, np, n_depth+1);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected <node> tag %s.", name);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering } else if (t == XML_TAG_CLOSE_EMPTY ||
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering (t == XML_TAG_CLOSE && streq_ptr(name, "node"))) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = context->ops->on_path(node_path ? node_path : np, context->userdata);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected token in <node>. (1)");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering node_path = strjoin(prefix, "/", name, NULL);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected token in <node>. (2)");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected <interface> attribute %s.", name);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering } else if (t == XML_TAG_OPEN) {
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering context->member_flags |= SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE;
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering } else if (streq_ptr(name, "annotation")) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = parse_xml_annotation(context, &context->interface_flags);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected <interface> tag %s.", name);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering } else if (t == XML_TAG_CLOSE_EMPTY ||
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering (t == XML_TAG_CLOSE && streq_ptr(name, "interface"))) {
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering r = context->ops->on_interface(context->interface_name, context->interface_flags, context->userdata);
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected token in <interface>. (1)");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected token in <interface>. (2)");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected <method> attribute %s", name);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering } else if (t == XML_TAG_OPEN) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering else if (streq_ptr(name, "annotation")) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = parse_xml_annotation(context, &context->member_flags);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected <method> tag %s.", name);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering } else if (t == XML_TAG_CLOSE_EMPTY ||
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering (t == XML_TAG_CLOSE && streq_ptr(name, "method"))) {
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering r = context->ops->on_method(context->interface_name, context->member_name, context->member_signature, context->member_result, context->member_flags, context->userdata);
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected token in <method> (1).");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected token in <method> (2).");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected method <arg> attribute %s.", name);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering } else if (t == XML_TAG_OPEN) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected method <arg> tag %s.", name);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering } else if (t == XML_TAG_CLOSE_EMPTY ||
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering (t == XML_TAG_CLOSE && streq_ptr(name, "arg"))) {
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering if (!argument_direction || streq(argument_direction, "in")) {
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering if (!strextend(&context->member_signature, argument_type, NULL))
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering } else if (streq(argument_direction, "out")) {
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering if (!strextend(&context->member_result, argument_type, NULL))
97b11eedff9d2e17101ad453caf9e48b73246719David Herrmann argument_direction = mfree(argument_direction);
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected token in method <arg>. (1)");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected token in method <arg>. (2)");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected token in method <arg>. (3)");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected token in method <arg>. (4)");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected <signal> attribute %s.", name);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering } else if (t == XML_TAG_OPEN) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering else if (streq_ptr(name, "annotation")) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = parse_xml_annotation(context, &context->member_flags);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected <signal> tag %s.", name);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering } else if (t == XML_TAG_CLOSE_EMPTY ||
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering (t == XML_TAG_CLOSE && streq_ptr(name, "signal"))) {
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering r = context->ops->on_signal(context->interface_name, context->member_name, context->member_signature, context->member_flags, context->userdata);
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected token in <signal>. (1)");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected token in <signal>. (2)");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected signal <arg> attribute %s.", name);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering } else if (t == XML_TAG_OPEN) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected signal <arg> tag %s.", name);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering } else if (t == XML_TAG_CLOSE_EMPTY ||
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering (t == XML_TAG_CLOSE && streq_ptr(name, "arg"))) {
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering if (!strextend(&context->member_signature, argument_type, NULL))
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected token in signal <arg> (1).");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected token in signal <arg> (2).");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected token in signal <arg> (3).");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected <property> attribute %s.", name);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering } else if (t == XML_TAG_OPEN) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = parse_xml_annotation(context, &context->member_flags);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected <property> tag %s.", name);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering } else if (t == XML_TAG_CLOSE_EMPTY ||
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering (t == XML_TAG_CLOSE && streq_ptr(name, "property"))) {
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering r = context->ops->on_property(context->interface_name, context->member_name, context->member_signature, context->member_writable, context->member_flags, context->userdata);
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected token in <property>. (1)");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected token in <property>. (2)");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected token in <property>. (3)");
0171da06ef8bb19c175c5aa8aff8cf95f3de7dc1Lennart Poettering if (streq(name, "readwrite") || streq(name, "write"))
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected token in <property>. (4)");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poetteringint parse_xml_introspect(const char *prefix, const char *xml, const XMLIntrospectOps *ops, void *userdata) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = xml_tokenize(&context.current, &name, &context.xml_state, NULL);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Unexpected tag '%s' in introspection data.", name);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering } else if (r != XML_TEXT || !in_charset(name, WHITESPACE)) {