chiark / gitweb /
[PATCH] 021_bk mark
[elogind.git] / udevstart.c
1 /*
2  * udevstart.c
3  *
4  * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
5  * 
6  * Quick and dirty way to populate a /dev with udev if your system
7  * does not have access to a shell.  Based originally on a patch to udev 
8  * from Harald Hoyer <harald@redhat.com>
9  *
10  *      This program is free software; you can redistribute it and/or modify it
11  *      under the terms of the GNU General Public License as published by the
12  *      Free Software Foundation version 2 of the License.
13  * 
14  *      This program is distributed in the hope that it will be useful, but
15  *      WITHOUT ANY WARRANTY; without even the implied warranty of
16  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *      General Public License for more details.
18  * 
19  *      You should have received a copy of the GNU General Public License along
20  *      with this program; if not, write to the Free Software Foundation, Inc.,
21  *      675 Mass Ave, Cambridge, MA 02139, USA.
22  *
23  */
24
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdio.h>
28 #include <errno.h>
29 #include <ctype.h>
30 #include <dirent.h>
31 #include <sys/wait.h>
32
33 #include "logging.h"
34
35
36 #ifdef LOG
37 unsigned char logname[42];
38 void log_message(int level, const char *format, ...)
39 {
40         va_list args;
41
42         va_start(args, format);
43         vsyslog(level, format, args);
44         va_end(args);
45 }
46 #endif
47
48
49 #define MAX_PATHLEN             1024
50 #define SYSBLOCK                "/sys/block"
51 #define SYSCLASS                "/sys/class"
52 #define UDEV_BIN                "/sbin/udev"
53
54 static void udev_exec(const char *path, const char* subsystem)
55 {
56         pid_t pid;
57         char action[] = "ACTION=add";
58         char devpath[MAX_PATHLEN];
59         char nosleep[] = "UDEV_NO_SLEEP=1";
60         char *env[] = { action, devpath, nosleep, NULL };
61
62         snprintf(devpath, MAX_PATHLEN, "DEVPATH=%s", path);
63         devpath[MAX_PATHLEN-1] = '\0';
64
65         pid = fork();
66         switch (pid) {
67         case 0:
68                 /* child */
69                 execle(UDEV_BIN, "udev", subsystem, NULL, env);
70                 dbg("exec of child failed");
71                 exit(1);
72                 break;
73         case -1:
74                 dbg("fork of child failed");
75                 break;
76         default:
77                 wait(NULL);
78         }
79 }
80
81 static int udev_scan(void)
82 {
83         char *devpath;
84         DIR *dir;
85         struct dirent *dent;
86         int retval = -EINVAL;
87
88         devpath = "block";
89         dir = opendir(SYSBLOCK);
90         if (dir != NULL) {
91                 for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
92                         char dirname[MAX_PATHLEN];
93                         DIR *dir2;
94                         struct dirent *dent2;
95
96                         if ((strcmp(dent->d_name, ".") == 0) ||
97                             (strcmp(dent->d_name, "..") == 0))
98                                 continue;
99
100                         snprintf(dirname, MAX_PATHLEN, "/block/%s", dent->d_name);
101                         dirname[MAX_PATHLEN-1] = '\0';
102                         udev_exec(dirname, "block");
103
104                         snprintf(dirname, MAX_PATHLEN, "%s/%s", SYSBLOCK, dent->d_name);
105                         dir2 = opendir(dirname);
106                         if (dir2 != NULL) {
107                                 for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) {
108                                         char dirname2[MAX_PATHLEN];
109                                         DIR *dir3;
110                                         struct dirent *dent3;
111
112                                         if ((strcmp(dent2->d_name, ".") == 0) ||
113                                             (strcmp(dent2->d_name, "..") == 0))
114                                                 continue;
115
116                                         snprintf(dirname2, MAX_PATHLEN, "%s/%s", dirname, dent2->d_name);
117                                         dirname2[MAX_PATHLEN-1] = '\0';
118
119                                         dir3 = opendir(dirname2);
120                                         if (dir3 != NULL) {
121                                                 for (dent3 = readdir(dir3); dent3 != NULL; dent3 = readdir(dir3)) {
122                                                         char filename[MAX_PATHLEN];
123
124                                                         if (strcmp(dent3->d_name, "dev") == 0) {
125                                                                 snprintf(filename, MAX_PATHLEN, "/block/%s/%s",
126                                                                          dent->d_name, dent2->d_name);
127                                                                 filename[MAX_PATHLEN-1] = '\0';
128                                                                 udev_exec(filename, "block");
129                                                         }
130                                                 }
131                                         }
132                                 }
133                         }
134                 }
135         }
136
137         devpath = "class";
138         dir = opendir(SYSCLASS);
139         if (dir != NULL) {
140                 for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
141                         char dirname[MAX_PATHLEN];
142                         DIR *dir2;
143                         struct dirent *dent2;
144
145                         if ((strcmp(dent->d_name, ".") == 0) ||
146                             (strcmp(dent->d_name, "..") == 0))
147                                 continue;
148
149                         snprintf(dirname, MAX_PATHLEN, "%s/%s", SYSCLASS, dent->d_name);
150                         dirname[MAX_PATHLEN] = '\0';
151                         dir2 = opendir(dirname);
152                         if (dir2 != NULL) {
153                                 for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) {
154                                         char dirname2[MAX_PATHLEN-1];
155                                         DIR *dir3;
156                                         struct dirent *dent3;
157
158                                         if ((strcmp(dent2->d_name, ".") == 0) ||
159                                             (strcmp(dent2->d_name, "..") == 0))
160                                                 continue;
161
162                                         snprintf(dirname2, MAX_PATHLEN, "%s/%s", dirname, dent2->d_name);
163                                         dirname2[MAX_PATHLEN-1] = '\0';
164
165                                         dir3 = opendir(dirname2);
166                                         if (dir3 != NULL) {
167                                                 for (dent3 = readdir(dir3); dent3 != NULL; dent3 = readdir(dir3)) {
168                                                         char filename[MAX_PATHLEN];
169
170                                                         if (strcmp(dent3->d_name, "dev") == 0) {
171                                                                 snprintf(filename, MAX_PATHLEN, "/class/%s/%s",
172                                                                          dent->d_name, dent2->d_name);
173                                                                 filename[MAX_PATHLEN-1] = '\0';
174                                                                 udev_exec(filename, dent->d_name);
175                                                         }
176                                                 }
177                                         }
178                                 }
179                         }
180                 }
181         }
182
183         if (retval > 0)
184                 retval = 0;
185
186         return -retval;
187 }
188
189
190 int main(int argc, char **argv, char **envp)
191 {
192         init_logging("udevstart");
193
194         return udev_scan();
195 }