aboutsummaryrefslogtreecommitdiff
path: root/utility.c
diff options
context:
space:
mode:
Diffstat (limited to 'utility.c')
-rw-r--r--utility.c1394
1 files changed, 696 insertions, 698 deletions
diff --git a/utility.c b/utility.c
index 10e107fc5..7f46f9bf4 100644
--- a/utility.c
+++ b/utility.c
@@ -1,3 +1,4 @@
1/* vi: set sw=4 ts=4: */
1/* 2/*
2 * Utility routines. 3 * Utility routines.
3 * 4 *
@@ -46,7 +47,7 @@
46#include <sys/stat.h> 47#include <sys/stat.h>
47#include <unistd.h> 48#include <unistd.h>
48#include <ctype.h> 49#include <ctype.h>
49#include <sys/param.h> /* for PATH_MAX */ 50#include <sys/param.h> /* for PATH_MAX */
50 51
51#if defined BB_FEATURE_MOUNT_LOOP 52#if defined BB_FEATURE_MOUNT_LOOP
52#include <fcntl.h> 53#include <fcntl.h>
@@ -70,10 +71,10 @@ const char mtab_file[] = "/etc/mtab";
70 71
71extern void usage(const char *usage) 72extern void usage(const char *usage)
72{ 73{
73 fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n\n", 74 fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n\n",
74 BB_VER, BB_BT); 75 BB_VER, BB_BT);
75 fprintf(stderr, "Usage: %s\n", usage); 76 fprintf(stderr, "Usage: %s\n", usage);
76 exit FALSE; 77 exit FALSE;
77} 78}
78 79
79 80
@@ -86,22 +87,21 @@ extern void usage(const char *usage)
86 * so, for example, to check if the kernel is greater than 2.2.11: 87 * so, for example, to check if the kernel is greater than 2.2.11:
87 * if (get_kernel_revision() <= 2*65536+2*256+11) { <stuff> } 88 * if (get_kernel_revision() <= 2*65536+2*256+11) { <stuff> }
88 */ 89 */
89int 90int get_kernel_revision()
90get_kernel_revision()
91{ 91{
92 FILE *file; 92 FILE *file;
93 int major=0, minor=0, patch=0; 93 int major = 0, minor = 0, patch = 0;
94 94
95 file = fopen("/proc/sys/kernel/osrelease", "r"); 95 file = fopen("/proc/sys/kernel/osrelease", "r");
96 if (file == NULL) { 96 if (file == NULL) {
97 /* bummer, /proc must not be mounted... */ 97 /* bummer, /proc must not be mounted... */
98 return( 0); 98 return (0);
99 } 99 }
100 fscanf(file,"%d.%d.%d",&major,&minor,&patch); 100 fscanf(file, "%d.%d.%d", &major, &minor, &patch);
101 fclose(file); 101 fclose(file);
102 return major*65536 + minor*256 + patch; 102 return major * 65536 + minor * 256 + patch;
103} 103}
104#endif /* BB_INIT || BB_PS */ 104#endif /* BB_INIT || BB_PS */
105 105
106 106
107 107
@@ -112,19 +112,19 @@ get_kernel_revision()
112 */ 112 */
113int isDirectory(const char *fileName, const int followLinks) 113int isDirectory(const char *fileName, const int followLinks)
114{ 114{
115 struct stat statBuf; 115 struct stat statBuf;
116 int status; 116 int status;
117 117
118 if (followLinks == TRUE) 118 if (followLinks == TRUE)
119 status = stat(fileName, &statBuf); 119 status = stat(fileName, &statBuf);
120 else 120 else
121 status = lstat(fileName, &statBuf); 121 status = lstat(fileName, &statBuf);
122 122
123 if (status < 0) 123 if (status < 0)
124 return FALSE; 124 return FALSE;
125 if (S_ISDIR(statBuf.st_mode)) 125 if (S_ISDIR(statBuf.st_mode))
126 return TRUE; 126 return TRUE;
127 return FALSE; 127 return FALSE;
128} 128}
129#endif 129#endif
130 130
@@ -137,148 +137,150 @@ int isDirectory(const char *fileName, const int followLinks)
137 * -Erik Andersen 137 * -Erik Andersen
138 */ 138 */
139int 139int
140copyFile( const char *srcName, const char *destName, 140copyFile(const char *srcName, const char *destName,
141 int setModes, int followLinks) 141 int setModes, int followLinks)
142{ 142{
143 int rfd; 143 int rfd;
144 int wfd; 144 int wfd;
145 int rcc; 145 int rcc;
146 int status; 146 int status;
147 char buf[BUF_SIZE]; 147 char buf[BUF_SIZE];
148 struct stat srcStatBuf; 148 struct stat srcStatBuf;
149 struct stat dstStatBuf; 149 struct stat dstStatBuf;
150 struct utimbuf times; 150 struct utimbuf times;
151 151
152 if (followLinks == TRUE) 152 if (followLinks == TRUE)
153 status = stat(srcName, &srcStatBuf); 153 status = stat(srcName, &srcStatBuf);
154 else 154 else
155 status = lstat(srcName, &srcStatBuf); 155 status = lstat(srcName, &srcStatBuf);
156
157 if (status < 0) {
158 perror(srcName);
159 return FALSE;
160 }
161 156
162 if (followLinks == TRUE) 157 if (status < 0) {
163 status = stat(destName, &dstStatBuf); 158 perror(srcName);
164 else 159 return FALSE;
165 status = lstat(destName, &dstStatBuf); 160 }
166 161
167 if (status < 0) { 162 if (followLinks == TRUE)
168 dstStatBuf.st_ino = -1; 163 status = stat(destName, &dstStatBuf);
169 dstStatBuf.st_dev = -1; 164 else
170 } 165 status = lstat(destName, &dstStatBuf);
171 166
172 if ((srcStatBuf.st_dev == dstStatBuf.st_dev) &&
173 (srcStatBuf.st_ino == dstStatBuf.st_ino)) {
174 fprintf(stderr, "Copying file \"%s\" to itself\n", srcName);
175 return FALSE;
176 }
177
178 if (S_ISDIR(srcStatBuf.st_mode)) {
179 //fprintf(stderr, "copying directory %s to %s\n", srcName, destName);
180 /* Make sure the directory is writable */
181 status = mkdir(destName, 0777777 ^ umask(0));
182 if (status < 0 && errno != EEXIST) {
183 perror(destName);
184 return FALSE;
185 }
186 } else if (S_ISLNK(srcStatBuf.st_mode)) {
187 char link_val[PATH_MAX + 1];
188 int link_size;
189
190 //fprintf(stderr, "copying link %s to %s\n", srcName, destName);
191 /* Warning: This could possibly truncate silently, to PATH_MAX chars */
192 link_size = readlink(srcName, &link_val[0], PATH_MAX);
193 if (link_size < 0) {
194 perror(srcName);
195 return FALSE;
196 }
197 link_val[link_size] = '\0';
198 status = symlink(link_val, destName);
199 if (status < 0) { 167 if (status < 0) {
200 perror(destName); 168 dstStatBuf.st_ino = -1;
201 return FALSE; 169 dstStatBuf.st_dev = -1;
202 } 170 }
203#if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) 171
204 if (setModes == TRUE) { 172 if ((srcStatBuf.st_dev == dstStatBuf.st_dev) &&
205 if (lchown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid) < 0) { 173 (srcStatBuf.st_ino == dstStatBuf.st_ino)) {
206 perror(destName); 174 fprintf(stderr, "Copying file \"%s\" to itself\n", srcName);
207 return FALSE; 175 return FALSE;
208 }
209 } 176 }
177
178 if (S_ISDIR(srcStatBuf.st_mode)) {
179 //fprintf(stderr, "copying directory %s to %s\n", srcName, destName);
180 /* Make sure the directory is writable */
181 status = mkdir(destName, 0777777 ^ umask(0));
182 if (status < 0 && errno != EEXIST) {
183 perror(destName);
184 return FALSE;
185 }
186 } else if (S_ISLNK(srcStatBuf.st_mode)) {
187 char link_val[PATH_MAX + 1];
188 int link_size;
189
190 //fprintf(stderr, "copying link %s to %s\n", srcName, destName);
191 /* Warning: This could possibly truncate silently, to PATH_MAX chars */
192 link_size = readlink(srcName, &link_val[0], PATH_MAX);
193 if (link_size < 0) {
194 perror(srcName);
195 return FALSE;
196 }
197 link_val[link_size] = '\0';
198 status = symlink(link_val, destName);
199 if (status < 0) {
200 perror(destName);
201 return FALSE;
202 }
203#if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1)
204 if (setModes == TRUE) {
205 if (lchown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid) < 0) {
206 perror(destName);
207 return FALSE;
208 }
209 }
210#endif 210#endif
211 return TRUE; 211 return TRUE;
212 } else if (S_ISFIFO(srcStatBuf.st_mode)) { 212 } else if (S_ISFIFO(srcStatBuf.st_mode)) {
213 //fprintf(stderr, "copying fifo %s to %s\n", srcName, destName); 213 //fprintf(stderr, "copying fifo %s to %s\n", srcName, destName);
214 if (mkfifo(destName, 0644) < 0) { 214 if (mkfifo(destName, 0644) < 0) {
215 perror(destName); 215 perror(destName);
216 return FALSE; 216 return FALSE;
217 } 217 }
218 } else if (S_ISBLK(srcStatBuf.st_mode) || S_ISCHR(srcStatBuf.st_mode) 218 } else if (S_ISBLK(srcStatBuf.st_mode) || S_ISCHR(srcStatBuf.st_mode)
219 || S_ISSOCK (srcStatBuf.st_mode)) { 219 || S_ISSOCK(srcStatBuf.st_mode)) {
220 //fprintf(stderr, "copying soc, blk, or chr %s to %s\n", srcName, destName); 220 //fprintf(stderr, "copying soc, blk, or chr %s to %s\n", srcName, destName);
221 if (mknod(destName, srcStatBuf.st_mode, srcStatBuf.st_rdev) < 0) { 221 if (mknod(destName, srcStatBuf.st_mode, srcStatBuf.st_rdev) < 0) {
222 perror(destName); 222 perror(destName);
223 return FALSE; 223 return FALSE;
224 } 224 }
225 } else if (S_ISREG(srcStatBuf.st_mode)) { 225 } else if (S_ISREG(srcStatBuf.st_mode)) {
226 //fprintf(stderr, "copying regular file %s to %s\n", srcName, destName); 226 //fprintf(stderr, "copying regular file %s to %s\n", srcName, destName);
227 rfd = open(srcName, O_RDONLY); 227 rfd = open(srcName, O_RDONLY);
228 if (rfd < 0) { 228 if (rfd < 0) {
229 perror(srcName); 229 perror(srcName);
230 return FALSE; 230 return FALSE;
231 } 231 }
232 232
233 wfd = open(destName, O_WRONLY | O_CREAT | O_TRUNC, srcStatBuf.st_mode); 233 wfd =
234 if (wfd < 0) { 234 open(destName, O_WRONLY | O_CREAT | O_TRUNC,
235 perror(destName); 235 srcStatBuf.st_mode);
236 close(rfd); 236 if (wfd < 0) {
237 return FALSE; 237 perror(destName);
238 } 238 close(rfd);
239 return FALSE;
240 }
239 241
240 while ((rcc = read(rfd, buf, sizeof(buf))) > 0) { 242 while ((rcc = read(rfd, buf, sizeof(buf))) > 0) {
241 if (fullWrite(wfd, buf, rcc) < 0) 243 if (fullWrite(wfd, buf, rcc) < 0)
242 goto error_exit; 244 goto error_exit;
243 } 245 }
244 if (rcc < 0) { 246 if (rcc < 0) {
245 goto error_exit; 247 goto error_exit;
246 } 248 }
247 249
248 close(rfd); 250 close(rfd);
249 if (close(wfd) < 0) { 251 if (close(wfd) < 0) {
250 return FALSE; 252 return FALSE;
253 }
251 } 254 }
252 }
253 255
254 if (setModes == TRUE) { 256 if (setModes == TRUE) {
255 /* This is fine, since symlinks never get here */ 257 /* This is fine, since symlinks never get here */
256 if (chown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid) < 0) { 258 if (chown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid) < 0) {
257 perror(destName); 259 perror(destName);
258 exit FALSE; 260 exit FALSE;
259 } 261 }
260 if (chmod(destName, srcStatBuf.st_mode) < 0) { 262 if (chmod(destName, srcStatBuf.st_mode) < 0) {
261 perror(destName); 263 perror(destName);
262 exit FALSE; 264 exit FALSE;
263 } 265 }
264 times.actime = srcStatBuf.st_atime; 266 times.actime = srcStatBuf.st_atime;
265 times.modtime = srcStatBuf.st_mtime; 267 times.modtime = srcStatBuf.st_mtime;
266 if (utime(destName, &times) < 0) { 268 if (utime(destName, &times) < 0) {
267 perror(destName); 269 perror(destName);
268 exit FALSE; 270 exit FALSE;
271 }
269 } 272 }
270 }
271 273
272 return TRUE; 274 return TRUE;
273 275
274 error_exit: 276 error_exit:
275 perror(destName); 277 perror(destName);
276 close(rfd); 278 close(rfd);
277 close(wfd); 279 close(wfd);
278 280
279 return FALSE; 281 return FALSE;
280} 282}
281#endif /* BB_CP_MV */ 283#endif /* BB_CP_MV */
282 284
283 285
284 286
@@ -289,16 +291,16 @@ copyFile( const char *srcName, const char *destName,
289 291
290/* The special bits. If set, display SMODE0/1 instead of MODE0/1 */ 292/* The special bits. If set, display SMODE0/1 instead of MODE0/1 */
291static const mode_t SBIT[] = { 293static const mode_t SBIT[] = {
292 0, 0, S_ISUID, 294 0, 0, S_ISUID,
293 0, 0, S_ISGID, 295 0, 0, S_ISGID,
294 0, 0, S_ISVTX 296 0, 0, S_ISVTX
295}; 297};
296 298
297/* The 9 mode bits to test */ 299/* The 9 mode bits to test */
298static const mode_t MBIT[] = { 300static const mode_t MBIT[] = {
299 S_IRUSR, S_IWUSR, S_IXUSR, 301 S_IRUSR, S_IWUSR, S_IXUSR,
300 S_IRGRP, S_IWGRP, S_IXGRP, 302 S_IRGRP, S_IWGRP, S_IXGRP,
301 S_IROTH, S_IWOTH, S_IXOTH 303 S_IROTH, S_IWOTH, S_IXOTH
302}; 304};
303 305
304#define MODE1 "rwxrwxrwx" 306#define MODE1 "rwxrwxrwx"
@@ -312,21 +314,20 @@ static const mode_t MBIT[] = {
312 */ 314 */
313const char *modeString(int mode) 315const char *modeString(int mode)
314{ 316{
315 static char buf[12]; 317 static char buf[12];
316 318
317 int i; 319 int i;
318 buf[0] = TYPECHAR(mode); 320
319 for (i=0; i<9; i++) { 321 buf[0] = TYPECHAR(mode);
320 if (mode & SBIT[i]) 322 for (i = 0; i < 9; i++) {
321 buf[i+1] = (mode & MBIT[i])? 323 if (mode & SBIT[i])
322 SMODE1[i] : SMODE0[i]; 324 buf[i + 1] = (mode & MBIT[i]) ? SMODE1[i] : SMODE0[i];
323 else 325 else
324 buf[i+1] = (mode & MBIT[i])? 326 buf[i + 1] = (mode & MBIT[i]) ? MODE1[i] : MODE0[i];
325 MODE1[i] : MODE0[i]; 327 }
326 } 328 return buf;
327 return buf;
328} 329}
329#endif /* BB_TAR || BB_LS */ 330#endif /* BB_TAR || BB_LS */
330 331
331 332
332#if defined BB_TAR 333#if defined BB_TAR
@@ -336,25 +337,25 @@ const char *modeString(int mode)
336 */ 337 */
337const char *timeString(time_t timeVal) 338const char *timeString(time_t timeVal)
338{ 339{
339 time_t now; 340 time_t now;
340 char *str; 341 char *str;
341 static char buf[26]; 342 static char buf[26];
342 343
343 time(&now); 344 time(&now);
344 345
345 str = ctime(&timeVal); 346 str = ctime(&timeVal);
346 347
347 strcpy(buf, &str[4]); 348 strcpy(buf, &str[4]);
348 buf[12] = '\0'; 349 buf[12] = '\0';
349 350
350 if ((timeVal > now) || (timeVal < now - 365 * 24 * 60 * 60L)) { 351 if ((timeVal > now) || (timeVal < now - 365 * 24 * 60 * 60L)) {
351 strcpy(&buf[7], &str[20]); 352 strcpy(&buf[7], &str[20]);
352 buf[11] = '\0'; 353 buf[11] = '\0';
353 } 354 }
354 355
355 return buf; 356 return buf;
356} 357}
357#endif /* BB_TAR */ 358#endif /* BB_TAR */
358 359
359#if defined BB_TAR || defined BB_CP_MV 360#if defined BB_TAR || defined BB_CP_MV
360/* 361/*
@@ -364,25 +365,25 @@ const char *timeString(time_t timeVal)
364 */ 365 */
365int fullWrite(int fd, const char *buf, int len) 366int fullWrite(int fd, const char *buf, int len)
366{ 367{
367 int cc; 368 int cc;
368 int total; 369 int total;
369 370
370 total = 0; 371 total = 0;
371 372
372 while (len > 0) { 373 while (len > 0) {
373 cc = write(fd, buf, len); 374 cc = write(fd, buf, len);
374 375
375 if (cc < 0) 376 if (cc < 0)
376 return -1; 377 return -1;
377 378
378 buf += cc; 379 buf += cc;
379 total += cc; 380 total += cc;
380 len -= cc; 381 len -= cc;
381 } 382 }
382 383
383 return total; 384 return total;
384} 385}
385#endif /* BB_TAR || BB_CP_MV */ 386#endif /* BB_TAR || BB_CP_MV */
386 387
387 388
388#if defined BB_TAR || defined BB_TAIL 389#if defined BB_TAR || defined BB_TAIL
@@ -394,28 +395,28 @@ int fullWrite(int fd, const char *buf, int len)
394 */ 395 */
395int fullRead(int fd, char *buf, int len) 396int fullRead(int fd, char *buf, int len)
396{ 397{
397 int cc; 398 int cc;
398 int total; 399 int total;
399 400
400 total = 0; 401 total = 0;
401 402
402 while (len > 0) { 403 while (len > 0) {
403 cc = read(fd, buf, len); 404 cc = read(fd, buf, len);
404 405
405 if (cc < 0) 406 if (cc < 0)
406 return -1; 407 return -1;
407 408
408 if (cc == 0) 409 if (cc == 0)
409 break; 410 break;
410 411
411 buf += cc; 412 buf += cc;
412 total += cc; 413 total += cc;
413 len -= cc; 414 len -= cc;
414 } 415 }
415 416
416 return total; 417 return total;
417} 418}
418#endif /* BB_TAR || BB_TAIL */ 419#endif /* BB_TAR || BB_TAIL */
419 420
420 421
421#if defined (BB_CHMOD_CHOWN_CHGRP) \ 422#if defined (BB_CHMOD_CHOWN_CHGRP) \
@@ -434,102 +435,104 @@ int fullRead(int fd, char *buf, int len)
434 * is so stinking huge. 435 * is so stinking huge.
435 */ 436 */
436int recursiveAction(const char *fileName, 437int recursiveAction(const char *fileName,
437 int recurse, int followLinks, int depthFirst, 438 int recurse, int followLinks, int depthFirst,
438 int (*fileAction) (const char *fileName, 439 int (*fileAction) (const char *fileName,
439 struct stat* statbuf), 440 struct stat * statbuf),
440 int (*dirAction) (const char *fileName, 441 int (*dirAction) (const char *fileName,
441 struct stat* statbuf)) 442 struct stat * statbuf))
442{ 443{
443 int status; 444 int status;
444 struct stat statbuf; 445 struct stat statbuf;
445 struct dirent *next; 446 struct dirent *next;
446 447
447 if (followLinks == TRUE) 448 if (followLinks == TRUE)
448 status = stat(fileName, &statbuf); 449 status = stat(fileName, &statbuf);
449 else 450 else
450 status = lstat(fileName, &statbuf); 451 status = lstat(fileName, &statbuf);
451 452
452 if (status < 0) { 453 if (status < 0) {
453#ifdef BB_DEBUG_PRINT_SCAFFOLD 454#ifdef BB_DEBUG_PRINT_SCAFFOLD
454 fprintf(stderr, 455 fprintf(stderr,
455 "status=%d followLinks=%d TRUE=%d\n", 456 "status=%d followLinks=%d TRUE=%d\n",
456 status, followLinks, TRUE); 457 status, followLinks, TRUE);
457#endif 458#endif
458 perror(fileName);
459 return FALSE;
460 }
461
462 if ((followLinks == FALSE) && (S_ISLNK(statbuf.st_mode)) ) {
463 if (fileAction == NULL)
464 return TRUE;
465 else
466 return fileAction(fileName, &statbuf);
467 }
468
469 if (recurse == FALSE) {
470 if (S_ISDIR(statbuf.st_mode)) {
471 if (dirAction != NULL)
472 return (dirAction(fileName, &statbuf));
473 else
474 return TRUE;
475 }
476 }
477
478 if (S_ISDIR(statbuf.st_mode)) {
479 DIR *dir;
480 dir = opendir(fileName);
481 if (!dir) {
482 perror(fileName);
483 return FALSE;
484 }
485 if (dirAction != NULL && depthFirst == FALSE) {
486 status = dirAction(fileName, &statbuf);
487 if (status == FALSE) {
488 perror(fileName); 459 perror(fileName);
489 return FALSE; 460 return FALSE;
490 }
491 } 461 }
492 while ((next = readdir(dir)) != NULL) { 462
493 char nextFile[PATH_MAX + 1]; 463 if ((followLinks == FALSE) && (S_ISLNK(statbuf.st_mode))) {
494 if ((strcmp(next->d_name, "..") == 0) 464 if (fileAction == NULL)
495 || (strcmp(next->d_name, ".") == 0)) { 465 return TRUE;
496 continue; 466 else
497 } 467 return fileAction(fileName, &statbuf);
498 if (strlen(fileName) + strlen(next->d_name) + 1 > PATH_MAX) {
499 fprintf(stderr, name_too_long, "ftw");
500 return FALSE;
501 }
502 sprintf(nextFile, "%s/%s", fileName, next->d_name);
503 status =
504 recursiveAction(nextFile, TRUE, followLinks, depthFirst,
505 fileAction, dirAction);
506 if (status < 0) {
507 closedir(dir);
508 return FALSE;
509 }
510 } 468 }
511 status = closedir(dir); 469
512 if (status < 0) { 470 if (recurse == FALSE) {
513 perror(fileName); 471 if (S_ISDIR(statbuf.st_mode)) {
514 return FALSE; 472 if (dirAction != NULL)
473 return (dirAction(fileName, &statbuf));
474 else
475 return TRUE;
476 }
515 } 477 }
516 if (dirAction != NULL && depthFirst == TRUE) { 478
517 status = dirAction(fileName, &statbuf); 479 if (S_ISDIR(statbuf.st_mode)) {
518 if (status == FALSE) { 480 DIR *dir;
519 perror(fileName); 481
520 return FALSE; 482 dir = opendir(fileName);
521 } 483 if (!dir) {
484 perror(fileName);
485 return FALSE;
486 }
487 if (dirAction != NULL && depthFirst == FALSE) {
488 status = dirAction(fileName, &statbuf);
489 if (status == FALSE) {
490 perror(fileName);
491 return FALSE;
492 }
493 }
494 while ((next = readdir(dir)) != NULL) {
495 char nextFile[PATH_MAX + 1];
496
497 if ((strcmp(next->d_name, "..") == 0)
498 || (strcmp(next->d_name, ".") == 0)) {
499 continue;
500 }
501 if (strlen(fileName) + strlen(next->d_name) + 1 > PATH_MAX) {
502 fprintf(stderr, name_too_long, "ftw");
503 return FALSE;
504 }
505 sprintf(nextFile, "%s/%s", fileName, next->d_name);
506 status =
507 recursiveAction(nextFile, TRUE, followLinks, depthFirst,
508 fileAction, dirAction);
509 if (status < 0) {
510 closedir(dir);
511 return FALSE;
512 }
513 }
514 status = closedir(dir);
515 if (status < 0) {
516 perror(fileName);
517 return FALSE;
518 }
519 if (dirAction != NULL && depthFirst == TRUE) {
520 status = dirAction(fileName, &statbuf);
521 if (status == FALSE) {
522 perror(fileName);
523 return FALSE;
524 }
525 }
526 } else {
527 if (fileAction == NULL)
528 return TRUE;
529 else
530 return fileAction(fileName, &statbuf);
522 } 531 }
523 } else { 532 return TRUE;
524 if (fileAction == NULL)
525 return TRUE;
526 else
527 return fileAction(fileName, &statbuf);
528 }
529 return TRUE;
530} 533}
531 534
532#endif /* BB_CHMOD_CHOWN_CHGRP || BB_CP_MV || BB_FIND || BB_LS || BB_INSMOD */ 535#endif /* BB_CHMOD_CHOWN_CHGRP || BB_CP_MV || BB_FIND || BB_LS || BB_INSMOD */
533 536
534 537
535 538
@@ -540,30 +543,30 @@ int recursiveAction(const char *fileName,
540 * while all previous ones get default protections. Errors are not reported 543 * while all previous ones get default protections. Errors are not reported
541 * here, as failures to restore files can be reported later. 544 * here, as failures to restore files can be reported later.
542 */ 545 */
543extern int createPath (const char *name, int mode) 546extern int createPath(const char *name, int mode)
544{ 547{
545 char *cp; 548 char *cp;
546 char *cpOld; 549 char *cpOld;
547 char buf[PATH_MAX + 1]; 550 char buf[PATH_MAX + 1];
548 int retVal=0; 551 int retVal = 0;
549 552
550 strcpy( buf, name); 553 strcpy(buf, name);
551 for (cp = buf; *cp == '/'; cp++); 554 for (cp = buf; *cp == '/'; cp++);
552 cp = strchr(cp, '/'); 555 cp = strchr(cp, '/');
553 while (cp) { 556 while (cp) {
554 cpOld = cp; 557 cpOld = cp;
555 cp = strchr(cp + 1, '/'); 558 cp = strchr(cp + 1, '/');
556 *cpOld = '\0'; 559 *cpOld = '\0';
557 retVal = mkdir(buf, cp ? 0777 : mode); 560 retVal = mkdir(buf, cp ? 0777 : mode);
558 if (retVal != 0 && errno != EEXIST) { 561 if (retVal != 0 && errno != EEXIST) {
559 perror(buf); 562 perror(buf);
560 return FALSE; 563 return FALSE;
564 }
565 *cpOld = '/';
561 } 566 }
562 *cpOld = '/'; 567 return TRUE;
563 }
564 return TRUE;
565} 568}
566#endif /* BB_TAR || BB_MKDIR */ 569#endif /* BB_TAR || BB_MKDIR */
567 570
568 571
569 572
@@ -572,67 +575,68 @@ extern int createPath (const char *name, int mode)
572 575
573 576
574 577
575extern int 578extern int parse_mode(const char *s, mode_t * theMode)
576parse_mode( const char* s, mode_t* theMode)
577{ 579{
578 mode_t andMode = S_ISVTX|S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; 580 mode_t andMode =
581
582 S_ISVTX | S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO;
579 mode_t orMode = 0; 583 mode_t orMode = 0;
580 mode_t mode = 0; 584 mode_t mode = 0;
581 mode_t groups = 0; 585 mode_t groups = 0;
582 char type; 586 char type;
583 char c; 587 char c;
584 588
585 do { 589 do {
586 for ( ; ; ) { 590 for (;;) {
587 switch ( c = *s++ ) { 591 switch (c = *s++) {
588 case '\0': 592 case '\0':
589 return -1; 593 return -1;
590 case 'u': 594 case 'u':
591 groups |= S_ISUID|S_IRWXU; 595 groups |= S_ISUID | S_IRWXU;
592 continue; 596 continue;
593 case 'g': 597 case 'g':
594 groups |= S_ISGID|S_IRWXG; 598 groups |= S_ISGID | S_IRWXG;
595 continue; 599 continue;
596 case 'o': 600 case 'o':
597 groups |= S_IRWXO; 601 groups |= S_IRWXO;
598 continue; 602 continue;
599 case 'a': 603 case 'a':
600 groups |= S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; 604 groups |= S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO;
601 continue; 605 continue;
602 case '+': 606 case '+':
603 case '=': 607 case '=':
604 case '-': 608 case '-':
605 type = c; 609 type = c;
606 if ( groups == 0 ) /* The default is "all" */ 610 if (groups == 0) /* The default is "all" */
607 groups |= S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; 611 groups |=
612 S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO;
608 break; 613 break;
609 default: 614 default:
610 if ( isdigit(c) && c >= '0' && c <= '7' && 615 if (isdigit(c) && c >= '0' && c <= '7' &&
611 mode == 0 && groups == 0 ) { 616 mode == 0 && groups == 0) {
612 *theMode = strtol(--s, NULL, 8); 617 *theMode = strtol(--s, NULL, 8);
613 return (TRUE); 618 return (TRUE);
614 } 619 } else
615 else
616 return (FALSE); 620 return (FALSE);
617 } 621 }
618 break; 622 break;
619 } 623 }
620 624
621 while ( (c = *s++) != '\0' ) { 625 while ((c = *s++) != '\0') {
622 switch ( c ) { 626 switch (c) {
623 case ',': 627 case ',':
624 break; 628 break;
625 case 'r': 629 case 'r':
626 mode |= S_IRUSR|S_IRGRP|S_IROTH; 630 mode |= S_IRUSR | S_IRGRP | S_IROTH;
627 continue; 631 continue;
628 case 'w': 632 case 'w':
629 mode |= S_IWUSR|S_IWGRP|S_IWOTH; 633 mode |= S_IWUSR | S_IWGRP | S_IWOTH;
630 continue; 634 continue;
631 case 'x': 635 case 'x':
632 mode |= S_IXUSR|S_IXGRP|S_IXOTH; 636 mode |= S_IXUSR | S_IXGRP | S_IXOTH;
633 continue; 637 continue;
634 case 's': 638 case 's':
635 mode |= S_IXGRP|S_ISUID|S_ISGID; 639 mode |= S_IXGRP | S_ISUID | S_ISGID;
636 continue; 640 continue;
637 case 't': 641 case 't':
638 mode |= 0; 642 mode |= 0;
@@ -640,11 +644,11 @@ parse_mode( const char* s, mode_t* theMode)
640 default: 644 default:
641 *theMode &= andMode; 645 *theMode &= andMode;
642 *theMode |= orMode; 646 *theMode |= orMode;
643 return( TRUE); 647 return (TRUE);
644 } 648 }
645 break; 649 break;
646 } 650 }
647 switch ( type ) { 651 switch (type) {
648 case '=': 652 case '=':
649 andMode &= ~(groups); 653 andMode &= ~(groups);
650 /* fall through */ 654 /* fall through */
@@ -656,14 +660,14 @@ parse_mode( const char* s, mode_t* theMode)
656 orMode &= andMode; 660 orMode &= andMode;
657 break; 661 break;
658 } 662 }
659 } while ( c == ',' ); 663 } while (c == ',');
660 *theMode &= andMode; 664 *theMode &= andMode;
661 *theMode |= orMode; 665 *theMode |= orMode;
662 return (TRUE); 666 return (TRUE);
663} 667}
664 668
665 669
666#endif /* BB_CHMOD_CHOWN_CHGRP || BB_MKDIR */ 670#endif /* BB_CHMOD_CHOWN_CHGRP || BB_MKDIR */
667 671
668 672
669 673
@@ -676,82 +680,77 @@ parse_mode( const char* s, mode_t* theMode)
676/* Use this to avoid needing the glibc NSS stuff 680/* Use this to avoid needing the glibc NSS stuff
677 * This uses storage buf to hold things. 681 * This uses storage buf to hold things.
678 * */ 682 * */
679uid_t 683uid_t my_getid(const char *filename, char *name, uid_t id)
680my_getid(const char *filename, char *name, uid_t id)
681{ 684{
682 FILE *file; 685 FILE *file;
683 char *rname, *start, *end, buf[128]; 686 char *rname, *start, *end, buf[128];
684 uid_t rid; 687 uid_t rid;
685 688
686 file=fopen(filename,"r"); 689 file = fopen(filename, "r");
687 if (file == NULL) { 690 if (file == NULL) {
688 perror(filename); 691 perror(filename);
689 return (-1); 692 return (-1);
690 } 693 }
691 694
692 while (fgets (buf, 128, file) != NULL) { 695 while (fgets(buf, 128, file) != NULL) {
693 if (buf[0] == '#') 696 if (buf[0] == '#')
694 continue; 697 continue;
695 698
696 start = buf; 699 start = buf;
697 end = strchr (start, ':'); 700 end = strchr(start, ':');
698 if (end == NULL) 701 if (end == NULL)
699 continue; 702 continue;
700 *end = '\0'; 703 *end = '\0';
701 rname = start; 704 rname = start;
702 705
703 start = end + 1; 706 start = end + 1;
704 end = strchr (start, ':'); 707 end = strchr(start, ':');
705 if (end == NULL) 708 if (end == NULL)
706 continue; 709 continue;
707 710
708 start = end + 1; 711 start = end + 1;
709 rid = (uid_t) strtol (start, &end, 10); 712 rid = (uid_t) strtol(start, &end, 10);
710 if (end == start) 713 if (end == start)
711 continue; 714 continue;
712 715
713 if (name) { 716 if (name) {
714 if (0 == strcmp(rname, name)) { 717 if (0 == strcmp(rname, name)) {
715 fclose( file); 718 fclose(file);
716 return( rid); 719 return (rid);
717 } 720 }
718 } 721 }
719 if ( id != -1 && id == rid ) { 722 if (id != -1 && id == rid) {
720 strncpy(name, rname, 8); 723 strncpy(name, rname, 8);
721 fclose( file); 724 fclose(file);
722 return( TRUE); 725 return (TRUE);
723 } 726 }
724 } 727 }
725 fclose(file); 728 fclose(file);
726 return (-1); 729 return (-1);
727} 730}
728 731
729uid_t 732uid_t my_getpwnam(char *name)
730my_getpwnam(char *name)
731{ 733{
732 return my_getid("/etc/passwd", name, -1); 734 return my_getid("/etc/passwd", name, -1);
733} 735}
734 736
735gid_t 737gid_t my_getgrnam(char *name)
736my_getgrnam(char *name)
737{ 738{
738 return my_getid("/etc/group", name, -1); 739 return my_getid("/etc/group", name, -1);
739} 740}
740 741
741void 742void my_getpwuid(char *name, uid_t uid)
742my_getpwuid(char* name, uid_t uid)
743{ 743{
744 my_getid("/etc/passwd", name, uid); 744 my_getid("/etc/passwd", name, uid);
745} 745}
746 746
747void 747void my_getgrgid(char *group, gid_t gid)
748my_getgrgid(char* group, gid_t gid)
749{ 748{
750 my_getid("/etc/group", group, gid); 749 my_getid("/etc/group", group, gid);
751} 750}
752 751
753 752
754#endif /* BB_CHMOD_CHOWN_CHGRP || BB_PS */ 753#endif /* BB_CHMOD_CHOWN_CHGRP || BB_PS */
755 754
756 755
757 756
@@ -762,43 +761,42 @@ my_getgrgid(char* group, gid_t gid)
762#include <linux/kd.h> 761#include <linux/kd.h>
763#include <sys/ioctl.h> 762#include <sys/ioctl.h>
764 763
765int is_a_console(int fd) 764int is_a_console(int fd)
766{ 765{
767 char arg; 766 char arg;
768 767
769 arg = 0; 768 arg = 0;
770 return (ioctl(fd, KDGKBTYPE, &arg) == 0 769 return (ioctl(fd, KDGKBTYPE, &arg) == 0
771 && ((arg == KB_101) || (arg == KB_84))); 770 && ((arg == KB_101) || (arg == KB_84)));
772} 771}
773 772
774static int open_a_console(char *fnam) 773static int open_a_console(char *fnam)
775{ 774{
776 int fd; 775 int fd;
777 776
778 /* try read-only */ 777 /* try read-only */
779 fd = open(fnam, O_RDWR); 778 fd = open(fnam, O_RDWR);
780 779
781 /* if failed, try read-only */ 780 /* if failed, try read-only */
782 if (fd < 0 && errno == EACCES) 781 if (fd < 0 && errno == EACCES)
783 fd = open(fnam, O_RDONLY); 782 fd = open(fnam, O_RDONLY);
784 783
785 /* if failed, try write-only */ 784 /* if failed, try write-only */
786 if (fd < 0 && errno == EACCES) 785 if (fd < 0 && errno == EACCES)
787 fd = open(fnam, O_WRONLY); 786 fd = open(fnam, O_WRONLY);
788 787
789 /* if failed, fail */ 788 /* if failed, fail */
790 if (fd < 0) 789 if (fd < 0)
791 return -1; 790 return -1;
792 791
793 /* if not a console, fail */ 792 /* if not a console, fail */
794 if (! is_a_console(fd)) 793 if (!is_a_console(fd)) {
795 { 794 close(fd);
796 close(fd); 795 return -1;
797 return -1; 796 }
798 } 797
799 798 /* success */
800 /* success */ 799 return fd;
801 return fd;
802} 800}
803 801
804/* 802/*
@@ -809,59 +807,59 @@ static int open_a_console(char *fnam)
809 * if tty_name is non-NULL, try this one instead. 807 * if tty_name is non-NULL, try this one instead.
810 */ 808 */
811 809
812int get_console_fd(char* tty_name) 810int get_console_fd(char *tty_name)
813{ 811{
814 int fd; 812 int fd;
815 813
816 if (tty_name) 814 if (tty_name) {
817 { 815 if (-1 == (fd = open_a_console(tty_name)))
818 if (-1 == (fd = open_a_console(tty_name))) 816 return -1;
819 return -1; 817 else
820 else 818 return fd;
821 return fd; 819 }
822 } 820
823 821 fd = open_a_console("/dev/tty");
824 fd = open_a_console("/dev/tty"); 822 if (fd >= 0)
825 if (fd >= 0) 823 return fd;
826 return fd; 824
827 825 fd = open_a_console("/dev/tty0");
828 fd = open_a_console("/dev/tty0"); 826 if (fd >= 0)
829 if (fd >= 0) 827 return fd;
830 return fd; 828
831 829 fd = open_a_console("/dev/console");
832 fd = open_a_console("/dev/console"); 830 if (fd >= 0)
833 if (fd >= 0) 831 return fd;
834 return fd; 832
835 833 for (fd = 0; fd < 3; fd++)
836 for (fd = 0; fd < 3; fd++) 834 if (is_a_console(fd))
837 if (is_a_console(fd)) 835 return fd;
838 return fd; 836
839 837 fprintf(stderr,
840 fprintf(stderr, 838 "Couldnt get a file descriptor referring to the console\n");
841 "Couldnt get a file descriptor referring to the console\n"); 839 return -1; /* total failure */
842 return -1; /* total failure */
843} 840}
844 841
845 842
846#endif /* BB_CHVT || BB_DEALLOCVT */ 843#endif /* BB_CHVT || BB_DEALLOCVT */
847 844
848 845
849#if !defined BB_REGEXP && (defined BB_GREP || defined BB_SED) 846#if !defined BB_REGEXP && (defined BB_GREP || defined BB_SED)
850 847
851/* Do a case insensitive strstr() */ 848/* Do a case insensitive strstr() */
852char* stristr(char *haystack, const char *needle) 849char *stristr(char *haystack, const char *needle)
853{ 850{
854 int len = strlen( needle ); 851 int len = strlen(needle);
855 while( *haystack ) {
856 if( !strncasecmp( haystack, needle, len ) )
857 break;
858 haystack++;
859 }
860 852
861 if( !(*haystack) ) 853 while (*haystack) {
862 haystack = NULL; 854 if (!strncasecmp(haystack, needle, len))
855 break;
856 haystack++;
857 }
863 858
864 return haystack; 859 if (!(*haystack))
860 haystack = NULL;
861
862 return haystack;
865} 863}
866 864
867/* This tries to find a needle in a haystack, but does so by 865/* This tries to find a needle in a haystack, but does so by
@@ -873,56 +871,61 @@ char* stristr(char *haystack, const char *needle)
873extern int find_match(char *haystack, char *needle, int ignoreCase) 871extern int find_match(char *haystack, char *needle, int ignoreCase)
874{ 872{
875 873
876 if (ignoreCase == FALSE) 874 if (ignoreCase == FALSE)
877 haystack = strstr (haystack, needle); 875 haystack = strstr(haystack, needle);
878 else 876 else
879 haystack = stristr (haystack, needle); 877 haystack = stristr(haystack, needle);
880 if (haystack == NULL) 878 if (haystack == NULL)
881 return FALSE; 879 return FALSE;
882 return TRUE; 880 return TRUE;
883} 881}
884 882
885 883
886/* This performs substitutions after a string match has been found. */ 884/* This performs substitutions after a string match has been found. */
887extern int replace_match(char *haystack, char *needle, char *newNeedle, int ignoreCase) 885extern int replace_match(char *haystack, char *needle, char *newNeedle,
886 int ignoreCase)
888{ 887{
889 int foundOne=0; 888 int foundOne = 0;
890 char *where, *slider, *slider1, *oldhayStack; 889 char *where, *slider, *slider1, *oldhayStack;
891 890
892 if (ignoreCase == FALSE) 891 if (ignoreCase == FALSE)
893 where = strstr (haystack, needle); 892 where = strstr(haystack, needle);
894 else 893 else
895 where = stristr (haystack, needle); 894 where = stristr(haystack, needle);
896 895
897 if (strcmp(needle, newNeedle)==0) 896 if (strcmp(needle, newNeedle) == 0)
898 return FALSE; 897 return FALSE;
899 898
900 oldhayStack = (char*)malloc((unsigned)(strlen(haystack))); 899 oldhayStack = (char *) malloc((unsigned) (strlen(haystack)));
901 while(where!=NULL) { 900 while (where != NULL) {
902 foundOne++; 901 foundOne++;
903 strcpy(oldhayStack, haystack); 902 strcpy(oldhayStack, haystack);
904#if 0 903#if 0
905 if ( strlen(newNeedle) > strlen(needle)) { 904 if (strlen(newNeedle) > strlen(needle)) {
906 haystack = (char *)realloc(haystack, (unsigned)(strlen(haystack) - 905 haystack =
907 strlen(needle) + strlen(newNeedle))); 906 (char *) realloc(haystack,
908 } 907 (unsigned) (strlen(haystack) -
908 strlen(needle) +
909 strlen(newNeedle)));
910 }
909#endif 911#endif
910 for(slider=haystack,slider1=oldhayStack;slider!=where;slider++,slider1++); 912 for (slider = haystack, slider1 = oldhayStack; slider != where;
911 *slider=0; 913 slider++, slider1++);
912 haystack=strcat(haystack, newNeedle); 914 *slider = 0;
913 slider1+=strlen(needle); 915 haystack = strcat(haystack, newNeedle);
914 haystack = strcat(haystack, slider1); 916 slider1 += strlen(needle);
915 where = strstr (slider, needle); 917 haystack = strcat(haystack, slider1);
916 } 918 where = strstr(slider, needle);
917 free( oldhayStack); 919 }
918 920 free(oldhayStack);
919 if (foundOne > 0) 921
920 return TRUE; 922 if (foundOne > 0)
921 else 923 return TRUE;
922 return FALSE; 924 else
925 return FALSE;
923} 926}
924 927
925#endif /* ! BB_REGEXP && (BB_GREP || BB_SED) */ 928#endif /* ! BB_REGEXP && (BB_GREP || BB_SED) */
926 929
927 930
928#if defined BB_FIND 931#if defined BB_FIND
@@ -940,91 +943,84 @@ extern int replace_match(char *haystack, char *needle, char *newNeedle, int igno
940 * provided that this copyright notice remains intact. 943 * provided that this copyright notice remains intact.
941 * Permission to distribute this code under the GPL has been granted. 944 * Permission to distribute this code under the GPL has been granted.
942 */ 945 */
943extern int 946extern int check_wildcard_match(const char *text, const char *pattern)
944check_wildcard_match(const char* text, const char* pattern)
945{ 947{
946 const char* retryPat; 948 const char *retryPat;
947 const char* retryText; 949 const char *retryText;
948 int ch; 950 int ch;
949 int found; 951 int found;
950
951 retryPat = NULL;
952 retryText = NULL;
953
954 while (*text || *pattern)
955 {
956 ch = *pattern++;
957
958 switch (ch)
959 {
960 case '*':
961 retryPat = pattern;
962 retryText = text;
963 break;
964 952
965 case '[': 953 retryPat = NULL;
966 found = FALSE; 954 retryText = NULL;
967 955
968 while ((ch = *pattern++) != ']') 956 while (*text || *pattern) {
969 { 957 ch = *pattern++;
970 if (ch == '\\')
971 ch = *pattern++;
972 958
973 if (ch == '\0') 959 switch (ch) {
974 return FALSE; 960 case '*':
961 retryPat = pattern;
962 retryText = text;
963 break;
975 964
976 if (*text == ch) 965 case '[':
977 found = TRUE; 966 found = FALSE;
978 }
979 967
980 //if (!found) 968 while ((ch = *pattern++) != ']') {
981 if (found==TRUE) 969 if (ch == '\\')
982 { 970 ch = *pattern++;
983 pattern = retryPat; 971
984 text = ++retryText; 972 if (ch == '\0')
985 } 973 return FALSE;
986 974
987 /* fall into next case */ 975 if (*text == ch)
976 found = TRUE;
977 }
988 978
989 case '?': 979 //if (!found)
990 if (*text++ == '\0') 980 if (found == TRUE) {
991 return FALSE; 981 pattern = retryPat;
982 text = ++retryText;
983 }
992 984
993 break; 985 /* fall into next case */
994 986
995 case '\\': 987 case '?':
996 ch = *pattern++; 988 if (*text++ == '\0')
989 return FALSE;
997 990
998 if (ch == '\0') 991 break;
999 return FALSE; 992
993 case '\\':
994 ch = *pattern++;
1000 995
1001 /* fall into next case */ 996 if (ch == '\0')
997 return FALSE;
1002 998
1003 default: 999 /* fall into next case */
1004 if (*text == ch)
1005 {
1006 if (*text)
1007 text++;
1008 break;
1009 }
1010 1000
1011 if (*text) 1001 default:
1012 { 1002 if (*text == ch) {
1013 pattern = retryPat; 1003 if (*text)
1014 text = ++retryText; 1004 text++;
1015 break; 1005 break;
1006 }
1007
1008 if (*text) {
1009 pattern = retryPat;
1010 text = ++retryText;
1011 break;
1012 }
1013
1014 return FALSE;
1016 } 1015 }
1017 1016
1018 return FALSE; 1017 if (pattern == NULL)
1018 return FALSE;
1019 } 1019 }
1020 1020
1021 if (pattern == NULL) 1021 return TRUE;
1022 return FALSE;
1023 }
1024
1025 return TRUE;
1026} 1022}
1027#endif /* BB_FIND */ 1023#endif /* BB_FIND */
1028 1024
1029 1025
1030 1026
@@ -1039,36 +1035,36 @@ check_wildcard_match(const char* text, const char* pattern)
1039 */ 1035 */
1040extern struct mntent *findMountPoint(const char *name, const char *table) 1036extern struct mntent *findMountPoint(const char *name, const char *table)
1041{ 1037{
1042 struct stat s; 1038 struct stat s;
1043 dev_t mountDevice; 1039 dev_t mountDevice;
1044 FILE *mountTable; 1040 FILE *mountTable;
1045 struct mntent *mountEntry; 1041 struct mntent *mountEntry;
1046 1042
1047 if (stat(name, &s) != 0) 1043 if (stat(name, &s) != 0)
1048 return 0; 1044 return 0;
1049 1045
1050 if ((s.st_mode & S_IFMT) == S_IFBLK) 1046 if ((s.st_mode & S_IFMT) == S_IFBLK)
1051 mountDevice = s.st_rdev; 1047 mountDevice = s.st_rdev;
1052 else 1048 else
1053 mountDevice = s.st_dev; 1049 mountDevice = s.st_dev;
1054 1050
1055 1051
1056 if ((mountTable = setmntent(table, "r")) == 0) 1052 if ((mountTable = setmntent(table, "r")) == 0)
1057 return 0; 1053 return 0;
1058 1054
1059 while ((mountEntry = getmntent(mountTable)) != 0) { 1055 while ((mountEntry = getmntent(mountTable)) != 0) {
1060 if (strcmp(name, mountEntry->mnt_dir) == 0 1056 if (strcmp(name, mountEntry->mnt_dir) == 0
1061 || strcmp(name, mountEntry->mnt_fsname) == 0) /* String match. */ 1057 || strcmp(name, mountEntry->mnt_fsname) == 0) /* String match. */
1062 break; 1058 break;
1063 if (stat(mountEntry->mnt_fsname, &s) == 0 && s.st_rdev == mountDevice) /* Match the device. */ 1059 if (stat(mountEntry->mnt_fsname, &s) == 0 && s.st_rdev == mountDevice) /* Match the device. */
1064 break; 1060 break;
1065 if (stat(mountEntry->mnt_dir, &s) == 0 && s.st_dev == mountDevice) /* Match the directory's mount point. */ 1061 if (stat(mountEntry->mnt_dir, &s) == 0 && s.st_dev == mountDevice) /* Match the directory's mount point. */
1066 break; 1062 break;
1067 } 1063 }
1068 endmntent(mountTable); 1064 endmntent(mountTable);
1069 return mountEntry; 1065 return mountEntry;
1070} 1066}
1071#endif /* BB_DF || BB_MTAB */ 1067#endif /* BB_DF || BB_MTAB */
1072 1068
1073 1069
1074 1070
@@ -1077,74 +1073,74 @@ extern struct mntent *findMountPoint(const char *name, const char *table)
1077 * Read a number with a possible multiplier. 1073 * Read a number with a possible multiplier.
1078 * Returns -1 if the number format is illegal. 1074 * Returns -1 if the number format is illegal.
1079 */ 1075 */
1080extern long getNum (const char *cp) 1076extern long getNum(const char *cp)
1081{ 1077{
1082 long value; 1078 long value;
1083 1079
1084 if (!isDecimal (*cp)) 1080 if (!isDecimal(*cp))
1085 return -1; 1081 return -1;
1086 1082
1087 value = 0; 1083 value = 0;
1088 1084
1089 while (isDecimal (*cp)) 1085 while (isDecimal(*cp))
1090 value = value * 10 + *cp++ - '0'; 1086 value = value * 10 + *cp++ - '0';
1091 1087
1092 switch (*cp++) { 1088 switch (*cp++) {
1093 case 'M': 1089 case 'M':
1094 case 'm': /* `tail' uses it traditionally */ 1090 case 'm': /* `tail' uses it traditionally */
1095 value *= 1048576; 1091 value *= 1048576;
1096 break; 1092 break;
1097 1093
1098 case 'k': 1094 case 'k':
1099 value *= 1024; 1095 value *= 1024;
1100 break; 1096 break;
1101 1097
1102 case 'b': 1098 case 'b':
1103 value *= 512; 1099 value *= 512;
1104 break; 1100 break;
1105 1101
1106 case 'w': 1102 case 'w':
1107 value *= 2; 1103 value *= 2;
1108 break; 1104 break;
1109 1105
1110 case '\0': 1106 case '\0':
1111 return value; 1107 return value;
1112 1108
1113 default: 1109 default:
1114 return -1; 1110 return -1;
1115 } 1111 }
1116 1112
1117 if (*cp) 1113 if (*cp)
1118 return -1; 1114 return -1;
1119 1115
1120 return value; 1116 return value;
1121} 1117}
1122#endif /* BB_DD || BB_TAIL */ 1118#endif /* BB_DD || BB_TAIL */
1123 1119
1124 1120
1125#if defined BB_INIT || defined BB_SYSLOGD 1121#if defined BB_INIT || defined BB_SYSLOGD
1126/* try to open up the specified device */ 1122/* try to open up the specified device */
1127extern int device_open(char *device, int mode) 1123extern int device_open(char *device, int mode)
1128{ 1124{
1129 int m, f, fd = -1; 1125 int m, f, fd = -1;
1130 1126
1131 m = mode | O_NONBLOCK; 1127 m = mode | O_NONBLOCK;
1132 1128
1133 /* Retry up to 5 times */ 1129 /* Retry up to 5 times */
1134 for (f = 0; f < 5; f++) 1130 for (f = 0; f < 5; f++)
1135 if ((fd = open(device, m, 0600)) >= 0) 1131 if ((fd = open(device, m, 0600)) >= 0)
1136 break; 1132 break;
1137 if (fd < 0) 1133 if (fd < 0)
1134 return fd;
1135 /* Reset original flags. */
1136 if (m != mode)
1137 fcntl(fd, F_SETFL, mode);
1138 return fd; 1138 return fd;
1139 /* Reset original flags. */
1140 if (m != mode)
1141 fcntl(fd, F_SETFL, mode);
1142 return fd;
1143} 1139}
1144#endif /* BB_INIT BB_SYSLOGD */ 1140#endif /* BB_INIT BB_SYSLOGD */
1145 1141
1146 1142
1147#if defined BB_INIT || defined BB_HALT || defined BB_REBOOT 1143#if defined BB_INIT || defined BB_HALT || defined BB_REBOOT
1148 1144
1149#if ! defined BB_FEATURE_USE_PROCFS 1145#if ! defined BB_FEATURE_USE_PROCFS
1150#error Sorry, I depend on the /proc filesystem right now. 1146#error Sorry, I depend on the /proc filesystem right now.
@@ -1158,101 +1154,103 @@ extern int device_open(char *device, int mode)
1158 * 0 failure 1154 * 0 failure
1159 * pid when init's pid is found. 1155 * pid when init's pid is found.
1160 */ 1156 */
1161extern pid_t 1157extern pid_t findInitPid()
1162findInitPid()
1163{ 1158{
1164 pid_t init_pid; 1159 pid_t init_pid;
1165 char filename[256]; 1160 char filename[256];
1166 char buffer[256]; 1161 char buffer[256];
1167 1162
1168 /* no need to opendir ;) */ 1163 /* no need to opendir ;) */
1169 for (init_pid = 1; init_pid < 65536; init_pid++) { 1164 for (init_pid = 1; init_pid < 65536; init_pid++) {
1170 FILE *status; 1165 FILE *status;
1171 1166
1172 sprintf(filename, "/proc/%d/status", init_pid); 1167 sprintf(filename, "/proc/%d/status", init_pid);
1173 status = fopen(filename, "r"); 1168 status = fopen(filename, "r");
1174 if (!status) { continue; } 1169 if (!status) {
1175 fgets(buffer, 256, status); 1170 continue;
1176 fclose(status); 1171 }
1177 1172 fgets(buffer, 256, status);
1178 if ( (strstr(buffer, "init\n") != NULL )) { 1173 fclose(status);
1179 return init_pid; 1174
1175 if ((strstr(buffer, "init\n") != NULL)) {
1176 return init_pid;
1177 }
1180 } 1178 }
1181 } 1179 return 0;
1182 return 0;
1183} 1180}
1184#endif /* BB_INIT || BB_HALT || BB_REBOOT */ 1181#endif /* BB_INIT || BB_HALT || BB_REBOOT */
1185 1182
1186#if defined BB_GUNZIP \ 1183#if defined BB_GUNZIP \
1187 || defined BB_GZIP \ 1184 || defined BB_GZIP \
1188 || defined BB_PRINTF \ 1185 || defined BB_PRINTF \
1189 || defined BB_TAIL 1186 || defined BB_TAIL
1190extern void *xmalloc (size_t size) 1187extern void *xmalloc(size_t size)
1191{ 1188{
1192 void *cp = malloc (size); 1189 void *cp = malloc(size);
1193 1190
1194 if (cp == NULL) { 1191 if (cp == NULL) {
1195 error("out of memory"); 1192 error("out of memory");
1196 } 1193 }
1197 return cp; 1194 return cp;
1198} 1195}
1199 1196
1200extern void error(char *msg) 1197extern void error(char *msg)
1201{ 1198{
1202 fprintf(stderr, "\n%s\n", msg); 1199 fprintf(stderr, "\n%s\n", msg);
1203 exit(1); 1200 exit(1);
1204} 1201}
1205#endif /* BB_GUNZIP || BB_GZIP || BB_PRINTF || BB_TAIL */ 1202#endif /* BB_GUNZIP || BB_GZIP || BB_PRINTF || BB_TAIL */
1206 1203
1207#if (__GLIBC__ < 2) && (defined BB_SYSLOGD || defined BB_INIT) 1204#if (__GLIBC__ < 2) && (defined BB_SYSLOGD || defined BB_INIT)
1208extern int vdprintf(int d, const char *format, va_list ap) 1205extern int vdprintf(int d, const char *format, va_list ap)
1209{ 1206{
1210 char buf[BUF_SIZE]; 1207 char buf[BUF_SIZE];
1211 int len; 1208 int len;
1212 1209
1213 len = vsprintf(buf, format, ap); 1210 len = vsprintf(buf, format, ap);
1214 return write(d, buf, len); 1211 return write(d, buf, len);
1215} 1212}
1216#endif /* BB_SYSLOGD */ 1213#endif /* BB_SYSLOGD */
1217 1214
1218#if defined BB_FEATURE_MOUNT_LOOP 1215#if defined BB_FEATURE_MOUNT_LOOP
1219extern int del_loop(const char *device) 1216extern int del_loop(const char *device)
1220{ 1217{
1221 int fd; 1218 int fd;
1222 1219
1223 if ((fd = open(device, O_RDONLY)) < 0) { 1220 if ((fd = open(device, O_RDONLY)) < 0) {
1224 perror(device); 1221 perror(device);
1225 return( FALSE); 1222 return (FALSE);
1226 } 1223 }
1227 if (ioctl(fd, LOOP_CLR_FD, 0) < 0) { 1224 if (ioctl(fd, LOOP_CLR_FD, 0) < 0) {
1228 perror("ioctl: LOOP_CLR_FD"); 1225 perror("ioctl: LOOP_CLR_FD");
1229 return( FALSE); 1226 return (FALSE);
1230 } 1227 }
1231 close(fd); 1228 close(fd);
1232 return( TRUE); 1229 return (TRUE);
1233} 1230}
1234 1231
1235extern int set_loop(const char *device, const char *file, int offset, int *loopro) 1232extern int set_loop(const char *device, const char *file, int offset,
1233 int *loopro)
1236{ 1234{
1237 struct loop_info loopinfo; 1235 struct loop_info loopinfo;
1238 int fd, ffd, mode; 1236 int fd, ffd, mode;
1239 1237
1240 mode = *loopro ? O_RDONLY : O_RDWR; 1238 mode = *loopro ? O_RDONLY : O_RDWR;
1241 if ((ffd = open (file, mode)) < 0 && !*loopro 1239 if ((ffd = open(file, mode)) < 0 && !*loopro
1242 && (errno != EROFS || (ffd = open (file, mode = O_RDONLY)) < 0)) { 1240 && (errno != EROFS || (ffd = open(file, mode = O_RDONLY)) < 0)) {
1243 perror (file); 1241 perror(file);
1244 return 1; 1242 return 1;
1245 } 1243 }
1246 if ((fd = open (device, mode)) < 0) { 1244 if ((fd = open(device, mode)) < 0) {
1247 close(ffd); 1245 close(ffd);
1248 perror (device); 1246 perror(device);
1249 return 1; 1247 return 1;
1250 } 1248 }
1251 *loopro = (mode == O_RDONLY); 1249 *loopro = (mode == O_RDONLY);
1252 1250
1253 memset(&loopinfo, 0, sizeof(loopinfo)); 1251 memset(&loopinfo, 0, sizeof(loopinfo));
1254 strncpy(loopinfo.lo_name, file, LO_NAME_SIZE); 1252 strncpy(loopinfo.lo_name, file, LO_NAME_SIZE);
1255 loopinfo.lo_name[LO_NAME_SIZE-1] = 0; 1253 loopinfo.lo_name[LO_NAME_SIZE - 1] = 0;
1256 1254
1257 loopinfo.lo_offset = offset; 1255 loopinfo.lo_offset = offset;
1258 1256
@@ -1275,30 +1273,30 @@ extern int set_loop(const char *device, const char *file, int offset, int *loopr
1275 return 0; 1273 return 0;
1276} 1274}
1277 1275
1278extern char *find_unused_loop_device (void) 1276extern char *find_unused_loop_device(void)
1279{ 1277{
1280 char dev[20]; 1278 char dev[20];
1281 int i, fd; 1279 int i, fd;
1282 struct stat statbuf; 1280 struct stat statbuf;
1283 struct loop_info loopinfo; 1281 struct loop_info loopinfo;
1284 1282
1285 for(i = 0; i <= 7; i++) { 1283 for (i = 0; i <= 7; i++) {
1286 sprintf(dev, "/dev/loop%d", i); 1284 sprintf(dev, "/dev/loop%d", i);
1287 if (stat (dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) { 1285 if (stat(dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) {
1288 if ((fd = open (dev, O_RDONLY)) >= 0) { 1286 if ((fd = open(dev, O_RDONLY)) >= 0) {
1289 if(ioctl (fd, LOOP_GET_STATUS, &loopinfo) == -1) { 1287 if (ioctl(fd, LOOP_GET_STATUS, &loopinfo) == -1) {
1290 if (errno == ENXIO) { /* probably free */ 1288 if (errno == ENXIO) { /* probably free */
1291 close (fd); 1289 close(fd);
1292 return strdup(dev); 1290 return strdup(dev);
1291 }
1292 }
1293 close(fd);
1293 } 1294 }
1294 }
1295 close (fd);
1296 } 1295 }
1297 }
1298 } 1296 }
1299 return NULL; 1297 return NULL;
1300} 1298}
1301#endif /* BB_FEATURE_MOUNT_LOOP */ 1299#endif /* BB_FEATURE_MOUNT_LOOP */
1302 1300
1303 1301
1304/* END CODE */ 1302/* END CODE */