/*
* This file is part of Cockpit.
*
* Copyright (C) 2016 Red Hat, Inc.
*
* Cockpit 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.
*
* Cockpit 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 Cockpit; If not, see .
*/
#include "config.h"
#include "cockpitdbusinternal.h"
#include "common/cockpitsystem.h"
#include
#include
static GVariant *
build_environment (void)
{
GVariantBuilder builder;
GVariant *variant;
gchar **environ = g_listenv ();
gint i;
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}"));
for (i = 0; environ[i] != NULL; i++)
{
const gchar *value = g_getenv (environ[i]);
if (value)
g_variant_builder_add (&builder, "{ss}", environ[i], value);
}
g_strfreev (environ);
variant = g_variant_builder_end (&builder);
return variant;
}
static GVariant *
lookup_session_id (void)
{
char *session_id;
GVariant *variant;
session_id = cockpit_system_session_id ();
variant = g_variant_new_string (session_id ? session_id : "");
free (session_id);
return variant;
}
static GVariant *
process_get_property (GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *property_name,
GError **error,
gpointer user_data)
{
g_return_val_if_fail (property_name != NULL, NULL);
if (g_str_equal (property_name, "Pid"))
return g_variant_new_uint32 (getpid ());
else if (g_str_equal (property_name, "Uid"))
return g_variant_new_int32 (getuid ());
else if (g_str_equal (property_name, "SessionId"))
return lookup_session_id ();
else if (g_str_equal (property_name, "StartTime"))
return g_variant_new_uint64 (cockpit_system_process_start_time ());
else if (g_str_equal (property_name, "Environment") || g_str_equal (property_name, "Variables"))
return build_environment ();
else
g_return_val_if_reached (NULL);
}
static GDBusInterfaceVTable process_vtable = {
.get_property = process_get_property,
};
static GDBusPropertyInfo pid_property = {
-1, "Pid", "u", G_DBUS_PROPERTY_INFO_FLAGS_READABLE, NULL
};
static GDBusPropertyInfo uid_property = {
-1, "Uid", "i", G_DBUS_PROPERTY_INFO_FLAGS_READABLE, NULL
};
static GDBusPropertyInfo start_time_property = {
-1, "StartTime", "t", G_DBUS_PROPERTY_INFO_FLAGS_READABLE, NULL
};
static GDBusPropertyInfo session_id_property = {
-1, "SessionId", "s", G_DBUS_PROPERTY_INFO_FLAGS_READABLE, NULL,
};
static GDBusPropertyInfo environment_property = {
-1, "Environment", "a{ss}", G_DBUS_PROPERTY_INFO_FLAGS_READABLE, NULL
};
static GDBusPropertyInfo *process_properties[] = {
&pid_property,
&uid_property,
&start_time_property,
&session_id_property,
&environment_property,
NULL
};
static GDBusInterfaceInfo process_interface = {
-1, "cockpit.Process", NULL, NULL, process_properties, NULL
};
static GDBusPropertyInfo variables_property = {
-1, "Variables", "a{ss}", G_DBUS_PROPERTY_INFO_FLAGS_READABLE, NULL
};
static GDBusPropertyInfo *environment_properties[] = {
&variables_property,
NULL
};
static GDBusInterfaceInfo environment_interface = {
-1, "cockpit.Environment", NULL, NULL, environment_properties, NULL
};
void
cockpit_dbus_process_startup (void)
{
GDBusConnection *connection;
GError *error = NULL;
connection = cockpit_dbus_internal_server ();
g_return_if_fail (connection != NULL);
g_dbus_connection_register_object (connection, "/environment", &environment_interface,
&process_vtable, NULL, NULL, &error);
if (error != NULL)
{
g_critical ("couldn't register DBus cockpit.Environment object: %s", error->message);
g_error_free (error);
}
g_dbus_connection_register_object (connection, "/bridge", &process_interface,
&process_vtable, NULL, NULL, &error);
if (error != NULL)
{
g_critical ("couldn't register DBus cockpit.Process object: %s", error->message);
g_error_free (error);
}
g_object_unref (connection);
}