chiark / gitweb /
[PATCH] add a question/answer about automounting usb devices to the FAQ.
[elogind.git] / udev.c
1 /*
2  * udev.c
3  *
4  * Userspace devfs
5  *
6  * Copyright (C) 2003,2004 Greg Kroah-Hartman <greg@kroah.com>
7  *
8  *      This program is free software; you can redistribute it and/or modify it
9  *      under the terms of the GNU General Public License as published by the
10  *      Free Software Foundation version 2 of the License.
11  * 
12  *      This program is distributed in the hope that it will be useful, but
13  *      WITHOUT ANY WARRANTY; without even the implied warranty of
14  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *      General Public License for more details.
16  * 
17  *      You should have received a copy of the GNU General Public License along
18  *      with this program; if not, write to the Free Software Foundation, Inc.,
19  *      675 Mass Ave, Cambridge, MA 02139, USA.
20  *
21  */
22
23 #include <stdio.h>
24 #include <stddef.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <ctype.h>
28 #include <errno.h>
29 #include <signal.h>
30
31 #include "libsysfs/sysfs/libsysfs.h"
32 #include "udev.h"
33 #include "udev_lib.h"
34 #include "udev_version.h"
35 #include "udev_dbus.h"
36 #include "logging.h"
37 #include "namedev.h"
38 #include "udevdb.h"
39
40 /* global variables */
41 char **main_argv;
42 char **main_envp;
43
44 #ifdef LOG
45 unsigned char logname[LOGNAME_SIZE];
46 void log_message(int level, const char *format, ...)
47 {
48         va_list args;
49
50         if (!udev_log)
51                 return;
52
53         va_start(args, format);
54         vsyslog(level, format, args);
55         va_end(args);
56 }
57 #endif
58
59 static void sig_handler(int signum)
60 {
61         switch (signum) {
62                 case SIGINT:
63                 case SIGTERM:
64                         sysbus_disconnect();
65                         udevdb_exit();
66                         exit(20 + signum);
67                 default:
68                         dbg("unhandled signal");
69         }
70 }
71
72 static char *subsystem_blacklist[] = {
73         "net",
74         "scsi_host",
75         "scsi_device",
76         "usb_host",
77         "pci_bus",
78         "pcmcia_socket",
79         ""
80 };
81
82 static int udev_hotplug(void)
83 {
84         char *action;
85         char *devpath;
86         char *subsystem;
87         int retval = -EINVAL;
88         int i;
89         struct sigaction act;
90
91         action = get_action();
92         if (!action) {
93                 dbg("no action?");
94                 goto exit;
95         }
96
97         devpath = get_devpath();
98         if (!devpath) {
99                 dbg("no devpath?");
100                 goto exit;
101         }
102         dbg("looking at '%s'", devpath);
103
104         /* we only care about class devices and block stuff */
105         if (!strstr(devpath, "class") &&
106             !strstr(devpath, "block")) {
107                 dbg("not a block or class device");
108                 goto exit;
109         }
110
111         /* skip blacklisted subsystems */
112         subsystem = get_subsystem(main_argv[1]);
113         if (!subsystem) {
114                 dbg("no subsystem?");
115                 goto exit;
116         }
117         i = 0;
118         while (subsystem_blacklist[i][0] != '\0') {
119                 if (strcmp(subsystem, subsystem_blacklist[i]) == 0) {
120                         dbg("don't care about '%s' devices", subsystem);
121                         goto exit;
122                 }
123                 i++;
124         }
125
126         /* connect to the system message bus */
127         sysbus_connect();
128
129         /* initialize udev database */
130         retval = udevdb_init(UDEVDB_DEFAULT);
131         if (retval != 0) {
132                 dbg("unable to initialize database");
133                 goto exit_sysbus;
134         }
135
136         /* set up a default signal handler for now */
137         act.sa_handler = sig_handler;
138         sigemptyset (&act.sa_mask);
139         act.sa_flags = SA_RESTART;
140         sigaction(SIGINT, &act, NULL);
141         sigaction(SIGTERM, &act, NULL);
142
143         /* initialize the naming deamon */
144         namedev_init();
145
146         if (strcmp(action, "add") == 0)
147                 retval = udev_add_device(devpath, subsystem, 0);
148
149         else if (strcmp(action, "remove") == 0)
150                 retval = udev_remove_device(devpath, subsystem);
151
152         else {
153                 dbg("unknown action '%s'", action);
154                 retval = -EINVAL;
155         }
156         udevdb_exit();
157
158 exit_sysbus:
159         /* disconnect from the system message bus */
160         sysbus_disconnect();
161
162 exit:
163         if (retval > 0)
164                 retval = 0;
165
166         return -retval;
167 }
168
169 int main(int argc, char *argv[], char *envp[])
170 {
171         main_argv = argv;
172         main_envp = envp;
173
174         init_logging("udev");
175
176         /* initialize our configuration */
177         udev_init_config();
178
179         dbg("version %s", UDEV_VERSION);
180
181         return udev_hotplug();
182 }