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