summaryrefslogtreecommitdiffstats
path: root/src/service-dbus
diff options
context:
space:
mode:
authorVitezslav Crhonek <vcrhonek@redhat.com>2013-05-13 16:37:48 +0200
committerVitezslav Crhonek <vcrhonek@redhat.com>2013-05-13 16:37:48 +0200
commit78244e3db39e98e3243f82f153cf9ca350904879 (patch)
tree9a7a05ac236cc66b0a920a6ce1ab52860755e22b /src/service-dbus
parent41d6143573157a999ce0ef8f5854a1f4bacd4a69 (diff)
downloadopenlmi-providers-78244e3db39e98e3243f82f153cf9ca350904879.tar.gz
openlmi-providers-78244e3db39e98e3243f82f153cf9ca350904879.tar.xz
openlmi-providers-78244e3db39e98e3243f82f153cf9ca350904879.zip
service: added dbus based service provider
Diffstat (limited to 'src/service-dbus')
-rw-r--r--src/service-dbus/CMakeLists.txt30
-rw-r--r--src/service-dbus/LMI_ServiceProvider.c382
-rw-r--r--src/service-dbus/util/serviceutil.c290
-rw-r--r--src/service-dbus/util/serviceutil.h61
4 files changed, 763 insertions, 0 deletions
diff --git a/src/service-dbus/CMakeLists.txt b/src/service-dbus/CMakeLists.txt
new file mode 100644
index 0000000..1627a0f
--- /dev/null
+++ b/src/service-dbus/CMakeLists.txt
@@ -0,0 +1,30 @@
+
+set(PROVIDER_NAME Service)
+set(LIBRARY_NAME cmpiLMI_${PROVIDER_NAME})
+set(MOF LMI_Service.mof)
+
+set(provider_SRCS
+ util/serviceutil.c
+)
+
+konkretcmpi_generate(${MOF}
+ CIM_PROVIDERS
+ CIM_HEADERS
+)
+
+add_library(${LIBRARY_NAME} SHARED
+ ${provider_SRCS}
+ ${CIM_PROVIDERS}
+ ${CIM_HEADERS}
+)
+
+# Require libgio
+pkg_check_modules(GIO REQUIRED gio-2.0)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMPI_INCLUDE_DIR} ${GIO_INCLUDE_DIRS})
+target_link_libraries(${LIBRARY_NAME} openlmicommon ${KONKRETCMPI_LIBRARIES} ${GIO_LIBRARIES})
+
+# Create registration file
+cim_registration(${PROVIDER_NAME} ${LIBRARY_NAME} ${MOF} share/openlmi-providers)
+
+install(TARGETS ${LIBRARY_NAME} DESTINATION lib${LIB_SUFFIX}/cmpi)
diff --git a/src/service-dbus/LMI_ServiceProvider.c b/src/service-dbus/LMI_ServiceProvider.c
new file mode 100644
index 0000000..cb7ef42
--- /dev/null
+++ b/src/service-dbus/LMI_ServiceProvider.c
@@ -0,0 +1,382 @@
+/*
+ * Copyright (C) 2012-2013 Red Hat, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Vitezslav Crhonek <vcrhonek@redhat.com>
+ * Radek Novacek <rnovacek@redhat.com>
+ */
+
+#include <konkret/konkret.h>
+#include <stdint.h>
+#include "LMI_Service.h"
+#include "util/serviceutil.h"
+#include "globals.h"
+
+static const CMPIBroker* _cb = NULL;
+
+static void LMI_ServiceInitialize()
+{
+}
+
+static CMPIStatus LMI_ServiceCleanup(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ CMPIBoolean term)
+{
+ CMReturn(CMPI_RC_OK);
+}
+
+static CMPIStatus LMI_ServiceEnumInstanceNames(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop)
+{
+ const char *ns = KNameSpace(cop);
+ SList *slist = NULL;
+
+ slist = service_find_all();
+ if (slist == NULL) {
+ KReturn2(_cb, ERR_FAILED, "Unable to enumerate instance names of LMI_Service");
+ }
+
+ for (int i = 0; i < slist->cnt; i++) {
+ LMI_ServiceRef w;
+ LMI_ServiceRef_Init(&w, _cb, ns);
+ LMI_ServiceRef_Set_CreationClassName(&w, LMI_Service_ClassName);
+ LMI_ServiceRef_Set_SystemCreationClassName(&w, get_system_creation_class_name());
+ LMI_ServiceRef_Set_SystemName(&w, get_system_name());
+ LMI_ServiceRef_Set_Name(&w, slist->name[i]);
+
+ KReturnObjectPath(cr, w);
+ }
+ service_free_slist(slist);
+
+ CMReturn(CMPI_RC_OK);
+}
+
+static CMPIStatus LMI_ServiceEnumInstances(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const char** properties)
+{
+ CMPIStatus st;
+ CMPIEnumeration* e;
+ if (!(e = _cb->bft->enumerateInstanceNames(_cb, cc, cop, &st))) {
+ KReturn2(_cb, ERR_FAILED, "Unable to enumerate instances of LMI_Service");
+ }
+ CMPIData cd;
+ while (CMHasNext(e, &st)) {
+
+ cd = CMGetNext(e, &st);
+ if (st.rc || cd.type != CMPI_ref) {
+ KReturn2(_cb, ERR_FAILED, "Enumerate instances didn't returned list of references");
+ }
+ CMPIInstance *in = _cb->bft->getInstance(_cb, cc, cd.value.ref, properties, &st);
+ if (st.rc) {
+ KReturn2(_cb, ERR_FAILED, "Unable to get instance of LMI_Service");
+ }
+ cr->ft->returnInstance(cr, in);
+ }
+ KReturn(OK);
+}
+
+static CMPIStatus LMI_ServiceGetInstance(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const char** properties)
+{
+ LMI_Service w;
+ LMI_Service_InitFromObjectPath(&w, _cb, cop);
+
+ Service servicebuf;
+ if (service_get_properties(&servicebuf, w.Name.chars)) {
+ LMI_Service_Set_Status(&w, servicebuf.svStatus);
+ free(servicebuf.svStatus);
+ LMI_Service_Set_Started(&w, servicebuf.svStarted);
+ LMI_Service_Set_Caption(&w, servicebuf.svCaption);
+ free(servicebuf.svCaption);
+ LMI_Service_Init_OperationalStatus(&w, servicebuf.svOperationalStatusCnt);
+ for (int i = 0; i < servicebuf.svOperationalStatusCnt; i++) {
+ LMI_Service_Set_OperationalStatus(&w, i, servicebuf.svOperationalStatus[i]);
+ }
+
+ switch (servicebuf.svEnabledDefault) {
+ case ENABLED:
+ LMI_Service_Set_EnabledDefault(&w, LMI_Service_EnabledDefault_Enabled);
+ break;
+ case DISABLED:
+ LMI_Service_Set_EnabledDefault(&w, LMI_Service_EnabledDefault_Disabled);
+ break;
+ default:
+ LMI_Service_Set_EnabledDefault(&w, LMI_Service_EnabledDefault_Not_Applicable);
+ break;
+ }
+
+ KReturnInstance(cr, w);
+ KReturn(OK);
+ } else {
+ KReturn(ERR_NOT_FOUND);
+ }
+}
+
+static CMPIStatus LMI_ServiceCreateInstance(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const CMPIInstance* ci)
+{
+ CMReturn(CMPI_RC_ERR_NOT_SUPPORTED);
+}
+
+static CMPIStatus LMI_ServiceModifyInstance(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const CMPIInstance* ci,
+ const char** properties)
+{
+ CMReturn(CMPI_RC_ERR_NOT_SUPPORTED);
+}
+
+static CMPIStatus LMI_ServiceDeleteInstance(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop)
+{
+ CMReturn(CMPI_RC_ERR_NOT_SUPPORTED);
+}
+
+static CMPIStatus LMI_ServiceExecQuery(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const char* lang,
+ const char* query)
+{
+ CMReturn(CMPI_RC_ERR_NOT_SUPPORTED);
+}
+
+CMInstanceMIStub(
+ LMI_Service,
+ LMI_Service,
+ _cb,
+ LMI_ServiceInitialize())
+
+static CMPIStatus LMI_ServiceMethodCleanup(
+ CMPIMethodMI* mi,
+ const CMPIContext* cc,
+ CMPIBoolean term)
+{
+ CMReturn(CMPI_RC_OK);
+}
+
+static CMPIStatus LMI_ServiceInvokeMethod(
+ CMPIMethodMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const char* meth,
+ const CMPIArgs* in,
+ CMPIArgs* out)
+{
+ return LMI_Service_DispatchMethod(
+ _cb, mi, cc, cr, cop, meth, in, out);
+}
+
+CMMethodMIStub(
+ LMI_Service,
+ LMI_Service,
+ _cb,
+ LMI_ServiceInitialize())
+
+KUint32 LMI_Service_RequestStateChange(
+ const CMPIBroker* cb,
+ CMPIMethodMI* mi,
+ const CMPIContext* context,
+ const LMI_ServiceRef* self,
+ const KUint16* RequestedState,
+ KRef* Job,
+ const KDateTime* TimeoutPeriod,
+ CMPIStatus* status)
+{
+ KUint32 result = KUINT32_INIT;
+
+ KSetStatus(status, ERR_NOT_SUPPORTED);
+ return result;
+}
+
+unsigned int Service_RunOperation(const char *service, const char *operation, CMPIStatus *status)
+{
+ char output[1024];
+ int res = service_operation(service, operation, output, sizeof(output));
+ if (res == 0) {
+ KSetStatus2(_cb, status, OK, output);
+ } else {
+ KSetStatus2(_cb, status, ERR_FAILED, output);
+ }
+ return res;
+}
+
+KUint32 LMI_Service_StartService(
+ const CMPIBroker* cb,
+ CMPIMethodMI* mi,
+ const CMPIContext* context,
+ const LMI_ServiceRef* self,
+ CMPIStatus* status)
+{
+ KUint32 result = KUINT32_INIT;
+ KUint32_Set(&result, Service_RunOperation(self->Name.chars, "StartUnit", status));
+ return result;
+}
+
+KUint32 LMI_Service_StopService(
+ const CMPIBroker* cb,
+ CMPIMethodMI* mi,
+ const CMPIContext* context,
+ const LMI_ServiceRef* self,
+ CMPIStatus* status)
+{
+ KUint32 result = KUINT32_INIT;
+ KUint32_Set(&result, Service_RunOperation(self->Name.chars, "StopUnit", status));
+ return result;
+}
+
+KUint32 LMI_Service_ChangeAffectedElementsAssignedSequence(
+ const CMPIBroker* cb,
+ CMPIMethodMI* mi,
+ const CMPIContext* context,
+ const LMI_ServiceRef* self,
+ const KRefA* ManagedElements,
+ const KUint16A* AssignedSequence,
+ KRef* Job,
+ CMPIStatus* status)
+{
+ KUint32 result = KUINT32_INIT;
+
+ KSetStatus(status, ERR_NOT_SUPPORTED);
+ return result;
+}
+
+KUint32 LMI_Service_ReloadService(
+ const CMPIBroker* cb,
+ CMPIMethodMI* mi,
+ const CMPIContext* context,
+ const LMI_ServiceRef* self,
+ CMPIStatus* status)
+{
+ KUint32 result = KUINT32_INIT;
+ KUint32_Set(&result, Service_RunOperation(self->Name.chars, "ReloadUnit", status));
+ return result;
+}
+
+KUint32 LMI_Service_RestartService(
+ const CMPIBroker* cb,
+ CMPIMethodMI* mi,
+ const CMPIContext* context,
+ const LMI_ServiceRef* self,
+ CMPIStatus* status)
+{
+ KUint32 result = KUINT32_INIT;
+ KUint32_Set(&result, Service_RunOperation(self->Name.chars, "RestartUnit", status));
+ return result;
+}
+
+KUint32 LMI_Service_TryRestartService(
+ const CMPIBroker* cb,
+ CMPIMethodMI* mi,
+ const CMPIContext* context,
+ const LMI_ServiceRef* self,
+ CMPIStatus* status)
+{
+ KUint32 result = KUINT32_INIT;
+ KUint32_Set(&result, Service_RunOperation(self->Name.chars, "TryRestartUnit", status));
+ return result;
+}
+
+KUint32 LMI_Service_CondRestartService(
+ const CMPIBroker* cb,
+ CMPIMethodMI* mi,
+ const CMPIContext* context,
+ const LMI_ServiceRef* self,
+ CMPIStatus* status)
+{
+ KUint32 result = KUINT32_INIT;
+ KUint32_Set(&result, Service_RunOperation(self->Name.chars, "TryRestartUnit", status));
+ return result;
+}
+
+KUint32 LMI_Service_ReloadOrRestartService(
+ const CMPIBroker* cb,
+ CMPIMethodMI* mi,
+ const CMPIContext* context,
+ const LMI_ServiceRef* self,
+ CMPIStatus* status)
+{
+ KUint32 result = KUINT32_INIT;
+ KUint32_Set(&result, Service_RunOperation(self->Name.chars, "ReloadOrRestartUnit", status));
+ return result;
+}
+
+KUint32 LMI_Service_ReloadOrTryRestartService(
+ const CMPIBroker* cb,
+ CMPIMethodMI* mi,
+ const CMPIContext* context,
+ const LMI_ServiceRef* self,
+ CMPIStatus* status)
+{
+ KUint32 result = KUINT32_INIT;
+ KUint32_Set(&result, Service_RunOperation(self->Name.chars, "ReloadOrTryRestartUnit", status));
+ return result;
+}
+
+KUint32 LMI_Service_TurnServiceOn(
+ const CMPIBroker* cb,
+ CMPIMethodMI* mi,
+ const CMPIContext* context,
+ const LMI_ServiceRef* self,
+ CMPIStatus* status)
+{
+ KUint32 result = KUINT32_INIT;
+ KUint32_Set(&result, Service_RunOperation(self->Name.chars, "EnableUnitFiles", status));
+ return result;
+}
+
+KUint32 LMI_Service_TurnServiceOff(
+ const CMPIBroker* cb,
+ CMPIMethodMI* mi,
+ const CMPIContext* context,
+ const LMI_ServiceRef* self,
+ CMPIStatus* status)
+{
+ KUint32 result = KUINT32_INIT;
+ KUint32_Set(&result, Service_RunOperation(self->Name.chars, "DisableUnitFiles", status));
+ return result;
+}
+
+KONKRET_REGISTRATION(
+ "root/cimv2",
+ "LMI_Service",
+ "LMI_Service",
+ "instance method")
diff --git a/src/service-dbus/util/serviceutil.c b/src/service-dbus/util/serviceutil.c
new file mode 100644
index 0000000..32bd76a
--- /dev/null
+++ b/src/service-dbus/util/serviceutil.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2012-2013 Red Hat, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Vitezslav Crhonek <vcrhonek@redhat.com>
+ * Radek Novacek <rnovacek@redhat.com>
+ */
+
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <gio/gio.h>
+
+#include "serviceutil.h"
+
+#define MAX_SLIST_CNT 1000
+
+#define MANAGER_NAME "org.freedesktop.systemd1"
+#define MANAGER_OP "/org/freedesktop/systemd1"
+#define MANAGER_INTERFACE "org.freedesktop.systemd1.Manager"
+#define UNIT_INTERFACE "org.freedesktop.systemd1.Unit"
+#define SERVICE_INTERFACE "org.freedesktop.systemd1.Service"
+#define PROPERTY_INTERFACE "org.freedesktop.DBus.Properties"
+
+void service_free_slist(SList *slist)
+{
+ int i;
+
+ if (!slist)
+ return;
+
+ for(i = 0; i < slist->cnt; i++)
+ free(slist->name[i]);
+ free(slist->name);
+ free(slist);
+
+ return;
+}
+
+SList *service_find_all(void)
+{
+ GDBusProxy *manager_proxy = NULL;
+ GVariantIter *arr = NULL;
+ GVariant *result = NULL;
+ GError *error = NULL;
+ SList *slist = NULL;
+ gchar *primary_unit_name = NULL;
+ char *tmps = NULL;
+
+ g_type_init();
+
+ manager_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, MANAGER_NAME, MANAGER_OP, MANAGER_INTERFACE, NULL, &error);
+ if (!manager_proxy) {
+ g_error_free(error);
+ return NULL;
+ }
+
+ error = NULL;
+ result = g_dbus_proxy_call_sync(manager_proxy, "ListUnitFiles", NULL,
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+ if (error) {
+ g_error_free(error);
+ g_object_unref(manager_proxy);
+ return NULL;
+ }
+
+ slist = malloc(sizeof(SList));
+ if (!slist) return NULL;
+ slist->name = malloc(MAX_SLIST_CNT * sizeof(char *));
+ if (!slist->name) {
+ free(slist);
+ return NULL;
+ }
+ slist->cnt = 0;
+
+ g_variant_get(result, "(a(ss))", &arr);
+ while (g_variant_iter_loop(arr, "(ss)", &primary_unit_name, NULL)) {
+ if (strstr(primary_unit_name, ".service")) {
+ tmps = strdup(primary_unit_name);
+ if (!tmps)
+ continue;
+ slist->name[slist->cnt] = strndup(basename(tmps), strlen(basename(tmps)));
+ if (!slist->name[slist->cnt]) {
+ free(tmps);
+ continue;
+ }
+ free(tmps);
+ slist->cnt++;
+ }
+ }
+ g_variant_iter_free(arr);
+
+ g_object_unref(manager_proxy);
+ return slist;
+}
+
+
+int service_get_properties(
+ Service *svc,
+ const char *service)
+{
+ GDBusProxy *manager_proxy = NULL;
+ GDBusProxy *proxy = NULL;
+ GVariantIter *arr = NULL;
+ GVariant *result = NULL;
+ GVariant *result2 = NULL;
+ GError *error = NULL;
+ gchar *fragment_path = NULL, *unit_file_state = NULL;
+ gchar *unit, *value_str;
+ unsigned long value_long;
+
+ g_type_init();
+
+ svc->svName = strdup(service);
+ if (!svc->svName) return 0;
+
+ manager_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, MANAGER_NAME, MANAGER_OP, MANAGER_INTERFACE, NULL, &error);
+ if (!manager_proxy) goto error;
+
+ error = NULL;
+ result = g_dbus_proxy_call_sync(manager_proxy, "ListUnitFiles", NULL,
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+ if (error) goto error;
+
+ svc->svEnabledDefault = NOT_APPLICABLE;
+ g_variant_get(result, "(a(ss))", &arr);
+ while (g_variant_iter_loop(arr, "(ss)", &fragment_path, &unit_file_state)) {
+ if (strstr(fragment_path, service) && strcmp(strstr(fragment_path, service), service) == 0) {
+ if (strncmp(unit_file_state, "enabled", 7) == 0)
+ svc->svEnabledDefault = ENABLED;
+ if (strncmp(unit_file_state, "disabled", 8) == 0)
+ svc->svEnabledDefault = DISABLED;
+ }
+ }
+ g_variant_iter_free(arr);
+ arr = NULL;
+
+ error = NULL;
+ result = g_dbus_proxy_call_sync(manager_proxy, "LoadUnit", g_variant_new("(s)", service),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+ if (error) goto error;
+
+ g_object_unref(manager_proxy);
+ manager_proxy = NULL;
+ g_variant_get(result, "(o)", &unit);
+
+ proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, MANAGER_NAME, unit, PROPERTY_INTERFACE, NULL, &error);
+ if (!proxy) goto error;
+
+ error = NULL;
+ result = g_dbus_proxy_call_sync(proxy, "Get", g_variant_new("(ss)", UNIT_INTERFACE, "Description"),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+ if (error) goto error;
+
+ g_variant_get(result, "(v)", &result2);
+ g_variant_get(result2, "s", &value_str);
+ svc->svCaption = strdup(value_str);
+ if (!svc->svCaption) goto error;
+
+ error = NULL;
+ result = g_dbus_proxy_call_sync(proxy, "Get", g_variant_new("(ss)", SERVICE_INTERFACE, "MainPID"),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+ if (error) goto error;
+
+ g_variant_get(result, "(v)", &result2);
+ g_variant_get(result2, "u", &value_long);
+ svc->pid = value_long;
+
+ error = NULL;
+ result = g_dbus_proxy_call_sync(proxy, "Get", g_variant_new("(ss)", UNIT_INTERFACE, "ActiveState"),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+ if (error) goto error;
+
+ g_variant_get(result, "(v)", &result2);
+ g_variant_get(result2, "s", &value_str);
+
+ if (!strcmp(value_str, "active")) {
+ svc->svOperationalStatus[0] = OS_OK;
+ svc->svOperationalStatusCnt = 1;
+ }
+ else if (!strcmp(value_str, "inactive")) {
+ svc->svOperationalStatus[0] = OS_COMPLETED;
+ svc->svOperationalStatus[1] = OS_OK;
+ svc->svOperationalStatusCnt = 2;
+ }
+ else if (!strcmp(value_str, "failed")) {
+ svc->svOperationalStatus[0] = OS_COMPLETED;
+ svc->svOperationalStatus[1] = OS_ERROR;
+ svc->svOperationalStatusCnt = 2;
+ }
+ else if (!strcmp(value_str, "activating")) {
+ svc->svOperationalStatus[0] = OS_STARTING;
+ svc->svOperationalStatusCnt = 1;
+ }
+ else if (!strcmp(value_str, "deactivating")) {
+ svc->svOperationalStatus[0] = OS_STOPPING;
+ svc->svOperationalStatusCnt = 1;
+ }
+
+ if (svc->pid) {
+ svc->svStarted = 1;
+ svc->svStatus = strdup("OK");
+ } else {
+ svc->svStarted = 0;
+ svc->svStatus = strdup("Stopped");
+ }
+ if (!svc->svStatus) goto error;
+
+ g_object_unref(proxy);
+ return 1;
+
+error:
+ if (svc->svName) free(svc->svName);
+ if (error) g_error_free(error);
+ if (manager_proxy) g_object_unref(manager_proxy);
+ if (proxy) g_object_unref(proxy);
+ if (svc->svCaption) free(svc->svCaption);
+
+ return 0;
+}
+
+unsigned int service_operation(
+ const char *service,
+ const char *method,
+ char *output,
+ int output_len)
+{
+ GDBusProxy *manager_proxy = NULL;
+ GVariant *result = NULL;
+ GError *error = NULL;
+ GVariantBuilder *builder;
+
+ g_type_init();
+
+ manager_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, MANAGER_NAME, MANAGER_OP, MANAGER_INTERFACE, NULL, &error);
+ if (!manager_proxy) {
+ g_error_free(error);
+ return -1;
+ }
+
+ error = NULL;
+ if (!strcasecmp(method, "EnableUnitFiles") || !strcasecmp(method, "DisableUnitFiles")) {
+ builder = g_variant_builder_new(G_VARIANT_TYPE ("as"));
+ g_variant_builder_add(builder, "s", service);
+ if (!strcasecmp(method, "EnableUnitFiles")) {
+ result = g_dbus_proxy_call_sync(manager_proxy, method, g_variant_new("(asbb)", builder, FALSE, TRUE),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+ } else {
+ result = g_dbus_proxy_call_sync(manager_proxy, method, g_variant_new("(asb)", builder, FALSE),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+ }
+ if (error) {
+ g_error_free(error);
+ g_object_unref(manager_proxy);
+ return -1;
+ }
+ } else {
+ result = g_dbus_proxy_call_sync(manager_proxy, method, g_variant_new("(ss)", service, "replace"),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+ if (error) {
+ g_error_free(error);
+ g_object_unref(manager_proxy);
+ return -1;
+ }
+ }
+
+ g_object_unref(manager_proxy);
+ return 0;
+}
diff --git a/src/service-dbus/util/serviceutil.h b/src/service-dbus/util/serviceutil.h
new file mode 100644
index 0000000..d3dcc33
--- /dev/null
+++ b/src/service-dbus/util/serviceutil.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2012-2013 Red Hat, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Vitezslav Crhonek <vcrhonek@redhat.com>
+ */
+
+
+#ifndef SERVICEUTIL_H
+#define SERVICEUTIL_H
+
+#include <stdio.h>
+
+#define ARRAY_SIZE(name) (sizeof(name) / sizeof(name[0]))
+
+enum OperationalStatus {OS_UNKNOWN = 0, OS_OK = 2, OS_ERROR = 6, OS_STARTING = 8, OS_STOPPING = 9, OS_STOPPED = 10, OS_COMPLETED = 17};
+enum ServiceEnabledDefault {ENABLED = 2, DISABLED = 3, NOT_APPLICABLE = 5};
+
+struct _Service {
+ char *svSystemCCname;
+ char *svSystemname;
+ char *svCCname;
+ char *svName; /* "rsyslog.service", "httpd.service", ... */
+ char *svCaption; /* "Description" field from unit file */
+ enum OperationalStatus svOperationalStatus[2]; /* see enum definition - current status of the element */
+ int svOperationalStatusCnt;
+ char *svStatus; /* "Stopped", "OK" - deprecated, but recommended to fill */
+ enum ServiceEnabledDefault svEnabledDefault;
+ int svStarted; /* 0, 1 */
+ int pid; /* PID */
+};
+
+struct _SList {
+ char **name;
+ int cnt;
+};
+
+typedef struct _Service Service;
+typedef struct _SList SList;
+
+void service_free_slist(SList *slist);
+SList *service_find_all(void);
+
+int service_get_properties(Service *svc, const char *service);
+
+unsigned int service_operation(const char *service, const char *method, char *output, int output_len);
+
+#endif