chiark / gitweb /
67b86e5916ced757a921bbbd442bee3e876c6298
[elogind.git] / udev.c
1 /*
2  * udev.c
3  *
4  * Userspace devfs
5  *
6  * Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
7  *
8  *
9  *      This program is free software; you can redistribute it and/or modify it
10  *      under the terms of the GNU General Public License as published by the
11  *      Free Software Foundation version 2 of the License.
12  * 
13  *      This program is distributed in the hope that it will be useful, but
14  *      WITHOUT ANY WARRANTY; without even the implied warranty of
15  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *      General Public License for more details.
17  * 
18  *      You should have received a copy of the GNU General Public License along
19  *      with this program; if not, write to the Free Software Foundation, Inc.,
20  *      675 Mass Ave, Cambridge, MA 02139, USA.
21  *
22  */
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <stdio.h>
27 #include <fcntl.h>
28 #include <unistd.h>
29 #include <errno.h>
30 #include <ctype.h>
31
32 #include "udev.h"
33 #include "udev_version.h"
34 #include "namedev.h"
35 #include "udevdb.h"
36 #include "libsysfs/libsysfs.h"
37
38 /* global variables */
39 char **main_argv;
40 char **main_envp;
41
42 static inline char *get_action(void)
43 {
44         char *action;
45
46         action = getenv("ACTION");
47         return action;
48 }
49
50 static inline char *get_devpath(void)
51 {
52         char *devpath;
53
54         devpath = getenv("DEVPATH");
55         return devpath;
56 }
57
58 static inline char *get_seqnum(void)
59 {
60         char *seqnum;
61
62         seqnum = getenv("SEQNUM");
63         return seqnum;
64 }
65
66 #ifdef USE_DBUS
67
68 /** Global variable for the connection the to system message bus or #NULL
69  *  if we cannot connect or acquire the org.kernel.udev service
70  */
71 DBusConnection* sysbus_connection;
72
73 /** Disconnect from the system message bus */
74 static void sysbus_disconnect()
75 {
76         if (sysbus_connection == NULL)
77                 return;
78
79         dbus_connection_disconnect(sysbus_connection);
80         sysbus_connection = NULL;
81 }
82
83 /** Connect to the system message bus */
84 static void sysbus_connect()
85 {
86         DBusError error;
87
88         /* Connect to a well-known bus instance, the system bus */
89         dbus_error_init(&error);
90         sysbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
91         if (sysbus_connection == NULL) {
92                 dbg("cannot connect to system message bus, error %s: %s", 
93                     error.name, error.message);
94                 dbus_error_free(&error);
95                 return;
96         }
97
98         /*  Acquire the org.kernel.udev service such that listeners
99          *  know that the message is really from us and not from a
100          *  random attacker. See the file udev_sysbus_policy.conf for
101          *  details.
102          *
103          *  Note that a service can have multiple owners (though there
104          *  is a concept of a primary owner for reception of messages)
105          *  so no race is introduced if two copies of udev is running
106          *  at the same time.
107          */
108         dbus_bus_acquire_service(sysbus_connection, "org.kernel.udev", 0, 
109                                  &error);
110         if (dbus_error_is_set(&error)) {
111                 printf("cannot acquire org.kernel.udev service, error %s: %s'",
112                        error.name, error.message);
113                 sysbus_disconnect();
114                 return;
115         }
116 }
117
118 #endif /* USE_DBUS */
119
120 int main(int argc, char **argv, char **envp)
121 {
122         char *action;
123         char *devpath;
124         char *subsystem;
125         int retval = -EINVAL;
126         
127         main_argv = argv;
128         main_envp = envp;
129
130         dbg("version %s", UDEV_VERSION);
131
132         if (argc != 2) {
133                 dbg ("unknown number of arguments");
134                 goto exit;
135         }
136
137         subsystem = argv[1];
138
139         devpath = get_devpath();
140         if (!devpath) {
141                 dbg ("no devpath?");
142                 goto exit;
143         }
144         dbg("looking at '%s'", devpath);
145
146         /* we only care about class devices and block stuff */
147         if (!strstr(devpath, "class") &&
148             !strstr(devpath, "block")) {
149                 dbg("not a block or class device");
150                 goto exit;
151         }
152
153         /* but we don't care about net class devices */
154         if (strcmp(subsystem, "net") == 0) {
155                 dbg("don't care about net devices");
156                 goto exit;
157         }
158
159         action = get_action();
160         if (!action) {
161                 dbg ("no action?");
162                 goto exit;
163         }
164
165         /* initialize our configuration */
166         udev_init_config();
167
168 #ifdef USE_DBUS
169         /* connect to the system message bus */
170         sysbus_connect();
171 #endif /* USE_DBUS */
172
173         /* initialize udev database */
174         retval = udevdb_init(UDEVDB_DEFAULT);
175         if (retval != 0) {
176                 dbg("unable to initialize database");
177                 goto exit;
178         }
179
180         /* initialize the naming deamon */
181         namedev_init();
182
183         if (strcmp(action, "add") == 0)
184                 retval = udev_add_device(devpath, subsystem);
185
186         else if (strcmp(action, "remove") == 0)
187                 retval = udev_remove_device(devpath, subsystem);
188
189         else {
190                 dbg("unknown action '%s'", action);
191                 retval = -EINVAL;
192         }
193         udevdb_exit();
194
195 #ifdef USE_DBUS
196         /* disconnect from the system message bus */
197         sysbus_disconnect();
198 #endif /* USE_DBUS */
199
200 exit:   
201         return retval;
202 }