chiark / gitweb /
Add __attribute__((const, pure, format)) in various places
[elogind.git] / src / shared / dbus-common.h
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 #pragma once
4
5 /***
6   This file is part of systemd.
7
8   Copyright 2010 Lennart Poettering
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
24 #include <dbus/dbus.h>
25 #include <inttypes.h>
26 #include <sys/types.h>
27
28 #include "macro.h"
29
30 #ifndef DBUS_ERROR_UNKNOWN_OBJECT
31 #define DBUS_ERROR_UNKNOWN_OBJECT "org.freedesktop.DBus.Error.UnknownObject"
32 #endif
33
34 #ifndef DBUS_ERROR_UNKNOWN_INTERFACE
35 #define DBUS_ERROR_UNKNOWN_INTERFACE "org.freedesktop.DBus.Error.UnknownInterface"
36 #endif
37
38 #ifndef DBUS_ERROR_UNKNOWN_PROPERTY
39 #define DBUS_ERROR_UNKNOWN_PROPERTY "org.freedesktop.DBus.Error.UnknownProperty"
40 #endif
41
42 #ifndef DBUS_ERROR_PROPERTY_READ_ONLY
43 #define DBUS_ERROR_PROPERTY_READ_ONLY "org.freedesktop.DBus.Error.PropertyReadOnly"
44 #endif
45
46 #define BUS_PROPERTIES_INTERFACE                                        \
47         " <interface name=\"org.freedesktop.DBus.Properties\">\n"       \
48         "  <method name=\"Get\">\n"                                     \
49         "   <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n"    \
50         "   <arg name=\"property\" direction=\"in\" type=\"s\"/>\n"     \
51         "   <arg name=\"value\" direction=\"out\" type=\"v\"/>\n"       \
52         "  </method>\n"                                                 \
53         "  <method name=\"GetAll\">\n"                                  \
54         "   <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n"    \
55         "   <arg name=\"properties\" direction=\"out\" type=\"a{sv}\"/>\n" \
56         "  </method>\n"                                                 \
57         "  <method name=\"Set\">\n"                                     \
58         "   <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n"    \
59         "   <arg name=\"property\" direction=\"in\" type=\"s\"/>\n"     \
60         "   <arg name=\"value\" direction=\"in\" type=\"v\"/>\n"        \
61         "  </method>\n"                                                 \
62         "  <signal name=\"PropertiesChanged\">\n"                       \
63         "   <arg type=\"s\" name=\"interface\"/>\n"                     \
64         "   <arg type=\"a{sv}\" name=\"changed_properties\"/>\n"        \
65         "   <arg type=\"as\" name=\"invalidated_properties\"/>\n"       \
66         "  </signal>\n"                                                 \
67         " </interface>\n"
68
69 #define BUS_INTROSPECTABLE_INTERFACE                                    \
70         " <interface name=\"org.freedesktop.DBus.Introspectable\">\n"   \
71         "  <method name=\"Introspect\">\n"                              \
72         "   <arg name=\"data\" type=\"s\" direction=\"out\"/>\n"        \
73         "  </method>\n"                                                 \
74         " </interface>\n"
75
76 #define BUS_PEER_INTERFACE                                              \
77         "<interface name=\"org.freedesktop.DBus.Peer\">\n"              \
78         " <method name=\"Ping\"/>\n"                                    \
79         " <method name=\"GetMachineId\">\n"                             \
80         "  <arg type=\"s\" name=\"machine_uuid\" direction=\"out\"/>\n" \
81         " </method>\n"                                                  \
82         "</interface>\n"
83
84 #define BUS_GENERIC_INTERFACES_LIST             \
85         "org.freedesktop.DBus.Properties\0"     \
86         "org.freedesktop.DBus.Introspectable\0" \
87         "org.freedesktop.DBus.Peer\0"
88
89 int bus_check_peercred(DBusConnection *c);
90
91 int bus_connect(DBusBusType t, DBusConnection **_bus, bool *private_bus, DBusError *error);
92
93 int bus_connect_system_ssh(const char *user, const char *host, DBusConnection **_bus, DBusError *error);
94 int bus_connect_system_polkit(DBusConnection **_bus, DBusError *error);
95
96 const char *bus_error_message(const DBusError *error);
97 const char *bus_error(const DBusError *e, int r);
98
99 typedef int (*BusPropertyCallback)(DBusMessageIter *iter, const char *property, void *data);
100 typedef int (*BusPropertySetCallback)(DBusMessageIter *iter, const char *property, void *data);
101
102 typedef struct BusProperty {
103         const char *property;            /* name of the property */
104         BusPropertyCallback append;      /* Function that is called to serialize this property */
105         const char *signature;
106         const uint16_t offset;           /* Offset from BusBoundProperties::base address to the property data.
107                                           * uint16_t is sufficient, because we have no structs too big.
108                                           * -Werror=overflow will catch it if this does not hold. */
109         bool indirect;                   /* data is indirect, ie. not base+offset, but *(base+offset) */
110         BusPropertySetCallback set;      /* Optional: Function that is called to set this property */
111 } BusProperty;
112
113 typedef struct BusBoundProperties {
114         const char *interface;           /* interface of the properties */
115         const BusProperty *properties;   /* array of properties, ended by a NULL-filled element */
116         const void *const base;          /* base pointer to which the offset must be added to reach data */
117 } BusBoundProperties;
118
119 dbus_bool_t bus_maybe_send_reply (DBusConnection   *c,
120                                   DBusMessage *message,
121                                   DBusMessage *reply);
122
123 DBusHandlerResult bus_send_error_reply(
124                 DBusConnection *c,
125                 DBusMessage *message,
126                 DBusError *bus_error,
127                 int error);
128
129 DBusHandlerResult bus_default_message_handler(
130                 DBusConnection *c,
131                 DBusMessage *message,
132                 const char *introspection,
133                 const char *interfaces,
134                 const BusBoundProperties *bound_properties);
135
136 int bus_property_append_string(DBusMessageIter *i, const char *property, void *data);
137 int bus_property_append_strv(DBusMessageIter *i, const char *property, void *data);
138 int bus_property_append_bool(DBusMessageIter *i, const char *property, void *data);
139 int bus_property_append_tristate_false(DBusMessageIter *i, const char *property, void *data);
140 int bus_property_append_int32(DBusMessageIter *i, const char *property, void *data);
141 int bus_property_append_uint32(DBusMessageIter *i, const char *property, void *data);
142 int bus_property_append_uint64(DBusMessageIter *i, const char *property, void *data);
143 int bus_property_append_size(DBusMessageIter *i, const char *property, void *data);
144 int bus_property_append_ul(DBusMessageIter *i, const char *property, void *data);
145 int bus_property_append_long(DBusMessageIter *i, const char *property, void *data);
146
147 #define bus_property_append_int bus_property_append_int32
148 #define bus_property_append_pid bus_property_append_uint32
149 #define bus_property_append_uid bus_property_append_uint32
150 #define bus_property_append_gid bus_property_append_uint32
151 #define bus_property_append_mode bus_property_append_uint32
152 #define bus_property_append_unsigned bus_property_append_uint32
153 #define bus_property_append_usec bus_property_append_uint64
154
155 int bus_property_set_uint64(DBusMessageIter *i, const char *property, void *data);
156 #define bus_property_set_usec bus_property_set_uint64
157
158 #define DEFINE_BUS_PROPERTY_APPEND_ENUM(function,name,type)             \
159         int function(DBusMessageIter *i, const char *property, void *data) { \
160                 const char *value;                                      \
161                 type *field = data;                                     \
162                                                                         \
163                 assert(i);                                              \
164                 assert(property);                                       \
165                                                                         \
166                 value = strempty(name##_to_string(*field));             \
167                                                                         \
168                 if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &value)) \
169                         return -ENOMEM;                                 \
170                                                                         \
171                 return 0;                                               \
172         }
173
174 #define DEFINE_BUS_PROPERTY_SET_ENUM(function,name,type)                \
175         int function(DBusMessageIter *i, const char *property, void *data) { \
176                 const char *value;                                      \
177                 type f, *field = data;                                  \
178                                                                         \
179                 assert(i);                                              \
180                 assert(property);                                       \
181                                                                         \
182                 dbus_message_iter_get_basic(i, &value);                 \
183                                                                         \
184                 f = name##_from_string(value);                          \
185                 if (f < 0)                                              \
186                         return f;                                       \
187                                                                         \
188                 *field = f;                                             \
189                 return 0;                                               \
190         }
191
192 const char *bus_errno_to_dbus(int error) _const_;
193
194 DBusMessage* bus_properties_changed_new(const char *path, const char *interface, const char *properties);
195 DBusMessage* bus_properties_changed_one_new(const char *path, const char *interface, const char *property);
196
197 uint32_t bus_flags_to_events(DBusWatch *bus_watch) _pure_;
198 unsigned bus_events_to_flags(uint32_t events) _const_;
199
200 int bus_parse_strv(DBusMessage *m, char ***_l);
201 int bus_parse_strv_iter(DBusMessageIter *iter, char ***_l);
202 int bus_parse_strv_pairs_iter(DBusMessageIter *iter, char ***_l);
203
204 struct unit_info {
205         const char *id;
206         const char *description;
207         const char *load_state;
208         const char *active_state;
209         const char *sub_state;
210         const char *following;
211         const char *unit_path;
212         uint32_t job_id;
213         const char *job_type;
214         const char *job_path;
215 };
216
217 int bus_parse_unit_info(DBusMessageIter *iter, struct unit_info *u);
218
219 int bus_append_strv_iter(DBusMessageIter *iter, char **l);
220
221 int bus_iter_get_basic_and_next(DBusMessageIter *iter, int type, void *data, bool next);
222
223 int generic_print_property(const char *name, DBusMessageIter *iter, bool all);
224
225 void bus_async_unregister_and_exit(DBusConnection *bus, const char *name);
226
227 DBusHandlerResult bus_exit_idle_filter(DBusConnection *bus, DBusMessage *m, void *userdata);
228
229 pid_t bus_get_unix_process_id(DBusConnection *connection, const char *name, DBusError *error);
230
231 bool bus_error_is_no_service(const DBusError *error);
232 int bus_method_call_with_reply(DBusConnection *bus,
233                                const char *destination,
234                                const char *path,
235                                const char *interface,
236                                const char *method,
237                                DBusMessage **return_reply,
238                                DBusError *return_error,
239                                int first_arg_type, ...);
240
241 const char *bus_message_get_sender_with_fallback(DBusMessage *m);
242
243 void bus_message_unrefp(DBusMessage **reply);
244
245 #define _cleanup_dbus_message_unref_ __attribute__((cleanup(bus_message_unrefp)))
246 #define _cleanup_dbus_error_free_ __attribute__((cleanup(dbus_error_free)))