]>
Commit | Line | Data |
---|---|---|
82b9a637 GKH |
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> | |
82b9a637 GKH |
30 | #include <dirent.h> |
31 | #include <sys/wait.h> | |
f27125f9 | 32 | #include <sys/types.h> |
33 | #include <unistd.h> | |
82b9a637 GKH |
34 | |
35 | #include "logging.h" | |
9b28a52a | 36 | #include "udev_lib.h" |
82b9a637 GKH |
37 | |
38 | ||
39 | #ifdef LOG | |
d00bd172 | 40 | unsigned char logname[LOGNAME_SIZE]; |
82b9a637 GKH |
41 | void log_message(int level, const char *format, ...) |
42 | { | |
43 | va_list args; | |
44 | ||
45 | va_start(args, format); | |
46 | vsyslog(level, format, args); | |
47 | va_end(args); | |
48 | } | |
49 | #endif | |
50 | ||
51 | ||
e4dc0e11 KS |
52 | #define MAX_PATHLEN 1024 |
53 | #define SYSBLOCK "/sys/block" | |
54 | #define SYSCLASS "/sys/class" | |
55 | #define UDEV_BIN "/sbin/udev" | |
82b9a637 | 56 | |
e4dc0e11 | 57 | static void udev_exec(const char *path, const char* subsystem) |
82b9a637 | 58 | { |
82b9a637 | 59 | pid_t pid; |
e4dc0e11 KS |
60 | char action[] = "ACTION=add"; |
61 | char devpath[MAX_PATHLEN]; | |
62 | char nosleep[] = "UDEV_NO_SLEEP=1"; | |
63 | char *env[] = { action, devpath, nosleep, NULL }; | |
64 | ||
5df33ccd KS |
65 | strcpy(devpath, "DEVPATH="); |
66 | strfieldcat(devpath, path); | |
e4dc0e11 | 67 | |
82b9a637 | 68 | pid = fork(); |
e4dc0e11 | 69 | switch (pid) { |
82b9a637 GKH |
70 | case 0: |
71 | /* child */ | |
e4dc0e11 KS |
72 | execle(UDEV_BIN, "udev", subsystem, NULL, env); |
73 | dbg("exec of child failed"); | |
82b9a637 | 74 | exit(1); |
e4dc0e11 | 75 | break; |
82b9a637 | 76 | case -1: |
e4dc0e11 KS |
77 | dbg("fork of child failed"); |
78 | break; | |
82b9a637 | 79 | default: |
e4dc0e11 | 80 | wait(NULL); |
82b9a637 | 81 | } |
82b9a637 GKH |
82 | } |
83 | ||
3f20eac0 | 84 | static void udev_scan(void) |
82b9a637 | 85 | { |
e4dc0e11 KS |
86 | char *devpath; |
87 | DIR *dir; | |
88 | struct dirent *dent; | |
82b9a637 GKH |
89 | |
90 | devpath = "block"; | |
91 | dir = opendir(SYSBLOCK); | |
e4dc0e11 KS |
92 | if (dir != NULL) { |
93 | for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { | |
94 | char dirname[MAX_PATHLEN]; | |
95 | DIR *dir2; | |
96 | struct dirent *dent2; | |
97 | ||
98 | if ((strcmp(dent->d_name, ".") == 0) || | |
99 | (strcmp(dent->d_name, "..") == 0)) | |
82b9a637 GKH |
100 | continue; |
101 | ||
102 | snprintf(dirname, MAX_PATHLEN, "/block/%s", dent->d_name); | |
e4dc0e11 KS |
103 | dirname[MAX_PATHLEN-1] = '\0'; |
104 | udev_exec(dirname, "block"); | |
82b9a637 GKH |
105 | |
106 | snprintf(dirname, MAX_PATHLEN, "%s/%s", SYSBLOCK, dent->d_name); | |
82b9a637 | 107 | dir2 = opendir(dirname); |
e4dc0e11 KS |
108 | if (dir2 != NULL) { |
109 | for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { | |
110 | char dirname2[MAX_PATHLEN]; | |
111 | DIR *dir3; | |
112 | struct dirent *dent3; | |
82b9a637 GKH |
113 | |
114 | if ((strcmp(dent2->d_name, ".") == 0) || | |
115 | (strcmp(dent2->d_name, "..") == 0)) | |
116 | continue; | |
117 | ||
118 | snprintf(dirname2, MAX_PATHLEN, "%s/%s", dirname, dent2->d_name); | |
e4dc0e11 | 119 | dirname2[MAX_PATHLEN-1] = '\0'; |
82b9a637 GKH |
120 | |
121 | dir3 = opendir(dirname2); | |
e4dc0e11 KS |
122 | if (dir3 != NULL) { |
123 | for (dent3 = readdir(dir3); dent3 != NULL; dent3 = readdir(dir3)) { | |
82b9a637 GKH |
124 | char filename[MAX_PATHLEN]; |
125 | ||
126 | if (strcmp(dent3->d_name, "dev") == 0) { | |
e4dc0e11 KS |
127 | snprintf(filename, MAX_PATHLEN, "/block/%s/%s", |
128 | dent->d_name, dent2->d_name); | |
129 | filename[MAX_PATHLEN-1] = '\0'; | |
130 | udev_exec(filename, "block"); | |
82b9a637 GKH |
131 | } |
132 | } | |
133 | } | |
134 | } | |
135 | } | |
136 | } | |
137 | } | |
138 | ||
139 | devpath = "class"; | |
140 | dir = opendir(SYSCLASS); | |
e4dc0e11 KS |
141 | if (dir != NULL) { |
142 | for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { | |
143 | char dirname[MAX_PATHLEN]; | |
144 | DIR *dir2; | |
145 | struct dirent *dent2; | |
146 | ||
147 | if ((strcmp(dent->d_name, ".") == 0) || | |
148 | (strcmp(dent->d_name, "..") == 0)) | |
82b9a637 GKH |
149 | continue; |
150 | ||
151 | snprintf(dirname, MAX_PATHLEN, "%s/%s", SYSCLASS, dent->d_name); | |
e4dc0e11 | 152 | dirname[MAX_PATHLEN] = '\0'; |
82b9a637 | 153 | dir2 = opendir(dirname); |
e4dc0e11 KS |
154 | if (dir2 != NULL) { |
155 | for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { | |
156 | char dirname2[MAX_PATHLEN-1]; | |
157 | DIR *dir3; | |
158 | struct dirent *dent3; | |
82b9a637 | 159 | |
e4dc0e11 KS |
160 | if ((strcmp(dent2->d_name, ".") == 0) || |
161 | (strcmp(dent2->d_name, "..") == 0)) | |
82b9a637 GKH |
162 | continue; |
163 | ||
164 | snprintf(dirname2, MAX_PATHLEN, "%s/%s", dirname, dent2->d_name); | |
e4dc0e11 | 165 | dirname2[MAX_PATHLEN-1] = '\0'; |
82b9a637 GKH |
166 | |
167 | dir3 = opendir(dirname2); | |
e4dc0e11 KS |
168 | if (dir3 != NULL) { |
169 | for (dent3 = readdir(dir3); dent3 != NULL; dent3 = readdir(dir3)) { | |
170 | char filename[MAX_PATHLEN]; | |
82b9a637 GKH |
171 | |
172 | if (strcmp(dent3->d_name, "dev") == 0) { | |
e4dc0e11 KS |
173 | snprintf(filename, MAX_PATHLEN, "/class/%s/%s", |
174 | dent->d_name, dent2->d_name); | |
175 | filename[MAX_PATHLEN-1] = '\0'; | |
176 | udev_exec(filename, dent->d_name); | |
82b9a637 GKH |
177 | } |
178 | } | |
179 | } | |
180 | } | |
181 | } | |
182 | } | |
183 | } | |
82b9a637 GKH |
184 | } |
185 | ||
186 | ||
d00bd172 | 187 | int main(int argc, char *argv[], char *envp[]) |
82b9a637 GKH |
188 | { |
189 | init_logging("udevstart"); | |
190 | ||
3f20eac0 MI |
191 | udev_scan(); |
192 | ||
193 | return 0; | |
82b9a637 | 194 | } |