chiark / gitweb /
[PATCH] udev_dbus can now compile properly, but linnking is another story...
[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_lib.h"
14 #include "logging.h"
15
16 #ifdef LOG
17 unsigned char logname[LOGNAME_SIZE];
18 void log_message(int level, const char *format, ...)
19 {
20         va_list args;
21
22         if (!udev_log)
23                 return;
24
25         va_start(args, format);
26         vsyslog(level, format, args);
27         va_end(args);
28 }
29 #endif
30
31 /** variable for the connection the to system message bus or #NULL
32  *  if we cannot connect or acquire the org.kernel.udev service
33  */
34 static DBusConnection* sysbus_connection;
35
36 /** Disconnect from the system message bus */
37 static void sysbus_disconnect(void)
38 {
39         if (sysbus_connection == NULL)
40                 return;
41
42         dbus_connection_disconnect(sysbus_connection);
43         sysbus_connection = NULL;
44 }
45
46 /** Connect to the system message bus */
47 static void sysbus_connect(void)
48 {
49         DBusError error;
50
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);
58                 return;
59         }
60
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
64          *  details.
65          *
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
69          *  at the same time.
70          */
71         dbus_bus_acquire_service(sysbus_connection, "org.kernel.udev", 0, 
72                                  &error);
73         if (dbus_error_is_set(&error)) {
74                 printf("cannot acquire org.kernel.udev service, error %s: %s'",
75                        error.name, error.message);
76                 sysbus_disconnect();
77                 return;
78         }
79 }
80
81
82 /** Send out a signal that a device node is created
83  *
84  *  @param  devnode             name of the device node, e.g. /dev/sda1
85  *  @param  path                Sysfs path of device
86  */
87 static void sysbus_send_create(const char *devnode, const char *path)
88 {
89         DBusMessage* message;
90         DBusMessageIter iter;
91
92         /* object, interface, member */
93         message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor", 
94                                           "org.kernel.udev.NodeMonitor",
95                                           "NodeCreated");
96
97         dbus_message_iter_init(message, &iter);
98         dbus_message_iter_append_string(&iter, devnode);
99         dbus_message_iter_append_string(&iter, path);
100
101         if ( !dbus_connection_send(sysbus_connection, message, NULL) )
102                 dbg("error sending d-bus signal");
103
104         dbus_message_unref(message);
105
106         dbus_connection_flush(sysbus_connection);
107 }
108
109 /** Send out a signal that a device node is deleted
110  *
111  *  @param  devnode             Name of the device node, e.g. /udev/sda1
112  *  @param  path                Sysfs path of device
113  */
114 static void sysbus_send_remove(const char *devnode, const char *path)
115 {
116         DBusMessage* message;
117         DBusMessageIter iter;
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, devnode);
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 }
135
136 int main(int argc, char *argv[], char *envp[])
137 {
138         char *action;
139         char *devpath;
140         char *devnode;
141         int retval = 0;
142
143         init_logging("udev_dbus");
144
145         sysbus_connect();
146         if (sysbus_connection == NULL)
147                 return 0;
148
149         action = get_action();
150         if (!action) {
151                 dbg("no action?");
152                 goto exit;
153         }
154         devpath = get_devpath();
155         if (!devpath) {
156                 dbg("no devpath?");
157                 goto exit;
158         }
159         devnode = get_devnode();
160         if (!devnode) {
161                 dbg("no devnode?");
162                 goto exit;
163         }
164
165         if (strcmp(action, "add") == 0) {
166                 sysbus_send_create(devnode, devpath);
167         } else {
168                 if (strcmp(action, "remove") == 0) {
169                         sysbus_send_remove(devnode, devpath);
170                 } else {
171                         dbg("unknown action '%s'", action);
172                         retval = -EINVAL;
173                 }
174         }
175
176 exit:
177         sysbus_disconnect();
178         return retval;
179 }