sssd_dbus_introspect.c revision f7adbb15dbdcb79e291f7cf361a400ce25f7b382
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek/*
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek Authors:
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek Jakub Hrozek <jhrozek@redhat.com>
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina Pavel Březina <pbrezina@redhat.com>
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek Copyright (C) 2014 Red Hat
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek SBUS: Interface introspection
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
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
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
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*/
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
1ecb16023779f912ba1c4e9e418acb59296ce8bcLukas Slebodnik#include "config.h"
1ecb16023779f912ba1c4e9e418acb59296ce8bcLukas Slebodnik
1ecb16023779f912ba1c4e9e418acb59296ce8bcLukas Slebodnik#include <stdio.h>
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek#include "util/util.h"
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek#include "sbus/sssd_dbus.h"
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek#include "sbus/sssd_dbus_meta.h"
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina#include "sbus/sssd_dbus_private.h"
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina#define FMT_DOCTYPE \
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
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina#define FMT_NODE "<node name=\"%s\">\n"
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina#define FMT_IFACE " <interface name=\"%s\">\n"
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina#define FMT_METHOD " <method name=\"%s\">\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_METHOD_CLOSE " </method>\n"
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina#define FMT_SIGNAL " <signal name=\"%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_SIGNAL_CLOSE " </signal>\n"
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina#define FMT_PROPERTY " <property name=\"%s\" type=\"%s\" access=\"%s\" />\n"
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina#define FMT_IFACE_CLOSE " </interface>\n"
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina#define FMT_CHILD_NODE " <node name=\"%s\" />\n"
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina#define FMT_NODE_CLOSE "</node>\n"
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina#define WRITE_OR_FAIL(file, ret, label, fmt, ...) do { \
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = fprintf(file, fmt, ##__VA_ARGS__); \
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina if (ret < 0) { \
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = EIO; \
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina goto label; \
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina } \
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina} while (0)
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina#define METHOD_HAS_ARGS(m) ((m)->in_args != NULL || (m)->out_args != NULL)
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina#define SIGNAL_HAS_ARGS(s) ((s)->args != NULL)
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinaenum sbus_arg_type {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina SBUS_ARG_IN,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina SBUS_ARG_OUT,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina SBUS_ARG_SIGNAL
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek};
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinastatic int
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinaiface_Introspect_finish(struct sbus_request *req, const char *arg_data)
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek{
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina return sbus_request_return_and_finish(req,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina DBUS_TYPE_STRING, &arg_data,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina DBUS_TYPE_INVALID);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek}
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinastruct iface_introspectable {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina struct sbus_vtable vtable; /* derive from sbus_vtable */
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina int (*Introspect)(struct sbus_request *req, void *data);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina};
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinastatic int sbus_introspect(struct sbus_request *sbus_req, void *pvt);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinastruct sbus_vtable *
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinasbus_introspect_vtable(void)
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek{
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina static const struct sbus_arg_meta iface_out[] = {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina {"data", "s"},
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina {NULL, NULL}
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina };
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina static const struct sbus_method_meta iface_methods[] = {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina {"Introspect", NULL, iface_out,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina offsetof(struct iface_introspectable, Introspect), NULL},
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina {NULL, }
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina };
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina static const struct sbus_interface_meta iface_meta = {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina "org.freedesktop.DBus.Introspectable", /* name */
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina iface_methods,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina NULL, /* no signals */
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina NULL, /* no properties */
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina NULL, /* no GetAll invoker */
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina };
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina static struct iface_introspectable iface = {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina { &iface_meta, 0 },
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina .Introspect = sbus_introspect
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina };
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina return &iface.vtable;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek}
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinastatic int
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinasbus_introspect_generate_args(FILE *file,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina const struct sbus_arg_meta *args,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina enum sbus_arg_type type)
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek{
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina const struct sbus_arg_meta *arg;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina int ret;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek int i;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina if (args == NULL) {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina return EOK;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina for (i = 0; args[i].name != NULL; i++) {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina arg = &args[i];
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina switch (type) {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina case SBUS_ARG_SIGNAL:
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(file, ret, done, FMT_SIGNAL_ARG,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina arg->type, arg->name);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina break;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina case SBUS_ARG_IN:
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(file, ret, done, FMT_METHOD_ARG,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina arg->type, arg->name, "in");
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina break;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina case SBUS_ARG_OUT:
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(file, ret, done, FMT_METHOD_ARG,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina arg->type, arg->name, "out");
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina break;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = EOK;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinadone:
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina return ret;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek}
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
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
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
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
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinastatic int
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinasbus_introspect_generate_methods(FILE *file,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina const struct sbus_method_meta *methods)
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek{
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina const struct sbus_method_meta *method;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina int ret;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek int i;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina if (methods == NULL) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek return EOK;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina for (i = 0; methods[i].name != NULL; i++) {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina method = &methods[i];
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina if (!METHOD_HAS_ARGS(method)) {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(file, ret, done, FMT_METHOD_NOARG, method->name);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek continue;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(file, ret, done, FMT_METHOD, method->name);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = sbus_introspect_generate_in_args(file, method->in_args);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina if (ret != EOK) {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina goto done;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = sbus_introspect_generate_out_args(file, method->out_args);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina if (ret != EOK) {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina goto done;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(file, ret, done, FMT_METHOD_CLOSE);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = EOK;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinadone:
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina return ret;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek}
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinastatic int
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinasbus_introspect_generate_signals(FILE *file,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina const struct sbus_signal_meta *signals)
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek{
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina const struct sbus_signal_meta *signal;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina int ret;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek int i;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina if (signals == NULL) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek return EOK;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina for (i = 0; signals[i].name != NULL; i++) {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina signal = &signals[i];
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina if (!SIGNAL_HAS_ARGS(signal)) {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(file, ret, done, FMT_SIGNAL_NOARG, signal->name);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek continue;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(file, ret, done, FMT_SIGNAL, signal->name);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = sbus_introspect_generate_signal_args(file, signal->args);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina if (ret != EOK) {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina goto done;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(file, ret, done, FMT_SIGNAL_CLOSE);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = EOK;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinadone:
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina return ret;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek}
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinastatic int
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinasbus_introspect_generate_properties(FILE *file,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina const struct sbus_property_meta *props)
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek{
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina const struct sbus_property_meta *prop;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina const char *access;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina int ret;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek int i;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina if (props == NULL) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek return EOK;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina for (i = 0; props[i].name != NULL; i++) {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina prop = &props[i];
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina access = prop->flags & SBUS_PROPERTY_WRITABLE ? "readwrite" : "read";
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(file, ret, done, FMT_PROPERTY,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina prop->name, prop->type, access);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina }
0d8fbc2cb822b4fef90588ca368ceb883b8379f2Jakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = EOK;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinadone:
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina return ret;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek}
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinastatic int
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinasbus_introspect_generate_iface(FILE *file, struct sbus_interface *iface)
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek{
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina const struct sbus_interface_meta *meta;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina int ret;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina meta = iface->vtable->meta;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(file, ret, done, FMT_IFACE, meta->name);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = sbus_introspect_generate_methods(file, meta->methods);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret != EOK) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek goto done;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = sbus_introspect_generate_signals(file, meta->signals);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret != EOK) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek goto done;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = sbus_introspect_generate_properties(file, meta->properties);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret != EOK) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek goto done;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(file, ret, done, FMT_IFACE_CLOSE);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = EOK;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinadone:
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina return ret;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina}
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březinastatic int
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březinasbus_introspect_generate_nodes(FILE *file, const char **nodes)
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina{
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina int ret;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina int i;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina if (nodes == NULL) {
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina return EOK;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina }
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina for (i = 0; nodes[i] != NULL; i++) {
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina WRITE_OR_FAIL(file, ret, done, FMT_CHILD_NODE, nodes[i]);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina }
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina ret = EOK;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březinadone:
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina return ret;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina}
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinastatic char *
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březinasbus_introspect_generate(TALLOC_CTX *mem_ctx,
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina const char *node,
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina const char **nodes,
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina struct sbus_interface_list *list)
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina{
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina struct sbus_interface_list *item;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina char *introspect = NULL;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina FILE *memstream;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina char *buffer;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina size_t size;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina int ret;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina memstream = open_memstream(&buffer, &size);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina if (memstream == NULL) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek goto done;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
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
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina DLIST_FOR_EACH(item, list) {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = sbus_introspect_generate_iface(memstream, item->interface);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina if (ret != EOK) {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina goto done;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina ret = sbus_introspect_generate_nodes(memstream, nodes);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina if (ret != EOK) {
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina goto done;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina }
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina WRITE_OR_FAIL(memstream, ret, done, FMT_NODE_CLOSE);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina fflush(memstream);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina introspect = talloc_memdup(mem_ctx, buffer, size + 1);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina DEBUG(SSSDBG_TRACE_ALL, "Introspection: \n%s\n", introspect);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozekdone:
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina if (memstream != NULL) {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina fclose(memstream);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina free(buffer);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina }
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina return introspect;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek}
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinastatic int
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinasbus_introspect(struct sbus_request *sbus_req, void *pvt)
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek{
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina DBusError *error;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina struct sbus_interface_list *list;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina struct sbus_connection *conn;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina const char **nodes;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina char *introspect;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina errno_t ret;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina conn = talloc_get_type(pvt, struct sbus_connection);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = sbus_opath_hash_lookup_supported(sbus_req, conn->managed_paths,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina sbus_req->path, &list);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina if (ret != EOK) {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina "%s", sss_strerror(ret));
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina return sbus_request_fail_and_finish(sbus_req, error);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina nodes = sbus_nodes_hash_lookup(sbus_req, conn->nodes_fns, sbus_req->path);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina introspect = sbus_introspect_generate(sbus_req, sbus_req->path,
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina nodes, list);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina if (introspect == NULL) {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = ENOMEM;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina goto done;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = EOK;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březinadone:
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina if (ret != EOK) {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED,
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina "%s", sss_strerror(ret));
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina return sbus_request_fail_and_finish(sbus_req, error);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina return iface_Introspect_finish(sbus_req, introspect);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek}