diff options
Diffstat (limited to 'urunlevel/runlevel/lib_init_d.c')
-rw-r--r-- | urunlevel/runlevel/lib_init_d.c | 721 |
1 files changed, 416 insertions, 305 deletions
diff --git a/urunlevel/runlevel/lib_init_d.c b/urunlevel/runlevel/lib_init_d.c index 866888c..25d21a1 100644 --- a/urunlevel/runlevel/lib_init_d.c +++ b/urunlevel/runlevel/lib_init_d.c | |||
@@ -1,6 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2004 by David Seikel won_fang@yahoo.com.au | 2 | * Copyright (C) 2004 by David Seikel won_fang@yahoo.com.au |
3 | * | 3 | * |
4 | * llist_add_to_end() lifted whole from busybox networking/ifupdown.c, | ||
5 | * so it should probably be in libbb. | ||
6 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
6 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
@@ -26,237 +29,235 @@ | |||
26 | #include <string.h> | 29 | #include <string.h> |
27 | #include <sys/poll.h> | 30 | #include <sys/poll.h> |
28 | #include <sys/wait.h> | 31 | #include <sys/wait.h> |
29 | #include <sys/utsname.h> /* for uname(2) */ | 32 | #include <sys/utsname.h> /* for uname(2) */ |
30 | 33 | ||
31 | #include "busybox.h" | 34 | #include "busybox.h" |
32 | #include "lib_init_d.h" | 35 | #include "lib_init_d.h" |
33 | 36 | ||
34 | 37 | ||
38 | const static nodes_t nodes[] = { | ||
39 | {"hda", S_IFBLK, 3, 0, 0}, | ||
40 | {"hdb", S_IFBLK, 3, 64, 0}, | ||
41 | {"hdc", S_IFBLK, 22, 0, 0}, | ||
42 | {"hdd", S_IFBLK, 22, 64, 0}, | ||
43 | {"ram", S_IFBLK, 1, 0, 9}, | ||
44 | {"fd", S_IFBLK, 2, 0, 1}, | ||
45 | {"loop", S_IFBLK, 7, 0, 63}, | ||
46 | {"cloop", S_IFBLK, 240, 0, 7}, | ||
47 | {"vcs", S_IFBLK, 7, 0, 9}, | ||
48 | {"vcsa", S_IFBLK, 7, 0, 9}, | ||
49 | {0, 0, 0, 0, 0} | ||
50 | }; | ||
51 | |||
52 | |||
35 | static char *shell = 0; | 53 | static char *shell = 0; |
36 | struct stat path_stat; | 54 | struct stat path_stat; |
37 | 55 | ||
38 | 56 | ||
39 | char *argv_cat(int argc, char **argv) | 57 | char *argv_cat(int argc, char **argv) |
40 | { | 58 | { |
41 | int i; | 59 | int i; |
42 | int length = 1; | 60 | int length = 1; |
43 | char *message = NULL; | 61 | char *message = NULL; |
44 | 62 | ||
45 | for (i = 0; i < argc; i++) | 63 | for (i = 0; i < argc; i++) |
46 | length += strlen(argv[i]); | 64 | length += strlen(argv[i]) + 1; |
47 | message = (char *) xmalloc(sizeof (char) * length); | 65 | message = (char *) xmalloc(sizeof(char) * length); |
48 | 66 | ||
49 | if (message != NULL) | 67 | if (message != NULL) { |
50 | { | 68 | message[0] = '\0'; |
51 | message[0] = '\0'; | 69 | for (i = 1; i < argc; i++) { |
52 | for (i = 1; i < argc; i++) | 70 | /* These strcat's are not dangerous, since we checked sizes above. */ |
53 | { | 71 | strcat(message, argv[i]); |
54 | strcat(message, argv[i]); | 72 | if (i < (argc - 1)) |
55 | if (i < (argc - 1)) | 73 | strcat(message, " "); |
56 | strcat(message, " "); | 74 | } |
57 | } | 75 | } |
58 | } | 76 | return message; |
59 | return message; | ||
60 | } | 77 | } |
61 | 78 | ||
62 | 79 | ||
63 | char *big_chomp(char *s) | 80 | char *big_chomp(char *s) |
64 | { | 81 | { |
65 | char *lc = index(s, '\n'); | 82 | char *lc = index(s, '\n'); |
66 | 83 | ||
67 | if(lc) | 84 | if (lc) |
68 | *lc = '\0'; | 85 | *lc = '\0'; |
69 | return s; | 86 | return s; |
70 | } | 87 | } |
71 | 88 | ||
72 | 89 | ||
90 | /* I found out that networking/ifupdown.c has a similar function | ||
91 | * with an identical name AFTER I wrote this. | ||
92 | */ | ||
73 | char *doit(int mode, char *command, ...) | 93 | char *doit(int mode, char *command, ...) |
74 | { | 94 | { |
75 | int buffsize = 63; | 95 | int buffsize = 63; |
76 | char *buffer = NULL; | 96 | char *buffer = NULL; |
77 | int dataPipe[2] = { -1, -1 }; | 97 | int dataPipe[2] = { -1, -1 }; |
78 | int statusPipe[2] = { -1, -1 }; | 98 | int statusPipe[2] = { -1, -1 }; |
79 | int n; | 99 | int n; |
80 | pid_t pid = 0; | 100 | pid_t pid = 0; |
81 | volatile int vfork_exec_errno = 0; | 101 | volatile int vfork_exec_errno = 0; |
82 | char **args; | 102 | char **args; |
83 | char *commandBuffer; | 103 | char *commandBuffer; |
84 | 104 | ||
85 | if (mode & DAEMON) | 105 | if (mode & DAEMON) |
86 | mode |= FORK | QUIET; | 106 | mode |= FORK | QUIET; |
87 | 107 | ||
88 | va_list p; | 108 | va_list p; |
89 | int r; | 109 | int r; |
90 | 110 | ||
91 | va_start(p, command); | 111 | va_start(p, command); |
92 | r = vasprintf(&commandBuffer, command, p); | 112 | r = vasprintf(&commandBuffer, command, p); |
93 | va_end(p); | 113 | va_end(p); |
94 | 114 | ||
95 | if (r < 0) | 115 | if (r < 0) |
96 | bb_perror_msg_and_die("doit"); | 116 | bb_perror_msg_and_die("doit"); |
97 | 117 | ||
98 | if (shell == 0) | 118 | if (shell == 0) { |
99 | { | 119 | shell = getenv("SHELL"); |
100 | shell = getenv("SHELL"); | 120 | if (shell == 0) |
101 | if (shell == 0) | 121 | shell = "/bin/sh"; |
102 | shell = "/bin/sh"; | ||
103 | } | ||
104 | |||
105 | args = (char **) xmalloc (sizeof (char *) * 4); | ||
106 | n = 0; | ||
107 | args[n++] = shell; | ||
108 | args[n++] = "-c"; | ||
109 | if (mode & QUIET) | ||
110 | bb_xasprintf(&(args[n++]), "%s 2>/dev/null", commandBuffer); | ||
111 | else | ||
112 | args[n++] = commandBuffer; | ||
113 | args[n++] = 0; | ||
114 | |||
115 | if (!(mode & NOFORK)) | ||
116 | { | ||
117 | if (!(mode & DAEMON)) | ||
118 | { | ||
119 | if (pipe(dataPipe) < 0 || pipe(statusPipe) < 0) | ||
120 | bb_perror_msg("Failed to create pipe"); | ||
121 | signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */ | ||
122 | } | ||
123 | // pid = vfork(); | ||
124 | pid = fork(); | ||
125 | } | ||
126 | if (pid == 0) /* child */ | ||
127 | { | ||
128 | if ((!(mode & NOFORK)) && (!(mode & NOFORK))) | ||
129 | { | ||
130 | close(STDIN_FILENO); | ||
131 | dup2(dataPipe[1], STDOUT_FILENO); | ||
132 | dup2(dataPipe[1], STDERR_FILENO); | ||
133 | close(dataPipe[0]); | ||
134 | close(statusPipe[0]); | ||
135 | fcntl(statusPipe[1], F_SETFD, FD_CLOEXEC); /* close on exec shows sucess */ | ||
136 | } | 122 | } |
137 | 123 | ||
138 | if ((mode & DAEMON)) | 124 | args = (char **) xmalloc(sizeof(char *) * 4); |
139 | { | 125 | n = 0; |
140 | if (!(mode & NOFORK)) | 126 | args[n++] = shell; |
141 | { | 127 | args[n++] = "-c"; |
142 | close(dataPipe[1]); | 128 | if (mode & QUIET) |
143 | close(statusPipe[1]); | 129 | bb_xasprintf(&(args[n++]), "%s 2>/dev/null", commandBuffer); |
144 | close(STDOUT_FILENO); | 130 | else |
145 | close(STDERR_FILENO); | 131 | args[n++] = commandBuffer; |
146 | } | 132 | args[n++] = 0; |
147 | daemon(1, 0); | 133 | |
148 | } | 134 | if (!(mode & NOFORK)) { |
149 | errno = 0; | 135 | if (!(mode & DAEMON)) { |
150 | execvp(shell, (char **) args ); | 136 | if (pipe(dataPipe) < 0 || pipe(statusPipe) < 0) |
151 | 137 | bb_perror_msg("Failed to create pipe"); | |
152 | vfork_exec_errno = errno; | 138 | signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */ |
153 | if (!(mode & NOFORK)) | 139 | } |
154 | close(statusPipe[1]); | 140 | // pid = vfork(); |
155 | _exit(-1); | 141 | pid = fork(); |
156 | } | ||
157 | else if (pid > 0) /* parent */ | ||
158 | { | ||
159 | close(dataPipe[1]); | ||
160 | close(statusPipe[1]); | ||
161 | |||
162 | while (1) | ||
163 | { | ||
164 | char buf; | ||
165 | |||
166 | n = read(statusPipe[0], &buf, 1); | ||
167 | |||
168 | if ((n < 0) && ((errno == EAGAIN) || (errno == EINTR)) && !(mode & FORK)) | ||
169 | continue; /* try it again */ | ||
170 | else if (n == 0 && vfork_exec_errno != 0) | ||
171 | { | ||
172 | errno = vfork_exec_errno; | ||
173 | bb_perror_msg("Could not exec process"); | ||
174 | } | ||
175 | break; | ||
176 | } | 142 | } |
177 | close(statusPipe[0]); | 143 | if (pid == 0) { /* child */ |
178 | 144 | if ((!(mode & NOFORK)) && (!(mode & NOFORK))) { | |
179 | if (buffer == NULL) | 145 | close(STDIN_FILENO); |
180 | buffer = (char *) xcalloc(buffsize + 1, sizeof (char)); | 146 | dup2(dataPipe[1], STDOUT_FILENO); |
181 | 147 | dup2(dataPipe[1], STDERR_FILENO); | |
182 | if ((mode & FORK) == 0) | 148 | close(dataPipe[0]); |
183 | { | 149 | close(statusPipe[0]); |
184 | ssize_t cc; | 150 | fcntl(statusPipe[1], F_SETFD, FD_CLOEXEC); /* close on exec shows sucess */ |
185 | struct pollfd poller[1]; | 151 | } |
186 | 152 | ||
187 | poller[0].fd = dataPipe[0]; | 153 | if ((mode & DAEMON)) { |
188 | poller[0].events = POLLIN | POLLPRI; | 154 | if (!(mode & NOFORK)) { |
189 | poller[0].revents = 0; | 155 | close(dataPipe[1]); |
156 | close(statusPipe[1]); | ||
157 | close(STDOUT_FILENO); | ||
158 | close(STDERR_FILENO); | ||
159 | } | ||
160 | daemon(1, 0); | ||
161 | } | ||
162 | errno = 0; | ||
163 | execvp(shell, (char **) args); | ||
190 | 164 | ||
191 | n = 0; | 165 | vfork_exec_errno = errno; |
192 | while (1) | 166 | if (!(mode & NOFORK)) |
193 | { | 167 | close(statusPipe[1]); |
194 | if ((buffsize - n) <= 0) | 168 | _exit(-1); |
195 | { | 169 | } else if (pid > 0) { /* parent */ |
196 | int i; | 170 | close(dataPipe[1]); |
171 | close(statusPipe[1]); | ||
197 | 172 | ||
198 | buffsize += buffsize; | 173 | while (1) { |
199 | buffer = xrealloc(buffer, sizeof(char) * (buffsize + 1)); | 174 | char buf; |
200 | for (i = n; i <= buffsize; i++) | ||
201 | buffer[i] = '\0'; | ||
202 | } | ||
203 | 175 | ||
204 | errno = 0; | 176 | n = read(statusPipe[0], &buf, 1); |
205 | cc = poll(poller, 1, 1010); /* network sleeps for 1000 between '.' outputs */ | ||
206 | if (cc > 0) | ||
207 | cc = read(dataPipe[0], &buffer[n], buffsize - n); | ||
208 | 177 | ||
209 | if (cc < 0) | 178 | if ((n < 0) && ((errno == EAGAIN) || (errno == EINTR)) |
210 | { | 179 | && !(mode & FORK)) |
211 | if (errno == EINTR) | 180 | continue; /* try it again */ |
212 | continue; | 181 | else if (n == 0 && vfork_exec_errno != 0) { |
213 | if (errno == EAGAIN) | 182 | errno = vfork_exec_errno; |
214 | continue; | 183 | bb_perror_msg("Could not exec process"); |
184 | } | ||
215 | break; | 185 | break; |
216 | } | 186 | } |
217 | else if (cc == 0) | 187 | close(statusPipe[0]); |
218 | break; | 188 | |
189 | if (buffer == NULL) | ||
190 | buffer = (char *) xcalloc(buffsize + 1, sizeof(char)); | ||
191 | |||
192 | if ((mode & FORK) == 0) { | ||
193 | ssize_t cc; | ||
194 | struct pollfd poller[1]; | ||
195 | |||
196 | poller[0].fd = dataPipe[0]; | ||
197 | poller[0].events = POLLIN | POLLPRI; | ||
198 | poller[0].revents = 0; | ||
199 | |||
200 | n = 0; | ||
201 | while (1) { | ||
202 | if ((buffsize - n) <= 0) { | ||
203 | int i; | ||
204 | |||
205 | buffsize += buffsize; | ||
206 | buffer = xrealloc(buffer, sizeof(char) * (buffsize + 1)); | ||
207 | for (i = n; i <= buffsize; i++) | ||
208 | buffer[i] = '\0'; | ||
209 | } | ||
210 | |||
211 | errno = 0; | ||
212 | cc = poll(poller, 1, 1010); /* network sleeps for 1000 between '.' outputs */ | ||
213 | if (cc > 0) | ||
214 | cc = read(dataPipe[0], &buffer[n], buffsize - n); | ||
215 | |||
216 | if (cc < 0) { | ||
217 | if (errno == EINTR) | ||
218 | continue; | ||
219 | if (errno == EAGAIN) | ||
220 | continue; | ||
221 | break; | ||
222 | } else if (cc == 0) | ||
223 | break; | ||
224 | |||
225 | if ((mode & (QUIET | REDIR)) == 0) | ||
226 | bb_printf(&buffer[n]); | ||
227 | n += cc; | ||
228 | } | ||
229 | } | ||
219 | 230 | ||
220 | if ((mode & (QUIET | REDIR)) == 0) | 231 | if (mode & REDIR) |
221 | bb_printf(&buffer[n]); | 232 | chomp(buffer); |
222 | n += cc; | 233 | } else { |
223 | } | 234 | bb_perror_msg("Failed to fork process"); |
224 | } | 235 | } |
225 | 236 | ||
226 | if (mode & REDIR) | 237 | n = 0; |
227 | chomp(buffer); | 238 | if (pid) { |
228 | } | 239 | close(dataPipe[0]); |
229 | else | 240 | |
230 | { | 241 | if ((mode & FORK) == 0) { |
231 | bb_perror_msg("Failed to fork process"); | 242 | if (waitpid(pid, &n, 0) == -1) |
232 | } | 243 | bb_printf("Couldn't wait?"); |
233 | 244 | } | |
234 | n = 0; | 245 | if (WIFEXITED(n)) |
235 | if (pid) | 246 | n = WEXITSTATUS(n); |
236 | { | 247 | else |
237 | close(dataPipe[0]); | 248 | n = -1; |
238 | |||
239 | if ((mode & FORK) == 0) | ||
240 | { | ||
241 | if (waitpid(pid, &n, 0) == -1) | ||
242 | bb_printf("Couldn't wait?"); | ||
243 | } | 249 | } |
244 | if (WIFEXITED(n)) | ||
245 | n = WEXITSTATUS(n); | ||
246 | else | ||
247 | n = -1; | ||
248 | } | ||
249 | 250 | ||
250 | free(args); | 251 | free(args); |
251 | free(commandBuffer); | 252 | free(commandBuffer); |
252 | errno = n; | 253 | errno = n; |
253 | return buffer; | 254 | return buffer; |
254 | } | 255 | } |
255 | 256 | ||
256 | 257 | ||
257 | #ifdef RUNLEVEL_LIST | 258 | #ifdef RUNLEVEL_LIST |
258 | // From ifupdown, so it should probably be in libbb. | 259 | // From ifupdown, so it should probably be in libbb. |
259 | llist_t *llist_add_to_end(llist_t *list_head, char *data) | 260 | llist_t *llist_add_to_end(llist_t * list_head, char *data) |
260 | { | 261 | { |
261 | llist_t *new_item, *tmp, *prev; | 262 | llist_t *new_item, *tmp, *prev; |
262 | 263 | ||
@@ -266,160 +267,270 @@ llist_t *llist_add_to_end(llist_t *list_head, char *data) | |||
266 | 267 | ||
267 | prev = NULL; | 268 | prev = NULL; |
268 | tmp = list_head; | 269 | tmp = list_head; |
269 | while(tmp) | 270 | while (tmp) { |
270 | { | 271 | prev = tmp; |
271 | prev = tmp; | 272 | tmp = tmp->link; |
272 | tmp = tmp->link; | ||
273 | } | 273 | } |
274 | if (prev) | 274 | if (prev) |
275 | prev->link = new_item; | 275 | prev->link = new_item; |
276 | else | 276 | else |
277 | list_head = new_item; | 277 | list_head = new_item; |
278 | 278 | ||
279 | return(list_head); | 279 | return (list_head); |
280 | } | 280 | } |
281 | #endif | 281 | #endif |
282 | 282 | ||
283 | 283 | ||
284 | llist_t *llist_delete(llist_t **head, llist_t *previous, llist_t *current) | 284 | llist_t *llist_delete(llist_t ** head, llist_t * previous, llist_t * current) |
285 | { | 285 | { |
286 | if (previous == NULL) | 286 | if (previous == NULL) { |
287 | { | 287 | *head = current->link; |
288 | *head = current->link; | 288 | free(current); |
289 | free(current); | 289 | current = *head; |
290 | current = *head; | 290 | } else { |
291 | } | 291 | previous->link = current->link; |
292 | else | 292 | free(current); |
293 | { | 293 | current = previous->link; |
294 | previous->link = current->link; | 294 | } |
295 | free(current); | 295 | |
296 | current = previous->link; | 296 | return current; |
297 | } | ||
298 | |||
299 | return current; | ||
300 | } | 297 | } |
301 | 298 | ||
302 | 299 | ||
303 | void make_disk(char *token, const nodes_t *nodes) | 300 | void make_disk(char *token) |
304 | { | 301 | { |
305 | int i; | 302 | int i; |
306 | char temp[32]; | 303 | |
307 | 304 | RESERVE_CONFIG_BUFFER(temp, PATH_MAX); | |
308 | for (i = 0; nodes[i].name != 0; i++) | 305 | |
309 | { | 306 | if (nodes == NULL) |
310 | if (strncmp(nodes[i].name, token, 3) == 0) | 307 | return; |
311 | { | 308 | |
312 | int m = atoi(&token[3]); | 309 | for (i = 0; nodes[i].name != NULL; i++) { |
313 | sprintf(temp, "/dev/%s", token); | 310 | if (strncmp(nodes[i].name, token, 3) == 0) { |
314 | mknod(temp, nodes[i].mode, makedev(nodes[i].major, nodes[i].minor + m)); | 311 | int m = atoi(&token[3]); |
315 | break; | 312 | |
313 | snprintf(temp, PATH_MAX, "/dev/%s", token); | ||
314 | mknod(temp, nodes[i].mode, | ||
315 | makedev(nodes[i].major, nodes[i].minor + m)); | ||
316 | break; | ||
317 | } | ||
316 | } | 318 | } |
317 | } | 319 | snprintf(temp, PATH_MAX, "/media/%s", token); |
318 | sprintf(temp, "/media/%s", token); | 320 | bb_make_directory(temp, -1l, FILEUTILS_RECUR); |
319 | bb_make_directory(temp, -1l, FILEUTILS_RECUR); | 321 | RELEASE_CONFIG_BUFFER(temp); |
320 | } | 322 | } |
321 | 323 | ||
322 | 324 | ||
323 | void make_ram_disk(int size, int number, char *place, int TMPFS) | 325 | void make_ram_disk(int size, int number, char *place, int TMPFS) |
324 | { | 326 | { |
325 | if (size > 0) | 327 | if (size > 0) { |
326 | { | 328 | char *place2; |
327 | char *place2; | 329 | |
328 | 330 | bb_printf("Creating ramdisk at %s\n", place); | |
329 | bb_printf( "Creating ramdisk at %s\n", place); | 331 | bb_xasprintf(&place2, "%s2", place); |
330 | bb_xasprintf(&place2, "%s2", place); | 332 | if (copy_file |
331 | if (copy_file(place, place2, FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS) >= 0) | 333 | (place, place2, FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS) >= 0) |
332 | remove_file(place, FILEUTILS_RECUR | FILEUTILS_FORCE); | 334 | remove_file(place, FILEUTILS_RECUR | FILEUTILS_FORCE); |
333 | bb_make_directory (place, -1l, 0); | 335 | bb_make_directory(place, -1l, 0); |
334 | if (TMPFS) | 336 | if (TMPFS) |
335 | quick_mount("tmpfs", "/dev/null", place, "-n -o size=%i", size * 1024); | 337 | quick_mount("tmpfs", "/dev/null", place, "-n -o size=%i", |
336 | else | 338 | size * 1024); |
337 | { | 339 | else { |
338 | doit(QUIET, "mkfs.minix /dev/ram%i %i", number, size); | 340 | doit(QUIET, "mkfs.minix /dev/ram%i %i", number, size); |
339 | quick_mount("minix", "", "", "/dev/ram%i %s", number, place); | 341 | quick_mount("minix", "", "", "/dev/ram%i %s", number, place); |
342 | } | ||
343 | if (copy_file | ||
344 | (place2, place, FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS) >= 0) | ||
345 | remove_file(place2, FILEUTILS_RECUR | FILEUTILS_FORCE); | ||
346 | free(place2); | ||
340 | } | 347 | } |
341 | if (copy_file(place2, place, FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS) >= 0) | ||
342 | remove_file(place2, FILEUTILS_RECUR | FILEUTILS_FORCE); | ||
343 | free(place2); | ||
344 | } | ||
345 | } | 348 | } |
346 | 349 | ||
347 | 350 | ||
348 | void quick_mount(char *type, char *device, char *path, char *data, ...) | 351 | void quick_mount(char *type, char *device, char *path, char *data, ...) |
349 | { | 352 | { |
350 | char *dataBuffer; | 353 | char *dataBuffer; |
351 | va_list p; | 354 | va_list p; |
352 | int r; | 355 | int r; |
353 | 356 | ||
354 | va_start(p, data); | 357 | va_start(p, data); |
355 | r = vasprintf(&dataBuffer, data, p); | 358 | r = vasprintf(&dataBuffer, data, p); |
356 | va_end(p); | 359 | va_end(p); |
357 | if (r < 0) | 360 | if (r < 0) |
358 | bb_perror_msg("quick_mount"); | 361 | bb_perror_msg("quick_mount"); |
359 | else | 362 | else { |
360 | { | 363 | doit(QUIET, "busybox mount -t %s %s %s %s", type, device, path, |
361 | doit(QUIET, "busybox mount -t %s %s %s %s", type, device, path, dataBuffer); | 364 | dataBuffer); |
362 | } | 365 | } |
363 | 366 | ||
364 | free(dataBuffer); | 367 | free(dataBuffer); |
365 | } | 368 | } |
366 | 369 | ||
367 | 370 | ||
368 | char *quick_read(char *filename) | 371 | char *quick_read(char *filename) |
369 | { | 372 | { |
370 | char *result = NULL; | 373 | char *result = NULL; |
371 | 374 | ||
372 | if (stat(filename, &path_stat) == 0) | 375 | if (stat(filename, &path_stat) == 0) { |
373 | { | 376 | // if (S_ISREG(path_stat.st_mode)) |
374 | // if (S_ISREG(path_stat.st_mode)) | 377 | { |
375 | { | 378 | int ifd; |
376 | int ifd; | 379 | ssize_t size = path_stat.st_size; |
377 | ssize_t size = path_stat.st_size; | 380 | |
378 | 381 | if (size <= 0) | |
379 | if (size <= 0) | 382 | size = 1024; |
380 | size = 1024; | 383 | result = (char *) xmalloc(sizeof(char) * size + 1); |
381 | result = (char *) xmalloc (sizeof (char) * size + 1); | 384 | if ((ifd = open(filename, O_RDONLY)) < 0) |
382 | if ((ifd = open(filename, O_RDONLY)) < 0) | 385 | bb_perror_msg("%s", filename); |
383 | bb_perror_msg("%s", filename); | 386 | else { |
384 | else | 387 | ssize_t total = bb_full_read(ifd, result, size); |
385 | { | 388 | |
386 | ssize_t total = bb_full_read(ifd, result, size); | 389 | // result[path_stat.st_size] = '\0'; |
387 | // result[path_stat.st_size] = '\0'; | 390 | result[total] = '\0'; |
388 | result[total] = '\0'; | 391 | if (close(ifd) < 0) |
389 | if (close (ifd) < 0) | 392 | bb_perror_msg("%s", filename); |
390 | bb_perror_msg("%s", filename); | 393 | } |
391 | } | 394 | } |
392 | } | 395 | } |
393 | } | ||
394 | 396 | ||
395 | return result; | 397 | return result; |
396 | } | 398 | } |
397 | 399 | ||
398 | 400 | ||
399 | void quick_write(const char *filename, const char *data, ...) | 401 | void quick_write(const char *filename, const char *data, ...) |
400 | { | 402 | { |
401 | char *dataBuffer; | 403 | char *dataBuffer; |
402 | va_list p; | 404 | va_list p; |
403 | int r; | 405 | int r; |
404 | 406 | ||
405 | va_start(p, data); | 407 | va_start(p, data); |
406 | r = vasprintf(&dataBuffer, data, p); | 408 | r = vasprintf(&dataBuffer, data, p); |
407 | va_end(p); | 409 | va_end(p); |
408 | if (r >= 0) | 410 | if (r >= 0) { |
409 | { | 411 | int ofd; |
410 | int ofd; | 412 | |
411 | 413 | if ((ofd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) | |
412 | if ((ofd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) | 414 | bb_perror_msg("%s", filename); |
413 | bb_perror_msg("%s", filename); | 415 | else { |
414 | else | 416 | r = bb_full_write(ofd, dataBuffer, r); |
415 | { | 417 | if (close(ofd) < 0) |
416 | r = bb_full_write(ofd, dataBuffer, r); | 418 | bb_perror_msg("%s", filename); |
417 | if (close (ofd) < 0) | 419 | } |
418 | bb_perror_msg("%s", filename); | 420 | } |
421 | if (r < 0) | ||
422 | bb_perror_msg("quick_write"); | ||
423 | |||
424 | free(dataBuffer); | ||
425 | } | ||
426 | |||
427 | |||
428 | void read_sysconfig(char *sysconfig) | ||
429 | { | ||
430 | if (sysconfig == NULL) | ||
431 | sysconfig = "/bootconfig"; | ||
432 | if (stat(sysconfig, &path_stat) == 0) { | ||
433 | char *line; | ||
434 | FILE *contents; | ||
435 | |||
436 | contents = fopen(sysconfig, "r"); | ||
437 | if (contents != NULL) { | ||
438 | char *buffer = (char *) xmalloc(sizeof(char) * 256); | ||
439 | |||
440 | //bb_printf("Parsing configuration.\n"); | ||
441 | do { | ||
442 | line = fgets(buffer, 255, contents); | ||
443 | set_sysconfig_env(buffer); | ||
444 | } while (line != NULL); | ||
445 | } | ||
446 | } | ||
447 | } | ||
448 | |||
449 | |||
450 | void set_sysconfig_env(char *token) | ||
451 | { | ||
452 | int i; | ||
453 | char *eq = NULL; | ||
454 | char *ha = NULL; | ||
455 | char quote = 0; | ||
456 | |||
457 | if (token == NULL) | ||
458 | return; | ||
459 | trim(token); | ||
460 | if (token[0] == '\0') | ||
461 | return; | ||
462 | for (i = 0; token[i] != '\0'; i++) { | ||
463 | switch (token[i]) { | ||
464 | case '=': | ||
465 | if (quote == 0) { | ||
466 | if (eq == NULL) | ||
467 | eq = &token[i]; | ||
468 | } | ||
469 | break; | ||
470 | case '#': | ||
471 | if (quote == 0) { | ||
472 | if (ha == NULL) | ||
473 | ha = &token[i]; | ||
474 | } | ||
475 | break; | ||
476 | |||
477 | case '"': | ||
478 | if (quote == 0) { | ||
479 | quote = '"'; | ||
480 | if (eq) { | ||
481 | *eq = '\0'; | ||
482 | eq = &token[i]; | ||
483 | } | ||
484 | } | ||
485 | else if (quote == '"') { | ||
486 | quote = 0; | ||
487 | token[i] = '\0'; | ||
488 | } | ||
489 | break; | ||
490 | |||
491 | case '\'': | ||
492 | if (quote == 0) { | ||
493 | quote = '\''; | ||
494 | if (eq) { | ||
495 | *eq = '\0'; | ||
496 | eq = &token[i]; | ||
497 | } | ||
498 | } | ||
499 | else if (quote == '\'') { | ||
500 | quote = 0; | ||
501 | token[i] = '\0'; | ||
502 | } | ||
503 | break; | ||
504 | } | ||
419 | } | 505 | } |
420 | } | ||
421 | if (r < 0) | ||
422 | bb_perror_msg("quick_write"); | ||
423 | 506 | ||
424 | free(dataBuffer); | 507 | if (eq == NULL) |
508 | return; | ||
509 | |||
510 | if ((eq != token) && (ha != token)) { | ||
511 | char *name = (char *) xmalloc(sizeof(char) * (i + 5)); | ||
512 | |||
513 | if (eq != NULL) | ||
514 | *eq = '\0'; | ||
515 | if (ha != NULL) | ||
516 | *ha = '\0'; | ||
517 | sprintf(name, "%s", token); | ||
518 | trim(name); | ||
519 | if (name[0] != '\0') { | ||
520 | if (eq != NULL) { | ||
521 | // Don't override previously set env. | ||
522 | if (getenv(name) == NULL) { | ||
523 | setenv(name, &eq[1], 1); | ||
524 | } | ||
525 | } else { | ||
526 | setenv(name, "", 1); | ||
527 | } | ||
528 | } | ||
529 | free(name); | ||
530 | // if (eq != NULL) | ||
531 | // *eq = '='; | ||
532 | // if (ha != NULL) | ||
533 | // *ha = '#'; | ||
534 | } | ||
425 | } | 535 | } |
536 | |||