sssd_dbus_introspect.c revision 0d8fbc2cb822b4fef90588ca368ceb883b8379f2
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek/*
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek Authors:
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek Jakub Hrozek <jhrozek@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
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek#include <sys/time.h>
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek#include <dbus/dbus.h>
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek#include "util/util.h"
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek#include "sbus/sssd_dbus.h"
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek#include "sbus/sssd_dbus_private.h"
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek#include "sbus/sssd_dbus_meta.h"
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
7a9a6ee1b5f5479c3a6958401f9b34c571c3b6bfJakub Hrozekstatic const struct sbus_arg_meta introspect_method_arg_out[] = {
7a9a6ee1b5f5479c3a6958401f9b34c571c3b6bfJakub Hrozek { "data", "s" },
7a9a6ee1b5f5479c3a6958401f9b34c571c3b6bfJakub Hrozek { NULL, }
7a9a6ee1b5f5479c3a6958401f9b34c571c3b6bfJakub Hrozek};
7a9a6ee1b5f5479c3a6958401f9b34c571c3b6bfJakub Hrozek
7a9a6ee1b5f5479c3a6958401f9b34c571c3b6bfJakub Hrozekconst struct sbus_method_meta introspect_method =
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter { DBUS_INTROSPECT_METHOD, NULL, introspect_method_arg_out, 0, NULL };
7a9a6ee1b5f5479c3a6958401f9b34c571c3b6bfJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek#define SSS_INTROSPECT_DOCTYPE \
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n" \
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek#define SSS_INTROSPECT_INTERFACE_INTROSPECTABLE \
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek " <interface name=\"org.freedesktop.DBus.Introspectable\">\n" \
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek " <method name=\"Introspect\">\n" \
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek " <arg name=\"data\" type=\"s\" direction=\"out\"/>\n" \
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek " </method>\n" \
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek " </interface>\n"
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
0d8fbc2cb822b4fef90588ca368ceb883b8379f2Jakub Hrozek#define SSS_INTROSPECT_INTERFACE_PROPERTIES \
0d8fbc2cb822b4fef90588ca368ceb883b8379f2Jakub Hrozek " <interface name=\"org.freedesktop.DBus.Properties\">\n" \
0d8fbc2cb822b4fef90588ca368ceb883b8379f2Jakub Hrozek " <method name=\"Get\">\n" \
0d8fbc2cb822b4fef90588ca368ceb883b8379f2Jakub Hrozek " <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n" \
0d8fbc2cb822b4fef90588ca368ceb883b8379f2Jakub Hrozek " <arg name=\"property\" direction=\"in\" type=\"s\"/>\n" \
0d8fbc2cb822b4fef90588ca368ceb883b8379f2Jakub Hrozek " <arg name=\"value\" direction=\"out\" type=\"v\"/>\n" \
0d8fbc2cb822b4fef90588ca368ceb883b8379f2Jakub Hrozek " </method>\n" \
0d8fbc2cb822b4fef90588ca368ceb883b8379f2Jakub Hrozek " </interface>\n"
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozekstruct introspect_ctx {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek FILE *f;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek char *buf;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek size_t size;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek const struct sbus_interface_meta *iface;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek};
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozekstatic int introspect_ctx_destructor(struct introspect_ctx *ictx)
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek{
09f6afae29a2e80655496f7f71a72e50424e6f1cJakub Hrozek if (ictx->f) {
09f6afae29a2e80655496f7f71a72e50424e6f1cJakub Hrozek fclose(ictx->f);
09f6afae29a2e80655496f7f71a72e50424e6f1cJakub Hrozek }
09f6afae29a2e80655496f7f71a72e50424e6f1cJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek free(ictx->buf);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ictx->buf = NULL;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek return 0;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek}
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozekstatic errno_t introspect_begin(struct introspect_ctx *ictx)
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek{
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek errno_t ret;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ictx->f = open_memstream(&ictx->buf, &ictx->size);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ictx->f == NULL) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek return ENOMEM;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = fputs(SSS_INTROSPECT_DOCTYPE, ictx->f);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret < 0) return EIO;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = fputs("<node>\n", ictx->f);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret < 0) return EIO;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = fprintf(ictx->f, " <interface name=\"%s\">\n", ictx->iface->name);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret <= 0) return EIO;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek return EOK;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek}
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozekstatic errno_t introspect_add_arg(struct introspect_ctx *ictx,
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek const struct sbus_arg_meta *a,
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek const char *direction)
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek{
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek errno_t ret;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = fprintf(ictx->f,
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek " <arg type=\"%s\" name=\"%s\"",
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek a->type, a->name);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret <= 0) return EIO;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (direction) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = fprintf(ictx->f, " direction=\"%s\"", direction);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret <= 0) return EIO;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = fprintf(ictx->f, "/>\n");
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret <= 0) return EIO;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek return EOK;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek}
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek#define introspect_add_in_arg(i, a) introspect_add_arg(i, a, "in");
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek#define introspect_add_out_arg(i, a) introspect_add_arg(i, a, "out");
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek#define introspect_add_sig_arg(i, a) introspect_add_arg(i, a, NULL);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozekstatic errno_t introspect_add_meth(struct introspect_ctx *ictx,
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek const struct sbus_method_meta *m)
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek{
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek errno_t ret;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek int i;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = fprintf(ictx->f, " <method name=\"%s\">\n", m->name);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret <= 0) return EIO;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (m->in_args != NULL) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek for (i = 0; m->in_args[i].name != NULL; i++) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = introspect_add_in_arg(ictx, &m->in_args[i]);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret != EOK) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek continue;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (m->out_args != NULL) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek for (i = 0; m->out_args[i].name != NULL; i++) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = introspect_add_out_arg(ictx, &m->out_args[i]);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret != EOK) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek continue;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = fputs(" </method>\n", ictx->f);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret < 0) return EIO;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek return EOK;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek}
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozekstatic errno_t introspect_add_methods(struct introspect_ctx *ictx)
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek{
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek errno_t ret;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek int i;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ictx->iface->methods == NULL) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek /* An interface with no methods */
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek return EOK;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek for (i = 0; ictx->iface->methods[i].name != NULL; i++) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = introspect_add_meth(ictx, &ictx->iface->methods[i]);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret != EOK) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek continue;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek return EOK;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek}
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozekstatic errno_t introspect_add_sig(struct introspect_ctx *ictx,
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek const struct sbus_signal_meta *s)
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek{
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek errno_t ret;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek int i;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = fprintf(ictx->f, " <signal name=\"%s\">\n", s->name);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret <= 0) return EIO;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (s->args != NULL) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek for (i = 0; s->args[i].name != NULL; i++) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = introspect_add_sig_arg(ictx, &s->args[i]);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret != EOK) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek continue;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = fputs(" </signal>\n", ictx->f);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret < 0) return EIO;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek return EOK;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek}
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozekstatic errno_t introspect_add_signals(struct introspect_ctx *ictx)
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek{
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek errno_t ret;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek int i;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ictx->iface->signals == NULL) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek /* An interface with no signals */
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek return EOK;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek for (i = 0; ictx->iface->signals[i].name != NULL; i++) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = introspect_add_sig(ictx, &ictx->iface->signals[i]);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret != EOK) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek continue;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek return EOK;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek}
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozekstatic errno_t introspect_add_prop(struct introspect_ctx *ictx,
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek const struct sbus_property_meta *p)
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek{
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek errno_t ret;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = fprintf(ictx->f, " <property name=\"%s\" type=\"%s\" access=\"%s\"/>\n",
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek p->name, p->type,
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek p->flags & SBUS_PROPERTY_WRITABLE ? "readwrite" : "read");
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret <= 0) return EIO;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek return EOK;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek}
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozekstatic errno_t introspect_add_properties(struct introspect_ctx *ictx)
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek{
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek errno_t ret;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek int i;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ictx->iface->properties == NULL) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek /* An interface with no properties */
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek return EOK;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek for (i = 0; ictx->iface->properties[i].name != NULL; i++) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = introspect_add_prop(ictx, &ictx->iface->properties[i]);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret != EOK) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek continue;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek return EOK;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek}
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozekstatic errno_t introspect_finish(struct introspect_ctx *ictx)
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek{
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek errno_t ret;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = fputs(" </interface>\n", ictx->f);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret < 0) return EIO;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = fputs(SSS_INTROSPECT_INTERFACE_INTROSPECTABLE, ictx->f);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret < 0) return EIO;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
0d8fbc2cb822b4fef90588ca368ceb883b8379f2Jakub Hrozek ret = fputs(SSS_INTROSPECT_INTERFACE_PROPERTIES, ictx->f);
0d8fbc2cb822b4fef90588ca368ceb883b8379f2Jakub Hrozek if (ret < 0) return EIO;
0d8fbc2cb822b4fef90588ca368ceb883b8379f2Jakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = fputs("</node>\n", ictx->f);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret < 0) return EIO;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek fflush(ictx->f);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek return EOK;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek}
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozekstatic char *sbus_introspect_xml(TALLOC_CTX *mem_ctx,
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek const struct sbus_interface_meta *iface)
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek{
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek struct introspect_ctx *ictx;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek char *buf_out = NULL;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek errno_t ret;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ictx = talloc_zero(mem_ctx, struct introspect_ctx);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ictx == NULL) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek return NULL;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ictx->iface = iface;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek talloc_set_destructor(ictx, introspect_ctx_destructor);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = introspect_begin(ictx);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret != EOK) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek DEBUG(SSSDBG_OP_FAILURE, "introspect_begin failed: %d\n", ret);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek goto done;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = introspect_add_methods(ictx);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret != EOK) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek DEBUG(SSSDBG_OP_FAILURE, "introspect_add_methods failed: %d\n", ret);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek goto done;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = introspect_add_signals(ictx);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret != EOK) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek DEBUG(SSSDBG_OP_FAILURE, "introspect_add_signals failed: %d\n", ret);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek goto done;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = introspect_add_properties(ictx);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret != EOK) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek DEBUG(SSSDBG_OP_FAILURE,
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek "introspect_add_properties failed: %d\n", ret);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek goto done;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ret = introspect_finish(ictx);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ret != EOK) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek DEBUG(SSSDBG_OP_FAILURE, "introspect_finish failed: %d\n", ret);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek goto done;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek buf_out = talloc_memdup(mem_ctx, ictx->buf, ictx->size + 1);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek DEBUG(SSSDBG_TRACE_LIBS, "Introspection: \n%s\n", buf_out);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozekdone:
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek talloc_free(ictx);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek return buf_out;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek}
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozekint sbus_introspect(struct sbus_request *dbus_req, void *pvt)
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek{
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek char *xml;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek DBusError dberr;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek const struct sbus_interface_meta *iface;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek struct sbus_introspect_ctx *ictx;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek ictx = talloc_get_type(pvt, struct sbus_introspect_ctx);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (ictx == NULL) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n");
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek iface = ictx->iface;
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek xml = sbus_introspect_xml(dbus_req, iface);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek if (xml == NULL) {
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek dbus_error_init(&dberr);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek dbus_set_error_const(&dberr,
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek DBUS_ERROR_NO_MEMORY,
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek "Failed to generate introspection data\n");
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek return sbus_request_fail_and_finish(dbus_req, &dberr);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek }
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek return sbus_request_return_and_finish(dbus_req,
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek DBUS_TYPE_STRING, &xml,
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek DBUS_TYPE_INVALID);
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek
42c28b9424b6ef8a0021b124773e171dd5defaddJakub Hrozek}