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