]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/bus-proxyd/synthesize.c
Merge branch 'hostnamectl-dot-v2'
[thirdparty/systemd.git] / src / bus-proxyd / synthesize.c
CommitLineData
f3c47246
DM
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Daniel Mack
8 Copyright 2014 Kay Sievers
9
10 systemd is free software; you can redistribute it and/or modify it
11 under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14
15 systemd is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
19
20 You should have received a copy of the GNU Lesser General Public License
21 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22***/
23
f3c47246
DM
24#include <stddef.h>
25
f3c47246
DM
26#include "util.h"
27#include "sd-bus.h"
28#include "bus-internal.h"
29#include "bus-message.h"
30#include "bus-util.h"
e23bc0e7 31#include "bus-match.h"
f3c47246
DM
32#include "synthesize.h"
33
52fa7a3a 34int synthetic_driver_send(sd_bus *b, sd_bus_message *m) {
f3c47246
DM
35 int r;
36
37 assert(b);
38 assert(m);
39
40 r = bus_message_append_sender(m, "org.freedesktop.DBus");
41 if (r < 0)
42 return r;
43
44 r = bus_seal_synthetic_message(b, m);
45 if (r < 0)
46 return r;
47
48 return sd_bus_send(b, m, NULL);
49}
50
51int synthetic_reply_method_error(sd_bus_message *call, const sd_bus_error *e) {
52 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
53 int r;
54
55 assert(call);
56
57 if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
58 return 0;
59
60 r = sd_bus_message_new_method_error(call, &m, e);
61 if (r < 0)
62 return r;
63
64 return synthetic_driver_send(call->bus, m);
65}
66
67int synthetic_reply_method_errorf(sd_bus_message *call, const char *name, const char *format, ...) {
68 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
69 va_list ap;
70
71 va_start(ap, format);
72 bus_error_setfv(&error, name, format, ap);
73 va_end(ap);
74
75 return synthetic_reply_method_error(call, &error);
76}
77
78int synthetic_reply_method_errno(sd_bus_message *call, int error, const sd_bus_error *p) {
f3c47246
DM
79 _cleanup_bus_error_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
80
81 assert(call);
82
83 if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
84 return 0;
85
86 if (sd_bus_error_is_set(p))
87 return synthetic_reply_method_error(call, p);
88
89 sd_bus_error_set_errno(&berror, error);
90
91 return synthetic_reply_method_error(call, &berror);
92}
93
5f6cb091
LP
94int synthetic_reply_method_errnof(sd_bus_message *call, int error, const char *format, ...) {
95 _cleanup_bus_error_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
96 va_list ap;
97
98 assert(call);
99
100 if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
101 return 0;
102
103 va_start(ap, format);
104 sd_bus_error_set_errnofv(&berror, error, format, ap);
105 va_end(ap);
106
107 return synthetic_reply_method_error(call, &berror);
108}
109
f3c47246
DM
110int synthetic_reply_method_return(sd_bus_message *call, const char *types, ...) {
111 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
112 int r;
113
114 assert(call);
115
116 if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
117 return 0;
118
119 r = sd_bus_message_new_method_return(call, &m);
120 if (r < 0)
121 return r;
122
123 if (!isempty(types)) {
124 va_list ap;
125
126 va_start(ap, types);
127 r = bus_message_append_ap(m, types, ap);
128 va_end(ap);
129 if (r < 0)
130 return r;
131 }
132
133 return synthetic_driver_send(call->bus, m);
134}
135
1433efd2 136int synthetic_reply_method_return_strv(sd_bus_message *call, char **l) {
f3c47246
DM
137 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
138 int r;
139
140 assert(call);
141
142 if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
143 return 0;
144
145 r = sd_bus_message_new_method_return(call, &m);
146 if (r < 0)
147 return synthetic_reply_method_errno(call, r, NULL);
148
149 r = sd_bus_message_append_strv(m, l);
150 if (r < 0)
151 return synthetic_reply_method_errno(call, r, NULL);
152
153 return synthetic_driver_send(call->bus, m);
154}
5e2de0eb 155
e23bc0e7 156int synthesize_name_acquired(Proxy *p, sd_bus *a, sd_bus *b, sd_bus_message *m) {
5e2de0eb
DM
157 _cleanup_bus_message_unref_ sd_bus_message *n = NULL;
158 const char *name, *old_owner, *new_owner;
159 int r;
160
e23bc0e7 161 assert(p);
5e2de0eb
DM
162 assert(a);
163 assert(b);
164 assert(m);
165
166 /* If we get NameOwnerChanged for our own name, we need to
167 * synthesize NameLost/NameAcquired, since socket clients need
168 * that, even though it is obsoleted on kdbus */
169
170 if (!a->is_kernel)
171 return 0;
172
173 if (!sd_bus_message_is_signal(m, "org.freedesktop.DBus", "NameOwnerChanged") ||
174 !streq_ptr(m->path, "/org/freedesktop/DBus") ||
175 !streq_ptr(m->sender, "org.freedesktop.DBus"))
176 return 0;
177
178 r = sd_bus_message_read(m, "sss", &name, &old_owner, &new_owner);
179 if (r < 0)
180 return r;
181
182 r = sd_bus_message_rewind(m, true);
183 if (r < 0)
184 return r;
185
186 if (streq(old_owner, a->unique_name)) {
187
188 r = sd_bus_message_new_signal(
189 b,
190 &n,
191 "/org/freedesktop/DBus",
192 "org.freedesktop.DBus",
193 "NameLost");
194
195 } else if (streq(new_owner, a->unique_name)) {
196
197 r = sd_bus_message_new_signal(
198 b,
199 &n,
200 "/org/freedesktop/DBus",
201 "org.freedesktop.DBus",
202 "NameAcquired");
203 } else
204 return 0;
205
206 if (r < 0)
207 return r;
208
209 r = sd_bus_message_append(n, "s", name);
210 if (r < 0)
211 return r;
212
213 r = bus_message_append_sender(n, "org.freedesktop.DBus");
214 if (r < 0)
215 return r;
216
e3c57a86
DH
217 r = sd_bus_message_set_destination(n, a->unique_name);
218 if (r < 0)
219 return r;
220
5e2de0eb
DM
221 r = bus_seal_synthetic_message(b, n);
222 if (r < 0)
223 return r;
224
a87d2ed1 225 return sd_bus_send(b, n, NULL);
5e2de0eb 226}