From 78244e3db39e98e3243f82f153cf9ca350904879 Mon Sep 17 00:00:00 2001 From: Vitezslav Crhonek Date: Mon, 13 May 2013 16:37:48 +0200 Subject: service: added dbus based service provider --- README | 4 +- src/CMakeLists.txt | 2 +- src/service-dbus/CMakeLists.txt | 30 +++ src/service-dbus/LMI_ServiceProvider.c | 382 +++++++++++++++++++++++++++++++++ src/service-dbus/util/serviceutil.c | 290 +++++++++++++++++++++++++ src/service-dbus/util/serviceutil.h | 61 ++++++ 6 files changed, 766 insertions(+), 3 deletions(-) create mode 100644 src/service-dbus/CMakeLists.txt create mode 100644 src/service-dbus/LMI_ServiceProvider.c create mode 100644 src/service-dbus/util/serviceutil.c create mode 100644 src/service-dbus/util/serviceutil.h diff --git a/README b/README index f1cf2a8..a80a1d2 100644 --- a/README +++ b/README @@ -74,8 +74,8 @@ Provider specific dependencies: - shutdown and reboot commands in $PATH (usually provided by systemd or upstart or SysVinit) * Service - - chkconfig - - systemd or upstart or SysVinit + - glib2-devel 2.26+ + - systemd * RealmD - glib2-devel - dbus-devel diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0cd11d9..9f714d0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,7 +26,7 @@ if (WITH-POWER) endif (WITH-POWER) if (WITH-SERVICE) - add_subdirectory(service) + add_subdirectory(service-dbus) endif (WITH-SERVICE) if (WITH-ACCOUNT) 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 + * Radek Novacek + */ + +#include +#include +#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 + * Radek Novacek + */ + + +#include +#include +#include +#include +#include +#include +#include + +#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 + */ + + +#ifndef SERVICEUTIL_H +#define SERVICEUTIL_H + +#include + +#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 -- cgit