chiark / gitweb /
[PATCH] udev - next round of udev event order daemon
[elogind.git] / udev_dbus.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include <stdio.h>
4 #include <fcntl.h>
5 #include <unistd.h>
6 #include <errno.h>
7 #include <ctype.h>
8
9 #define DBUS_API_SUBJECT_TO_CHANGE
10 #include <dbus/dbus.h>
11
12 #include "udev.h"
13 #include "udev_version.h"
14 #include "udev_dbus.h"
15
16
17 /** variable for the connection the to system message bus or #NULL
18  *  if we cannot connect or acquire the org.kernel.udev service
19  */
20 static DBusConnection* sysbus_connection;
21
22 /** Disconnect from the system message bus */
23 void sysbus_disconnect(void)
24 {
25         if (sysbus_connection == NULL)
26                 return;
27
28         dbus_connection_disconnect(sysbus_connection);
29         sysbus_connection = NULL;
30 }
31
32 /** Connect to the system message bus */
33 void sysbus_connect(void)
34 {
35         DBusError error;
36
37         /* Connect to a well-known bus instance, the system bus */
38         dbus_error_init(&error);
39         sysbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
40         if (sysbus_connection == NULL) {
41                 dbg("cannot connect to system message bus, error %s: %s", 
42                     error.name, error.message);
43                 dbus_error_free(&error);
44                 return;
45         }
46
47         /*  Acquire the org.kernel.udev service such that listeners
48          *  know that the message is really from us and not from a
49          *  random attacker. See the file udev_sysbus_policy.conf for
50          *  details.
51          *
52          *  Note that a service can have multiple owners (though there
53          *  is a concept of a primary owner for reception of messages)
54          *  so no race is introduced if two copies of udev is running
55          *  at the same time.
56          */
57         dbus_bus_acquire_service(sysbus_connection, "org.kernel.udev", 0, 
58                                  &error);
59         if (dbus_error_is_set(&error)) {
60                 printf("cannot acquire org.kernel.udev service, error %s: %s'",
61                        error.name, error.message);
62                 sysbus_disconnect();
63                 return;
64         }
65 }
66
67
68 /** Send out a signal that a device node is created
69  *
70  *  @param  dev                 udevice object
71  *  @param  path                Sysfs path of device
72  */
73 void sysbus_send_create(struct udevice *dev, const char *path)
74 {
75         char filename[255];
76         DBusMessage* message;
77         DBusMessageIter iter;
78
79         if (sysbus_connection == NULL)
80                 return;
81
82         strncpy(filename, udev_root, sizeof(filename));
83         strncat(filename, dev->name, sizeof(filename));
84
85         /* object, interface, member */
86         message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor", 
87                                           "org.kernel.udev.NodeMonitor",
88                                           "NodeCreated");
89
90         dbus_message_iter_init(message, &iter);
91         dbus_message_iter_append_string(&iter, filename);
92         dbus_message_iter_append_string(&iter, path);
93
94         if ( !dbus_connection_send(sysbus_connection, message, NULL) )
95                 dbg("error sending d-bus signal");
96
97         dbus_message_unref(message);
98
99         dbus_connection_flush(sysbus_connection);
100 }
101
102 /** Send out a signal that a device node is deleted
103  *
104  *  @param  name                Name of the device node, e.g. /udev/sda1
105  *  @param  path                Sysfs path of device
106  */
107 void sysbus_send_remove(const char* name, const char *path)
108 {
109         char filename[255];
110         DBusMessage* message;
111         DBusMessageIter iter;
112
113         if (sysbus_connection == NULL)
114                 return;
115
116         strncpy(filename, udev_root, sizeof(filename));
117         strncat(filename, name, sizeof(filename));
118
119         /* object, interface, member */
120         message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor", 
121                                           "org.kernel.udev.NodeMonitor",
122                                           "NodeDeleted");
123
124         dbus_message_iter_init(message, &iter);
125         dbus_message_iter_append_string(&iter, filename);
126         dbus_message_iter_append_string(&iter, path);
127
128         if ( !dbus_connection_send(sysbus_connection, message, NULL) )
129                 dbg("error sending d-bus signal");
130
131         dbus_message_unref(message);
132
133         dbus_connection_flush(sysbus_connection);
134 }