2010-08-14 21:59:25 +04:00
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2010-02-01 05:33:24 +03:00
2010-02-03 15:03:47 +03:00
/***
This file is part of systemd .
Copyright 2010 Lennart Poettering
systemd is free software ; you can redistribute it and / or modify it
2012-04-12 02:20:58 +04:00
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
2010-02-03 15:03:47 +03:00
( at your option ) any later version .
systemd 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
2012-04-12 02:20:58 +04:00
Lesser General Public License for more details .
2010-02-03 15:03:47 +03:00
2012-04-12 02:20:58 +04:00
You should have received a copy of the GNU Lesser General Public License
2010-02-03 15:03:47 +03:00
along with systemd ; If not , see < http : //www.gnu.org/licenses/>.
* * */
2010-02-01 05:33:24 +03:00
# include <errno.h>
2011-03-30 04:12:46 +04:00
# include <unistd.h>
2010-02-01 05:33:24 +03:00
# include "dbus.h"
# include "log.h"
2010-04-18 05:08:16 +04:00
# include "dbus-manager.h"
2010-05-10 01:53:52 +04:00
# include "strv.h"
2010-07-08 04:43:18 +04:00
# include "bus-errors.h"
2011-03-04 20:34:56 +03:00
# include "build.h"
2011-04-16 03:54:49 +04:00
# include "dbus-common.h"
2011-07-23 05:44:47 +04:00
# include "install.h"
2012-09-07 00:23:11 +04:00
# include "selinux-access.h"
2012-04-13 23:33:28 +04:00
# include "watchdog.h"
2012-05-07 23:06:55 +04:00
# include "hwclock.h"
2012-05-09 03:24:50 +04:00
# include "path-util.h"
2012-10-03 01:07:00 +04:00
# include "dbus-unit.h"
2012-10-04 22:08:17 +04:00
# include "virt.h"
2010-02-01 05:33:24 +03:00
2010-09-21 07:23:12 +04:00
# define BUS_MANAGER_INTERFACE_BEGIN \
" <interface name= \" org.freedesktop.systemd1.Manager \" > \n "
# define BUS_MANAGER_INTERFACE_METHODS \
2010-05-23 05:45:33 +04:00
" <method name= \" GetUnit \" > \n " \
" <arg name= \" name \" type= \" s \" direction= \" in \" /> \n " \
" <arg name= \" unit \" type= \" o \" direction= \" out \" /> \n " \
" </method> \n " \
2010-08-13 04:07:22 +04:00
" <method name= \" GetUnitByPID \" > \n " \
2010-09-21 07:23:12 +04:00
" <arg name= \" pid \" type= \" u \" direction= \" in \" /> \n " \
2010-08-13 04:07:22 +04:00
" <arg name= \" unit \" type= \" o \" direction= \" out \" /> \n " \
" </method> \n " \
2010-05-23 05:45:33 +04:00
" <method name= \" LoadUnit \" > \n " \
" <arg name= \" name \" type= \" s \" direction= \" in \" /> \n " \
" <arg name= \" unit \" type= \" o \" direction= \" out \" /> \n " \
" </method> \n " \
2010-06-01 21:47:46 +04:00
" <method name= \" StartUnit \" > \n " \
" <arg name= \" name \" type= \" s \" direction= \" in \" /> \n " \
" <arg name= \" mode \" type= \" s \" direction= \" in \" /> \n " \
" <arg name= \" job \" type= \" o \" direction= \" out \" /> \n " \
" </method> \n " \
2010-10-19 23:53:19 +04:00
" <method name= \" StartUnitReplace \" > \n " \
" <arg name= \" old_unit \" type= \" s \" direction= \" in \" /> \n " \
" <arg name= \" new_unit \" type= \" s \" direction= \" in \" /> \n " \
" <arg name= \" mode \" type= \" s \" direction= \" in \" /> \n " \
" <arg name= \" job \" type= \" o \" direction= \" out \" /> \n " \
" </method> \n " \
2010-06-01 21:47:46 +04:00
" <method name= \" StopUnit \" > \n " \
" <arg name= \" name \" type= \" s \" direction= \" in \" /> \n " \
" <arg name= \" mode \" type= \" s \" direction= \" in \" /> \n " \
" <arg name= \" job \" type= \" o \" direction= \" out \" /> \n " \
" </method> \n " \
" <method name= \" ReloadUnit \" > \n " \
" <arg name= \" name \" type= \" s \" direction= \" in \" /> \n " \
" <arg name= \" mode \" type= \" s \" direction= \" in \" /> \n " \
" <arg name= \" job \" type= \" o \" direction= \" out \" /> \n " \
" </method> \n " \
" <method name= \" RestartUnit \" > \n " \
" <arg name= \" name \" type= \" s \" direction= \" in \" /> \n " \
" <arg name= \" mode \" type= \" s \" direction= \" in \" /> \n " \
" <arg name= \" job \" type= \" o \" direction= \" out \" /> \n " \
" </method> \n " \
2010-07-06 07:06:40 +04:00
" <method name= \" TryRestartUnit \" > \n " \
" <arg name= \" name \" type= \" s \" direction= \" in \" /> \n " \
" <arg name= \" mode \" type= \" s \" direction= \" in \" /> \n " \
" <arg name= \" job \" type= \" o \" direction= \" out \" /> \n " \
" </method> \n " \
2010-07-13 22:20:36 +04:00
" <method name= \" ReloadOrRestartUnit \" > \n " \
" <arg name= \" name \" type= \" s \" direction= \" in \" /> \n " \
" <arg name= \" mode \" type= \" s \" direction= \" in \" /> \n " \
" <arg name= \" job \" type= \" o \" direction= \" out \" /> \n " \
" </method> \n " \
" <method name= \" ReloadOrTryRestartUnit \" > \n " \
" <arg name= \" name \" type= \" s \" direction= \" in \" /> \n " \
" <arg name= \" mode \" type= \" s \" direction= \" in \" /> \n " \
" <arg name= \" job \" type= \" o \" direction= \" out \" /> \n " \
" </method> \n " \
2010-10-22 18:11:50 +04:00
" <method name= \" KillUnit \" > \n " \
" <arg name= \" name \" type= \" s \" direction= \" in \" /> \n " \
" <arg name= \" who \" type= \" s \" direction= \" in \" /> \n " \
" <arg name= \" signal \" type= \" i \" direction= \" in \" /> \n " \
" </method> \n " \
2010-08-31 02:23:34 +04:00
" <method name= \" ResetFailedUnit \" > \n " \
2010-07-18 06:58:01 +04:00
" <arg name= \" name \" type= \" s \" direction= \" in \" /> \n " \
" </method> \n " \
2010-05-23 05:45:33 +04:00
" <method name= \" GetJob \" > \n " \
" <arg name= \" id \" type= \" u \" direction= \" in \" /> \n " \
" <arg name= \" job \" type= \" o \" direction= \" out \" /> \n " \
" </method> \n " \
" <method name= \" ClearJobs \" /> \n " \
2010-08-31 02:23:34 +04:00
" <method name= \" ResetFailed \" /> \n " \
2010-05-23 05:45:33 +04:00
" <method name= \" ListUnits \" > \n " \
2010-07-20 22:33:19 +04:00
" <arg name= \" units \" type= \" a(ssssssouso) \" direction= \" out \" /> \n " \
2010-05-23 05:45:33 +04:00
" </method> \n " \
" <method name= \" ListJobs \" > \n " \
" <arg name= \" jobs \" type= \" a(usssoo) \" direction= \" out \" /> \n " \
" </method> \n " \
" <method name= \" Subscribe \" /> \n " \
" <method name= \" Unsubscribe \" /> \n " \
2012-06-29 18:14:01 +04:00
" <method name= \" Dump \" > \n " \
" <arg name= \" dump \" type= \" s \" direction= \" out \" /> \n " \
" </method> \n " \
2010-05-23 05:45:33 +04:00
" <method name= \" CreateSnapshot \" > \n " \
" <arg name= \" name \" type= \" s \" direction= \" in \" /> \n " \
2010-08-19 00:27:58 +04:00
" <arg name= \" cleanup \" type= \" b \" direction= \" in \" /> \n " \
2010-05-23 05:45:33 +04:00
" <arg name= \" unit \" type= \" o \" direction= \" out \" /> \n " \
" </method> \n " \
" <method name= \" Reload \" /> \n " \
" <method name= \" Reexecute \" /> \n " \
" <method name= \" Exit \" /> \n " \
2010-10-14 02:53:51 +04:00
" <method name= \" Reboot \" /> \n " \
" <method name= \" PowerOff \" /> \n " \
" <method name= \" Halt \" /> \n " \
" <method name= \" KExec \" /> \n " \
2012-05-09 03:24:50 +04:00
" <method name= \" SwitchRoot \" > \n " \
" <arg name= \" new_root \" type= \" s \" direction= \" in \" /> \n " \
" <arg name= \" init \" type= \" s \" direction= \" in \" /> \n " \
" </method> \n " \
2010-05-23 05:45:33 +04:00
" <method name= \" SetEnvironment \" > \n " \
" <arg name= \" names \" type= \" as \" direction= \" in \" /> \n " \
" </method> \n " \
" <method name= \" UnsetEnvironment \" > \n " \
" <arg name= \" names \" type= \" as \" direction= \" in \" /> \n " \
2011-06-15 17:31:54 +04:00
" </method> \n " \
" <method name= \" UnsetAndSetEnvironment \" > \n " \
" <arg name= \" unset \" type= \" as \" direction= \" in \" /> \n " \
" <arg name= \" set \" type= \" as \" direction= \" in \" /> \n " \
2011-07-23 05:44:47 +04:00
" </method> \n " \
" <method name= \" ListUnitFiles \" > \n " \
2012-07-16 21:11:27 +04:00
" <arg name= \" files \" type= \" a(ss) \" direction= \" out \" /> \n " \
2011-07-23 05:44:47 +04:00
" </method> \n " \
" <method name= \" GetUnitFileState \" > \n " \
" <arg name= \" file \" type= \" s \" direction= \" in \" /> \n " \
" <arg name= \" state \" type= \" s \" direction= \" out \" /> \n " \
" </method> \n " \
" <method name= \" EnableUnitFiles \" > \n " \
" <arg name= \" files \" type= \" as \" direction= \" in \" /> \n " \
" <arg name= \" runtime \" type= \" b \" direction= \" in \" /> \n " \
" <arg name= \" force \" type= \" b \" direction= \" in \" /> \n " \
2011-08-24 14:10:06 +04:00
" <arg name= \" carries_install_info \" type= \" b \" direction= \" out \" /> \n " \
2011-07-23 05:44:47 +04:00
" <arg name= \" changes \" type= \" a(sss) \" direction= \" out \" /> \n " \
" </method> \n " \
" <method name= \" DisableUnitFiles \" > \n " \
" <arg name= \" files \" type= \" as \" direction= \" in \" /> \n " \
" <arg name= \" runtime \" type= \" b \" direction= \" in \" /> \n " \
" <arg name= \" changes \" type= \" a(sss) \" direction= \" out \" /> \n " \
" </method> \n " \
" <method name= \" ReenableUnitFiles \" > \n " \
" <arg name= \" files \" type= \" as \" direction= \" in \" /> \n " \
" <arg name= \" runtime \" type= \" b \" direction= \" in \" /> \n " \
" <arg name= \" force \" type= \" b \" direction= \" in \" /> \n " \
2011-08-24 14:10:06 +04:00
" <arg name= \" carries_install_info \" type= \" b \" direction= \" out \" /> \n " \
2011-07-23 05:44:47 +04:00
" <arg name= \" changes \" type= \" a(sss) \" direction= \" out \" /> \n " \
" </method> \n " \
" <method name= \" LinkUnitFiles \" > \n " \
" <arg name= \" files \" type= \" as \" direction= \" in \" /> \n " \
" <arg name= \" runtime \" type= \" b \" direction= \" in \" /> \n " \
" <arg name= \" force \" type= \" b \" direction= \" in \" /> \n " \
" <arg name= \" changes \" type= \" a(sss) \" direction= \" out \" /> \n " \
" </method> \n " \
" <method name= \" PresetUnitFiles \" > \n " \
" <arg name= \" files \" type= \" as \" direction= \" in \" /> \n " \
" <arg name= \" runtime \" type= \" b \" direction= \" in \" /> \n " \
" <arg name= \" force \" type= \" b \" direction= \" in \" /> \n " \
2011-08-24 14:10:06 +04:00
" <arg name= \" carries_install_info \" type= \" b \" direction= \" out \" /> \n " \
2011-07-23 05:44:47 +04:00
" <arg name= \" changes \" type= \" a(sss) \" direction= \" out \" /> \n " \
" </method> \n " \
" <method name= \" MaskUnitFiles \" > \n " \
" <arg name= \" files \" type= \" as \" direction= \" in \" /> \n " \
" <arg name= \" runtime \" type= \" b \" direction= \" in \" /> \n " \
" <arg name= \" force \" type= \" b \" direction= \" in \" /> \n " \
" <arg name= \" changes \" type= \" a(sss) \" direction= \" out \" /> \n " \
" </method> \n " \
" <method name= \" UnmaskUnitFiles \" > \n " \
" <arg name= \" files \" type= \" as \" direction= \" in \" /> \n " \
" <arg name= \" runtime \" type= \" b \" direction= \" in \" /> \n " \
" <arg name= \" changes \" type= \" a(sss) \" direction= \" out \" /> \n " \
2010-09-21 07:23:12 +04:00
" </method> \n "
# define BUS_MANAGER_INTERFACE_SIGNALS \
2010-05-23 05:45:33 +04:00
" <signal name= \" UnitNew \" > \n " \
" <arg name= \" id \" type= \" s \" /> \n " \
" <arg name= \" unit \" type= \" o \" /> \n " \
" </signal> \n " \
" <signal name= \" UnitRemoved \" > \n " \
" <arg name= \" id \" type= \" s \" /> \n " \
" <arg name= \" unit \" type= \" o \" /> \n " \
" </signal> \n " \
" <signal name= \" JobNew \" > \n " \
" <arg name= \" id \" type= \" u \" /> \n " \
" <arg name= \" job \" type= \" o \" /> \n " \
2012-05-04 00:53:25 +04:00
" <arg name= \" unit \" type= \" s \" /> \n " \
2010-05-23 05:45:33 +04:00
" </signal> \n " \
" <signal name= \" JobRemoved \" > \n " \
" <arg name= \" id \" type= \" u \" /> \n " \
" <arg name= \" job \" type= \" o \" /> \n " \
2012-05-04 00:53:25 +04:00
" <arg name= \" unit \" type= \" s \" /> \n " \
2011-02-24 04:36:34 +03:00
" <arg name= \" result \" type= \" s \" /> \n " \
2011-06-27 15:47:03 +04:00
" </signal> " \
" <signal name= \" StartupFinished \" > \n " \
2012-09-13 20:54:32 +04:00
" <arg name= \" firmware \" type= \" t \" /> \n " \
" <arg name= \" loader \" type= \" t \" /> \n " \
2011-06-27 15:47:03 +04:00
" <arg name= \" kernel \" type= \" t \" /> \n " \
" <arg name= \" initrd \" type= \" t \" /> \n " \
" <arg name= \" userspace \" type= \" t \" /> \n " \
" <arg name= \" total \" type= \" t \" /> \n " \
2011-07-23 05:44:47 +04:00
" </signal> " \
" <signal name= \" UnitFilesChanged \" /> \n "
2010-09-21 07:23:12 +04:00
# define BUS_MANAGER_INTERFACE_PROPERTIES_GENERAL \
2010-05-23 05:45:33 +04:00
" <property name= \" Version \" type= \" s \" access= \" read \" /> \n " \
2011-03-04 20:34:56 +03:00
" <property name= \" Distribution \" type= \" s \" access= \" read \" /> \n " \
2011-03-04 21:47:43 +03:00
" <property name= \" Features \" type= \" s \" access= \" read \" /> \n " \
" <property name= \" Tainted \" type= \" s \" access= \" read \" /> \n " \
2012-09-13 20:54:32 +04:00
" <property name= \" FirmwareTimestamp \" type= \" t \" access= \" read \" /> \n " \
" <property name= \" FirmwareTimestampMonotonic \" type= \" t \" access= \" read \" /> \n " \
" <property name= \" LoaderTimestamp \" type= \" t \" access= \" read \" /> \n " \
" <property name= \" LoaderTimestampMonotonic \" type= \" t \" access= \" read \" /> \n " \
" <property name= \" KernelTimestamp \" type= \" t \" access= \" read \" /> \n " \
" <property name= \" KernelTimestampMonotonic \" type= \" t \" access= \" read \" /> \n " \
2010-11-08 08:31:09 +03:00
" <property name= \" InitRDTimestamp \" type= \" t \" access= \" read \" /> \n " \
2011-04-07 23:35:37 +04:00
" <property name= \" InitRDTimestampMonotonic \" type= \" t \" access= \" read \" /> \n " \
2012-09-13 20:54:32 +04:00
" <property name= \" UserspaceTimestamp \" type= \" t \" access= \" read \" /> \n " \
" <property name= \" UserspaceTimestampMonotonic \" type= \" t \" access= \" read \" /> \n " \
2010-11-08 08:31:09 +03:00
" <property name= \" FinishTimestamp \" type= \" t \" access= \" read \" /> \n " \
2011-04-07 23:35:37 +04:00
" <property name= \" FinishTimestampMonotonic \" type= \" t \" access= \" read \" /> \n " \
2011-03-06 19:17:02 +03:00
" <property name= \" LogLevel \" type= \" s \" access= \" readwrite \" /> \n " \
" <property name= \" LogTarget \" type= \" s \" access= \" readwrite \" /> \n " \
2010-05-23 05:45:33 +04:00
" <property name= \" NNames \" type= \" u \" access= \" read \" /> \n " \
" <property name= \" NJobs \" type= \" u \" access= \" read \" /> \n " \
2010-09-21 05:51:31 +04:00
" <property name= \" NInstalledJobs \" type= \" u \" access= \" read \" /> \n " \
2010-09-23 17:38:42 +04:00
" <property name= \" NFailedJobs \" type= \" u \" access= \" read \" /> \n " \
2010-09-21 18:55:35 +04:00
" <property name= \" Progress \" type= \" d \" access= \" read \" /> \n " \
2010-05-23 05:45:33 +04:00
" <property name= \" Environment \" type= \" as \" access= \" read \" /> \n " \
2010-07-04 06:47:19 +04:00
" <property name= \" ConfirmSpawn \" type= \" b \" access= \" read \" /> \n " \
2010-07-07 02:00:59 +04:00
" <property name= \" ShowStatus \" type= \" b \" access= \" read \" /> \n " \
2010-07-04 06:47:19 +04:00
" <property name= \" UnitPath \" type= \" as \" access= \" read \" /> \n " \
2010-07-11 02:50:49 +04:00
" <property name= \" ControlGroupHierarchy \" type= \" s \" access= \" read \" /> \n " \
2011-02-15 13:52:29 +03:00
" <property name= \" DefaultControllers \" type= \" as \" access= \" read \" /> \n " \
" <property name= \" DefaultStandardOutput \" type= \" s \" access= \" read \" /> \n " \
2012-04-06 00:08:10 +04:00
" <property name= \" DefaultStandardError \" type= \" s \" access= \" read \" /> \n " \
2012-04-13 23:33:28 +04:00
" <property name= \" RuntimeWatchdogUSec \" type= \" s \" access= \" readwrite \" /> \n " \
2012-10-04 22:08:17 +04:00
" <property name= \" ShutdownWatchdogUSec \" type= \" s \" access= \" readwrite \" /> \n " \
" <property name= \" Virtualization \" type= \" s \" access= \" read \" /> \n "
2010-09-21 07:23:12 +04:00
# define BUS_MANAGER_INTERFACE_END \
2010-05-23 05:45:33 +04:00
" </interface> \n "
2010-09-21 07:23:12 +04:00
# define BUS_MANAGER_INTERFACE \
BUS_MANAGER_INTERFACE_BEGIN \
BUS_MANAGER_INTERFACE_METHODS \
BUS_MANAGER_INTERFACE_SIGNALS \
BUS_MANAGER_INTERFACE_PROPERTIES_GENERAL \
BUS_MANAGER_INTERFACE_END
2010-02-01 05:33:24 +03:00
# define INTROSPECTION_BEGIN \
DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \
2010-05-23 05:45:33 +04:00
" <node> \n " \
BUS_MANAGER_INTERFACE \
2010-02-01 05:33:24 +03:00
BUS_PROPERTIES_INTERFACE \
2010-08-20 04:26:05 +04:00
BUS_PEER_INTERFACE \
2010-02-01 05:33:24 +03:00
BUS_INTROSPECTABLE_INTERFACE
# define INTROSPECTION_END \
2010-05-23 05:45:33 +04:00
" </node> \n "
2011-03-09 22:01:53 +03:00
# define INTERFACES_LIST \
BUS_GENERIC_INTERFACES_LIST \
" org.freedesktop.systemd1.Manager \0 "
2010-11-23 23:12:11 +03:00
const char bus_manager_interface [ ] _introspect_ ( " Manager " ) = BUS_MANAGER_INTERFACE ;
2010-02-01 05:33:24 +03:00
2011-02-15 13:52:29 +03:00
static DEFINE_BUS_PROPERTY_APPEND_ENUM ( bus_manager_append_exec_output , exec_output , ExecOutput ) ;
2010-04-10 19:40:18 +04:00
2011-04-16 03:54:49 +04:00
static int bus_manager_append_tainted ( DBusMessageIter * i , const char * property , void * data ) {
2011-03-04 21:47:43 +03:00
const char * t ;
2011-04-16 03:54:49 +04:00
Manager * m = data ;
2011-04-07 20:48:50 +04:00
char buf [ LINE_MAX ] = " " , * e = buf , * p = NULL ;
2011-03-04 21:47:43 +03:00
assert ( i ) ;
assert ( property ) ;
2011-04-16 03:54:49 +04:00
assert ( m ) ;
2011-03-04 21:47:43 +03:00
2011-03-30 02:47:50 +04:00
if ( m - > taint_usr )
2012-05-03 17:46:04 +04:00
e = stpcpy ( e , " split-usr: " ) ;
2011-03-04 21:47:43 +03:00
2011-03-30 04:12:46 +04:00
if ( readlink_malloc ( " /etc/mtab " , & p ) < 0 )
2012-05-03 17:46:04 +04:00
e = stpcpy ( e , " mtab-not-symlink: " ) ;
2011-03-30 04:12:46 +04:00
else
2011-03-04 21:47:43 +03:00
free ( p ) ;
2011-03-30 04:12:46 +04:00
if ( access ( " /proc/cgroups " , F_OK ) < 0 )
2012-05-09 23:42:56 +04:00
e = stpcpy ( e , " cgroups-missing: " ) ;
2011-03-30 04:12:46 +04:00
2012-05-03 17:46:04 +04:00
if ( hwclock_is_localtime ( ) > 0 )
2012-05-09 23:42:56 +04:00
e = stpcpy ( e , " local-hwclock: " ) ;
2012-05-03 17:46:04 +04:00
2012-05-09 23:42:56 +04:00
/* remove the last ':' */
if ( e ! = buf )
e [ - 1 ] = 0 ;
2012-05-03 17:46:04 +04:00
t = buf ;
2011-03-04 21:47:43 +03:00
if ( ! dbus_message_iter_append_basic ( i , DBUS_TYPE_STRING , & t ) )
return - ENOMEM ;
return 0 ;
}
2011-04-16 03:54:49 +04:00
static int bus_manager_append_log_target ( DBusMessageIter * i , const char * property , void * data ) {
2010-04-10 19:40:18 +04:00
const char * t ;
assert ( i ) ;
assert ( property ) ;
t = log_target_to_string ( log_get_target ( ) ) ;
if ( ! dbus_message_iter_append_basic ( i , DBUS_TYPE_STRING , & t ) )
return - ENOMEM ;
return 0 ;
}
2012-04-06 23:38:00 +04:00
static int bus_manager_set_log_target ( DBusMessageIter * i , const char * property , void * data ) {
2011-03-06 19:17:02 +03:00
const char * t ;
assert ( i ) ;
assert ( property ) ;
dbus_message_iter_get_basic ( i , & t ) ;
return log_set_target_from_string ( t ) ;
}
2011-04-16 03:54:49 +04:00
static int bus_manager_append_log_level ( DBusMessageIter * i , const char * property , void * data ) {
2010-04-10 19:40:18 +04:00
const char * t ;
assert ( i ) ;
assert ( property ) ;
t = log_level_to_string ( log_get_max_level ( ) ) ;
if ( ! dbus_message_iter_append_basic ( i , DBUS_TYPE_STRING , & t ) )
return - ENOMEM ;
return 0 ;
}
2012-04-06 23:38:00 +04:00
static int bus_manager_set_log_level ( DBusMessageIter * i , const char * property , void * data ) {
2011-03-06 19:17:02 +03:00
const char * t ;
assert ( i ) ;
assert ( property ) ;
dbus_message_iter_get_basic ( i , & t ) ;
return log_set_max_level_from_string ( t ) ;
}
2011-04-16 03:54:49 +04:00
static int bus_manager_append_n_names ( DBusMessageIter * i , const char * property , void * data ) {
Manager * m = data ;
2010-04-22 04:56:42 +04:00
uint32_t u ;
assert ( i ) ;
assert ( property ) ;
2011-04-16 03:54:49 +04:00
assert ( m ) ;
2010-04-22 04:56:42 +04:00
u = hashmap_size ( m - > units ) ;
if ( ! dbus_message_iter_append_basic ( i , DBUS_TYPE_UINT32 , & u ) )
return - ENOMEM ;
return 0 ;
}
2011-04-16 03:54:49 +04:00
static int bus_manager_append_n_jobs ( DBusMessageIter * i , const char * property , void * data ) {
Manager * m = data ;
2010-04-22 04:56:42 +04:00
uint32_t u ;
assert ( i ) ;
assert ( property ) ;
2011-04-16 03:54:49 +04:00
assert ( m ) ;
2010-04-22 04:56:42 +04:00
u = hashmap_size ( m - > jobs ) ;
if ( ! dbus_message_iter_append_basic ( i , DBUS_TYPE_UINT32 , & u ) )
return - ENOMEM ;
return 0 ;
}
2011-04-16 03:54:49 +04:00
static int bus_manager_append_progress ( DBusMessageIter * i , const char * property , void * data ) {
2010-09-21 06:25:48 +04:00
double d ;
2011-04-16 03:54:49 +04:00
Manager * m = data ;
2010-09-21 06:25:48 +04:00
assert ( i ) ;
assert ( property ) ;
2011-04-16 03:54:49 +04:00
assert ( m ) ;
2010-09-21 06:25:48 +04:00
if ( dual_timestamp_is_set ( & m - > finish_timestamp ) )
d = 1.0 ;
else
d = 1.0 - ( ( double ) hashmap_size ( m - > jobs ) / ( double ) m - > n_installed_jobs ) ;
if ( ! dbus_message_iter_append_basic ( i , DBUS_TYPE_DOUBLE , & d ) )
return - ENOMEM ;
return 0 ;
}
2012-10-04 22:08:17 +04:00
static int bus_manager_append_virt ( DBusMessageIter * i , const char * property , void * data ) {
Manager * m = data ;
const char * id = " " ;
assert ( i ) ;
assert ( property ) ;
assert ( m ) ;
detect_virtualization ( & id ) ;
if ( ! dbus_message_iter_append_basic ( i , DBUS_TYPE_STRING , & id ) )
return - ENOMEM ;
return 0 ;
}
2011-07-25 06:58:02 +04:00
static DBusMessage * message_from_file_changes (
DBusMessage * m ,
UnitFileChange * changes ,
unsigned n_changes ,
int carries_install_info ) {
2011-07-23 05:44:47 +04:00
DBusMessageIter iter , sub , sub2 ;
DBusMessage * reply ;
unsigned i ;
reply = dbus_message_new_method_return ( m ) ;
if ( ! reply )
return NULL ;
dbus_message_iter_init_append ( reply , & iter ) ;
2011-07-25 06:58:02 +04:00
if ( carries_install_info > = 0 ) {
dbus_bool_t b ;
2011-08-17 21:38:07 +04:00
b = ! ! carries_install_info ;
2011-07-25 06:58:02 +04:00
if ( ! dbus_message_iter_append_basic ( & iter , DBUS_TYPE_BOOLEAN , & b ) )
goto oom ;
}
2011-07-23 05:44:47 +04:00
if ( ! dbus_message_iter_open_container ( & iter , DBUS_TYPE_ARRAY , " (sss) " , & sub ) )
goto oom ;
for ( i = 0 ; i < n_changes ; i + + ) {
const char * type , * path , * source ;
type = unit_file_change_type_to_string ( changes [ i ] . type ) ;
path = strempty ( changes [ i ] . path ) ;
source = strempty ( changes [ i ] . source ) ;
if ( ! dbus_message_iter_open_container ( & sub , DBUS_TYPE_STRUCT , NULL , & sub2 ) | |
2011-07-25 06:58:02 +04:00
! dbus_message_iter_append_basic ( & sub2 , DBUS_TYPE_STRING , & type ) | |
! dbus_message_iter_append_basic ( & sub2 , DBUS_TYPE_STRING , & path ) | |
! dbus_message_iter_append_basic ( & sub2 , DBUS_TYPE_STRING , & source ) | |
2011-07-23 05:44:47 +04:00
! dbus_message_iter_close_container ( & sub , & sub2 ) )
goto oom ;
}
if ( ! dbus_message_iter_close_container ( & iter , & sub ) )
goto oom ;
return reply ;
oom :
dbus_message_unref ( reply ) ;
return NULL ;
}
static int bus_manager_send_unit_files_changed ( Manager * m ) {
DBusMessage * s ;
int r ;
s = dbus_message_new_signal ( " /org/freedesktop/systemd1 " , " org.freedesktop.systemd1.Manager " , " UnitFilesChanged " ) ;
if ( ! s )
return - ENOMEM ;
r = bus_broadcast ( m , s ) ;
dbus_message_unref ( s ) ;
return r ;
}
2012-04-13 23:33:28 +04:00
static int bus_manager_set_runtime_watchdog_usec ( DBusMessageIter * i , const char * property , void * data ) {
uint64_t * t = data ;
assert ( i ) ;
assert ( property ) ;
dbus_message_iter_get_basic ( i , t ) ;
return watchdog_set_timeout ( t ) ;
}
2012-04-06 00:08:10 +04:00
static const char systemd_property_string [ ] =
PACKAGE_STRING " \0 "
DISTRIBUTION " \0 "
SYSTEMD_FEATURES ;
2012-01-16 03:23:59 +04:00
static const BusProperty bus_systemd_properties [ ] = {
{ " Version " , bus_property_append_string , " s " , 0 } ,
{ " Distribution " , bus_property_append_string , " s " , sizeof ( PACKAGE_STRING ) } ,
{ " Features " , bus_property_append_string , " s " , sizeof ( PACKAGE_STRING ) + sizeof ( DISTRIBUTION ) } ,
{ NULL , }
} ;
static const BusProperty bus_manager_properties [ ] = {
2012-10-04 22:08:17 +04:00
{ " Tainted " , bus_manager_append_tainted , " s " , 0 } ,
{ " FirmwareTimestamp " , bus_property_append_uint64 , " t " , offsetof ( Manager , firmware_timestamp . realtime ) } ,
{ " FirmwareTimestampMonotonic " , bus_property_append_uint64 , " t " , offsetof ( Manager , firmware_timestamp . monotonic ) } ,
{ " LoaderTimestamp " , bus_property_append_uint64 , " t " , offsetof ( Manager , loader_timestamp . realtime ) } ,
{ " LoaderTimestampMonotonic " , bus_property_append_uint64 , " t " , offsetof ( Manager , loader_timestamp . monotonic ) } ,
{ " KernelTimestamp " , bus_property_append_uint64 , " t " , offsetof ( Manager , kernel_timestamp . realtime ) } ,
{ " KernelTimestampMonotonic " , bus_property_append_uint64 , " t " , offsetof ( Manager , kernel_timestamp . monotonic ) } ,
{ " InitRDTimestamp " , bus_property_append_uint64 , " t " , offsetof ( Manager , initrd_timestamp . realtime ) } ,
{ " InitRDTimestampMonotonic " , bus_property_append_uint64 , " t " , offsetof ( Manager , initrd_timestamp . monotonic ) } ,
{ " UserspaceTimestamp " , bus_property_append_uint64 , " t " , offsetof ( Manager , userspace_timestamp . realtime ) } ,
{ " UserspaceTimestampMonotonic " , bus_property_append_uint64 , " t " , offsetof ( Manager , userspace_timestamp . monotonic ) } ,
{ " FinishTimestamp " , bus_property_append_uint64 , " t " , offsetof ( Manager , finish_timestamp . realtime ) } ,
{ " FinishTimestampMonotonic " , bus_property_append_uint64 , " t " , offsetof ( Manager , finish_timestamp . monotonic ) } ,
{ " LogLevel " , bus_manager_append_log_level , " s " , 0 , false , bus_manager_set_log_level } ,
{ " LogTarget " , bus_manager_append_log_target , " s " , 0 , false , bus_manager_set_log_target } ,
{ " NNames " , bus_manager_append_n_names , " u " , 0 } ,
{ " NJobs " , bus_manager_append_n_jobs , " u " , 0 } ,
{ " NInstalledJobs " , bus_property_append_uint32 , " u " , offsetof ( Manager , n_installed_jobs ) } ,
{ " NFailedJobs " , bus_property_append_uint32 , " u " , offsetof ( Manager , n_failed_jobs ) } ,
{ " Progress " , bus_manager_append_progress , " d " , 0 } ,
{ " Environment " , bus_property_append_strv , " as " , offsetof ( Manager , environment ) , true } ,
{ " ConfirmSpawn " , bus_property_append_bool , " b " , offsetof ( Manager , confirm_spawn ) } ,
{ " ShowStatus " , bus_property_append_bool , " b " , offsetof ( Manager , show_status ) } ,
{ " UnitPath " , bus_property_append_strv , " as " , offsetof ( Manager , lookup_paths . unit_path ) , true } ,
{ " ControlGroupHierarchy " , bus_property_append_string , " s " , offsetof ( Manager , cgroup_hierarchy ) , true } ,
{ " DefaultControllers " , bus_property_append_strv , " as " , offsetof ( Manager , default_controllers ) , true } ,
{ " DefaultStandardOutput " , bus_manager_append_exec_output , " s " , offsetof ( Manager , default_std_output ) } ,
{ " DefaultStandardError " , bus_manager_append_exec_output , " s " , offsetof ( Manager , default_std_error ) } ,
{ " RuntimeWatchdogUSec " , bus_property_append_usec , " t " , offsetof ( Manager , runtime_watchdog ) , false , bus_manager_set_runtime_watchdog_usec } ,
{ " ShutdownWatchdogUSec " , bus_property_append_usec , " t " , offsetof ( Manager , shutdown_watchdog ) , false , bus_property_set_usec } ,
{ " Virtualization " , bus_manager_append_virt , " s " , 0 , } ,
2012-01-16 03:23:59 +04:00
{ NULL , }
} ;
static DBusHandlerResult bus_manager_message_handler ( DBusConnection * connection , DBusMessage * message , void * data ) {
2012-10-03 01:07:00 +04:00
_cleanup_dbus_message_unref_ DBusMessage * reply = NULL ;
_cleanup_free_ char * path = NULL ;
2012-01-16 03:23:59 +04:00
Manager * m = data ;
2010-04-10 19:40:18 +04:00
int r ;
2010-02-01 05:33:24 +03:00
DBusError error ;
2010-06-01 21:47:46 +04:00
JobType job_type = _JOB_TYPE_INVALID ;
2010-07-13 22:20:36 +04:00
bool reload_if_possible = false ;
2011-07-23 05:44:47 +04:00
const char * member ;
2010-02-01 05:33:24 +03:00
assert ( connection ) ;
assert ( message ) ;
assert ( m ) ;
dbus_error_init ( & error ) ;
2011-07-23 05:44:47 +04:00
member = dbus_message_get_member ( message ) ;
2010-04-18 05:08:16 +04:00
if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " GetUnit " ) ) {
2010-02-01 05:33:24 +03:00
const char * name ;
Unit * u ;
if ( ! dbus_message_get_args (
message ,
& error ,
DBUS_TYPE_STRING , & name ,
DBUS_TYPE_INVALID ) )
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , - EINVAL ) ;
2010-02-01 05:33:24 +03:00
2012-10-03 01:07:00 +04:00
u = manager_get_unit ( m , name ) ;
if ( ! u ) {
2010-07-08 04:43:18 +04:00
dbus_set_error ( & error , BUS_ERROR_NO_SUCH_UNIT , " Unit %s is not loaded. " , name ) ;
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , - ENOENT ) ;
2010-07-08 04:43:18 +04:00
}
2010-02-01 05:33:24 +03:00
2012-10-03 01:07:00 +04:00
SELINUX_UNIT_ACCESS_CHECK ( u , connection , message , " status " ) ;
reply = dbus_message_new_method_return ( message ) ;
if ( ! reply )
2010-02-01 05:33:24 +03:00
goto oom ;
2012-10-03 01:07:00 +04:00
path = unit_dbus_path ( u ) ;
if ( ! path )
2010-02-01 05:33:24 +03:00
goto oom ;
if ( ! dbus_message_append_args (
reply ,
DBUS_TYPE_OBJECT_PATH , & path ,
DBUS_TYPE_INVALID ) )
goto oom ;
2010-08-13 04:07:22 +04:00
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " GetUnitByPID " ) ) {
Unit * u ;
uint32_t pid ;
if ( ! dbus_message_get_args (
message ,
& error ,
DBUS_TYPE_UINT32 , & pid ,
DBUS_TYPE_INVALID ) )
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , - EINVAL ) ;
2010-08-13 04:07:22 +04:00
2012-10-03 01:07:00 +04:00
u = cgroup_unit_by_pid ( m , ( pid_t ) pid ) ;
if ( ! u ) {
2010-08-13 04:07:22 +04:00
dbus_set_error ( & error , BUS_ERROR_NO_SUCH_UNIT , " No unit for PID %lu is loaded. " , ( unsigned long ) pid ) ;
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , - ENOENT ) ;
2010-08-13 04:07:22 +04:00
}
2012-10-03 01:07:00 +04:00
SELINUX_UNIT_ACCESS_CHECK ( u , connection , message , " status " ) ;
reply = dbus_message_new_method_return ( message ) ;
if ( ! reply )
2010-08-13 04:07:22 +04:00
goto oom ;
2012-10-03 01:07:00 +04:00
path = unit_dbus_path ( u ) ;
if ( ! reply )
2010-08-13 04:07:22 +04:00
goto oom ;
2010-02-01 05:33:24 +03:00
2010-08-13 04:07:22 +04:00
if ( ! dbus_message_append_args (
reply ,
DBUS_TYPE_OBJECT_PATH , & path ,
DBUS_TYPE_INVALID ) )
goto oom ;
2010-04-18 05:08:16 +04:00
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " LoadUnit " ) ) {
2010-02-01 05:33:24 +03:00
const char * name ;
Unit * u ;
if ( ! dbus_message_get_args (
message ,
& error ,
DBUS_TYPE_STRING , & name ,
DBUS_TYPE_INVALID ) )
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , - EINVAL ) ;
2010-02-01 05:33:24 +03:00
2012-10-03 01:07:00 +04:00
r = manager_load_unit ( m , name , NULL , & error , & u ) ;
if ( r < 0 )
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , r ) ;
2010-02-01 05:33:24 +03:00
2012-10-03 01:07:00 +04:00
SELINUX_UNIT_ACCESS_CHECK ( u , connection , message , " status " ) ;
reply = dbus_message_new_method_return ( message ) ;
if ( ! reply )
2010-02-01 05:33:24 +03:00
goto oom ;
2012-10-03 01:07:00 +04:00
path = unit_dbus_path ( u ) ;
if ( ! path )
2010-02-01 05:33:24 +03:00
goto oom ;
if ( ! dbus_message_append_args (
reply ,
DBUS_TYPE_OBJECT_PATH , & path ,
DBUS_TYPE_INVALID ) )
goto oom ;
2010-06-01 21:47:46 +04:00
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " StartUnit " ) )
job_type = JOB_START ;
2010-10-19 23:53:19 +04:00
else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " StartUnitReplace " ) )
job_type = JOB_START ;
2010-06-01 21:47:46 +04:00
else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " StopUnit " ) )
job_type = JOB_STOP ;
else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " ReloadUnit " ) )
job_type = JOB_RELOAD ;
else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " RestartUnit " ) )
job_type = JOB_RESTART ;
2010-07-06 07:06:40 +04:00
else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " TryRestartUnit " ) )
job_type = JOB_TRY_RESTART ;
2010-07-13 22:20:36 +04:00
else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " ReloadOrRestartUnit " ) ) {
reload_if_possible = true ;
job_type = JOB_RESTART ;
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " ReloadOrTryRestartUnit " ) ) {
reload_if_possible = true ;
job_type = JOB_TRY_RESTART ;
2010-10-22 18:11:50 +04:00
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " KillUnit " ) ) {
2012-07-20 02:00:04 +04:00
const char * name , * swho ;
2010-10-22 18:11:50 +04:00
int32_t signo ;
Unit * u ;
KillWho who ;
if ( ! dbus_message_get_args (
message ,
& error ,
DBUS_TYPE_STRING , & name ,
DBUS_TYPE_STRING , & swho ,
DBUS_TYPE_INT32 , & signo ,
DBUS_TYPE_INVALID ) )
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , - EINVAL ) ;
2010-10-22 18:11:50 +04:00
2011-07-13 21:56:40 +04:00
if ( isempty ( swho ) )
who = KILL_ALL ;
else {
who = kill_who_from_string ( swho ) ;
if ( who < 0 )
return bus_send_error_reply ( connection , message , & error , - EINVAL ) ;
}
if ( signo < = 0 | | signo > = _NSIG )
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , - EINVAL ) ;
2010-10-22 18:11:50 +04:00
2012-07-20 02:00:04 +04:00
u = manager_get_unit ( m , name ) ;
if ( ! u ) {
2010-10-22 18:11:50 +04:00
dbus_set_error ( & error , BUS_ERROR_NO_SUCH_UNIT , " Unit %s is not loaded. " , name ) ;
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , - ENOENT ) ;
2010-10-22 18:11:50 +04:00
}
2012-10-03 01:07:00 +04:00
SELINUX_UNIT_ACCESS_CHECK ( u , connection , message , " stop " ) ;
2012-07-20 02:00:04 +04:00
r = unit_kill ( u , who , signo , & error ) ;
if ( r < 0 )
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , r ) ;
2010-10-22 18:11:50 +04:00
if ( ! ( reply = dbus_message_new_method_return ( message ) ) )
goto oom ;
2010-07-13 22:20:36 +04:00
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " GetJob " ) ) {
2010-02-01 05:33:24 +03:00
uint32_t id ;
Job * j ;
if ( ! dbus_message_get_args (
message ,
& error ,
DBUS_TYPE_UINT32 , & id ,
DBUS_TYPE_INVALID ) )
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , - EINVAL ) ;
2010-02-01 05:33:24 +03:00
2012-10-03 01:07:00 +04:00
j = manager_get_job ( m , id ) ;
if ( ! j ) {
2010-07-08 04:43:18 +04:00
dbus_set_error ( & error , BUS_ERROR_NO_SUCH_JOB , " Job %u does not exist. " , ( unsigned ) id ) ;
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , - ENOENT ) ;
2010-07-08 04:43:18 +04:00
}
2010-02-01 05:33:24 +03:00
2012-10-03 01:07:00 +04:00
SELINUX_UNIT_ACCESS_CHECK ( j - > unit , connection , message , " status " ) ;
reply = dbus_message_new_method_return ( message ) ;
if ( ! reply )
2010-02-01 05:33:24 +03:00
goto oom ;
2012-10-03 01:07:00 +04:00
path = job_dbus_path ( j ) ;
if ( ! path )
2010-02-01 05:33:24 +03:00
goto oom ;
if ( ! dbus_message_append_args (
reply ,
DBUS_TYPE_OBJECT_PATH , & path ,
DBUS_TYPE_INVALID ) )
goto oom ;
2010-04-18 05:08:16 +04:00
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " ClearJobs " ) ) {
2010-02-01 05:33:24 +03:00
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , " reboot " ) ;
2012-10-03 01:07:00 +04:00
2010-02-01 05:33:24 +03:00
manager_clear_jobs ( m ) ;
2012-10-03 01:07:00 +04:00
reply = dbus_message_new_method_return ( message ) ;
if ( ! reply )
2010-02-01 05:33:24 +03:00
goto oom ;
2010-08-31 02:23:34 +04:00
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " ResetFailed " ) ) {
2010-07-18 06:58:01 +04:00
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , " reload " ) ;
2012-10-03 01:07:00 +04:00
2010-08-31 02:23:34 +04:00
manager_reset_failed ( m ) ;
2010-07-18 06:58:01 +04:00
2012-10-03 01:07:00 +04:00
reply = dbus_message_new_method_return ( message ) ;
if ( ! reply )
2010-07-18 06:58:01 +04:00
goto oom ;
2010-08-31 02:23:34 +04:00
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " ResetFailedUnit " ) ) {
2010-07-18 06:58:01 +04:00
const char * name ;
Unit * u ;
if ( ! dbus_message_get_args (
message ,
& error ,
DBUS_TYPE_STRING , & name ,
DBUS_TYPE_INVALID ) )
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , - EINVAL ) ;
2010-07-18 06:58:01 +04:00
2012-10-03 01:07:00 +04:00
u = manager_get_unit ( m , name ) ;
if ( ! u ) {
2010-07-18 06:58:01 +04:00
dbus_set_error ( & error , BUS_ERROR_NO_SUCH_UNIT , " Unit %s is not loaded. " , name ) ;
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , - ENOENT ) ;
2010-07-18 06:58:01 +04:00
}
2012-10-03 01:07:00 +04:00
SELINUX_UNIT_ACCESS_CHECK ( u , connection , message , " reload " ) ;
2010-08-31 02:23:34 +04:00
unit_reset_failed ( u ) ;
2010-07-18 06:58:01 +04:00
2012-10-03 01:07:00 +04:00
reply = dbus_message_new_method_return ( message ) ;
if ( ! reply )
2010-07-18 06:58:01 +04:00
goto oom ;
2010-04-18 05:08:16 +04:00
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " ListUnits " ) ) {
2010-02-01 05:33:24 +03:00
DBusMessageIter iter , sub ;
Iterator i ;
Unit * u ;
const char * k ;
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , " status " ) ;
2012-10-03 01:07:00 +04:00
reply = dbus_message_new_method_return ( message ) ;
if ( ! reply )
2010-02-01 05:33:24 +03:00
goto oom ;
dbus_message_iter_init_append ( reply , & iter ) ;
2010-07-20 22:33:19 +04:00
if ( ! dbus_message_iter_open_container ( & iter , DBUS_TYPE_ARRAY , " (ssssssouso) " , & sub ) )
2010-02-01 05:33:24 +03:00
goto oom ;
HASHMAP_FOREACH_KEY ( u , k , m - > units , i ) {
2010-02-03 16:21:48 +03:00
char * u_path , * j_path ;
2010-07-20 22:33:19 +04:00
const char * description , * load_state , * active_state , * sub_state , * sjob_type , * following ;
2010-02-01 05:33:24 +03:00
DBusMessageIter sub2 ;
uint32_t job_id ;
2010-07-21 07:00:29 +04:00
Unit * f ;
2010-02-01 05:33:24 +03:00
2012-01-15 15:04:08 +04:00
if ( k ! = u - > id )
2010-02-01 05:33:24 +03:00
continue ;
if ( ! dbus_message_iter_open_container ( & sub , DBUS_TYPE_STRUCT , NULL , & sub2 ) )
goto oom ;
description = unit_description ( u ) ;
2012-01-15 15:04:08 +04:00
load_state = unit_load_state_to_string ( u - > load_state ) ;
2010-02-01 05:33:24 +03:00
active_state = unit_active_state_to_string ( unit_active_state ( u ) ) ;
2010-04-13 22:59:01 +04:00
sub_state = unit_sub_state_to_string ( u ) ;
2010-07-21 07:00:29 +04:00
f = unit_following ( u ) ;
2012-01-15 15:04:08 +04:00
following = f ? f - > id : " " ;
2010-02-01 05:33:24 +03:00
2012-10-03 01:07:00 +04:00
u_path = unit_dbus_path ( u ) ;
if ( ! u_path )
2010-02-01 05:33:24 +03:00
goto oom ;
2012-01-15 15:04:08 +04:00
if ( u - > job ) {
job_id = ( uint32_t ) u - > job - > id ;
2010-02-01 05:33:24 +03:00
2012-01-15 15:04:08 +04:00
if ( ! ( j_path = job_dbus_path ( u - > job ) ) ) {
2010-02-03 16:21:48 +03:00
free ( u_path ) ;
2010-02-01 05:33:24 +03:00
goto oom ;
}
2012-01-15 15:04:08 +04:00
sjob_type = job_type_to_string ( u - > job - > type ) ;
2010-02-01 05:33:24 +03:00
} else {
job_id = 0 ;
2010-02-03 16:21:48 +03:00
j_path = u_path ;
2010-06-01 21:47:46 +04:00
sjob_type = " " ;
2010-02-01 05:33:24 +03:00
}
2012-01-15 15:04:08 +04:00
if ( ! dbus_message_iter_append_basic ( & sub2 , DBUS_TYPE_STRING , & u - > id ) | |
2010-02-01 05:33:24 +03:00
! dbus_message_iter_append_basic ( & sub2 , DBUS_TYPE_STRING , & description ) | |
! dbus_message_iter_append_basic ( & sub2 , DBUS_TYPE_STRING , & load_state ) | |
! dbus_message_iter_append_basic ( & sub2 , DBUS_TYPE_STRING , & active_state ) | |
2010-04-13 22:59:01 +04:00
! dbus_message_iter_append_basic ( & sub2 , DBUS_TYPE_STRING , & sub_state ) | |
2010-07-20 22:33:19 +04:00
! dbus_message_iter_append_basic ( & sub2 , DBUS_TYPE_STRING , & following ) | |
2010-02-03 16:21:48 +03:00
! dbus_message_iter_append_basic ( & sub2 , DBUS_TYPE_OBJECT_PATH , & u_path ) | |
2010-02-01 05:33:24 +03:00
! dbus_message_iter_append_basic ( & sub2 , DBUS_TYPE_UINT32 , & job_id ) | |
2010-06-01 21:47:46 +04:00
! dbus_message_iter_append_basic ( & sub2 , DBUS_TYPE_STRING , & sjob_type ) | |
2010-02-03 16:21:48 +03:00
! dbus_message_iter_append_basic ( & sub2 , DBUS_TYPE_OBJECT_PATH , & j_path ) ) {
free ( u_path ) ;
2012-01-15 15:04:08 +04:00
if ( u - > job )
2010-02-03 16:21:48 +03:00
free ( j_path ) ;
2010-02-01 05:33:24 +03:00
goto oom ;
}
2010-02-03 16:21:48 +03:00
free ( u_path ) ;
2012-01-15 15:04:08 +04:00
if ( u - > job )
2010-02-03 16:21:48 +03:00
free ( j_path ) ;
2010-02-01 05:33:24 +03:00
if ( ! dbus_message_iter_close_container ( & sub , & sub2 ) )
goto oom ;
}
if ( ! dbus_message_iter_close_container ( & iter , & sub ) )
goto oom ;
2010-04-18 05:08:16 +04:00
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " ListJobs " ) ) {
2010-02-01 05:33:24 +03:00
DBusMessageIter iter , sub ;
Iterator i ;
Job * j ;
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , " status " ) ;
2012-10-03 01:07:00 +04:00
reply = dbus_message_new_method_return ( message ) ;
if ( ! reply )
2010-02-01 05:33:24 +03:00
goto oom ;
dbus_message_iter_init_append ( reply , & iter ) ;
if ( ! dbus_message_iter_open_container ( & iter , DBUS_TYPE_ARRAY , " (usssoo) " , & sub ) )
goto oom ;
HASHMAP_FOREACH ( j , m - > jobs , i ) {
2010-02-03 16:21:48 +03:00
char * u_path , * j_path ;
2010-04-15 05:11:11 +04:00
const char * state , * type ;
2010-02-01 05:33:24 +03:00
uint32_t id ;
DBusMessageIter sub2 ;
if ( ! dbus_message_iter_open_container ( & sub , DBUS_TYPE_STRUCT , NULL , & sub2 ) )
goto oom ;
id = ( uint32_t ) j - > id ;
state = job_state_to_string ( j - > state ) ;
2010-02-03 14:39:44 +03:00
type = job_type_to_string ( j - > type ) ;
2010-02-01 05:33:24 +03:00
2012-10-03 01:07:00 +04:00
j_path = job_dbus_path ( j ) ;
if ( ! j_path )
2010-02-01 05:33:24 +03:00
goto oom ;
2012-10-03 01:07:00 +04:00
u_path = unit_dbus_path ( j - > unit ) ;
if ( ! u_path ) {
2010-02-03 16:21:48 +03:00
free ( j_path ) ;
2010-02-01 05:33:24 +03:00
goto oom ;
}
if ( ! dbus_message_iter_append_basic ( & sub2 , DBUS_TYPE_UINT32 , & id ) | |
2012-01-15 15:04:08 +04:00
! dbus_message_iter_append_basic ( & sub2 , DBUS_TYPE_STRING , & j - > unit - > id ) | |
2010-02-01 05:33:24 +03:00
! dbus_message_iter_append_basic ( & sub2 , DBUS_TYPE_STRING , & type ) | |
! dbus_message_iter_append_basic ( & sub2 , DBUS_TYPE_STRING , & state ) | |
2010-02-03 16:21:48 +03:00
! dbus_message_iter_append_basic ( & sub2 , DBUS_TYPE_OBJECT_PATH , & j_path ) | |
! dbus_message_iter_append_basic ( & sub2 , DBUS_TYPE_OBJECT_PATH , & u_path ) ) {
free ( j_path ) ;
free ( u_path ) ;
2010-02-01 05:33:24 +03:00
goto oom ;
}
2010-02-03 16:21:48 +03:00
free ( j_path ) ;
free ( u_path ) ;
2010-02-01 05:33:24 +03:00
if ( ! dbus_message_iter_close_container ( & sub , & sub2 ) )
goto oom ;
}
if ( ! dbus_message_iter_close_container ( & iter , & sub ) )
goto oom ;
2010-04-18 05:08:16 +04:00
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " Subscribe " ) ) {
2010-02-05 02:38:41 +03:00
char * client ;
2010-07-05 02:58:07 +04:00
Set * s ;
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , " status " ) ;
2012-10-03 01:07:00 +04:00
s = BUS_CONNECTION_SUBSCRIBED ( m , connection ) ;
if ( ! s ) {
s = set_new ( string_hash_func , string_compare_func ) ;
if ( ! s )
2010-07-05 02:58:07 +04:00
goto oom ;
2012-10-03 01:07:00 +04:00
if ( ! dbus_connection_set_data ( connection , m - > subscribed_data_slot , s , NULL ) ) {
2010-07-05 02:58:07 +04:00
set_free ( s ) ;
goto oom ;
}
}
2010-02-05 02:38:41 +03:00
2012-10-03 01:07:00 +04:00
client = strdup ( bus_message_get_sender_with_fallback ( message ) ) ;
if ( ! client )
2010-02-05 02:38:41 +03:00
goto oom ;
2012-10-03 01:07:00 +04:00
r = set_put ( s , client ) ;
if ( r < 0 ) {
2010-07-05 02:58:07 +04:00
free ( client ) ;
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , NULL , r ) ;
2010-07-05 02:58:07 +04:00
}
2010-02-05 02:38:41 +03:00
2012-10-03 01:07:00 +04:00
reply = dbus_message_new_method_return ( message ) ;
if ( ! reply )
2010-02-05 02:38:41 +03:00
goto oom ;
2010-04-18 05:08:16 +04:00
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " Unsubscribe " ) ) {
2010-02-05 02:38:41 +03:00
char * client ;
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , " status " ) ;
2012-10-03 01:07:00 +04:00
client = set_remove ( BUS_CONNECTION_SUBSCRIBED ( m , connection ) , ( char * ) bus_message_get_sender_with_fallback ( message ) ) ;
if ( ! client ) {
2010-07-08 04:43:18 +04:00
dbus_set_error ( & error , BUS_ERROR_NOT_SUBSCRIBED , " Client is not subscribed. " ) ;
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , - ENOENT ) ;
2010-07-08 04:43:18 +04:00
}
2010-02-05 02:38:41 +03:00
free ( client ) ;
2012-10-03 01:07:00 +04:00
reply = dbus_message_new_method_return ( message ) ;
if ( ! reply )
2010-02-05 02:38:41 +03:00
goto oom ;
2010-04-18 05:08:16 +04:00
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " Dump " ) ) {
2010-04-10 19:37:56 +04:00
FILE * f ;
char * dump = NULL ;
size_t size ;
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , " status " ) ;
2012-10-03 01:07:00 +04:00
reply = dbus_message_new_method_return ( message ) ;
if ( ! reply )
2010-04-10 19:37:56 +04:00
goto oom ;
2012-10-03 01:07:00 +04:00
f = open_memstream ( & dump , & size ) ;
if ( ! f )
2010-04-10 19:37:56 +04:00
goto oom ;
manager_dump_units ( m , f , NULL ) ;
manager_dump_jobs ( m , f , NULL ) ;
if ( ferror ( f ) ) {
fclose ( f ) ;
free ( dump ) ;
goto oom ;
}
fclose ( f ) ;
if ( ! dbus_message_append_args ( reply , DBUS_TYPE_STRING , & dump , DBUS_TYPE_INVALID ) ) {
free ( dump ) ;
goto oom ;
}
free ( dump ) ;
2010-04-18 05:08:16 +04:00
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " CreateSnapshot " ) ) {
const char * name ;
dbus_bool_t cleanup ;
Snapshot * s ;
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , " start " ) ;
2012-10-03 01:07:00 +04:00
2010-04-18 05:08:16 +04:00
if ( ! dbus_message_get_args (
message ,
& error ,
DBUS_TYPE_STRING , & name ,
DBUS_TYPE_BOOLEAN , & cleanup ,
DBUS_TYPE_INVALID ) )
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , - EINVAL ) ;
2010-04-18 05:08:16 +04:00
2012-10-03 01:07:00 +04:00
if ( isempty ( name ) )
2010-04-18 05:08:16 +04:00
name = NULL ;
2012-10-03 01:07:00 +04:00
r = snapshot_create ( m , name , cleanup , & error , & s ) ;
if ( r < 0 )
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , r ) ;
2010-04-18 05:08:16 +04:00
2012-10-03 01:07:00 +04:00
reply = dbus_message_new_method_return ( message ) ;
if ( ! reply )
2010-04-18 05:08:16 +04:00
goto oom ;
2012-10-03 01:07:00 +04:00
path = unit_dbus_path ( UNIT ( s ) ) ;
if ( ! path )
2010-04-18 05:08:16 +04:00
goto oom ;
if ( ! dbus_message_append_args (
reply ,
DBUS_TYPE_OBJECT_PATH , & path ,
DBUS_TYPE_INVALID ) )
goto oom ;
2010-04-10 19:37:56 +04:00
2010-02-01 05:33:24 +03:00
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.DBus.Introspectable " , " Introspect " ) ) {
char * introspection = NULL ;
FILE * f ;
Iterator i ;
Unit * u ;
Job * j ;
const char * k ;
size_t size ;
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , " status " ) ;
2012-10-03 01:07:00 +04:00
reply = dbus_message_new_method_return ( message ) ;
if ( ! reply )
2010-02-01 05:33:24 +03:00
goto oom ;
/* We roll our own introspection code here, instead of
* relying on bus_default_message_handler ( ) because we
* need to generate our introspection string
* dynamically . */
2012-10-03 01:07:00 +04:00
f = open_memstream ( & introspection , & size ) ;
if ( ! f )
2010-02-01 05:33:24 +03:00
goto oom ;
fputs ( INTROSPECTION_BEGIN , f ) ;
HASHMAP_FOREACH_KEY ( u , k , m - > units , i ) {
char * p ;
2012-01-15 15:04:08 +04:00
if ( k ! = u - > id )
2010-02-01 05:33:24 +03:00
continue ;
2012-10-03 01:07:00 +04:00
p = bus_path_escape ( k ) ;
if ( ! p ) {
2010-02-01 05:33:24 +03:00
fclose ( f ) ;
free ( introspection ) ;
goto oom ;
}
fprintf ( f , " <node name= \" unit/%s \" /> " , p ) ;
free ( p ) ;
}
HASHMAP_FOREACH ( j , m - > jobs , i )
fprintf ( f , " <node name= \" job/%lu \" /> " , ( unsigned long ) j - > id ) ;
fputs ( INTROSPECTION_END , f ) ;
if ( ferror ( f ) ) {
fclose ( f ) ;
free ( introspection ) ;
goto oom ;
}
fclose ( f ) ;
if ( ! introspection )
goto oom ;
if ( ! dbus_message_append_args ( reply , DBUS_TYPE_STRING , & introspection , DBUS_TYPE_INVALID ) ) {
free ( introspection ) ;
goto oom ;
}
free ( introspection ) ;
2010-04-21 05:27:44 +04:00
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " Reload " ) ) {
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , " reload " ) ;
2012-10-03 01:07:00 +04:00
2010-04-21 05:27:44 +04:00
assert ( ! m - > queued_message ) ;
/* Instead of sending the reply back right away, we
* just remember that we need to and then send it
* after the reload is finished . That way the caller
* knows when the reload finished . */
2012-10-03 01:07:00 +04:00
m - > queued_message = dbus_message_new_method_return ( message ) ;
if ( ! m - > queued_message )
2010-04-21 05:27:44 +04:00
goto oom ;
2010-07-07 04:21:16 +04:00
m - > queued_message_connection = connection ;
2010-04-21 05:27:44 +04:00
m - > exit_code = MANAGER_RELOAD ;
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " Reexecute " ) ) {
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , " reload " ) ;
2012-10-03 01:07:00 +04:00
2011-04-29 00:07:01 +04:00
/* We don't send a reply back here, the client should
* just wait for us disconnecting . */
2010-04-21 05:27:44 +04:00
m - > exit_code = MANAGER_REEXECUTE ;
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " Exit " ) ) {
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , " halt " ) ;
2012-10-03 01:07:00 +04:00
2012-09-18 19:11:12 +04:00
if ( m - > running_as = = SYSTEMD_SYSTEM ) {
2010-11-16 00:12:41 +03:00
dbus_set_error ( & error , BUS_ERROR_NOT_SUPPORTED , " Exit is only supported for user service managers. " ) ;
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , - ENOTSUP ) ;
2010-07-08 04:43:18 +04:00
}
2010-04-21 05:27:44 +04:00
2012-10-03 01:07:00 +04:00
reply = dbus_message_new_method_return ( message ) ;
if ( ! reply )
2010-04-21 05:27:44 +04:00
goto oom ;
m - > exit_code = MANAGER_EXIT ;
2010-10-14 02:53:51 +04:00
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " Reboot " ) ) {
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , " reboot " ) ;
2012-10-03 01:07:00 +04:00
2012-09-18 19:11:12 +04:00
if ( m - > running_as ! = SYSTEMD_SYSTEM ) {
2010-10-14 02:53:51 +04:00
dbus_set_error ( & error , BUS_ERROR_NOT_SUPPORTED , " Reboot is only supported for system managers. " ) ;
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , - ENOTSUP ) ;
2010-10-14 02:53:51 +04:00
}
2012-10-03 01:07:00 +04:00
reply = dbus_message_new_method_return ( message ) ;
if ( ! reply )
2010-10-14 02:53:51 +04:00
goto oom ;
m - > exit_code = MANAGER_REBOOT ;
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " PowerOff " ) ) {
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , " halt " ) ;
2012-10-03 01:07:00 +04:00
2012-09-18 19:11:12 +04:00
if ( m - > running_as ! = SYSTEMD_SYSTEM ) {
2010-10-14 02:53:51 +04:00
dbus_set_error ( & error , BUS_ERROR_NOT_SUPPORTED , " Powering off is only supported for system managers. " ) ;
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , - ENOTSUP ) ;
2010-10-14 02:53:51 +04:00
}
2012-10-03 01:07:00 +04:00
reply = dbus_message_new_method_return ( message ) ;
if ( ! reply )
2010-10-14 02:53:51 +04:00
goto oom ;
m - > exit_code = MANAGER_POWEROFF ;
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " Halt " ) ) {
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , " halt " ) ;
2012-10-03 01:07:00 +04:00
2012-09-18 19:11:12 +04:00
if ( m - > running_as ! = SYSTEMD_SYSTEM ) {
2010-10-14 02:53:51 +04:00
dbus_set_error ( & error , BUS_ERROR_NOT_SUPPORTED , " Halting is only supported for system managers. " ) ;
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , - ENOTSUP ) ;
2010-10-14 02:53:51 +04:00
}
2012-10-03 01:07:00 +04:00
reply = dbus_message_new_method_return ( message ) ;
if ( ! reply )
2010-10-14 02:53:51 +04:00
goto oom ;
m - > exit_code = MANAGER_HALT ;
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " KExec " ) ) {
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , " reboot " ) ;
2012-10-03 01:07:00 +04:00
2012-09-18 19:11:12 +04:00
if ( m - > running_as ! = SYSTEMD_SYSTEM ) {
2010-10-14 02:53:51 +04:00
dbus_set_error ( & error , BUS_ERROR_NOT_SUPPORTED , " kexec is only supported for system managers. " ) ;
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , - ENOTSUP ) ;
2010-10-14 02:53:51 +04:00
}
2012-10-03 01:07:00 +04:00
reply = dbus_message_new_method_return ( message ) ;
if ( ! reply )
2010-10-14 02:53:51 +04:00
goto oom ;
m - > exit_code = MANAGER_KEXEC ;
2012-05-09 03:24:50 +04:00
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " SwitchRoot " ) ) {
const char * switch_root , * switch_root_init ;
char * u , * v ;
2012-05-11 19:17:57 +04:00
int k ;
2012-05-09 03:24:50 +04:00
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , " reboot " ) ;
2012-10-03 01:07:00 +04:00
2012-05-09 03:24:50 +04:00
if ( ! dbus_message_get_args (
message ,
& error ,
DBUS_TYPE_STRING , & switch_root ,
DBUS_TYPE_STRING , & switch_root_init ,
DBUS_TYPE_INVALID ) )
return bus_send_error_reply ( connection , message , & error , - EINVAL ) ;
2012-05-16 05:23:54 +04:00
if ( path_equal ( switch_root , " / " ) | | ! path_is_absolute ( switch_root ) )
2012-05-09 03:24:50 +04:00
return bus_send_error_reply ( connection , message , NULL , - EINVAL ) ;
2012-05-16 05:23:54 +04:00
if ( ! isempty ( switch_root_init ) & & ! path_is_absolute ( switch_root_init ) )
2012-05-09 03:24:50 +04:00
return bus_send_error_reply ( connection , message , NULL , - EINVAL ) ;
2012-09-18 19:11:12 +04:00
if ( m - > running_as ! = SYSTEMD_SYSTEM ) {
2012-05-09 03:24:50 +04:00
dbus_set_error ( & error , BUS_ERROR_NOT_SUPPORTED , " Switching root is only supported for system managers. " ) ;
return bus_send_error_reply ( connection , message , & error , - ENOTSUP ) ;
}
2012-05-11 19:17:57 +04:00
/* Safety check */
if ( isempty ( switch_root_init ) )
k = access ( switch_root , F_OK ) ;
else {
char * p ;
2012-07-13 15:41:01 +04:00
p = strjoin ( switch_root , " / " , switch_root_init , NULL ) ;
2012-05-11 19:17:57 +04:00
if ( ! p )
goto oom ;
k = access ( p , X_OK ) ;
free ( p ) ;
}
if ( k < 0 )
return bus_send_error_reply ( connection , message , NULL , - errno ) ;
2012-05-09 03:24:50 +04:00
u = strdup ( switch_root ) ;
if ( ! u )
goto oom ;
if ( ! isempty ( switch_root_init ) ) {
v = strdup ( switch_root_init ) ;
if ( ! v ) {
free ( u ) ;
goto oom ;
}
} else
v = NULL ;
free ( m - > switch_root ) ;
free ( m - > switch_root_init ) ;
m - > switch_root = u ;
m - > switch_root_init = v ;
reply = dbus_message_new_method_return ( message ) ;
if ( ! reply )
goto oom ;
m - > exit_code = MANAGER_SWITCH_ROOT ;
2010-05-10 01:53:52 +04:00
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " SetEnvironment " ) ) {
char * * l = NULL , * * e = NULL ;
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , " reboot " ) ;
2010-05-10 01:53:52 +04:00
2012-10-03 01:07:00 +04:00
r = bus_parse_strv ( message , & l ) ;
if ( r = = - ENOMEM )
goto oom ;
if ( r < 0 )
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , NULL , r ) ;
2010-05-10 01:53:52 +04:00
2010-06-16 23:54:17 +04:00
e = strv_env_merge ( 2 , m - > environment , l ) ;
2010-05-10 01:53:52 +04:00
strv_free ( l ) ;
if ( ! e )
goto oom ;
2012-10-03 01:07:00 +04:00
reply = dbus_message_new_method_return ( message ) ;
if ( ! reply ) {
2010-05-10 01:53:52 +04:00
strv_free ( e ) ;
goto oom ;
}
strv_free ( m - > environment ) ;
m - > environment = e ;
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " UnsetEnvironment " ) ) {
char * * l = NULL , * * e = NULL ;
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , " reboot " ) ;
2010-05-10 01:53:52 +04:00
2012-10-03 01:07:00 +04:00
r = bus_parse_strv ( message , & l ) ;
if ( r = = - ENOMEM )
goto oom ;
if ( r < 0 )
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , NULL , r ) ;
2010-05-10 01:53:52 +04:00
2010-06-16 23:54:17 +04:00
e = strv_env_delete ( m - > environment , 1 , l ) ;
2010-05-10 01:53:52 +04:00
strv_free ( l ) ;
if ( ! e )
goto oom ;
2011-03-31 17:35:40 +04:00
if ( ! ( reply = dbus_message_new_method_return ( message ) ) ) {
strv_free ( e ) ;
2010-05-10 01:53:52 +04:00
goto oom ;
2011-03-31 17:35:40 +04:00
}
2010-05-10 01:53:52 +04:00
strv_free ( m - > environment ) ;
m - > environment = e ;
2011-06-15 17:31:54 +04:00
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " UnsetAndSetEnvironment " ) ) {
char * * l_set = NULL , * * l_unset = NULL , * * e = NULL , * * f = NULL ;
DBusMessageIter iter ;
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , " reboot " ) ;
2012-10-03 01:07:00 +04:00
2011-06-15 17:31:54 +04:00
if ( ! dbus_message_iter_init ( message , & iter ) )
2011-07-23 05:44:47 +04:00
goto oom ;
2011-06-15 17:31:54 +04:00
r = bus_parse_strv_iter ( & iter , & l_unset ) ;
2012-10-03 01:07:00 +04:00
if ( r = = - ENOMEM )
goto oom ;
if ( r < 0 )
2011-06-15 17:31:54 +04:00
return bus_send_error_reply ( connection , message , NULL , r ) ;
if ( ! dbus_message_iter_next ( & iter ) ) {
strv_free ( l_unset ) ;
return bus_send_error_reply ( connection , message , NULL , - EINVAL ) ;
}
r = bus_parse_strv_iter ( & iter , & l_set ) ;
if ( r < 0 ) {
strv_free ( l_unset ) ;
if ( r = = - ENOMEM )
goto oom ;
return bus_send_error_reply ( connection , message , NULL , r ) ;
}
e = strv_env_delete ( m - > environment , 1 , l_unset ) ;
strv_free ( l_unset ) ;
if ( ! e ) {
strv_free ( l_set ) ;
goto oom ;
}
f = strv_env_merge ( 2 , e , l_set ) ;
strv_free ( l_set ) ;
strv_free ( e ) ;
if ( ! f )
goto oom ;
if ( ! ( reply = dbus_message_new_method_return ( message ) ) ) {
strv_free ( f ) ;
goto oom ;
}
strv_free ( m - > environment ) ;
m - > environment = f ;
2011-07-23 05:44:47 +04:00
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " ListUnitFiles " ) ) {
DBusMessageIter iter , sub , sub2 ;
Hashmap * h ;
Iterator i ;
UnitFileList * item ;
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , " status " ) ;
2012-10-03 01:07:00 +04:00
2011-07-23 05:44:47 +04:00
reply = dbus_message_new_method_return ( message ) ;
if ( ! reply )
goto oom ;
h = hashmap_new ( string_hash_func , string_compare_func ) ;
if ( ! h )
goto oom ;
2012-09-18 19:11:12 +04:00
r = unit_file_get_list ( m - > running_as = = SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER , NULL , h ) ;
2011-07-23 05:44:47 +04:00
if ( r < 0 ) {
unit_file_list_free ( h ) ;
dbus_message_unref ( reply ) ;
return bus_send_error_reply ( connection , message , NULL , r ) ;
}
dbus_message_iter_init_append ( reply , & iter ) ;
if ( ! dbus_message_iter_open_container ( & iter , DBUS_TYPE_ARRAY , " (ss) " , & sub ) ) {
unit_file_list_free ( h ) ;
goto oom ;
}
HASHMAP_FOREACH ( item , h , i ) {
const char * state ;
state = unit_file_state_to_string ( item - > state ) ;
assert ( state ) ;
if ( ! dbus_message_iter_open_container ( & sub , DBUS_TYPE_STRUCT , NULL , & sub2 ) | |
! dbus_message_iter_append_basic ( & sub2 , DBUS_TYPE_STRING , & item - > path ) | |
! dbus_message_iter_append_basic ( & sub2 , DBUS_TYPE_STRING , & state ) | |
! dbus_message_iter_close_container ( & sub , & sub2 ) ) {
unit_file_list_free ( h ) ;
goto oom ;
}
}
unit_file_list_free ( h ) ;
if ( ! dbus_message_iter_close_container ( & iter , & sub ) )
goto oom ;
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " GetUnitFileState " ) ) {
const char * name ;
UnitFileState state ;
const char * s ;
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , " status " ) ;
2012-10-03 01:07:00 +04:00
2011-07-23 05:44:47 +04:00
if ( ! dbus_message_get_args (
message ,
& error ,
DBUS_TYPE_STRING , & name ,
DBUS_TYPE_INVALID ) )
return bus_send_error_reply ( connection , message , & error , - EINVAL ) ;
2012-09-18 19:11:12 +04:00
state = unit_file_get_state ( m - > running_as = = SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER , NULL , name ) ;
2011-07-23 05:44:47 +04:00
if ( state < 0 )
return bus_send_error_reply ( connection , message , NULL , state ) ;
s = unit_file_state_to_string ( state ) ;
assert ( s ) ;
reply = dbus_message_new_method_return ( message ) ;
if ( ! reply )
goto oom ;
if ( ! dbus_message_append_args (
reply ,
DBUS_TYPE_STRING , & s ,
DBUS_TYPE_INVALID ) )
goto oom ;
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " EnableUnitFiles " ) | |
dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " ReenableUnitFiles " ) | |
dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " LinkUnitFiles " ) | |
dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " PresetUnitFiles " ) | |
dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " MaskUnitFiles " ) ) {
char * * l = NULL ;
DBusMessageIter iter ;
2012-09-18 19:11:12 +04:00
UnitFileScope scope = m - > running_as = = SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER ;
2011-07-23 05:44:47 +04:00
UnitFileChange * changes = NULL ;
unsigned n_changes = 0 ;
dbus_bool_t runtime , force ;
2011-08-02 02:10:40 +04:00
int carries_install_info = - 1 ;
2011-07-23 05:44:47 +04:00
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , streq ( member , " MaskUnitFiles " ) ? " disable " : " enable " ) ;
2012-10-03 01:07:00 +04:00
2011-07-23 05:44:47 +04:00
if ( ! dbus_message_iter_init ( message , & iter ) )
goto oom ;
r = bus_parse_strv_iter ( & iter , & l ) ;
if ( r < 0 ) {
if ( r = = - ENOMEM )
goto oom ;
return bus_send_error_reply ( connection , message , NULL , r ) ;
}
if ( ! dbus_message_iter_next ( & iter ) | |
bus_iter_get_basic_and_next ( & iter , DBUS_TYPE_BOOLEAN , & runtime , true ) < 0 | |
bus_iter_get_basic_and_next ( & iter , DBUS_TYPE_BOOLEAN , & force , false ) < 0 ) {
strv_free ( l ) ;
return bus_send_error_reply ( connection , message , NULL , - EIO ) ;
}
2011-07-25 06:58:02 +04:00
if ( streq ( member , " EnableUnitFiles " ) ) {
2011-07-23 05:44:47 +04:00
r = unit_file_enable ( scope , runtime , NULL , l , force , & changes , & n_changes ) ;
2011-07-25 06:58:02 +04:00
carries_install_info = r ;
} else if ( streq ( member , " ReenableUnitFiles " ) ) {
2011-07-23 05:44:47 +04:00
r = unit_file_reenable ( scope , runtime , NULL , l , force , & changes , & n_changes ) ;
2011-07-25 06:58:02 +04:00
carries_install_info = r ;
} else if ( streq ( member , " LinkUnitFiles " ) )
2011-07-23 05:44:47 +04:00
r = unit_file_link ( scope , runtime , NULL , l , force , & changes , & n_changes ) ;
2011-07-25 06:58:02 +04:00
else if ( streq ( member , " PresetUnitFiles " ) ) {
2011-07-23 05:44:47 +04:00
r = unit_file_preset ( scope , runtime , NULL , l , force , & changes , & n_changes ) ;
2011-07-25 06:58:02 +04:00
carries_install_info = r ;
} else if ( streq ( member , " MaskUnitFiles " ) )
2011-07-23 05:44:47 +04:00
r = unit_file_mask ( scope , runtime , NULL , l , force , & changes , & n_changes ) ;
else
assert_not_reached ( " Uh? Wrong method " ) ;
strv_free ( l ) ;
bus_manager_send_unit_files_changed ( m ) ;
if ( r < 0 ) {
unit_file_changes_free ( changes , n_changes ) ;
return bus_send_error_reply ( connection , message , NULL , r ) ;
}
2011-07-25 06:58:02 +04:00
reply = message_from_file_changes ( message , changes , n_changes , carries_install_info ) ;
2011-07-23 05:44:47 +04:00
unit_file_changes_free ( changes , n_changes ) ;
if ( ! reply )
goto oom ;
} else if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " DisableUnitFiles " ) | |
dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " UnmaskUnitFiles " ) ) {
char * * l = NULL ;
DBusMessageIter iter ;
2012-09-18 19:11:12 +04:00
UnitFileScope scope = m - > running_as = = SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER ;
2011-07-23 05:44:47 +04:00
UnitFileChange * changes = NULL ;
unsigned n_changes = 0 ;
dbus_bool_t runtime ;
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , streq ( member , " UnmaskUnitFiles " ) ? " enable " : " disable " ) ;
2012-10-03 01:07:00 +04:00
2011-07-23 05:44:47 +04:00
if ( ! dbus_message_iter_init ( message , & iter ) )
goto oom ;
r = bus_parse_strv_iter ( & iter , & l ) ;
if ( r < 0 ) {
if ( r = = - ENOMEM )
goto oom ;
return bus_send_error_reply ( connection , message , NULL , r ) ;
}
if ( ! dbus_message_iter_next ( & iter ) | |
bus_iter_get_basic_and_next ( & iter , DBUS_TYPE_BOOLEAN , & runtime , false ) < 0 ) {
strv_free ( l ) ;
return bus_send_error_reply ( connection , message , NULL , - EIO ) ;
}
if ( streq ( member , " DisableUnitFiles " ) )
r = unit_file_disable ( scope , runtime , NULL , l , & changes , & n_changes ) ;
else if ( streq ( member , " UnmaskUnitFiles " ) )
r = unit_file_unmask ( scope , runtime , NULL , l , & changes , & n_changes ) ;
else
assert_not_reached ( " Uh? Wrong method " ) ;
strv_free ( l ) ;
bus_manager_send_unit_files_changed ( m ) ;
if ( r < 0 ) {
unit_file_changes_free ( changes , n_changes ) ;
return bus_send_error_reply ( connection , message , NULL , r ) ;
}
2011-07-25 06:58:02 +04:00
reply = message_from_file_changes ( message , changes , n_changes , - 1 ) ;
2011-07-23 05:44:47 +04:00
unit_file_changes_free ( changes , n_changes ) ;
if ( ! reply )
goto oom ;
2011-06-15 17:31:54 +04:00
2012-01-16 03:23:59 +04:00
} else {
const BusBoundProperties bps [ ] = {
{ " org.freedesktop.systemd1.Manager " , bus_systemd_properties , systemd_property_string } ,
{ " org.freedesktop.systemd1.Manager " , bus_manager_properties , m } ,
{ NULL , }
} ;
2012-10-03 01:07:00 +04:00
2012-10-03 01:56:54 +04:00
SELINUX_ACCESS_CHECK ( connection , message , " status " ) ;
2012-10-03 01:07:00 +04:00
2012-01-16 03:23:59 +04:00
return bus_default_message_handler ( connection , message , NULL , INTERFACES_LIST , bps ) ;
}
2010-02-01 05:33:24 +03:00
2010-06-01 21:47:46 +04:00
if ( job_type ! = _JOB_TYPE_INVALID ) {
2010-10-19 23:53:19 +04:00
const char * name , * smode , * old_name = NULL ;
2010-06-01 21:47:46 +04:00
JobMode mode ;
Unit * u ;
2012-10-03 01:07:00 +04:00
dbus_bool_t b ;
2010-10-19 23:53:19 +04:00
if ( dbus_message_is_method_call ( message , " org.freedesktop.systemd1.Manager " , " StartUnitReplace " ) )
b = dbus_message_get_args (
message ,
& error ,
DBUS_TYPE_STRING , & old_name ,
DBUS_TYPE_STRING , & name ,
DBUS_TYPE_STRING , & smode ,
DBUS_TYPE_INVALID ) ;
else
b = dbus_message_get_args (
message ,
& error ,
DBUS_TYPE_STRING , & name ,
DBUS_TYPE_STRING , & smode ,
DBUS_TYPE_INVALID ) ;
if ( ! b )
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , - EINVAL ) ;
2010-06-01 21:47:46 +04:00
2012-10-03 01:07:00 +04:00
if ( old_name ) {
u = manager_get_unit ( m , old_name ) ;
if ( ! u | | ! u - > job | | u - > job - > type ! = JOB_START ) {
2010-10-19 23:53:19 +04:00
dbus_set_error ( & error , BUS_ERROR_NO_SUCH_JOB , " No job queued for unit %s " , old_name ) ;
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , - ENOENT ) ;
2010-10-19 23:53:19 +04:00
}
2012-10-03 01:07:00 +04:00
}
2010-10-19 23:53:19 +04:00
2012-10-03 01:07:00 +04:00
mode = job_mode_from_string ( smode ) ;
if ( mode < 0 ) {
2010-07-08 04:43:18 +04:00
dbus_set_error ( & error , BUS_ERROR_INVALID_JOB_MODE , " Job mode %s is invalid. " , smode ) ;
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , - EINVAL ) ;
2010-07-08 04:43:18 +04:00
}
2010-06-01 21:47:46 +04:00
2012-10-03 01:07:00 +04:00
r = manager_load_unit ( m , name , NULL , & error , & u ) ;
if ( r < 0 )
2011-04-16 03:54:49 +04:00
return bus_send_error_reply ( connection , message , & error , r ) ;
2010-06-01 21:47:46 +04:00
2012-10-03 01:07:00 +04:00
return bus_unit_queue_job ( connection , message , u , job_type , mode , reload_if_possible ) ;
2010-06-01 21:47:46 +04:00
}
2012-10-03 01:07:00 +04:00
if ( reply )
2010-02-01 05:33:24 +03:00
if ( ! dbus_connection_send ( connection , reply , NULL ) )
goto oom ;
return DBUS_HANDLER_RESULT_HANDLED ;
oom :
dbus_error_free ( & error ) ;
return DBUS_HANDLER_RESULT_NEED_MEMORY ;
}
const DBusObjectPathVTable bus_manager_vtable = {
. message_function = bus_manager_message_handler
} ;