9 #define DBUS_API_SUBJECT_TO_CHANGE
10 #include <dbus/dbus.h>
17 unsigned char logname[LOGNAME_SIZE];
18 void log_message(int level, const char *format, ...)
25 va_start(args, format);
26 vsyslog(level, format, args);
31 /** variable for the connection the to system message bus or #NULL
32 * if we cannot connect or acquire the org.kernel.udev service
34 static DBusConnection* sysbus_connection;
36 /** Disconnect from the system message bus */
37 static void sysbus_disconnect(void)
39 if (sysbus_connection == NULL)
42 dbus_connection_disconnect(sysbus_connection);
43 sysbus_connection = NULL;
46 /** Connect to the system message bus */
47 static void sysbus_connect(void)
51 /* Connect to a well-known bus instance, the system bus */
52 dbus_error_init(&error);
53 sysbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
54 if (sysbus_connection == NULL) {
55 dbg("cannot connect to system message bus, error %s: %s",
56 error.name, error.message);
57 dbus_error_free(&error);
61 /* Acquire the org.kernel.udev service such that listeners
62 * know that the message is really from us and not from a
63 * random attacker. See the file udev_sysbus_policy.conf for
66 * Note that a service can have multiple owners (though there
67 * is a concept of a primary owner for reception of messages)
68 * so no race is introduced if two copies of udev is running
71 dbus_bus_acquire_service(sysbus_connection, "org.kernel.udev", 0,
73 if (dbus_error_is_set(&error)) {
74 printf("cannot acquire org.kernel.udev service, error %s: %s'",
75 error.name, error.message);
82 /** Send out a signal that a device node is created
84 * @param devnode name of the device node, e.g. /dev/sda1
85 * @param path Sysfs path of device
87 static void sysbus_send_create(const char *devnode, const char *path)
92 /* object, interface, member */
93 message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor",
94 "org.kernel.udev.NodeMonitor",
97 dbus_message_iter_init(message, &iter);
98 dbus_message_iter_append_string(&iter, devnode);
99 dbus_message_iter_append_string(&iter, path);
101 if ( !dbus_connection_send(sysbus_connection, message, NULL) )
102 dbg("error sending d-bus signal");
104 dbus_message_unref(message);
106 dbus_connection_flush(sysbus_connection);
109 /** Send out a signal that a device node is deleted
111 * @param devnode Name of the device node, e.g. /udev/sda1
112 * @param path Sysfs path of device
114 static void sysbus_send_remove(const char *devnode, const char *path)
116 DBusMessage* message;
117 DBusMessageIter iter;
119 /* object, interface, member */
120 message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor",
121 "org.kernel.udev.NodeMonitor",
124 dbus_message_iter_init(message, &iter);
125 dbus_message_iter_append_string(&iter, devnode);
126 dbus_message_iter_append_string(&iter, path);
128 if ( !dbus_connection_send(sysbus_connection, message, NULL) )
129 dbg("error sending d-bus signal");
131 dbus_message_unref(message);
133 dbus_connection_flush(sysbus_connection);
136 int main(int argc, char *argv[], char *envp[])
143 init_logging("udev_dbus");
146 if (sysbus_connection == NULL)
149 action = get_action();
154 devpath = get_devpath();
159 devnode = get_devnode();
165 if (strcmp(action, "add") == 0) {
166 sysbus_send_create(devnode, devpath);
168 if (strcmp(action, "remove") == 0) {
169 sysbus_send_remove(devnode, devpath);
171 dbg("unknown action '%s'", action);