42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek Jakub Hrozek <jhrozek@redhat.com>
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina Pavel Březina <pbrezina@redhat.com>
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek Copyright (C) 2014 Red Hat
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek SBUS: Interface introspection
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek This program is free software; you can redistribute it and/or modify
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek it under the terms of the GNU General Public License as published by
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek the Free Software Foundation; either version 3 of the License, or
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek (at your option) any later version.
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek This program is distributed in the hope that it will be useful,
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek but WITHOUT ANY WARRANTY; without even the implied warranty of
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek GNU General Public License for more details.
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek You should have received a copy of the GNU General Public License
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek along with this program. If not, see <http://www.gnu.org/licenses/>.
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n" \
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina " \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina#define FMT_METHOD_NOARG " <method name=\"%s\" />\n"
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina#define FMT_METHOD_ARG " <arg type=\"%s\" name=\"%s\" direction=\"%s\" />\n"
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina#define FMT_SIGNAL_NOARG " <signal name=\"%s\" />\n"
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina#define FMT_SIGNAL_ARG " <arg type=\"%s\" name=\"%s\" />\n"
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina#define FMT_PROPERTY " <property name=\"%s\" type=\"%s\" access=\"%s\" />\n"
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina#define FMT_CHILD_NODE " <node name=\"%s\" />\n"
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina#define WRITE_OR_FAIL(file, ret, label, fmt, ...) do { \
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina if (ret < 0) { \
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina#define METHOD_HAS_ARGS(m) ((m)->in_args != NULL || (m)->out_args != NULL)
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinaiface_Introspect_finish(struct sbus_request *req, const char *arg_data)
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina struct sbus_vtable vtable; /* derive from sbus_vtable */
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina int (*Introspect)(struct sbus_request *req, void *data);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinastatic int sbus_introspect(struct sbus_request *sbus_req, void *pvt);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina static const struct sbus_arg_meta iface_out[] = {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina static const struct sbus_method_meta iface_methods[] = {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina offsetof(struct iface_introspectable, Introspect), NULL},
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina static const struct sbus_interface_meta iface_meta = {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina "org.freedesktop.DBus.Introspectable", /* name */
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(file, ret, done, FMT_SIGNAL_ARG,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(file, ret, done, FMT_METHOD_ARG,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(file, ret, done, FMT_METHOD_ARG,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina#define sbus_introspect_generate_in_args(file, args) \
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina sbus_introspect_generate_args(file, args, SBUS_ARG_IN)
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina#define sbus_introspect_generate_out_args(file, args) \
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina sbus_introspect_generate_args(file, args, SBUS_ARG_OUT)
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina#define sbus_introspect_generate_signal_args(file, args) \
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina sbus_introspect_generate_args(file, args, SBUS_ARG_SIGNAL)
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(file, ret, done, FMT_METHOD_NOARG, method->name);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(file, ret, done, FMT_METHOD, method->name);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = sbus_introspect_generate_in_args(file, method->in_args);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = sbus_introspect_generate_out_args(file, method->out_args);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(file, ret, done, FMT_METHOD_CLOSE);
365fe7479c753f198430812337a7ba8cdb0baf7dLukas Slebodnik WRITE_OR_FAIL(file, ret, done, FMT_SIGNAL_NOARG, a_signal->name);
365fe7479c753f198430812337a7ba8cdb0baf7dLukas Slebodnik WRITE_OR_FAIL(file, ret, done, FMT_SIGNAL, a_signal->name);
365fe7479c753f198430812337a7ba8cdb0baf7dLukas Slebodnik ret = sbus_introspect_generate_signal_args(file, a_signal->args);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(file, ret, done, FMT_SIGNAL_CLOSE);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinasbus_introspect_generate_properties(FILE *file,
365fe7479c753f198430812337a7ba8cdb0baf7dLukas Slebodnik access_mode = prop->flags & SBUS_PROPERTY_WRITABLE
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinasbus_introspect_generate_iface(FILE *file, struct sbus_interface *iface)
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(file, ret, done, FMT_IFACE, meta->name);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = sbus_introspect_generate_methods(file, meta->methods);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = sbus_introspect_generate_signals(file, meta->signals);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = sbus_introspect_generate_properties(file, meta->properties);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(file, ret, done, FMT_IFACE_CLOSE);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březinasbus_introspect_generate_nodes(FILE *file, const char **nodes)
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina WRITE_OR_FAIL(file, ret, done, FMT_CHILD_NODE, nodes[i]);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina const char **nodes,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(memstream, ret, done, FMT_DOCTYPE);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina WRITE_OR_FAIL(memstream, ret, done, FMT_NODE, node);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = sbus_introspect_generate_iface(memstream, item->interface);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina ret = sbus_introspect_generate_nodes(memstream, nodes);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(memstream, ret, done, FMT_NODE_CLOSE);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina introspect = talloc_memdup(mem_ctx, buffer, size + 1);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina DEBUG(SSSDBG_TRACE_ALL, "Introspection: \n%s\n", introspect);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinasbus_introspect(struct sbus_request *sbus_req, void *pvt)
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina conn = talloc_get_type(pvt, struct sbus_connection);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = sbus_opath_hash_lookup_supported(sbus_req, conn->managed_paths,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina return sbus_request_fail_and_finish(sbus_req, error);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina nodes = sbus_nodes_hash_lookup(sbus_req, conn->nodes_fns, sbus_req->path);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina introspect = sbus_introspect_generate(sbus_req, sbus_req->path,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina return sbus_request_fail_and_finish(sbus_req, error);