]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/dbus-job.c
Always check asprintf return code
[thirdparty/systemd.git] / src / core / dbus-job.c
CommitLineData
d6c9574f 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
ea430986 2
a7334b09
LP
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
a7334b09
LP
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 16 Lesser General Public License for more details.
a7334b09 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
ea430986 22#include "log.h"
718db961 23#include "sd-bus.h"
cad45ba1 24#include "selinux-access.h"
718db961
LP
25#include "job.h"
26#include "dbus-job.h"
8f8f05a9 27#include "dbus.h"
718db961
LP
28
29static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, job_type, JobType);
30static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_state, job_state, JobState);
31
32static int property_get_unit(
33 sd_bus *bus,
34 const char *path,
35 const char *interface,
36 const char *property,
37 sd_bus_message *reply,
ebcf1f97
LP
38 void *userdata,
39 sd_bus_error *error) {
ea430986 40
68eda4bd 41 _cleanup_free_ char *p = NULL;
718db961 42 Job *j = userdata;
86fbf370 43
718db961
LP
44 assert(bus);
45 assert(reply);
86fbf370
LP
46 assert(j);
47
cad45ba1
LP
48 p = unit_dbus_path(j->unit);
49 if (!p)
86fbf370
LP
50 return -ENOMEM;
51
718db961 52 return sd_bus_message_append(reply, "(so)", j->unit->id, p);
86fbf370
LP
53}
54
ebcf1f97 55static int method_cancel(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961 56 Job *j = userdata;
ebcf1f97 57 int r;
ea430986 58
718db961 59 assert(bus);
ea430986 60 assert(message);
718db961 61 assert(j);
86fbf370 62
4f4f7036 63 r = selinux_unit_access_check(j->unit, message, "stop", error);
ebcf1f97
LP
64 if (r < 0)
65 return r;
66
718db961 67 job_finish_and_invalidate(j, JOB_CANCELED, true);
2cccbca4 68
df2d202e 69 return sd_bus_reply_method_return(message, NULL);
ea430986
LP
70}
71
718db961
LP
72const sd_bus_vtable bus_job_vtable[] = {
73 SD_BUS_VTABLE_START(0),
74 SD_BUS_METHOD("Cancel", NULL, NULL, method_cancel, 0),
556089dc
LP
75 SD_BUS_PROPERTY("Id", "u", NULL, offsetof(Job, id), SD_BUS_VTABLE_PROPERTY_CONST),
76 SD_BUS_PROPERTY("Unit", "(so)", property_get_unit, 0, SD_BUS_VTABLE_PROPERTY_CONST),
77 SD_BUS_PROPERTY("JobType", "s", property_get_type, offsetof(Job, type), SD_BUS_VTABLE_PROPERTY_CONST),
718db961
LP
78 SD_BUS_PROPERTY("State", "s", property_get_state, offsetof(Job, state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
79 SD_BUS_VTABLE_END
ea430986 80};
c1e1601e 81
8f8f05a9 82static int send_new_signal(sd_bus *bus, void *userdata) {
718db961 83 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
1508e858 84 _cleanup_free_ char *p = NULL;
8f8f05a9 85 Job *j = userdata;
718db961
LP
86 int r;
87
88 assert(bus);
89 assert(j);
c1e1601e 90
97e6a119
MS
91 p = job_dbus_path(j);
92 if (!p)
718db961 93 return -ENOMEM;
c1e1601e 94
718db961
LP
95 r = sd_bus_message_new_signal(
96 bus,
151b9b96 97 &m,
718db961
LP
98 "/org/freedesktop/systemd1",
99 "org.freedesktop.systemd1.Manager",
151b9b96 100 "JobNew");
718db961
LP
101 if (r < 0)
102 return r;
103
104 r = sd_bus_message_append(m, "uos", j->id, p, j->unit->id);
105 if (r < 0)
106 return r;
107
8f8f05a9 108 return sd_bus_send(bus, m, NULL);
c1e1601e
LP
109}
110
8f8f05a9 111static int send_changed_signal(sd_bus *bus, void *userdata) {
1508e858 112 _cleanup_free_ char *p = NULL;
8f8f05a9 113 Job *j = userdata;
718db961
LP
114
115 assert(bus);
116 assert(j);
c1e1601e 117
97e6a119
MS
118 p = job_dbus_path(j);
119 if (!p)
718db961 120 return -ENOMEM;
c1e1601e 121
718db961 122 return sd_bus_emit_properties_changed(bus, p, "org.freedesktop.systemd1.Job", "State", NULL);
97e6a119
MS
123}
124
125void bus_job_send_change_signal(Job *j) {
718db961
LP
126 int r;
127
97e6a119
MS
128 assert(j);
129
130 if (j->in_dbus_queue) {
71fda00f 131 LIST_REMOVE(dbus_queue, j->manager->dbus_job_queue, j);
97e6a119
MS
132 j->in_dbus_queue = false;
133 }
134
8f8f05a9 135 r = bus_foreach_bus(j->manager, j->subscribed, j->sent_dbus_new_signal ? send_changed_signal : send_new_signal, j);
718db961 136 if (r < 0)
39abcaee 137 log_debug("Failed to send job change signal for %u: %s", j->id, strerror(-r));
97e6a119
MS
138
139 j->sent_dbus_new_signal = true;
718db961
LP
140}
141
8f8f05a9 142static int send_removed_signal(sd_bus *bus, void *userdata) {
718db961
LP
143 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
144 _cleanup_free_ char *p = NULL;
8f8f05a9 145 Job *j = userdata;
718db961
LP
146 int r;
147
148 assert(bus);
149 assert(j);
150
151 p = job_dbus_path(j);
152 if (!p)
153 return -ENOMEM;
c1e1601e 154
718db961
LP
155 r = sd_bus_message_new_signal(
156 bus,
151b9b96 157 &m,
718db961
LP
158 "/org/freedesktop/systemd1",
159 "org.freedesktop.systemd1.Manager",
151b9b96 160 "JobRemoved");
718db961
LP
161 if (r < 0)
162 return r;
163
164 r = sd_bus_message_append(m, "uoss", j->id, p, j->unit->id, job_result_to_string(j->result));
165 if (r < 0)
166 return r;
167
8f8f05a9 168 return sd_bus_send(bus, m, NULL);
97e6a119 169}
c1e1601e 170
97e6a119 171void bus_job_send_removed_signal(Job *j) {
718db961 172 int r;
c1e1601e 173
718db961 174 assert(j);
97e6a119
MS
175
176 if (!j->sent_dbus_new_signal)
177 bus_job_send_change_signal(j);
178
8f8f05a9 179 r = bus_foreach_bus(j->manager, j->subscribed, send_removed_signal, j);
718db961 180 if (r < 0)
39abcaee 181 log_debug("Failed to send job remove signal for %u: %s", j->id, strerror(-r));
c1e1601e 182}