blob: f23cd31bc99d61f8610312f83d7a7647d3fad9d1 [file] [log] [blame]
Richard Hughes3d005222019-05-17 14:02:41 +01001/*
Richard Hughes5c9b1fc2021-01-07 14:20:49 +00002 * Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
Richard Hughes3d005222019-05-17 14:02:41 +01003 *
4 * SPDX-License-Identifier: LGPL-2.1+
5 */
6
7#include <config.h>
8
9#include <stdio.h>
10#include <glib/gi18n.h>
Richard Hughesdd0159d2021-01-13 18:39:59 +000011#include <gio/gio.h>
Richard Hughes3d005222019-05-17 14:02:41 +010012
13#include "fu-systemd.h"
14
15#define SYSTEMD_SERVICE "org.freedesktop.systemd1"
16#define SYSTEMD_OBJECT_PATH "/org/freedesktop/systemd1"
17#define SYSTEMD_INTERFACE "org.freedesktop.systemd1"
18#define SYSTEMD_MANAGER_INTERFACE "org.freedesktop.systemd1.Manager"
Mario Limonciello3a10c3c2019-10-12 17:46:32 -050019#define SYSTEMD_UNIT_INTERFACE "org.freedesktop.systemd1.Unit"
Richard Hughes3d005222019-05-17 14:02:41 +010020
21static GDBusProxy *
22fu_systemd_get_manager (GError **error)
23{
24 g_autoptr(GDBusConnection) connection = NULL;
25 g_autoptr(GDBusProxy) proxy = NULL;
26
27 connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error);
28 if (connection == NULL) {
29 g_prefix_error (error, "failed to get bus: ");
30 return NULL;
31 }
32 proxy = g_dbus_proxy_new_sync (connection,
33 G_DBUS_PROXY_FLAGS_NONE, NULL,
34 SYSTEMD_SERVICE,
35 SYSTEMD_OBJECT_PATH,
36 SYSTEMD_MANAGER_INTERFACE,
37 NULL, error);
38 if (proxy == NULL) {
39 g_prefix_error (error, "failed to find %s: ", SYSTEMD_SERVICE);
40 return NULL;
41 }
42 return g_steal_pointer (&proxy);
43}
44
45static gchar *
46fu_systemd_unit_get_path (GDBusProxy *proxy_manager, const gchar *unit, GError **error)
47{
48 g_autofree gchar *path = NULL;
49 g_autoptr(GVariant) val = NULL;
50
51 val = g_dbus_proxy_call_sync (proxy_manager,
52 "GetUnit",
53 g_variant_new ("(s)", unit),
54 G_DBUS_CALL_FLAGS_NONE,
55 -1, NULL, error);
56 if (val == NULL) {
57 g_prefix_error (error, "failed to find %s: ", unit);
58 return NULL;
59 }
60 g_variant_get (val, "(o)", &path);
61 return g_steal_pointer (&path);
62}
63
64static GDBusProxy *
65fu_systemd_unit_get_proxy (GDBusProxy *proxy_manager, const gchar *unit, GError **error)
66{
67 g_autofree gchar *path = NULL;
68 g_autoptr(GDBusProxy) proxy_unit = NULL;
69
70 path = fu_systemd_unit_get_path (proxy_manager, unit, error);
71 if (path == NULL)
72 return NULL;
73 proxy_unit = g_dbus_proxy_new_sync (g_dbus_proxy_get_connection (proxy_manager),
74 G_DBUS_PROXY_FLAGS_NONE, NULL,
75 SYSTEMD_SERVICE,
76 path,
Mario Limonciello3a10c3c2019-10-12 17:46:32 -050077 SYSTEMD_UNIT_INTERFACE,
Richard Hughes3d005222019-05-17 14:02:41 +010078 NULL, error);
79 if (proxy_unit == NULL) {
80 g_prefix_error (error, "failed to register proxy for %s: ", path);
81 return NULL;
82 }
83 return g_steal_pointer (&proxy_unit);
84}
85
86gchar *
87fu_systemd_get_default_target (GError **error)
88{
89 const gchar *path = NULL;
90 g_autoptr(GDBusProxy) proxy_manager = NULL;
91 g_autoptr(GVariant) val = NULL;
92
93 proxy_manager = fu_systemd_get_manager (error);
94 if (proxy_manager == NULL)
95 return NULL;
96 val = g_dbus_proxy_call_sync (proxy_manager,
97 "GetDefaultTarget", NULL,
98 G_DBUS_CALL_FLAGS_NONE,
99 -1, NULL, error);
100 if (val == NULL)
101 return NULL;
102 g_variant_get (val, "(&s)", &path);
103 return g_strdup (path);
104
105}
106
107gboolean
108fu_systemd_unit_stop (const gchar *unit, GError **error)
109{
110 g_autoptr(GDBusProxy) proxy_manager = NULL;
111 g_autoptr(GDBusProxy) proxy_unit = NULL;
112 g_autoptr(GVariant) val = NULL;
113
114 g_return_val_if_fail (unit != NULL, FALSE);
115
116 proxy_manager = fu_systemd_get_manager (error);
117 if (proxy_manager == NULL)
118 return FALSE;
119 proxy_unit = fu_systemd_unit_get_proxy (proxy_manager, unit, error);
120 if (proxy_unit == NULL)
121 return FALSE;
122 val = g_dbus_proxy_call_sync (proxy_unit,
Mario Limonciello3a10c3c2019-10-12 17:46:32 -0500123 "Stop",
124 g_variant_new ("(s)", "replace"),
Richard Hughes3d005222019-05-17 14:02:41 +0100125 G_DBUS_CALL_FLAGS_NONE,
126 -1, NULL, error);
127 return val != NULL;
128}
129
130gboolean
131fu_systemd_unit_enable (const gchar *unit, GError **error)
132{
133 const gchar *units[] = { unit, NULL };
134 g_autoptr(GDBusProxy) proxy_manager = NULL;
135 g_autoptr(GVariant) val = NULL;
136
137 g_return_val_if_fail (unit != NULL, FALSE);
138
139 proxy_manager = fu_systemd_get_manager (error);
140 if (proxy_manager == NULL)
141 return FALSE;
142 val = g_dbus_proxy_call_sync (proxy_manager,
143 "EnableUnitFiles",
144 g_variant_new ("(^asbb)", units, TRUE, TRUE),
145 G_DBUS_CALL_FLAGS_NONE,
146 -1, NULL, error);
147 return val != NULL;
148}
149
150gboolean
151fu_systemd_unit_disable (const gchar *unit, GError **error)
152{
153 const gchar *units[] = { unit, NULL };
154 g_autoptr(GDBusProxy) proxy_manager = NULL;
155 g_autoptr(GVariant) val = NULL;
156
157 g_return_val_if_fail (unit != NULL, FALSE);
158
159 proxy_manager = fu_systemd_get_manager (error);
160 if (proxy_manager == NULL)
161 return FALSE;
162 val = g_dbus_proxy_call_sync (proxy_manager,
163 "DisableUnitFiles",
164 g_variant_new ("(^asb)", units, TRUE),
165 G_DBUS_CALL_FLAGS_NONE,
166 -1, NULL, error);
167 return val != NULL;
168}
169
170gboolean
171fu_systemd_unit_check_exists (const gchar *unit, GError **error)
172{
173 g_autoptr(GDBusProxy) proxy_manager = NULL;
174 g_autofree gchar *path = NULL;
175
176 g_return_val_if_fail (unit != NULL, FALSE);
177
178 proxy_manager = fu_systemd_get_manager (error);
179 if (proxy_manager == NULL)
180 return FALSE;
181 path = fu_systemd_unit_get_path (proxy_manager, unit, error);
182 return path != NULL;
183}