Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Side by Side Diff: dhcpcd-dbus.c

Issue 2428004: Overhaul dhcpcd for chrome os use (Closed) Base URL: ssh://git@chromiumos-git//dhcpcd.git
Patch Set: purge hooks from configure to silence complaint Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « dhcpcd-dbus.h ('k') | dhcpcd-dbus.conf » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * dhcpcd-dbus
3 * Copyright 2009 Roy Marples <roy@marples.name>
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27 #include <errno.h>
28 #include <poll.h>
29 #include <signal.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <syslog.h>
34
35 #include <dbus/dbus.h>
36
37 #include "config.h"
38 #include "eloop.h"
39 #include "dbus-dict.h"
40 #include "dhcpcd-dbus.h"
41 #include "dhcpcd.h"
42
43 #define S_EINVAL DHCPCD_SERVICE ".InvalidArgument"
44 #define S_ARGS "Not enough arguments"
45
46 static DBusConnection *connection;
47
48 static const char dhcpcd_introspection_xml[] =
49 " <method name=\"GetVersion\">\n"
50 " <arg name=\"version\" direction=\"out\" type=\"s\"/>\n"
51 " </method>\n"
52 " <method name=\"GetInterfaces\">\n"
53 " <arg name=\"interfaces\" direction=\"out\" type=\"a{sa{sv}}\"/>\n"
54 " </method>\n"
55 " <method name=\"GetStatus\">\n"
56 " <arg name=\"Status\" direction=\"out\" type=\"s\"/>\n"
57 " </method>\n"
58 " <method name=\"Rebind\">\n"
59 " <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n"
60 " </method>\n"
61 " <method name=\"Release\">\n"
62 " <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n"
63 " </method>\n"
64 " <method name=\"Stop\">\n"
65 " <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n"
66 " </method>\n"
67 " <signal name=\"Event\">\n"
68 " <arg name=\"configuration\" type=\"usa{sv}\"/>\n"
69 " </signal>\n"
70 " <signal name=\"StatusChanged\">\n"
71 " <arg name=\"status\" type=\"us\"/>\n"
72 " </signal>\n";
73
74 static const struct o_dbus const dhos[] = {
75 { "ip_address=", DBUS_TYPE_UINT32, 0, "IPAddress" },
76 { "server_name=", DBUS_TYPE_STRING, 0, "ServerName"},
77 { "subnet_mask=", DBUS_TYPE_UINT32, 0, "SubnetMask" },
78 { "subnet_cidr=", DBUS_TYPE_BYTE, 0, "SubnetCIDR" },
79 { "network_number=", DBUS_TYPE_UINT32, 0, "NetworkNumber" },
80 { "classless_static_routes=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
81 "ClasslessStaticRoutes" },
82 { "ms_classless_static_routes=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
83 "MSClasslessStaticRoutes" },
84 { "static_routes=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
85 "StaticRoutes"} ,
86 { "routers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "Routers" },
87 { "time_offset=", DBUS_TYPE_UINT32, 0, "TimeOffset" },
88 { "time_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "TimeServers" },
89 { "ien116_name_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
90 "IEN116NameServers" },
91 { "domain_name_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
92 "DomainNameServers" },
93 { "log_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "LogServers" },
94 { "cookie_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
95 "CookieServers" },
96 { "lpr_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "LPRServers" },
97 { "impress_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
98 "ImpressServers" },
99 { "resource_location_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
100 "ResourceLocationServers" },
101 { "host_name=", DBUS_TYPE_STRING, 0, "Hostname" },
102 { "boot_size=", DBUS_TYPE_UINT16, 0, "BootSize" },
103 { "merit_dump=", DBUS_TYPE_STRING, 0, "MeritDump" },
104 { "domain_name=", DBUS_TYPE_STRING, 0, "DomainName" },
105 { "swap_server=", DBUS_TYPE_UINT32, 0, "SwapServer" },
106 { "root_path=", DBUS_TYPE_STRING, 0, "RootPath" },
107 { "extensions_path=", DBUS_TYPE_STRING, 0, "ExtensionsPath" },
108 { "ip_forwarding=", DBUS_TYPE_BOOLEAN, 0, "IPForwarding" },
109 { "non_local_source_routing=", DBUS_TYPE_BOOLEAN, 0,
110 "NonLocalSourceRouting" },
111 { "policy_filter=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
112 "PolicyFilter" },
113 { "max_dgram_reassembly=", DBUS_TYPE_INT16, 0,
114 "MaxDatagramReassembly" },
115 { "default_ip_ttl=", DBUS_TYPE_UINT16, 0, "DefaultIPTTL" },
116 { "path_mtu_aging_timeout=", DBUS_TYPE_UINT32, 0,
117 "PathMTUAgingTimeout" },
118 { "path_mtu_plateau_table=" ,DBUS_TYPE_ARRAY, DBUS_TYPE_UINT16,
119 "PolicyFilter"} ,
120 { "interface_mtu=", DBUS_TYPE_UINT16, 0, "InterfaceMTU" },
121 { "all_subnets_local=", DBUS_TYPE_BOOLEAN, 0, "AllSubnetsLocal" },
122 { "broadcast_address=", DBUS_TYPE_UINT32, 0, "BroadcastAddress" },
123 { "perform_mask_discovery=", DBUS_TYPE_BOOLEAN, 0,
124 "PerformMaskDiscovery" },
125 { "mask_supplier=", DBUS_TYPE_BOOLEAN, 0, "MaskSupplier" },
126 { "router_discovery=", DBUS_TYPE_BOOLEAN, 0, "RouterDiscovery" },
127 { "router_solicitiation_address=", DBUS_TYPE_UINT32, 0,
128 "RouterSolicationAddress" },
129 { "trailer_encapsulation=", DBUS_TYPE_BOOLEAN, 0,
130 "TrailerEncapsulation" },
131 { "arp_cache_timeout=", DBUS_TYPE_UINT32, 0, "ARPCacheTimeout" },
132 { "ieee802_3_encapsulation=", DBUS_TYPE_UINT16, 0,
133 "IEEE8023Encapsulation" },
134 { "default_tcp_ttl=", DBUS_TYPE_BYTE, 0, "DefaultTCPTTL" },
135 { "tcp_keepalive_interval=", DBUS_TYPE_UINT32, 0,
136 "TCPKeepAliveInterval" },
137 { "tcp_keepalive_garbage=", DBUS_TYPE_BOOLEAN, 0,
138 "TCPKeepAliveGarbage" },
139 { "nis_domain=", DBUS_TYPE_STRING, 0, "NISDomain" },
140 { "nis_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "NISServers" },
141 { "ntp_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "NTPServers" },
142 { "vendor_encapsulated_optons=", DBUS_TYPE_STRING, 0,
143 "VendorEncapsulatedOptions" },
144 { "netbios_name_servers=" ,DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
145 "NetBIOSNameServers" },
146 { "netbios_dd_server=", DBUS_TYPE_UINT32, 0, "NetBIOSDDServer" },
147 { "netbios_node_type=", DBUS_TYPE_BYTE, 0, "NetBIOSNodeType" },
148 { "netbios_scope=", DBUS_TYPE_STRING, 0, "NetBIOSScope" },
149 { "font_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "FontServers" },
150 { "x_display_manager=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
151 "XDisplayManager" },
152 { "dhcp_requested_address=", DBUS_TYPE_UINT32, 0,
153 "DHCPRequestedAddress" },
154 { "dhcp_lease_time=", DBUS_TYPE_UINT32, 0, "DHCPLeaseTime" },
155 { "dhcp_option_overload=", DBUS_TYPE_BOOLEAN, 0,
156 "DHCPOptionOverload" },
157 { "dhcp_message_type=", DBUS_TYPE_BYTE, 0, "DHCPMessageType" },
158 { "dhcp_server_identifier=", DBUS_TYPE_UINT32, 0,
159 "DHCPServerIdentifier" },
160 { "dhcp_message=", DBUS_TYPE_STRING, 0, "DHCPMessage" },
161 { "dhcp_max_message_size=", DBUS_TYPE_UINT16, 0,
162 "DHCPMaxMessageSize" },
163 { "dhcp_renewal_time=", DBUS_TYPE_UINT32, 0, "DHCPRenewalTime" },
164 { "dhcp_rebinding_time=", DBUS_TYPE_UINT32, 0, "DHCPRebindingTime" },
165 { "nisplus_domain=", DBUS_TYPE_STRING, 0, "NISPlusDomain" },
166 { "nisplus_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
167 "NISPlusServers" },
168 { "tftp_server_name=", DBUS_TYPE_STRING, 0, "TFTPServerName" },
169 { "bootfile_name=", DBUS_TYPE_STRING, 0, "BootFileName" },
170 { "mobile_ip_home_agent=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
171 "MobileIPHomeAgent" },
172 { "smtp_server=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "SMTPServer" },
173 { "pop_server=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "POPServer" },
174 { "nntp_server=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "NNTPServer" },
175 { "www_server=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "WWWServer" },
176 { "finger_server=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
177 "FingerServer" },
178 { "irc_server=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "IRCServer" },
179 { "streettalk_server=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
180 "StreetTalkServer" },
181 { "streettalk_directory_assistance_server=", DBUS_TYPE_ARRAY,
182 DBUS_TYPE_UINT32, "StreetTalkDirectoryAssistanceServer" },
183 { "user_class=", DBUS_TYPE_STRING, 0, "UserClass" },
184 { "new_fqdn_name=", DBUS_TYPE_STRING, 0, "FQDNName" },
185 { "nds_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "NDSServers" },
186 { "nds_tree_name=", DBUS_TYPE_STRING, 0, "NDSTreeName" },
187 { "nds_context=", DBUS_TYPE_STRING, 0, "NDSContext" },
188 { "bcms_controller_names=", DBUS_TYPE_STRING, 0,
189 "BCMSControllerNames" },
190 { "client_last_transaction_time=", DBUS_TYPE_UINT32, 0,
191 "ClientLastTransactionTime" },
192 { "associated_ip=", DBUS_TYPE_UINT32, 0, "AssociatedIP" },
193 { "uap_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "UAPServers" },
194 { "netinfo_server_address=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
195 "NetinfoServerAddress" },
196 { "netinfo_server_tag=", DBUS_TYPE_STRING, 0, "NetinfoServerTag" },
197 { "default_url=", DBUS_TYPE_STRING, 0, "DefaultURL" },
198 { "subnet_selection=", DBUS_TYPE_UINT32, 0, "SubnetSelection" },
199 { "domain_search=", DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
200 "DomainSearch" },
201 { NULL, 0, 0, NULL }
202 };
203
204 static int
205 append_config(DBusMessageIter *iter,
206 const char *prefix, char **env, ssize_t elen)
207 {
208 char **eenv, *p;
209 const struct o_dbus *dhop;
210 size_t l, lp;
211 int retval;
212
213 retval = 0;
214 lp = strlen(prefix);
215 for (eenv = env + elen; env < eenv; env++) {
216 p = env[0];
217 for (dhop = dhos; dhop->var; dhop++) {
218 l = strlen(dhop->var);
219 if (strncmp(p, dhop->var, l) == 0) {
220 retval = dict_append_config_item(iter,
221 dhop, p + l);
222 break;
223 }
224 if (strncmp(p, prefix, lp) == 0 &&
225 strncmp(p + lp, dhop->var, l) == 0)
226 {
227 retval = dict_append_config_item(iter,
228 dhop, p + l + lp);
229 break;
230 }
231 }
232 if (retval == -1)
233 break;
234 }
235 return retval;
236 }
237
238 DBusHandlerResult _printf(4, 5)
239 return_dbus_error(DBusConnection *con, DBusMessage *msg,
240 const char *name, const char *fmt, ...)
241 {
242 char buffer[1024];
243 DBusMessage *reply;
244 va_list args;
245
246 va_start(args, fmt);
247 vsnprintf(buffer, sizeof(buffer), fmt, args);
248 va_end(args);
249 reply = dbus_message_new_error(msg, name, buffer);
250 dbus_connection_send(con, reply, NULL);
251 dbus_message_unref(reply);
252 return DBUS_HANDLER_RESULT_HANDLED;
253 }
254
255 const char *dhcpcd_status = NULL; /* XXX */
256
257 static DBusHandlerResult
258 return_status(DBusConnection *con, DBusMessage *msg)
259 {
260 DBusMessage *reply;
261
262 reply = dbus_message_new_method_return(msg);
263 dbus_message_append_args(reply,
264 DBUS_TYPE_STRING, &dhcpcd_status,
265 DBUS_TYPE_INVALID);
266 dbus_connection_send(con, reply, NULL);
267 dbus_message_unref(reply);
268 return DBUS_HANDLER_RESULT_HANDLED;
269 }
270
271 void
272 dhcpcd_dbus_signal_status(const char *status)
273 {
274 DBusMessage *msg;
275 DBusMessageIter args;
276 int pid = getpid();
277
278 syslog(LOG_INFO, "status changed to %s", status);
279
280 msg = dbus_message_new_signal(DHCPCD_PATH, DHCPCD_SERVICE,
281 "StatusChanged");
282 if (msg == NULL) {
283 syslog(LOG_ERR, "failed to make a status changed message");
284 return;
285 }
286 dbus_message_iter_init_append(msg, &args);
287 dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT32, &pid);
288 dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &status);
289 if (!dbus_connection_send(connection, msg, NULL))
290 syslog(LOG_ERR, "failed to send status to dbus");
291 dbus_message_unref(msg);
292 }
293
294 void
295 dhcpcd_dbus_configure(const struct interface *ifp, const char *reason)
296 {
297 const struct if_options *ifo = ifp->state->options;
298 DBusMessage* msg;
299 DBusMessageIter args, dict;
300 int pid = getpid();
301 char **env;
302 ssize_t e, elen;
303 int retval;
304
305 syslog(LOG_INFO, "event %s on interface %s", reason, ifp->name);
306
307 msg = dbus_message_new_signal(DHCPCD_PATH, DHCPCD_SERVICE, "Event");
308 if (msg == NULL) {
309 syslog(LOG_ERR, "failed to make a configure message");
310 return;
311 }
312 dbus_message_iter_init_append(msg, &args);
313 dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT32, &pid);
314 dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &reason);
315 dbus_message_iter_open_container(&args, DBUS_TYPE_ARRAY,
316 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
317 DBUS_TYPE_STRING_AS_STRING
318 DBUS_TYPE_VARIANT_AS_STRING
319 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
320 &dict);
321 if (ifp->state->new != NULL) {
322 e = configure_env(NULL, NULL, ifp->state->new, ifo);
323 if (e > 0) {
324 env = xzalloc(sizeof(char *) * (e + 1));
325 elen = configure_env(env, "new", ifp->state->new, ifo);
326 }
327 retval = append_config(&dict, "new_", env, elen);
328 } else if (ifp->state->old != NULL) {
329 e = configure_env(NULL, NULL, ifp->state->old, ifo);
330 if (e > 0) {
331 env = xzalloc(sizeof(char *) * (elen + e + 1));
332 elen = configure_env(env, "old", ifp->state->old, ifo);
333 }
334 retval = append_config(&dict, "old_", env, elen);
335 } else
336 retval = 0;
337 /* XXX reclaim env */
338 dbus_message_iter_close_container(&args, &dict);
339 if (retval == 0) {
340 if (!dbus_connection_send(connection, msg, NULL))
341 syslog(LOG_ERR, "failed to send dhcp to dbus");
342 } else
343 syslog(LOG_ERR, "failed to construct dbus message");
344 dbus_message_unref(msg);
345 }
346
347 static const char introspection_header_xml[] =
348 "<!DOCTYPE node PUBLIC \"-//freedesktop//"
349 "DTD D-BUS Object Introspection 1.0//EN\"\n"
350 "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
351 "<node name=\"" DHCPCD_PATH "\">\n"
352 " <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
353 " <method name=\"Introspect\">\n"
354 " <arg name=\"data\" direction=\"out\" type=\"s\"/>\n"
355 " </method>\n"
356 " </interface>\n"
357 " <interface name=\"" DHCPCD_SERVICE "\">\n";
358
359 static const char introspection_footer_xml[] =
360 " </interface>\n"
361 "</node>\n";
362
363 static DBusHandlerResult
364 introspect(DBusConnection *con, DBusMessage *msg)
365 {
366 DBusMessage *reply;
367 char *xml;
368 size_t len;
369
370 len = sizeof(introspection_header_xml) - 1
371 + sizeof(dhcpcd_introspection_xml) - 1
372 + sizeof(introspection_footer_xml) - 1
373 + 1; /* terminal \0 */
374 xml = malloc(len);
375 if (xml == NULL)
376 return DBUS_HANDLER_RESULT_HANDLED;
377 snprintf(xml, len, "%s%s%s",
378 introspection_header_xml,
379 dhcpcd_introspection_xml,
380 introspection_footer_xml);
381 reply = dbus_message_new_method_return(msg);
382 dbus_message_append_args(reply,
383 DBUS_TYPE_STRING, &xml,
384 DBUS_TYPE_INVALID);
385 dbus_connection_send(con, reply, NULL);
386 dbus_message_unref(reply);
387 free(xml);
388 return DBUS_HANDLER_RESULT_HANDLED;
389 }
390
391 static DBusHandlerResult
392 version(DBusConnection *con, DBusMessage *msg, const char *ver)
393 {
394 DBusMessage *reply;
395
396 reply = dbus_message_new_method_return(msg);
397 dbus_message_append_args(reply,
398 DBUS_TYPE_STRING, &ver,
399 DBUS_TYPE_INVALID);
400 dbus_connection_send(con, reply, NULL);
401 dbus_message_unref(reply);
402 return DBUS_HANDLER_RESULT_HANDLED;
403 }
404
405 static DBusHandlerResult
406 dhcpcd_get_interfaces(DBusConnection *con, DBusMessage *msg)
407 {
408 DBusMessage *reply;
409 DBusMessageIter _ifaces, _iface, entry, dict;
410 struct interface *ifp;
411 char **env;
412 ssize_t e, elen;
413 int retval;
414
415 reply = dbus_message_new_method_return(msg);
416 dbus_message_iter_init_append(reply, &_ifaces);
417
418 dbus_message_iter_open_container(&_ifaces, DBUS_TYPE_ARRAY,
419 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
420 DBUS_TYPE_STRING_AS_STRING
421 DBUS_TYPE_ARRAY_AS_STRING
422 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
423 DBUS_TYPE_STRING_AS_STRING
424 DBUS_TYPE_VARIANT_AS_STRING
425 DBUS_DICT_ENTRY_END_CHAR_AS_STRING
426 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
427 &_iface);
428
429 for (ifp = ifaces; ifp != NULL; ifp = ifp->next) {
430 const struct if_options *ifo = ifp->state->options;
431
432 dbus_message_iter_open_container(&_iface,
433 DBUS_TYPE_DICT_ENTRY, NULL, &entry);
434 dbus_message_iter_append_basic(&entry,
435 DBUS_TYPE_STRING, &ifp->name);
436 dbus_message_iter_open_container(&entry, DBUS_TYPE_ARRAY,
437 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
438 DBUS_TYPE_STRING_AS_STRING
439 DBUS_TYPE_VARIANT_AS_STRING
440 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
441 &dict);
442 e = configure_env(NULL, NULL, ifp->state->new, ifo);
443 if (e > 0) {
444 env = xzalloc(sizeof(char *) * (e + 1));
445 elen = configure_env(env, "new", ifp->state->new, ifo);
446 }
447 retval = append_config(&dict, "new_", env, elen);
448 /* XXX reclaim env */
449 dbus_message_iter_close_container(&entry, &dict);
450 dbus_message_iter_close_container(&_iface, &entry);
451 }
452
453 dbus_message_iter_close_container(&_ifaces, &_iface);
454 dbus_connection_send(con, reply, NULL);
455 dbus_message_unref(reply);
456 return DBUS_HANDLER_RESULT_HANDLED;
457 }
458
459 static DBusHandlerResult
460 dbus_ack(DBusConnection *con, DBusMessage *msg)
461 {
462 DBusMessage *reply;
463
464 reply = dbus_message_new_method_return(msg);
465 dbus_connection_send(con, reply, NULL);
466 dbus_message_unref(reply);
467 return DBUS_HANDLER_RESULT_HANDLED;
468 }
469
470 static DBusHandlerResult
471 msg_handler(DBusConnection *con, DBusMessage *msg, _unused void *data)
472 {
473 #define IsMethod(msg, method) \
474 dbus_message_is_method_call(msg, DHCPCD_SERVICE, method)
475 if (IsMethod(msg, "Introspect")) {
476 return introspect(con, msg);
477 } else if (IsMethod(msg, "GetVersion")) {
478 return version(con, msg, VERSION);
479 } else if (IsMethod(msg, "GetInterfaces")) {
480 return dhcpcd_get_interfaces(con, msg);
481 } else if (IsMethod(msg, "GetStatus")) {
482 return return_status(con, msg);
483 } else if (IsMethod(msg, "Rebind")) {
484 bind_interface(ifaces); /* XXX */
485 return dbus_ack(con, msg);
486 } else if (IsMethod(msg, "Release")) {
487 handle_signal(SIGHUP);
488 return dbus_ack(con, msg);
489 } else if (IsMethod(msg, "Stop")) {
490 /* NB: must ack first 'cuz handle_signal exit's */
491 (void) dbus_ack(con, msg);
492 handle_signal(SIGINT);
493 /*NOTREACHED*/
494 }
495 return return_dbus_error(con, msg, S_EINVAL, S_ARGS);
496 #undef IsMethod
497 }
498
499 static void
500 dbus_event(int revents, void *watch)
501 {
502 int flags;
503
504 flags = 0;
505 if (revents & POLLIN)
506 flags |= DBUS_WATCH_READABLE;
507 if (revents & POLLOUT)
508 flags |= DBUS_WATCH_WRITABLE;
509 if (revents & POLLHUP)
510 flags |= DBUS_WATCH_HANGUP;
511 if (revents & POLLERR)
512 flags |= DBUS_WATCH_ERROR;
513 if (flags != 0)
514 dbus_watch_handle((DBusWatch *)watch, flags);
515
516 if (connection != NULL) {
517 dbus_connection_ref(connection);
518 while (dbus_connection_dispatch(connection) ==
519 DBUS_DISPATCH_DATA_REMAINS)
520 ;
521 dbus_connection_unref(connection);
522 }
523 }
524
525 static dbus_bool_t
526 add_watch(DBusWatch *watch, _unused void *data)
527 {
528 int fd, flags, eflags;
529
530 fd = dbus_watch_get_unix_fd(watch);
531 flags = dbus_watch_get_flags(watch);
532 eflags = POLLHUP | POLLERR;
533 if (flags & DBUS_WATCH_READABLE)
534 eflags |= POLLIN;
535 if (flags & DBUS_WATCH_WRITABLE)
536 eflags |= POLLOUT;
537 if (add_event_flags(fd, eflags, dbus_event, watch) == 0)
538 return TRUE;
539 return FALSE;
540 }
541
542 static void
543 remove_watch(DBusWatch *watch, _unused void *data)
544 {
545 int fd;
546
547 fd = dbus_watch_get_unix_fd(watch);
548 delete_event(fd);
549 }
550
551 void
552 dhcpcd_dbus_close(void)
553 {
554 if (connection) {
555 dbus_connection_unref(connection);
556 connection = NULL;
557 }
558 }
559
560 int
561 dhcpcd_dbus_init(void)
562 {
563 DBusObjectPathVTable vt = {
564 NULL, &msg_handler, NULL, NULL, NULL, NULL
565 };
566 DBusError err;
567 int ret;
568
569 dbus_error_init(&err);
570 connection = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
571 if (connection == NULL) {
572 if (dbus_error_is_set(&err))
573 syslog(LOG_ERR, "%s", err.message);
574 else
575 syslog(LOG_ERR, "failed to get a dbus connection");
576 return -1;
577 }
578 atexit(dhcpcd_dbus_close);
579
580 #if 0
581 ret = dbus_bus_request_name(connection, DHCPCD_SERVICE,
582 DBUS_NAME_FLAG_REPLACE_EXISTING, &err);
583 if (dbus_error_is_set(&err)) {
584 syslog(LOG_ERR, "%s", err.message);
585 return -1;
586 }
587 #endif
588 if (!dbus_connection_set_watch_functions(connection,
589 add_watch, remove_watch, NULL, NULL, NULL))
590 {
591 syslog(LOG_ERR, "dbus: failed to set watch functions");
592 return -1;
593 }
594 if (!dbus_connection_register_object_path(connection,
595 DHCPCD_PATH, &vt, NULL))
596 {
597 syslog(LOG_ERR, "dbus: failed to register object path");
598 return -1;
599 }
600 return 0;
601 }
602
603 int
604 configure(struct interface *ifp)
605 {
606 if (ifp->state->new != NULL) {
607 /* push state over d-bus */
608 dhcpcd_dbus_configure(ifp, ifp->state->reason);
609
610 if (write_lease(ifp, ifp->state->new) == -1)
611 syslog(LOG_ERR, "write_lease: %m");
612 }
613 return 0;
614 }
615
616 int
617 run_script(const struct interface *ifp)
618 {
619 syslog(LOG_DEBUG, "executing `%s', reason %s",
620 ifp->name, ifp->state->reason);
621 #if 0
622 /* push state over d-bus */
623 dhcpcd_dbus_configure(ifp, ifp->state->reason);
624 #endif
625 return 0;
626 }
OLDNEW
« no previous file with comments | « dhcpcd-dbus.h ('k') | dhcpcd-dbus.conf » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698