Hi, I'm sending updated patch with the changes from previous mail. For full
history you can look into dbus_new branch in fedorahosted git.
Radek Novacek
---
src/CMakeLists.txt | 23 ++
src/cmake/modules/DBusMacros.cmake | 31 ++
src/common/mh_dbus_common.c | 331 +++++++++++++++++++++
src/common/mh_dbus_common.h | 128 +++++++++
src/common/mh_gobject_class.h | 51 ++++
src/dbus-to-c.xsl | 101 +++++++
src/dbus-to-polkit.xsl | 44 +++
src/host/CMakeLists.txt | 40 +++
src/host/matahari-host-dbus.c | 243 ++++++++++++++++
src/host/org.matahariproject.Host.conf | 18 ++
src/host/org.matahariproject.Host.policy | 153 ++++++++++
src/host/org.matahariproject.Host.service | 4 +
src/net/CMakeLists.txt | 40 +++
src/net/matahari-network-dbus.c | 220 ++++++++++++++
src/net/org.matahariproject.Network.conf | 25 ++
src/net/org.matahariproject.Network.policy | 55 ++++
src/net/org.matahariproject.Network.service | 4 +
src/schema-to-dbus.xsl | 210 ++++++++++++++
src/service/CMakeLists.txt | 40 +++
src/service/matahari-services-dbus.c | 256 +++++++++++++++++
src/service/org.matahariproject.Services.conf | 25 ++
src/service/org.matahariproject.Services.policy | 76 +++++
src/service/org.matahariproject.Services.service | 4 +
23 files changed, 2122 insertions(+), 0 deletions(-)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 5749656..7bb409d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -20,10 +20,14 @@ set(MHOST_VERSION 0.0.1)
set(MSRV_VERSION 0.0.1)
set(MNET_VERSION 0.0.1)
+option(WITH-QMF "Build the QMF daemon" ON)
+option(WITH-DBUS "Build the DBus daemon" ON)
+
include(FindPkgConfig)
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
include_directories("${CMAKE_CURRENT_SOURCE_DIR}")
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include")
+include_directories("${CMAKE_CURRENT_SOURCE_DIR}/common")
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules
${CMAKE_MODULE_PATH} )
@@ -104,6 +108,8 @@ configure_file
(${CMAKE_CURRENT_SOURCE_DIR}/include/matahari.h.in ${CMAKE_CURREN
## Modules
pkg_check_modules(glib REQUIRED glib-2.0)
pkg_check_modules(pcre REQUIRED libpcre)
+pkg_check_modules(dbus-glib REQUIRED dbus-glib-1)
+pkg_check_modules(polkit REQUIRED polkit-gobject-1)
if(NOT PKG_CONFIG_FOUND)
message("pkg-config not found")
@@ -138,6 +144,23 @@ else(glib_FOUND)
message(FATAL_ERROR "Glib2 header/library not found.")
endif(glib_FOUND)
+## dbus
+
+# Create src/dbus directory and generate DBus XML definition files into it
+execute_process(COMMAND mkdir -p src/dbus)
+find_file(XSLTPROC xsltproc)
+execute_process(
+ COMMAND ${XSLTPROC} ${CMAKE_CURRENT_SOURCE_DIR}/schema-to-dbus.xsl
${CMAKE_CURRENT_SOURCE_DIR}/schema.xml
+ WORKING_DIRECTORY src/dbus
+)
+
+
+### DBus
+
+add_subdirectory(host)
+add_subdirectory(service)
+add_subdirectory(net)
+
## qpid
find_package(QPID REQUIRED)
diff --git a/src/cmake/modules/DBusMacros.cmake
b/src/cmake/modules/DBusMacros.cmake
new file mode 100644
index 0000000..b8e7a28
--- /dev/null
+++ b/src/cmake/modules/DBusMacros.cmake
@@ -0,0 +1,31 @@
+# Generator for files specific to DBus interface
+
+# This macro takes name of the API and then creates two files
+# matahari-${API}-dbus-glue.h and matahari-${API}-dbus-properties.h
+# First one contains gobject definition generated by dbus-binding-tool
+# Second one is definition of properties of the object
+
+macro(generate_dbus_headers API)
+ find_file(XSLTPROC xsltproc)
+ find_file(BIND_TOOL dbus-binding-tool)
+
+ # Lowercase
+ string(TOLOWER ${API} lAPI)
+
+ # Convert dbus interface to glue and properties files
+ add_custom_command(
+ OUTPUT matahari-${lAPI}-dbus-glue.h
+ COMMAND ${BIND_TOOL} --prefix=matahari --mode=glib-server
+ --output=matahari-${lAPI}-dbus-glue.h
+ ${CMAKE_BINARY_DIR}/src/dbus/org.matahariproject.${API}.xml
+ COMMENT "Generating matahari-${lAPI}-dbus-glue.h"
+ )
+
+ add_custom_command(
+ OUTPUT matahari-${lAPI}-dbus-properties.h
+ COMMAND ${XSLTPROC} --output matahari-${lAPI}-dbus-properties.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/../dbus-to-c.xsl
+ ${CMAKE_BINARY_DIR}/src/dbus/org.matahariproject.${API}.xml
+ COMMENT "Generating matahari-${lAPI}-dbus-properties.h"
+ )
+endmacro(generate_dbus_headers)
diff --git a/src/common/mh_dbus_common.c b/src/common/mh_dbus_common.c
new file mode 100644
index 0000000..b516729
--- /dev/null
+++ b/src/common/mh_dbus_common.c
@@ -0,0 +1,331 @@
+/*
+ * mh_dbus_common.c
+ *
+ * Copyright (C) 2011 Red Hat, Inc.
+ * Written by Radek Novacek <rnovacek(a)redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
USA.
+ *
+ */
+
+#include "mh_dbus_common.h"
+#include "matahari/logging.h"
+#include <glib/gi18n.h>
+
+#include <polkit/polkit.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <dbus/dbus-glib-bindings.h>
+
+/* Generate the GObject boilerplate */
+G_DEFINE_TYPE(Matahari, matahari, G_TYPE_OBJECT)
+
+const DBusGObjectInfo dbus_glib_matahari_object_info;
+
+GQuark
+matahari_error_quark (void)
+{
+ return g_quark_from_static_string ("matahari-error-quark");
+}
+
+
+gboolean
+check_authorization(const gchar *action, GError** error,
DBusGMethodInvocation *context)
+{
+ GError *err;
+ PolkitAuthorizationResult *result;
+ PolkitSubject *subject;
+ PolkitAuthority *authority;
+ gboolean res;
+
+ if (context == NULL)
+ {
+ g_printerr("Context is not set!\n");
+ return FALSE;
+ }
+ err = NULL;
+ subject = polkit_system_bus_name_new(dbus_g_method_get_sender(context));
+ authority = polkit_authority_get_sync(NULL, &err);
+ if (err != NULL)
+ {
+ g_printerr("Error in obtaining authority: %s", err-
message);
+ g_propagate_error(error, err);
+ g_error_free(err);
+ return FALSE;
+ }
+
+ result = polkit_authority_check_authorization_sync(authority, subject,
action, NULL, POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, NULL,
&err);
+ if (err != NULL)
+ {
+ g_printerr("Error in checking authorization: %s", err-
message);
+ g_propagate_error(error, err);
+ g_error_free(err);
+ return FALSE;
+ }
+ res = polkit_authorization_result_get_is_authorized(result);
+ g_object_unref(subject);
+ g_object_unref(result);
+ g_object_unref(authority);
+ if (!res)
+ {
+ g_set_error(error, MATAHARI_ERROR, MATAHARI_AUTHENTICATION_ERROR, "You
are not authorized for specified action");
+ g_printerr("Caller is not authorized for action %s\n", action);
+ }
+ return res;
+}
+
+gboolean
+get_paramspec_from_property(Property prop, GParamSpec** pspec)
+{
+ GType value_type;
+ switch (prop.type)
+ {
+ case 's':
+ *pspec = g_param_spec_string(prop.name,
+ prop.nick,
+ prop.desc,
+ NULL,
+ prop.flags);
+ break;
+ case 'b':
+ *pspec = g_param_spec_boolean(prop.name,
+ prop.nick,
+ prop.desc,
+ FALSE,
+ prop.flags);
+ break;
+ case 'n':
+ case 'i':
+ *pspec = g_param_spec_int(prop.name,
+ prop.nick,
+ prop.desc,
+ G_MININT, G_MAXINT, 0,
+ prop.flags);
+ break;
+ case 'x':
+ *pspec = g_param_spec_int64(prop.name,
+ prop.nick,
+ prop.desc,
+ G_MININT64, G_MAXINT64, 0,
+ prop.flags);
+
+ break;
+ case 'y':
+ case 'q':
+ case 'u':
+ *pspec = g_param_spec_uint(prop.name,
+ prop.nick,
+ prop.desc,
+ 0, G_MAXUINT, 0,
+ prop.flags);
+ break;
+ case 't':
+ *pspec = g_param_spec_uint64(prop.name,
+ prop.nick,
+ prop.desc,
+ 0, G_MAXUINT64, 0,
+ prop.flags);
+
+ break;
+ case 'd':
+ *pspec = g_param_spec_double(prop.name,
+ prop.nick,
+ prop.desc,
+ -G_MAXDOUBLE, G_MAXDOUBLE, 0,
+ prop.flags);
+ break;
+ case 'e':
+ // Type is map - key is string, type of value must be added
manually!
+ value_type = matahari_dict_type(prop.prop);
+ *pspec = g_param_spec_boxed(prop.name,
+ prop.nick,
+ prop.desc,
+ dbus_g_type_get_map("GHashTable",
G_TYPE_STRING, value_type),
+ prop.flags);
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+
+}
+
+int
+run_dbus_server(char *bus_name, char *object_path)
+{
+ GMainLoop* loop = NULL;
+ DBusGConnection *connection = NULL;
+ GError *error = NULL;
+ GObject *obj = NULL;
+ DBusGProxy *driver_proxy = NULL;
+ guint32 request_name_ret;
+
+ mh_log_init(bus_name, LOG_DEBUG, FALSE);
+
+ loop = g_main_loop_new(NULL, FALSE);
+
+ /* Obtain a connection to the system bus */
+ connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
+ if (!connection)
+ {
+ g_printerr(_("Failed to open connection to bus: %s\n"), error-
message);
+ g_error_free(error);
+ return 1;
+ }
+
+ obj = g_object_new(MATAHARI_TYPE, NULL);
+ dbus_g_connection_register_g_object(connection, object_path, obj);
+
+ driver_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
+
+ if (!org_freedesktop_DBus_request_name(driver_proxy, bus_name, 0,
+ &request_name_ret, &error))
+ {
+ g_printerr(_("Failed to get name: %s\n"), error-
message);
+ g_error_free(error);
+ return 1;
+ }
+
+ switch (request_name_ret)
+ {
+ case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
+ break;
+ case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
+ g_printerr(
+ _("Looks like another server of this type is already running: Reply
in queue\n"));
+ return 1;
+ case DBUS_REQUEST_NAME_REPLY_EXISTS:
+ g_printerr(
+ _("Looks like another server of this type is already running: Reply
exists\n"));
+ return 1;
+ case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
+ g_printerr(_("We are already running\n"));
+ return 1;
+ default:
+ g_printerr(_("Unspecified error\n"));
+ return 1;
+ }
+
+ g_main_loop_run(loop);
+ g_main_loop_unref(loop);
+ g_object_unref(obj);
+ g_object_unref(driver_proxy);
+ return 0;
+}
+
+gboolean
+matahari_get(Matahari* matahari, const char *interface, const char *name,
DBusGMethodInvocation *context)
+{
+ GError* error = NULL;
+ GParamSpec *spec;
+ GValue value = {0, };
+
+ char *action = malloc((strlen(interface) + strlen(name) + 2) *
sizeof(char));
+ sprintf(action, "%s.%s", interface, name);
+ if (!check_authorization(action, &error, context))
+ {
+ dbus_g_method_return_error(context, error);
+ free(action);
+ return FALSE;
+ }
+ free(action);
+
+ spec = g_object_class_find_property(G_OBJECT_GET_CLASS(matahari), name);
+ g_value_init(&value, spec->value_type);
+ g_object_get_property(G_OBJECT(matahari), name, &value);
+ dbus_g_method_return(context, &value);
+ return TRUE;
+}
+
+gboolean
+matahari_set(Matahari *matahari, const char *interface, const char *name,
GValue *value, DBusGMethodInvocation *context)
+{
+ GError* error = NULL;
+ char *action = malloc((strlen(interface) + strlen(name) + 2) *
sizeof(char));
+ sprintf(action, "%s.%s", interface, name);
+ if (!check_authorization(action, &error, context))
+ {
+ dbus_g_method_return_error(context, error);
+ free(action);
+ return FALSE;
+ }
+ free(action);
+
+ g_object_set_property(G_OBJECT(matahari), name, value);
+ dbus_g_method_return(context);
+ return TRUE;
+}
+
+/* Class init */
+static void
+matahari_class_init(MatahariClass *matahari_class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(matahari_class);
+ GParamSpec *pspec = NULL;
+
+ //g_type_class_add_private(matahari_class, sizeof (MatahariPrivate));
+
+ gobject_class->set_property = matahari_set_property;
+ gobject_class->get_property = matahari_get_property;
+
+ int i;
+ for (i = 0; properties[i].name != NULL; i++)
+ {
+ if (!get_paramspec_from_property(properties[i], &pspec))
+ {
+ g_printerr("Unknown type: %c\n", properties[i].type);
+ pspec = NULL;
+ }
+ if (pspec)
+ g_object_class_install_property(gobject_class, properties[i].prop,
pspec);
+ }
+
+ dbus_g_object_type_install_info(MATAHARI_TYPE,
&dbus_glib_matahari_object_info);
+}
+
+/* Instance init */
+static void
+matahari_init(Matahari *matahari)
+{
+ MatahariPrivate *priv;
+ matahari->priv = priv = MATAHARI_GET_PRIVATE(matahari);
+}
+
+Dict *dict_new(GValue *value)
+{
+ gpointer ret;
+ Dict *dict = malloc(sizeof(Dict));
+ dict->key = calloc(sizeof(GValue), 1);
+ dict->value = value;
+ g_value_init(dict->key, G_TYPE_STRING);
+ ret = dbus_g_type_specialized_construct (G_VALUE_TYPE (value));
+ g_value_set_boxed_take_ownership (value, ret);
+
+ dbus_g_type_specialized_init_append (value, &(dict->appendctx));
+
+ return dict;
+}
+
+void dict_add(Dict *dict, const gchar *key, GValue *value)
+{
+ g_value_set_static_string(dict->key, key);
+ dbus_g_type_specialized_map_append (&(dict->appendctx), dict->key,
value);
+}
+
+void dict_free(Dict *dict)
+{
+ free(dict->key);
+ free(dict);
+}
diff --git a/src/common/mh_dbus_common.h b/src/common/mh_dbus_common.h
new file mode 100644
index 0000000..b7edc53
--- /dev/null
+++ b/src/common/mh_dbus_common.h
@@ -0,0 +1,128 @@
+/*
+ * mh_dbus_common.h
+ *
+ * Copyright (C) 2011 Red Hat, Inc.
+ * Written by Radek Novacek <rnovacek(a)redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
USA.
+ *
+ */
+
+#ifndef MH_DBUS_COMMON_H
+#define MH_DBUS_COMMON_H
+
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+
+/* GObject class definition */
+#include "mh_gobject_class.h"
+
+/* Private struct in Matahari class */
+#define MATAHARI_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj),
MATAHARI_TYPE, MatahariPrivate))
+
+// Matahari error codes
+#define MATAHARI_ERROR matahari_error_quark ()
+enum { MATAHARI_AUTHENTICATION_ERROR, MATAHARI_NOT_IMPLEMENTED };
+
+GQuark
+matahari_error_quark (void);
+
+/**
+ * Check the authorization for given 'action' using PolicyKit. Returns TRUE
if
+ * user is authorized, otherwise return FALSE and 'error' is set.
+ */
+gboolean
+check_authorization(const gchar *action, GError** error,
DBusGMethodInvocation *context);
+
+typedef struct {
+ int prop;
+ gchar *name, *nick, *desc;
+ GParamFlags flags;
+ char type;
+} Property;
+
+// This array is defined in auto-generated matahari-module-properties.h
+extern Property properties[];
+
+/**
+ * Start DBus server with name 'bus_name' and object path 'object_path'
+ */
+int
+run_dbus_server(char *bus_name, char *object_path);
+
+/**
+ * Check the authorization for getting the parameter 'name' using PolicyKit
+ * action interface.name
+ */
+gboolean
+matahari_get(Matahari* matahari, const char *interface, const char *name,
DBusGMethodInvocation *context);
+
+/**
+ * Check the authorization for setting the parameter 'name' using PolicyKit
+ * action interface.name
+ */
+gboolean
+matahari_set(Matahari *matahari, const char *interface, const char *name,
GValue *value, DBusGMethodInvocation *context);
+
+/**
+ * This method is used for getting value of DBus property.
+ * It must be implemented in each module.
+ * Set the value of property_id parameter to parameter value.
+ */
+void
+matahari_get_property(GObject *object, guint property_id, GValue *value,
GParamSpec *pspec);
+
+/**
+ * This method is used for setting value of DBus property.
+ * It must be implemented in each module.
+ * New value of property_id is in parameter value.
+ */
+void
+matahari_set_property(GObject *object, guint property_id, const GValue
*value, GParamSpec *pspec);
+
+/**
+ * This method is used to determine type of value in all dictionary
parameters.
+ * It must be implemented in each module.
+ */
+GType
+matahari_dict_type(int prop);
+
+/**
+ * Dictionary type. Key is always string, value is set in constructor
dict_new.
+ */
+typedef struct
+{
+ GValue *value;
+ GValue *key;
+ DBusGTypeSpecializedAppendContext appendctx;
+} Dict;
+
+/**
+ * Constructor of dictionary type. Key is string, type of value is defined by
type of 'value'.
+ * New value will be stored in 'value'. Use dict_free after setting all
values.
+ */
+Dict *dict_new(GValue *value);
+
+/**
+ * Add 'value' to the dictionary 'dict'.
+ */
+void dict_add(Dict *dict, const gchar *key, GValue *value);
+
+/**
+ * Frees memory allocated by dict_new.
+ */
+void dict_free(Dict *dict);
+
+#endif
diff --git a/src/common/mh_gobject_class.h b/src/common/mh_gobject_class.h
new file mode 100644
index 0000000..821d0ac
--- /dev/null
+++ b/src/common/mh_gobject_class.h
@@ -0,0 +1,51 @@
+/*
+ * mh_gobject_class.h
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ * Written by Roman Rakus <rrakus(a)redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
USA.
+ *
+ */
+
+#ifndef MHGOBJECTCLASS_H_
+#define MHGOBJECTCLASS_H_
+
+#define MATAHARI_TYPE (matahari_get_type())
+#define MATAHARI(object) (G_TYPE_CHECK_INSTANCE_CAST ((object),
MATAHARI_TYPE, Matahari))
+#define MATAHARI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
MATAHARI_TYPE, MatahariClass))
+#define IS_MATAHARI(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object),
MATAHARI_TYPE))
+#define IS_MATAHARI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
MATAHARI_TYPE))
+#define MATAHARI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
MATAHARI_TYPE, MatahariClass))
+
+typedef struct _Matahari Matahari;
+typedef struct _MatahariClass MatahariClass;
+typedef struct _MatahariPrivate MatahariPrivate;
+
+GType
+matahari_get_type(void);
+
+struct _Matahari
+{
+ GObject parent;
+ MatahariPrivate *priv;
+};
+
+struct _MatahariClass
+{
+ GObjectClass parent;
+};
+
+#endif /* MHGOBJECTCLASS_H_ */
diff --git a/src/dbus-to-c.xsl b/src/dbus-to-c.xsl
new file mode 100644
index 0000000..96c796f
--- /dev/null
+++ b/src/dbus-to-c.xsl
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<xsl:stylesheet version="1.0"
+
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:output method="text" indent="no" />
+<xsl:strip-space elements="*" />
+
+<!-- This xsl file is for tranforming dbus interface file to
+ C code that can be used by glib-dbus for automated generating
+ of dbus properties.
+
+ It create enum named Prop with list of properties for internal
+ identification.
+
+ Then it create struct Property which contains enum of property, its
name,
+ nick, description, flags (readable, readwrite) and type. Type is then
+ used to automaticly create the property from dbus.
+
+ Last step is to create array of Property structs with info about all
+ properties.
+-->
+
+<xsl:template match="/node/interface">
+ <!-- Do not generate anything for interface Properies -->
+ <xsl:if test="(a)name!='org.freedesktop.DBus.Properties'">
+ <!-- Create enum of the properties -->
+ <xsl:call-template name="enum" />
+ <!-- Define Property struct and create array of it with properties
+ info -->
+ <xsl:call-template name="struct" />
+ </xsl:if>
+</xsl:template>
+
+<!-- This is needed for converting properties names to uppercase -->
+<xsl:variable name="smallcase"
select="'abcdefghijklmnopqrstuvwxyz'" />
+<xsl:variable name="uppercase"
select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
+
+<xsl:template name="enum">
+ <!-- Create enum of the properties and first property with id 0 -->
+ <xsl:text>enum Prop {
+ PROP_0,
+ </xsl:text>
+ <!-- Iterate through all properties -->
+ <xsl:for-each select="property">
+ <xsl:value-of select="concat('PROP_', translate(@name,
$smallcase,
$uppercase))" />,
+ </xsl:for-each>
+ <xsl:text>}; </xsl:text>
+</xsl:template>
+
+<xsl:template name="struct">
+ <!-- Create the array of Property structs -->
+ <xsl:text>Property properties[] = { </xsl:text>
+ <!-- Iterate through all properties -->
+ <xsl:for-each select="property">
+ <xsl:text> { </xsl:text>
+ <!-- Enum of the item -->
+ <xsl:value-of select="concat('PROP_', translate(@name,
$smallcase,
$uppercase))" />
+ <xsl:text>, "</xsl:text>
+
+ <!-- Name of the item -->
+ <xsl:value-of select="@name" />
+ <xsl:text>", "</xsl:text>
+
+ <!-- Nickname - same as the name -->
+ <xsl:value-of select="@name" />
+ <xsl:text>", "</xsl:text>
+
+ <!-- Description is taken from the comment that is preceding the item
-->
+ <xsl:value-of select="preceding::comment()[1]" />
+ <xsl:text>", </xsl:text>
+
+ <!-- Flags - readable or readwrite -->
+ <xsl:choose>
+ <xsl:when test="@access='readwrite'">
+ <xsl:text>G_PARAM_READWRITE</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>G_PARAM_READABLE</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text>, '</xsl:text>
+
+ <!-- Type of the property - some must be converted -->
+ <xsl:choose>
+ <!-- Convert dict to type 'e' -->
+ <xsl:when test="@type='a{sv}'">
+ <xsl:text>e</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@type" />
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text>'</xsl:text>
+ <xsl:text> }, </xsl:text>
+ </xsl:for-each>
+ <!-- This item is used as sentinel node -->
+ <xsl:text> { PROP_0, NULL, NULL, NULL, 0, '\0'
}, </xsl:text>
+ <xsl:text>};</xsl:text>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/src/dbus-to-polkit.xsl b/src/dbus-to-polkit.xsl
new file mode 100644
index 0000000..fcbcd7d
--- /dev/null
+++ b/src/dbus-to-polkit.xsl
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<xsl:stylesheet version="1.0"
+
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:output method="xml"
+ indent="yes"
+ doctype-public="-//freedesktop//DTD PolicyKit Policy
Configuration 1.0//EN"
+ doctype-
system="http://www.freedesktop.org/standards/PolicyKit/1.0/policycon...
/>
+
+<xsl:template match="/">
+ <policyconfig>
+ <vendor>Matahari</vendor>
+ <
vendor_url>https://fedorahosted.org/matahari/</vendor_url>
+ <!-- TODO: icon <icon_name>matahari</icon_name> -->
+ <xsl:variable name="interface">
+ <xsl:value-of select="node/interface/@name" />
+ </xsl:variable>
+ <xsl:for-each select="node/interface/property|node/interface/statistics|
node/interface/method">
+ <action>
+ <xsl:attribute name="id">
+ <xsl:value-of select="concat($interface, '.',
@name)" />
+ </xsl:attribute>
+ <!-- TODO: description -->
+ <!-- TODO: message -->
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>
+ <xsl:choose>
+ <xsl:when test="@access='read'">
+ <xsl:text>yes</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>auth_admin</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </allow_active>
+ </defaults>
+ </action>
+ </xsl:for-each>
+ </policyconfig>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/src/host/CMakeLists.txt b/src/host/CMakeLists.txt
new file mode 100644
index 0000000..a3dac7e
--- /dev/null
+++ b/src/host/CMakeLists.txt
@@ -0,0 +1,40 @@
+set(MHOST_VERSION 0.0.1)
+
+include(DBusMacros)
+generate_dbus_headers(Host)
+
+set(HOST_DBUS_SOURCE
+ matahari-host-dbus.c
+ ../common/mh_dbus_common.c
+ ${CMAKE_CURRENT_BINARY_DIR}/matahari-host-dbus-glue.h
+ ${CMAKE_CURRENT_BINARY_DIR}/matahari-host-dbus-properties.h
+)
+
+# Daemon
+set(M_HOST_DBUS "matahari-host-dbusd")
+add_executable(${M_HOST_DBUS} ${HOST_DBUS_SOURCE})
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+target_link_libraries(${M_HOST_DBUS} mhost )
+
+if(polkit_FOUND)
+ include_directories(${polkit_INCLUDE_DIRS})
+ target_link_libraries(${M_HOST_DBUS} ${polkit_LIBRARIES})
+else(polkit_FOUND)
+ message(FATAL_ERROR "polkit headers/libraries not found.")
+endif(polkit_FOUND)
+
+if(dbus-glib_FOUND)
+ include_directories(${dbus-glib_INCLUDE_DIRS})
+ target_link_libraries(${M_HOST_DBUS} ${dbus-glib_LIBRARIES})
+else(dbus-glib_FOUND)
+ message(FATAL_ERROR "dbus-glib headers/libraries not found.")
+endif(dbus-glib_FOUND)
+
+# Install targets
+# TODO: fix hardcoded paths, should go to libexec
+install(TARGETS ${M_HOST_DBUS} DESTINATION sbin)
+install(FILES ${CMAKE_BINARY_DIR}/src/dbus/org.matahariproject.Host.xml
DESTINATION share/dbus-1/interfaces)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.matahariproject.Host.service
DESTINATION share/dbus-1/system-services)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.matahariproject.Host.conf
DESTINATION /etc/dbus-1/system.d)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.matahariproject.Host.policy
DESTINATION share/polkit-1/actions)
diff --git a/src/host/matahari-host-dbus.c b/src/host/matahari-host-dbus.c
new file mode 100644
index 0000000..9605ab0
--- /dev/null
+++ b/src/host/matahari-host-dbus.c
@@ -0,0 +1,243 @@
+/*
+ * matahari-host-dbus.c
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ * Written by Roman Rakus <rrakus(a)redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
USA.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "mh_dbus_common.h"
+
+/* Host methods */
+#include "matahari/host.h"
+
+/* Generated properties list */
+#include "matahari-host-dbus-properties.h"
+
+/* DBus names */
+#define HOST_BUS_NAME "org.matahariproject.Host"
+#define HOST_OBJECT_PATH "/org/matahariproject/Host"
+#define HOST_INTERFACE_NAME "org.matahariproject.Host"
+#define DBUS_PROPERTY_INTERAFACE_NAME "org.freedesktop.DBus.Properties"
+
+struct Private
+{
+ guint update_interval;
+};
+
+struct Private priv;
+
+/* Dbus methods */
+gboolean
+Host_identify(Matahari* matahari, DBusGMethodInvocation *context)
+{
+ GError* error = NULL;
+ if (!check_authorization(HOST_BUS_NAME ".identify", &error, context))
+ {
+ dbus_g_method_return_error(context, error);
+ return FALSE;
+ }
+ // TODO: Implement when implemented in backend
+ error = g_error_new(MATAHARI_ERROR, MATAHARI_NOT_IMPLEMENTED, "Action
identify is not implemented yet!");
+ dbus_g_method_return(context, TRUE);
+ return TRUE;
+}
+
+gboolean
+Host_shutdown(Matahari* matahari, DBusGMethodInvocation *context)
+{
+ GError* error = NULL;
+ if (!check_authorization(HOST_BUS_NAME ".shutdown", &error, context))
+ {
+ dbus_g_method_return_error(context, error);
+ return FALSE;
+ }
+ host_shutdown();
+ dbus_g_method_return(context, TRUE);
+ return TRUE;
+}
+
+gboolean
+Host_reboot(Matahari* matahari, DBusGMethodInvocation *context)
+{
+ GError* error = NULL;
+ if (!check_authorization(HOST_BUS_NAME ".reboot", &error, context))
+ {
+ dbus_g_method_return_error(context, error);
+ return FALSE;
+ }
+ host_reboot();
+ dbus_g_method_return(context, TRUE);
+ return TRUE;
+}
+
+/* Generated dbus stuff for host
+ * MUST be after declaration of user defined functions.
+ */
+#include "matahari-host-dbus-glue.h"
+
+void
+matahari_set_property(GObject *object, guint property_id, const GValue
*value,
+ GParamSpec *pspec)
+{
+ switch (property_id)
+ {
+ case PROP_UPDATE_INTERVAL:
+ priv.update_interval = g_value_get_uint (value);
+ break;
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+void
+matahari_get_property(GObject *object, guint property_id, GValue *value,
+ GParamSpec *pspec)
+{
+ sigar_proc_stat_t procs;
+ sigar_loadavg_t avg;
+ Dict *dict;
+ GValue value_value = {0, };
+
+ switch (property_id)
+ {
+ case PROP_UUID:
+ g_value_set_string (value, host_get_uuid());
+ break;
+ case PROP_HOSTNAME:
+ g_value_set_string (value, host_get_hostname());
+ break;
+ case PROP_OS:
+ g_value_set_string (value, host_get_operating_system());
+ break;
+ case PROP_ARCH:
+ g_value_set_string (value, host_get_architecture());
+ break;
+ case PROP_WORDSIZE:
+ g_value_set_uint (value, host_get_cpu_wordsize());
+ break;
+ case PROP_MEMORY:
+ g_value_set_uint64 (value, host_get_memory());
+ break;
+ case PROP_SWAP:
+ g_value_set_uint64 (value, host_get_swap());
+ break;
+ case PROP_CPU_COUNT:
+ g_value_set_uint (value, host_get_cpu_count());
+ break;
+ case PROP_CPU_CORES:
+ g_value_set_uint (value, host_get_cpu_number_of_cores());
+ break;
+ case PROP_CPU_MODEL:
+ g_value_set_string (value, host_get_cpu_model());
+ break;
+ case PROP_CPU_FLAGS:
+ g_value_set_string (value, host_get_cpu_flags());
+ break;
+ case PROP_UPDATE_INTERVAL:
+ g_value_set_uint (value, priv.update_interval);
+ break;
+ case PROP_LAST_UPDATED:
+ // Not used in DBus module
+ break;
+ case PROP_SEQUENCE:
+ // Not used in DBus module
+ break;
+ case PROP_FREE_MEM:
+ g_value_set_uint64 (value, host_get_mem_free());
+ break;
+ case PROP_FREE_SWAP:
+ g_value_set_uint64 (value, host_get_swap_free());
+ break;
+ case PROP_LOAD:
+ // 1/5/15 minute load average - map
+ host_get_load_averages(&avg);
+
+ dict = dict_new(value);
+ g_value_init (&value_value, G_TYPE_DOUBLE);
+
+ g_value_set_double(&value_value, avg.loadavg[0]);
+ dict_add(dict, "1", &value_value);
+
+ g_value_set_double(&value_value, avg.loadavg[1]);
+ dict_add(dict, "5", &value_value);
+
+ g_value_set_double(&value_value, avg.loadavg[2]);
+ dict_add(dict, "15", &value_value);
+ dict_free(dict);
+ break;
+ case PROP_PROCESS_STATISTICS:
+ // Process statistics is type map string -> int
+ host_get_processes(&procs);
+
+ dict = dict_new(value);
+ g_value_init (&value_value, G_TYPE_INT);
+
+ g_value_set_int(&value_value, procs.total);
+ dict_add(dict, "total", &value_value);
+
+ g_value_set_int(&value_value, procs.idle);
+ dict_add(dict, "idle", &value_value);
+
+ g_value_set_int(&value_value, procs.zombie);
+ dict_add(dict, "zombie", &value_value);
+
+ g_value_set_int(&value_value, procs.running);
+ dict_add(dict, "running", &value_value);
+
+ g_value_set_int(&value_value, procs.stopped);
+ dict_add(dict, "stopped", &value_value);
+
+ g_value_set_int(&value_value, procs.sleeping);
+ dict_add(dict, "sleeping", &value_value);
+ dict_free(dict);
+ break;
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+GType matahari_dict_type(int prop)
+{
+ switch (prop)
+ {
+ case PROP_LOAD:
+ return G_TYPE_DOUBLE;
+ break;
+ case PROP_PROCESS_STATISTICS:
+ return G_TYPE_INT;
+ break;
+ default:
+ g_printerr("Type of property %s is map of unknown types\n",
properties[prop].name);
+ return G_TYPE_VALUE;
+ }
+}
+
+int
+main(int argc, char** argv)
+{
+ g_type_init();
+ priv.update_interval = 5;
+ return run_dbus_server(HOST_BUS_NAME, HOST_OBJECT_PATH);
+}
diff --git a/src/host/org.matahariproject.Host.conf
b/src/host/org.matahariproject.Host.conf
new file mode 100644
index 0000000..a86dce8
--- /dev/null
+++ b/src/host/org.matahariproject.Host.conf
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE busconfig PUBLIC
+ "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+
+ <!-- Only root can own the service -->
+ <policy user="root">
+ <allow own="org.matahariproject.Host"/>
+ </policy>
+
+ <!-- Allow anyone to invoke methods on the interfaces -->
+ <policy context="default">
+ <allow send_destination="org.matahariproject.Host"/>
+ </policy>
+
+</busconfig>
diff --git a/src/host/org.matahariproject.Host.policy
b/src/host/org.matahariproject.Host.policy
new file mode 100644
index 0000000..587330c
--- /dev/null
+++ b/src/host/org.matahariproject.Host.policy
@@ -0,0 +1,153 @@
+<?xml version="1.0"?>
+<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy
Configuration 1.0//EN"
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
+<policyconfig>
+ <vendor>Matahari</vendor>
+ <
vendor_url>https://fedorahosted.org/matahari/</vendor_url>
+ <action id="org.matahariproject.Host.uuid">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Host.hostname">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Host.os">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Host.arch">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Host.wordsize">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Host.memory">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Host.swap">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Host.cpu_count">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Host.cpu_cores">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Host.cpu_model">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Host.cpu_flags">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Host.update_interval">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Host.last_updated">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Host.sequence">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Host.free_mem">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Host.free_swap">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Host.load">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Host.process_statistics">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Host.identify">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Host.shutdown">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Host.reboot">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin</allow_active>
+ </defaults>
+ </action>
+</policyconfig>
diff --git a/src/host/org.matahariproject.Host.service
b/src/host/org.matahariproject.Host.service
new file mode 100644
index 0000000..ce47e40
--- /dev/null
+++ b/src/host/org.matahariproject.Host.service
@@ -0,0 +1,4 @@
+[D-BUS Service]
+Name=org.matahariproject.Host
+Exec=/usr/sbin/matahari-host-dbusd
+User=root
diff --git a/src/net/CMakeLists.txt b/src/net/CMakeLists.txt
new file mode 100644
index 0000000..1ca5c65
--- /dev/null
+++ b/src/net/CMakeLists.txt
@@ -0,0 +1,40 @@
+set(MHOST_VERSION 0.0.1)
+
+include(DBusMacros)
+generate_dbus_headers(Network)
+
+set(NET_DBUS_SOURCE
+ matahari-network-dbus.c
+ ../common/mh_dbus_common.c
+ ${CMAKE_CURRENT_BINARY_DIR}/matahari-network-dbus-glue.h
+ ${CMAKE_CURRENT_BINARY_DIR}/matahari-network-dbus-properties.h
+)
+
+# Daemon
+set(M_NET_DBUS "matahari-network-dbusd")
+add_executable(${M_NET_DBUS} ${NET_DBUS_SOURCE})
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+target_link_libraries(${M_NET_DBUS} mnet)
+
+if(polkit_FOUND)
+ include_directories(${polkit_INCLUDE_DIRS})
+ target_link_libraries(${M_NET_DBUS} ${polkit_LIBRARIES})
+else(polkit_FOUND)
+ message(FATAL_ERROR "polkit headers/libraries not found.")
+endif(polkit_FOUND)
+
+if(dbus-glib_FOUND)
+ include_directories(${dbus-glib_INCLUDE_DIRS})
+ target_link_libraries(${M_NET_DBUS} ${dbus-glib_LIBRARIES})
+else(dbus-glib_FOUND)
+ message(FATAL_ERROR "dbus-glib headers/libraries not found.")
+endif(dbus-glib_FOUND)
+
+# Install targets
+# TODO: fix hardcoded paths, should go to libexec
+install(TARGETS ${M_NET_DBUS} DESTINATION sbin)
+install(FILES ${CMAKE_BINARY_DIR}/src/dbus/org.matahariproject.Network.xml
DESTINATION share/dbus-1/interfaces)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.matahariproject.Network.service
DESTINATION share/dbus-1/system-services)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.matahariproject.Network.conf
DESTINATION /etc/dbus-1/system.d)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.matahariproject.Network.policy
DESTINATION share/polkit-1/actions)
diff --git a/src/net/matahari-network-dbus.c b/src/net/matahari-network-dbus.c
new file mode 100644
index 0000000..71b3100
--- /dev/null
+++ b/src/net/matahari-network-dbus.c
@@ -0,0 +1,220 @@
+/*
+ * matahari-network-dbus.c
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ * Written by Radek Novacek <rnovacek(a)redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
USA.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <sigar.h>
+
+#include "mh_dbus_common.h"
+
+/* Network methods */
+#include "matahari/network.h"
+#include "matahari/utilities.h"
+
+/* Generated properties list */
+#include "matahari-network-dbus-properties.h"
+
+/* DBus names */
+#define NETWORK_BUS_NAME "org.matahariproject.Network"
+#define NETWORK_OBJECT_PATH "/org/matahariproject/Network"
+#define NETWORK_INTERFACE_NAME "org.matahariproject.Network"
+
+
+enum status { INACTIVE = 0, RUNNING };
+
+/* Get status of the interface */
+static enum status interface_status(const char *iface)
+{
+ uint64_t flags = 0;
+ network_status(iface, &flags);
+
+ if(flags & SIGAR_IFF_UP)
+ return RUNNING;
+ return INACTIVE; /* Inactive */
+}
+
+/* Dbus methods */
+
+gboolean
+Network_list(Matahari *matahari, DBusGMethodInvocation *context)
+{
+ GError* error = NULL;
+ GList *interface_list;
+ GList *plist;
+ sigar_net_interface_config_t *ifconfig;
+ char **list;
+ int i = 0;
+
+ if (!check_authorization(NETWORK_BUS_NAME ".list", &error, context))
+ {
+ dbus_g_method_return_error(context, error);
+ return FALSE;
+ }
+
+ // Get the list of interfaces
+ interface_list = network_get_interfaces();
+
+ // Alloc array for list of interface names
+ list = g_new(char *, g_list_length(interface_list) + 1);
+
+ // Convert list of interfaces to the array of names
+ for(plist = g_list_first(interface_list); plist; plist =
g_list_next(plist))
+ {
+ ifconfig = (sigar_net_interface_config_t *)plist->data;
+ list[i++] = strdup(ifconfig->name);
+ }
+ list[i] = NULL; // Sentinel
+
+ dbus_g_method_return(context, list);
+ g_strfreev(list);
+ g_list_free(interface_list);
+ return TRUE;
+}
+
+gboolean
+Network_start(Matahari *matahari, const char *iface, DBusGMethodInvocation
*context)
+{
+ GError* error = NULL;
+ int status;
+
+ if (!check_authorization(NETWORK_BUS_NAME ".start", &error, context))
+ {
+ dbus_g_method_return_error(context, error);
+ return FALSE;
+ }
+
+ status = interface_status(iface);
+ if (status != RUNNING)
+ {
+ network_start(iface);
+ status = interface_status(iface);
+ }
+ dbus_g_method_return(context, status);
+ return TRUE;
+}
+
+gboolean
+Network_stop(Matahari *matahari, const char *iface, DBusGMethodInvocation
*context)
+{
+ GError* error = NULL;
+ int status;
+
+ if (!check_authorization(NETWORK_BUS_NAME ".stop", &error, context))
+ {
+ dbus_g_method_return_error(context, error);
+ return FALSE;
+ }
+
+ status = interface_status(iface);
+ if (status != INACTIVE)
+ {
+ network_stop(iface);
+ status = interface_status(iface);
+ }
+ dbus_g_method_return(context, status);
+ return TRUE;
+}
+
+gboolean
+Network_status(Matahari *matahari, const char *iface, DBusGMethodInvocation
*context)
+{
+ GError* error = NULL;
+ if (!check_authorization(NETWORK_BUS_NAME ".status", &error, context))
+ {
+ dbus_g_method_return_error(context, error);
+ return FALSE;
+ }
+
+ dbus_g_method_return(context, interface_status(iface));
+ return TRUE;
+}
+
+gboolean
+Network_get_ip_address(Matahari *matahari, const char *iface,
DBusGMethodInvocation *context)
+{
+ GError* error = NULL;
+ if (!check_authorization(NETWORK_BUS_NAME ".get_ip_address", &error,
context))
+ {
+ dbus_g_method_return_error(context, error);
+ return FALSE;
+ }
+
+ dbus_g_method_return(context, g_strdup(network_get_ip_address(iface)));
+ return TRUE;
+}
+
+gboolean
+Network_get_mac_address(Matahari *matahari, const char *iface,
DBusGMethodInvocation *context)
+{
+ GError* error = NULL;
+ if (!check_authorization(NETWORK_BUS_NAME ".get_mac_address", &error,
context))
+ {
+ dbus_g_method_return_error(context, error);
+ return FALSE;
+ }
+
+ dbus_g_method_return(context, g_strdup(network_get_mac_address(iface)));
+ return TRUE;
+}
+
+/* Generated dbus stuff for network
+ * MUST be after declaration of user defined functions.
+ */
+#include "matahari-network-dbus-glue.h"
+
+void
+matahari_set_property(GObject *object, guint property_id, const GValue
*value,
+ GParamSpec *pspec)
+{
+ // We don't have writable other property...
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+void
+matahari_get_property(GObject *object, guint property_id, GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id)
+ {
+ case PROP_HOSTNAME:
+ g_value_set_string (value, get_hostname());
+ break;
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+GType matahari_dict_type(int prop)
+{
+ g_printerr("Type of property %s is map of unknown types\n",
properties[prop].name);
+ return G_TYPE_VALUE;
+}
+
+int
+main(int argc, char** argv)
+{
+ g_type_init();
+ return run_dbus_server(NETWORK_BUS_NAME, NETWORK_OBJECT_PATH);
+}
diff --git a/src/net/org.matahariproject.Network.conf
b/src/net/org.matahariproject.Network.conf
new file mode 100644
index 0000000..b6fa070
--- /dev/null
+++ b/src/net/org.matahariproject.Network.conf
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*-
-->
+
+<!DOCTYPE busconfig PUBLIC
+ "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+
+ <!-- Only root can own the service and send signals -->
+ <policy user="root">
+ <allow own="org.matahariproject.Network"/>
+ </policy>
+
+ <policy context="default">
+ <allow send_destination="org.matahariproject.Network"
+ send_interface="org.matahariproject.Network"/>
+
+ <allow send_destination="org.matahariproject.Network"
+ send_interface="org.freedesktop.DBus.Introspectable"/>
+
+ <allow send_destination="org.matahariproject.Network"
+ send_interface="org.freedesktop.DBus.Properties"/>
+ </policy>
+
+
+</busconfig>
diff --git a/src/net/org.matahariproject.Network.policy
b/src/net/org.matahariproject.Network.policy
new file mode 100644
index 0000000..5c847c2
--- /dev/null
+++ b/src/net/org.matahariproject.Network.policy
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy
Configuration 1.0//EN"
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
+<policyconfig>
+ <vendor>Matahari</vendor>
+ <
vendor_url>https://fedorahosted.org/matahari/</vendor_url>
+ <action id="org.matahariproject.Network.hostname">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Network.list">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Network.start">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Network.stop">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Network.status">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Network.get_ip_address">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Network.get_mac_address">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin</allow_active>
+ </defaults>
+ </action>
+</policyconfig>
diff --git a/src/net/org.matahariproject.Network.service
b/src/net/org.matahariproject.Network.service
new file mode 100644
index 0000000..9eabcab
--- /dev/null
+++ b/src/net/org.matahariproject.Network.service
@@ -0,0 +1,4 @@
+[D-BUS Service]
+Name=org.matahariproject.Network
+Exec=/usr/sbin/matahari-network-dbusd
+User=root
diff --git a/src/schema-to-dbus.xsl b/src/schema-to-dbus.xsl
new file mode 100644
index 0000000..4af20ba
--- /dev/null
+++ b/src/schema-to-dbus.xsl
@@ -0,0 +1,210 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<xsl:stylesheet version="1.0"
+
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+
xmlns:exsl="http://exslt.org/common"
+ extension-element-prefixes="exsl">
+
+<!-- This xsl transformation takes schema.xml and converts it to multiple
+ DBus interfaces, one per each class.
+
+ The DBus files will be name org.matahariproject.class_name.xml and will
+ be created in current directory. Description of the properties/methods
+ will be added as a comment for future processing.
+-->
+
+<xsl:template match="/">
+ <xsl:variable name="package">
+ <xsl:value-of select="schema/@package" />
+ </xsl:variable>
+ <xsl:for-each select="schema/class">
+ <xsl:variable name="filename"
select="concat('org.matahariproject.',
@name,'.xml')" />
+ <exsl:document method="xml" indent="yes"
version="1.0"
encoding="utf-8" href="{$filename}">
+ <node>
+ <interface>
+ <xsl:attribute name="name">
+ <xsl:value-of select="concat($package, '.',
@name)"
/>
+ </xsl:attribute>
+ <annotation
name="org.freedesktop.DBus.GLib.CSymbol">
+ <xsl:attribute name="value">
+ <xsl:value-of select="@name"/>
+ </xsl:attribute>
+ </annotation>
+ <xsl:for-each select="property|statistic">
+ <!-- What with doc? Add as comment now. -->
+ <xsl:if test="@desc">
+ <xsl:comment>
+ <xsl:value-of select="@desc" />
+ </xsl:comment>
+ </xsl:if>
+ <property>
+ <xsl:attribute name="name">
+ <xsl:value-of select="@name" />
+ </xsl:attribute>
+
+ <!-- Tranform data types -->
+ <xsl:call-template name="type" />
+
+ <!-- Tranform access rights -->
+ <xsl:call-template name="access" />
+ </property>
+ </xsl:for-each>
+
+ <!-- Methods -->
+ <xsl:for-each select="method">
+ <!-- What with doc? Add as comment now. -->
+ <xsl:if test="@desc">
+ <xsl:comment>
+ <xsl:value-of select="@desc" />
+ </xsl:comment>
+ </xsl:if>
+ <method>
+ <xsl:attribute name="name">
+ <xsl:value-of select="@name" />
+ </xsl:attribute>
+ <xsl:if test="not(arg[@dir='O'])">
+ <annotation
name="org.freedesktop.DBus.GLib.NoReply" value="yes" />
+ </xsl:if>
+ <annotation
name="org.freedesktop.DBus.GLib.Async" value="" />
+ <xsl:for-each select="arg">
+ <arg>
+ <xsl:attribute name="name">
+ <xsl:value-of select="@name" />
+ </xsl:attribute>
+
+ <!-- Tranform data types -->
+ <xsl:call-template name="type" />
+
+ <!-- Parameter direction-->
+ <xsl:call-template name="dir" />
+
+ </arg>
+ </xsl:for-each>
+ </method>
+ </xsl:for-each>
+ </interface>
+ <!-- Get and set function will be used for accessing
parameters.
+ It enables to obtain authorization via Polkit -->
+ <interface name="org.freedesktop.DBus.Properties">
+ <method name="Get">
+ <annotation name="org.freedesktop.DBus.GLib.Async"
value=""/>
+ <arg name="interface" direction="in"
type="s"/>
+ <arg name="property" direction="in"
type="s"/>
+ <arg name="value" direction="out"
type="v"/>
+ </method>
+ <method name="Set">
+ <annotation name="org.freedesktop.DBus.GLib.Async"
value=""/>
+ <arg name="interface" direction="in"
type="s"/>
+ <arg name="property" direction="in"
type="s"/>
+ <arg name="value" direction="in"
type="v"/>
+ </method>
+ </interface>
+ </node>
+ </exsl:document>
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="type">
+ <!-- Transform data types -->
+ <xsl:choose>
+ <xsl:when test="@type='list'">
+ <!-- Convert list to list of strings -->
+ <xsl:attribute name="type">as</xsl:attribute>
+ </xsl:when>
+
+ <xsl:when test="@type='int8'">
+ <xsl:attribute name="type">n</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='int16'">
+ <xsl:attribute name="type">n</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='int32'">
+ <xsl:attribute name="type">i</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='int64'">
+ <xsl:attribute name="type">x</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='uint8'">
+ <xsl:attribute name="type">y</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='uint16'">
+ <xsl:attribute name="type">q</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='uint32'">
+ <xsl:attribute name="type">u</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='uint64'">
+ <xsl:attribute name="type">t</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='bool'">
+ <xsl:attribute name="type">b</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='double'">
+ <xsl:attribute name="type">d</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='float'">
+ <xsl:attribute name="type">d</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='sstr'">
+ <xsl:attribute name="type">s</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='lstr'">
+ <xsl:attribute name="type">s</xsl:attribute>
+ </xsl:when>
+
+ <xsl:when test="@type='list'">
+ <!-- Convert list to list of strings -->
+ <xsl:attribute name="type">as</xsl:attribute>
+ </xsl:when>
+
+ <!-- Warning: Uncompatible -->
+ <xsl:when test="@type='absTime'">
+ <xsl:attribute name="type">i</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='deltaTime'">
+ <xsl:attribute name="type">i</xsl:attribute>
+ </xsl:when>
+
+ <xsl:when test="@type='uuid'">
+ <xsl:attribute name="type">x</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='map'">
+ <xsl:attribute name="type">a{sv}</xsl:attribute>
+ </xsl:when>
+
+ <!-- TODO: check if compatible -->
+ <xsl:when test="@type='objId'">
+ <xsl:attribute name="type">o</xsl:attribute>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="access">
+ <xsl:choose>
+ <xsl:when test="@access='RW'">
+ <xsl:attribute name="access">readwrite</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@access='RO'">
+ <xsl:attribute name="access">read</xsl:attribute>
+ </xsl:when>
+ <!-- No Read-Create in DBus -->
+ <xsl:when test="@access='RC'">
+ <xsl:attribute name="access">readwrite</xsl:attribute>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:attribute name="access">read</xsl:attribute>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="dir">
+ <xsl:choose>
+ <xsl:when test="@dir='I'">
+ <xsl:attribute name="direction">in</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@dir='O'">
+ <xsl:attribute name="direction">out</xsl:attribute>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/src/service/CMakeLists.txt b/src/service/CMakeLists.txt
new file mode 100644
index 0000000..7559082
--- /dev/null
+++ b/src/service/CMakeLists.txt
@@ -0,0 +1,40 @@
+set(MHOST_VERSION 0.0.1)
+
+include(DBusMacros)
+generate_dbus_headers(Services)
+
+set(SRV_DBUS_SOURCE
+ matahari-services-dbus.c
+ ../common/mh_dbus_common.c
+ ${CMAKE_CURRENT_BINARY_DIR}/matahari-services-dbus-glue.h
+ ${CMAKE_CURRENT_BINARY_DIR}/matahari-services-dbus-properties.h
+)
+
+# Daemon
+set(M_SRV_DBUS "matahari-services-dbusd")
+add_executable(${M_SRV_DBUS} ${SRV_DBUS_SOURCE})
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+target_link_libraries(${M_SRV_DBUS} msrv)
+
+if(polkit_FOUND)
+ include_directories(${polkit_INCLUDE_DIRS})
+ target_link_libraries(${M_SRV_DBUS} ${polkit_LIBRARIES})
+else(polkit_FOUND)
+ message(FATAL_ERROR "polkit headers/libraries not found.")
+endif(polkit_FOUND)
+
+if(dbus-glib_FOUND)
+ include_directories(${dbus-glib_INCLUDE_DIRS})
+ target_link_libraries(${M_SRV_DBUS} ${dbus-glib_LIBRARIES})
+else(dbus-glib_FOUND)
+ message(FATAL_ERROR "dbus-glib headers/libraries not found.")
+endif(dbus-glib_FOUND)
+
+# Install targets
+# TODO: fix hardcoded paths, should go to libexec
+install(TARGETS ${M_SRV_DBUS} DESTINATION sbin)
+install(FILES ${CMAKE_BINARY_DIR}/src/dbus/org.matahariproject.Services.xml
DESTINATION share/dbus-1/interfaces)
+install(FILES
${CMAKE_CURRENT_SOURCE_DIR}/org.matahariproject.Services.service DESTINATION
share/dbus-1/system-services)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.matahariproject.Services.conf
DESTINATION /etc/dbus-1/system.d)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.matahariproject.Services.policy
DESTINATION share/polkit-1/actions)
diff --git a/src/service/matahari-services-dbus.c b/src/service/matahari-
services-dbus.c
new file mode 100644
index 0000000..ef2973a
--- /dev/null
+++ b/src/service/matahari-services-dbus.c
@@ -0,0 +1,256 @@
+/*
+ * matahari-services-dbus.c
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ * Written by Radek Novacek <rnovacek(a)redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
USA.
+ *
+ */
+
+#include <string.h>
+
+#include "mh_dbus_common.h"
+
+/* Services methods */
+#include "matahari/services.h"
+#include "matahari/utilities.h"
+
+/* Generated properties list */
+#include "matahari-services-dbus-properties.h"
+
+/* DBus names */
+#define SERVICES_BUS_NAME "org.matahariproject.Services"
+#define SERVICES_OBJECT_PATH "/org/matahariproject/Services"
+#define SERVICES_INTERFACE_NAME "org.matahariproject.Services"
+
+#define TIMEOUT_MS 60000
+
+/* Dbus methods */
+
+gboolean
+Services_list(Matahari *matahari, DBusGMethodInvocation *context)
+{
+ GError* error = NULL;
+ int i = 0;
+ GList *services;
+ char **list;
+
+ if (!check_authorization(SERVICES_BUS_NAME ".list", &error, context))
+ {
+ dbus_g_method_return_error(context, error);
+ return FALSE;
+ }
+
+ // Get list of services
+ services = services_list();
+
+ // Convert GList to (char **)
+ list = g_new(char *, g_list_length(services) + 1);
+ for (; services != NULL; services = services->next)
+ list[i++] = strdup(services->data);
+ list[i] = NULL; // Sentinel
+
+ dbus_g_method_return(context, list);
+ g_strfreev(list);
+ g_list_free(services);
+ return TRUE;
+}
+
+gboolean
+Services_enable(Matahari *matahari, const char *name, DBusGMethodInvocation
*context)
+{
+ GError* error = NULL;
+ svc_action_t *op;
+ gboolean res;
+
+ if (!check_authorization(SERVICES_BUS_NAME ".enable", &error, context))
+ {
+ dbus_g_method_return_error(context, error);
+ return FALSE;
+ }
+ op = services_action_create(name, "enable", 0, TIMEOUT_MS);
+ res = services_action_sync(op);
+ services_action_free(op);
+ dbus_g_method_return(context, res);
+ return res;
+}
+
+gboolean
+Services_disable(Matahari *matahari, const char *name, DBusGMethodInvocation
*context)
+{
+ GError* error = NULL;
+ svc_action_t *op;
+ gboolean res;
+
+ if (!check_authorization(SERVICES_BUS_NAME ".disable", &error, context))
+ {
+ dbus_g_method_return_error(context, error);
+ return FALSE;
+ }
+ op = services_action_create(name, "disable", 0, TIMEOUT_MS);
+ res = services_action_sync(op);
+ services_action_free(op);
+ dbus_g_method_return(context, res);
+ return res;
+}
+
+gboolean
+Services_start(Matahari *matahari, const char *name, unsigned int timeout,
DBusGMethodInvocation *context)
+{
+ GError* error = NULL;
+ svc_action_t *op;
+ int rc;
+
+ if (!check_authorization(SERVICES_BUS_NAME ".start", &error, context))
+ {
+ dbus_g_method_return_error(context, error);
+ return FALSE;
+ }
+ op = services_action_create(name, "start", 0, timeout);
+ services_action_sync(op);
+ rc = op->rc;
+ services_action_free(op);
+ dbus_g_method_return(context, rc);
+ return TRUE;
+}
+
+gboolean
+Services_stop(Matahari *matahari, const char *name, unsigned int timeout,
DBusGMethodInvocation *context)
+{
+ GError* error = NULL;
+ svc_action_t *op;
+ int rc;
+
+ if (!check_authorization(SERVICES_BUS_NAME ".stop", &error, context))
+ {
+ dbus_g_method_return_error(context, error);
+ return FALSE;
+ }
+ op = services_action_create(name, "stop", 0, timeout);
+ services_action_sync(op);
+ rc = op->rc;
+ services_action_free(op);
+ dbus_g_method_return(context, rc);
+ return TRUE;
+}
+
+gboolean
+Services_status(Matahari *matahari, const char *name, unsigned int interval,
unsigned int timeout, DBusGMethodInvocation *context)
+{
+ GError* error = NULL;
+ svc_action_t *op;
+ int rc;
+
+ if (!check_authorization(SERVICES_BUS_NAME ".status", &error, context))
+ {
+ dbus_g_method_return_error(context, error);
+ return FALSE;
+ }
+ op = services_action_create(name, "status", interval, timeout);
+ services_action_sync(op);
+ rc = op->rc;
+ services_action_free(op);
+ dbus_g_method_return(context, rc);
+ return TRUE;
+}
+
+gboolean
+Services_cancel(Matahari *matahari, const char *name, const char *action,
unsigned int interval, DBusGMethodInvocation *context)
+{
+ GError* error = NULL;
+ int res;
+
+ if (!check_authorization(SERVICES_BUS_NAME ".cancel", &error, context))
+ {
+ dbus_g_method_return_error(context, error);
+ return FALSE;
+ }
+ res = services_action_cancel(name, action, interval);
+ dbus_g_method_return(context);
+ return res;
+}
+
+gboolean
+Services_fail(Matahari *matahari, const char *name, DBusGMethodInvocation
*context)
+{
+ GError* error = NULL;
+ if (!check_authorization(SERVICES_BUS_NAME ".fail", &error, context))
+ {
+ dbus_g_method_return_error(context, error);
+ return FALSE;
+ }
+ // TODO: Implement when implemented in backend
+ error = g_error_new(MATAHARI_ERROR, MATAHARI_NOT_IMPLEMENTED, "Action fail
is not implemented yet!");
+ dbus_g_method_return_error(context, error);
+ return TRUE;
+}
+
+gboolean
+Services_describe(Matahari *matahari, const char *name, DBusGMethodInvocation
*context)
+{
+ GError* error = NULL;
+ if (!check_authorization(SERVICES_BUS_NAME ".describe", &error,
context))
+ {
+ dbus_g_method_return_error(context, error);
+ return FALSE;
+ }
+ // TODO: Implement when implemented in backend
+ error = g_error_new(MATAHARI_ERROR, MATAHARI_NOT_IMPLEMENTED, "Action
describe is not implemented yet!");
+ dbus_g_method_return_error(context, error);
+ return TRUE;
+}
+
+/* Generated dbus stuff for services
+ * MUST be after declaration of user defined functions.
+ */
+#include "matahari-services-dbus-glue.h"
+
+void
+matahari_set_property(GObject *object, guint property_id, const GValue
*value,
+ GParamSpec *pspec)
+{
+ // We don't have writable other property...
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+void
+matahari_get_property(GObject *object, guint property_id, GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id)
+ {
+ case PROP_HOSTNAME:
+ g_value_set_string (value, get_hostname());
+ break;
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+GType matahari_dict_type(int prop)
+{
+ g_printerr("Type of property %s is map of unknown types\n",
properties[prop].name);
+ return G_TYPE_VALUE;
+}
+
+int
+main(int argc, char** argv)
+{
+ g_type_init();
+ return run_dbus_server(SERVICES_BUS_NAME, SERVICES_OBJECT_PATH);
+}
diff --git a/src/service/org.matahariproject.Services.conf
b/src/service/org.matahariproject.Services.conf
new file mode 100644
index 0000000..7bad5b8
--- /dev/null
+++ b/src/service/org.matahariproject.Services.conf
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*-
-->
+
+<!DOCTYPE busconfig PUBLIC
+ "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+
+ <!-- Only root can own the service and send signals -->
+ <policy user="root">
+ <allow own="org.matahariproject.Services"/>
+ </policy>
+
+ <policy context="default">
+ <allow send_destination="org.matahariproject.Services"
+ send_interface="org.matahariproject.Services"/>
+
+ <allow send_destination="org.matahariproject.Services"
+ send_interface="org.freedesktop.DBus.Introspectable"/>
+
+ <allow send_destination="org.matahariproject.Services"
+ send_interface="org.freedesktop.DBus.Properties"/>
+ </policy>
+
+
+</busconfig>
diff --git a/src/service/org.matahariproject.Services.policy
b/src/service/org.matahariproject.Services.policy
new file mode 100644
index 0000000..8fb2ce5
--- /dev/null
+++ b/src/service/org.matahariproject.Services.policy
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy
Configuration 1.0//EN"
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
+<policyconfig>
+ <vendor>Matahari</vendor>
+ <
vendor_url>https://fedorahosted.org/matahari/</vendor_url>
+ <action id="org.matahariproject.Services.hostname">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Services.list">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Services.enable">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Services.disable">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Services.start">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Services.stop">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Services.status">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Services.cancel">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Services.fail">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin</allow_active>
+ </defaults>
+ </action>
+ <action id="org.matahariproject.Services.describe">
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin</allow_active>
+ </defaults>
+ </action>
+</policyconfig>
diff --git a/src/service/org.matahariproject.Services.service
b/src/service/org.matahariproject.Services.service
new file mode 100644
index 0000000..470c6ca
--- /dev/null
+++ b/src/service/org.matahariproject.Services.service
@@ -0,0 +1,4 @@
+[D-BUS Service]
+Name=org.matahariproject.Services
+Exec=/usr/sbin/matahari-services-dbusd
+User=root