summaryrefslogtreecommitdiffstats
path: root/src/service-dbus/util/serviceutil.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/service-dbus/util/serviceutil.c')
-rw-r--r--src/service-dbus/util/serviceutil.c199
1 files changed, 199 insertions, 0 deletions
diff --git a/src/service-dbus/util/serviceutil.c b/src/service-dbus/util/serviceutil.c
index b56bd16..bca196e 100644
--- a/src/service-dbus/util/serviceutil.c
+++ b/src/service-dbus/util/serviceutil.c
@@ -56,6 +56,24 @@ void service_free_slist(SList *slist)
return;
}
+void service_free_all_services(AllServices *svcs)
+{
+ int i;
+
+ if (!svcs)
+ return;
+
+ for(i = 0; i < svcs->cnt; i++) {
+ free(svcs->svc[i]->svName);
+ free(svcs->svc[i]->svCaption);
+ free(svcs->svc[i]->svStatus);
+ free(svcs->svc[i]);
+ }
+ free(svcs);
+
+ return;
+}
+
SList *service_find_all(
char *output,
int output_len)
@@ -140,6 +158,187 @@ SList *service_find_all(
return slist;
}
+AllServices *service_get_properties_all(
+ char *output,
+ int output_len)
+{
+ GDBusProxy *manager_proxy = NULL;
+ GDBusProxy *proxy = NULL;
+ GVariantIter *arr = NULL;
+ GVariant *result = NULL;
+ GVariant *result2 = NULL;
+ GError *error = NULL;
+ gchar *primary_unit_name = NULL, *unit_file_state = NULL;
+ gchar *unit, *value_str;
+ AllServices *svcs = NULL;
+ char *tmps = NULL;
+
+ svcs = malloc(sizeof(AllServices));
+ if (!svcs) {
+ strncpy(output, "Insufficient memory", output_len);
+ return NULL;
+ }
+ svcs->nalloc = INITIAL_SLIST_NALLOC;
+ svcs->svc = malloc(svcs->nalloc * sizeof(Service *));
+ if (!svcs->svc) {
+ free(svcs);
+ strncpy(output, "Insufficient memory", output_len);
+ return NULL;
+ }
+ svcs->cnt = 0;
+
+#if !defined(GLIB_VERSION_2_36)
+ g_type_init();
+#endif
+
+ 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 err;
+
+ error = NULL;
+ result = g_dbus_proxy_call_sync(manager_proxy, "ListUnitFiles", NULL,
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+ if (error) goto err;
+
+ g_variant_get(result, "(a(ss))", &arr);
+ while (g_variant_iter_loop(arr, "(ss)", &primary_unit_name, &unit_file_state)) {
+ /* Ignore instantiable units (containing '@') until we find out how to properly present them */
+ if (strstr(primary_unit_name, ".service") && strchr(primary_unit_name, '@') == NULL) {
+
+ /* Realloc we are out of space */
+ if (svcs->cnt >= svcs->nalloc) {
+ Service **tmpp = NULL;
+ svcs->nalloc *= 2;
+ tmpp = realloc(svcs->svc, svcs->nalloc * sizeof(Service *));
+ if (!tmpp) {
+ g_variant_iter_free(arr);
+ service_free_all_services(svcs);
+ g_object_unref(manager_proxy);
+ strncpy(output, "Insufficient memory", output_len);
+ return NULL;
+ }
+ svcs->svc = tmpp;
+ }
+
+ svcs->svc[svcs->cnt] = malloc(sizeof(Service));
+
+ /* Fill svName */
+ tmps = strdup(primary_unit_name);
+ if (!tmps) {
+ g_variant_iter_free(arr);
+ service_free_all_services(svcs);
+ g_object_unref(manager_proxy);
+ strncpy(output, "Insufficient memory", output_len);
+ return NULL;
+ }
+ svcs->svc[svcs->cnt]->svName = strndup(basename(tmps), strlen(basename(tmps)));
+ if (!svcs->svc[svcs->cnt]->svName) {
+ free(tmps);
+ g_variant_iter_free(arr);
+ service_free_all_services(svcs);
+ g_object_unref(manager_proxy);
+ strncpy(output, "Insufficient memory", output_len);
+ return NULL;
+ }
+ free(tmps);
+
+ /* Fill svEnabledDefault */
+ svcs->svc[svcs->cnt]->svEnabledDefault = NOT_APPLICABLE;
+ if (strncmp(unit_file_state, "enabled", 7) == 0)
+ svcs->svc[svcs->cnt]->svEnabledDefault = ENABLED;
+ if (strncmp(unit_file_state, "disabled", 8) == 0)
+ svcs->svc[svcs->cnt]->svEnabledDefault = DISABLED;
+
+ error = NULL;
+ result = g_dbus_proxy_call_sync(manager_proxy, "LoadUnit", g_variant_new("(s)", svcs->svc[svcs->cnt]->svName),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+ if (error) goto err;
+
+ 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 err;
+
+ 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 err;
+
+ /* Fill svCaption */
+ g_variant_get(result, "(v)", &result2);
+ g_variant_get(result2, "s", &value_str);
+ svcs->svc[svcs->cnt]->svCaption = strdup(value_str);
+ if (!svcs->svc[svcs->cnt]->svCaption) goto err;
+
+ 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 err;
+
+ /* Fill svOperationalStatus, svStarted, svStatus */
+ g_variant_get(result, "(v)", &result2);
+ g_variant_get(result2, "s", &value_str);
+
+ if (strcmp(value_str, "active") == 0) {
+ svcs->svc[svcs->cnt]->svOperationalStatus[0] = OS_OK;
+ svcs->svc[svcs->cnt]->svOperationalStatusCnt = 1;
+ svcs->svc[svcs->cnt]->svStarted = 1;
+ svcs->svc[svcs->cnt]->svStatus = strdup("OK");
+ }
+ else if (strcmp(value_str, "inactive") == 0) {
+ svcs->svc[svcs->cnt]->svOperationalStatus[0] = OS_COMPLETED;
+ svcs->svc[svcs->cnt]->svOperationalStatus[1] = OS_OK;
+ svcs->svc[svcs->cnt]->svOperationalStatusCnt = 2;
+ svcs->svc[svcs->cnt]->svStarted = 0;
+ svcs->svc[svcs->cnt]->svStatus = strdup("Stopped");
+ }
+ else if (strcmp(value_str, "failed") == 0) {
+ svcs->svc[svcs->cnt]->svOperationalStatus[0] = OS_COMPLETED;
+ svcs->svc[svcs->cnt]->svOperationalStatus[1] = OS_ERROR;
+ svcs->svc[svcs->cnt]->svOperationalStatusCnt = 2;
+ svcs->svc[svcs->cnt]->svStarted = 0;
+ svcs->svc[svcs->cnt]->svStatus = strdup("Stopped");
+ }
+ else if (strcmp(value_str, "activating") == 0) {
+ svcs->svc[svcs->cnt]->svOperationalStatus[0] = OS_STARTING;
+ svcs->svc[svcs->cnt]->svOperationalStatusCnt = 1;
+ svcs->svc[svcs->cnt]->svStarted = 0;
+ svcs->svc[svcs->cnt]->svStatus = strdup("Stopped");
+ }
+ else if (strcmp(value_str, "deactivating") == 0) {
+ svcs->svc[svcs->cnt]->svOperationalStatus[0] = OS_STOPPING;
+ svcs->svc[svcs->cnt]->svOperationalStatusCnt = 1;
+ svcs->svc[svcs->cnt]->svStarted = 1;
+ svcs->svc[svcs->cnt]->svStatus = strdup("OK");
+ }
+ if (!svcs->svc[svcs->cnt]->svStatus) goto err;
+
+ g_object_unref(proxy);
+ svcs->cnt++;
+ }
+ }
+ g_variant_iter_free(arr);
+ arr = NULL;
+
+ g_object_unref(manager_proxy);
+ manager_proxy = NULL;
+
+ return svcs;
+
+err:
+ service_free_all_services(svcs);
+ if (error) {
+ strncpy(output, error->message, output_len);
+ g_error_free(error);
+ }
+ if (arr) g_variant_iter_free(arr);
+ if (manager_proxy) g_object_unref(manager_proxy);
+ if (proxy) g_object_unref(proxy);
+
+ return NULL;
+}
+
int service_get_properties(
Service *svc,