diff options
Diffstat (limited to 'src/service-dbus/util/serviceutil.c')
-rw-r--r-- | src/service-dbus/util/serviceutil.c | 199 |
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, |