9 #define DBUS_API_SUBJECT_TO_CHANGE
10 #include <dbus/dbus.h>
12 #include "../../udev_lib.h"
13 #include "../../logging.h"
16 unsigned char logname[LOGNAME_SIZE];
17 void log_message(int level, const char *format, ...)
24 va_start(args, format);
25 vsyslog(level, format, args);
30 /** variable for the connection the to system message bus or #NULL
31 * if we cannot connect or acquire the org.kernel.udev service
33 static DBusConnection* sysbus_connection;
35 /** Disconnect from the system message bus */
36 static void sysbus_disconnect(void)
38 if (sysbus_connection == NULL)
41 dbus_connection_disconnect(sysbus_connection);
42 sysbus_connection = NULL;
45 /** Connect to the system message bus */
46 static void sysbus_connect(void)
50 /* Connect to a well-known bus instance, the system bus */
51 dbus_error_init(&error);
52 sysbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
53 if (sysbus_connection == NULL) {
54 dbg("cannot connect to system message bus, error %s: %s",
55 error.name, error.message);
56 dbus_error_free(&error);
60 /* Acquire the org.kernel.udev service such that listeners
61 * know that the message is really from us and not from a
62 * random attacker. See the file udev_sysbus_policy.conf for
65 * Note that a service can have multiple owners (though there
66 * is a concept of a primary owner for reception of messages)
67 * so no race is introduced if two copies of udev is running
70 dbus_bus_acquire_service(sysbus_connection, "org.kernel.udev", 0,
72 if (dbus_error_is_set(&error)) {
73 printf("cannot acquire org.kernel.udev service, error %s: %s'",
74 error.name, error.message);
81 /** Send out a signal that a device node is created
83 * @param devnode name of the device node, e.g. /dev/sda1
84 * @param path Sysfs path of device
86 static void sysbus_send_create(const char *devnode, const char *path)
91 /* object, interface, member */
92 message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor",
93 "org.kernel.udev.NodeMonitor",
96 dbus_message_iter_init(message, &iter);
97 dbus_message_iter_append_string(&iter, devnode);
98 dbus_message_iter_append_string(&iter, path);
100 if ( !dbus_connection_send(sysbus_connection, message, NULL) )
101 dbg("error sending d-bus signal");
103 dbus_message_unref(message);
105 dbus_connection_flush(sysbus_connection);
108 /** Send out a signal that a device node is deleted
110 * @param devnode Name of the device node, e.g. /udev/sda1
111 * @param path Sysfs path of device
113 static void sysbus_send_remove(const char *devnode, const char *path)
115 DBusMessage* message;
116 DBusMessageIter iter;
118 /* object, interface, member */
119 message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor",
120 "org.kernel.udev.NodeMonitor",
123 dbus_message_iter_init(message, &iter);
124 dbus_message_iter_append_string(&iter, devnode);
125 dbus_message_iter_append_string(&iter, path);
127 if ( !dbus_connection_send(sysbus_connection, message, NULL) )
128 dbg("error sending d-bus signal");
130 dbus_message_unref(message);
132 dbus_connection_flush(sysbus_connection);
135 int main(int argc, char *argv[], char *envp[])
142 init_logging("udev_dbus");
145 if (sysbus_connection == NULL)
148 action = get_action();
153 devpath = get_devpath();
158 devnode = get_devnode();
164 if (strcmp(action, "add") == 0) {
165 sysbus_send_create(devnode, devpath);
167 if (strcmp(action, "remove") == 0) {
168 sysbus_send_remove(devnode, devpath);
170 dbg("unknown action '%s'", action);