diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-03-10 16:58:49 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-03-10 16:58:49 +0000 |
commit | 49622d784672bf2f7b2fe80589714cdef5adde0c (patch) | |
tree | 892bb79b0ef031d729e688d6be4950f6d17f13b9 /coreutils/stat.c | |
parent | 4eb8b936cb0aeb27c3e12f9a93fc43aa1e9668f5 (diff) | |
download | busybox-w32-49622d784672bf2f7b2fe80589714cdef5adde0c.tar.gz busybox-w32-49622d784672bf2f7b2fe80589714cdef5adde0c.tar.bz2 busybox-w32-49622d784672bf2f7b2fe80589714cdef5adde0c.zip |
selinux support by Yuichi Nakamura <ynakam@hitachisoft.jp> (HitachiSoft)
Diffstat (limited to 'coreutils/stat.c')
-rw-r--r-- | coreutils/stat.c | 169 |
1 files changed, 153 insertions, 16 deletions
diff --git a/coreutils/stat.c b/coreutils/stat.c index 20ade9472..37a924057 100644 --- a/coreutils/stat.c +++ b/coreutils/stat.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation. | 5 | * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation. |
6 | * Copyright (C) 2005 by Erik Andersen <andersen@codepoet.org> | 6 | * Copyright (C) 2005 by Erik Andersen <andersen@codepoet.org> |
7 | * Copyright (C) 2005 by Mike Frysinger <vapier@gentoo.org> | 7 | * Copyright (C) 2005 by Mike Frysinger <vapier@gentoo.org> |
8 | * Copyright (C) 2006 by Yoshinori Sato <ysato@users.sourceforge.jp> | ||
8 | * | 9 | * |
9 | * Written by Michael Meskes | 10 | * Written by Michael Meskes |
10 | * Taken from coreutils and turned into a busybox applet by Mike Frysinger | 11 | * Taken from coreutils and turned into a busybox applet by Mike Frysinger |
@@ -17,6 +18,7 @@ | |||
17 | /* vars to control behavior */ | 18 | /* vars to control behavior */ |
18 | #define OPT_TERSE 2 | 19 | #define OPT_TERSE 2 |
19 | #define OPT_DEREFERENCE 4 | 20 | #define OPT_DEREFERENCE 4 |
21 | #define OPT_SELINUX 8 | ||
20 | static long flags; | 22 | static long flags; |
21 | 23 | ||
22 | static char const *file_type(struct stat const *st) | 24 | static char const *file_type(struct stat const *st) |
@@ -114,7 +116,8 @@ static char const *human_fstype(long f_type) | |||
114 | #ifdef CONFIG_FEATURE_STAT_FORMAT | 116 | #ifdef CONFIG_FEATURE_STAT_FORMAT |
115 | /* print statfs info */ | 117 | /* print statfs info */ |
116 | static void print_statfs(char *pformat, size_t buf_len, char m, | 118 | static void print_statfs(char *pformat, size_t buf_len, char m, |
117 | char const *filename, void const *data) | 119 | char const *filename, void const *data |
120 | USE_SELINUX(,security_context_t scontext) ) | ||
118 | { | 121 | { |
119 | struct statfs const *statfsbuf = data; | 122 | struct statfs const *statfsbuf = data; |
120 | 123 | ||
@@ -164,6 +167,14 @@ static void print_statfs(char *pformat, size_t buf_len, char m, | |||
164 | strncat(pformat, "jd", buf_len); | 167 | strncat(pformat, "jd", buf_len); |
165 | printf(pformat, (intmax_t) (statfsbuf->f_ffree)); | 168 | printf(pformat, (intmax_t) (statfsbuf->f_ffree)); |
166 | break; | 169 | break; |
170 | #if ENABLE_SELINUX | ||
171 | case 'C': | ||
172 | if (flags & OPT_SELINUX) { | ||
173 | strncat(pformat, "s", buf_len); | ||
174 | printf(scontext); | ||
175 | } | ||
176 | break; | ||
177 | #endif | ||
167 | default: | 178 | default: |
168 | strncat(pformat, "c", buf_len); | 179 | strncat(pformat, "c", buf_len); |
169 | printf(pformat, m); | 180 | printf(pformat, m); |
@@ -173,7 +184,8 @@ static void print_statfs(char *pformat, size_t buf_len, char m, | |||
173 | 184 | ||
174 | /* print stat info */ | 185 | /* print stat info */ |
175 | static void print_stat(char *pformat, size_t buf_len, char m, | 186 | static void print_stat(char *pformat, size_t buf_len, char m, |
176 | char const *filename, void const *data) | 187 | char const *filename, void const *data |
188 | USE_SELINUX(, security_context_t scontext)) | ||
177 | { | 189 | { |
178 | #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) | 190 | #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) |
179 | struct stat *statbuf = (struct stat *) data; | 191 | struct stat *statbuf = (struct stat *) data; |
@@ -301,6 +313,14 @@ static void print_stat(char *pformat, size_t buf_len, char m, | |||
301 | strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len); | 313 | strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len); |
302 | printf(pformat, (unsigned long int) statbuf->st_ctime); | 314 | printf(pformat, (unsigned long int) statbuf->st_ctime); |
303 | break; | 315 | break; |
316 | #if ENABLE_SELINUX | ||
317 | case 'C': | ||
318 | if (flags & OPT_SELINUX) { | ||
319 | strncat(pformat, "s", buf_len); | ||
320 | printf(pformat, scontext); | ||
321 | } | ||
322 | break; | ||
323 | #endif | ||
304 | default: | 324 | default: |
305 | strncat(pformat, "c", buf_len); | 325 | strncat(pformat, "c", buf_len); |
306 | printf(pformat, m); | 326 | printf(pformat, m); |
@@ -309,8 +329,9 @@ static void print_stat(char *pformat, size_t buf_len, char m, | |||
309 | } | 329 | } |
310 | 330 | ||
311 | static void print_it(char const *masterformat, char const *filename, | 331 | static void print_it(char const *masterformat, char const *filename, |
312 | void (*print_func) (char *, size_t, char, char const *, void const *), | 332 | void (*print_func) (char *, size_t, char, char const *, void const * |
313 | void const *data) | 333 | USE_SELINUX(, security_context_t scontext)), |
334 | void const *data USE_SELINUX(, security_context_t scontext) ) | ||
314 | { | 335 | { |
315 | char *b; | 336 | char *b; |
316 | 337 | ||
@@ -350,7 +371,7 @@ static void print_it(char const *masterformat, char const *filename, | |||
350 | putchar('%'); | 371 | putchar('%'); |
351 | break; | 372 | break; |
352 | default: | 373 | default: |
353 | print_func(dest, n_alloc, *p, filename, data); | 374 | print_func(dest, n_alloc, *p, filename, data USE_SELINUX(,scontext)); |
354 | break; | 375 | break; |
355 | } | 376 | } |
356 | } | 377 | } |
@@ -365,6 +386,16 @@ static int do_statfs(char const *filename, char const *format) | |||
365 | { | 386 | { |
366 | struct statfs statfsbuf; | 387 | struct statfs statfsbuf; |
367 | 388 | ||
389 | #if ENABLE_SELINUX | ||
390 | security_context_t scontext = NULL; | ||
391 | if (flags & OPT_SELINUX) { | ||
392 | if ((flags & OPT_DEREFERENCE ? lgetfilecon(filename, scontext): | ||
393 | getfilecon(filename, scontext))< 0) { | ||
394 | bb_perror_msg(filename); | ||
395 | return 0; | ||
396 | } | ||
397 | } | ||
398 | #endif | ||
368 | if (statfs(filename, &statfsbuf) != 0) { | 399 | if (statfs(filename, &statfsbuf) != 0) { |
369 | bb_perror_msg("cannot read file system information for '%s'", filename); | 400 | bb_perror_msg("cannot read file system information for '%s'", filename); |
370 | return 0; | 401 | return 0; |
@@ -372,6 +403,7 @@ static int do_statfs(char const *filename, char const *format) | |||
372 | 403 | ||
373 | #ifdef CONFIG_FEATURE_STAT_FORMAT | 404 | #ifdef CONFIG_FEATURE_STAT_FORMAT |
374 | if (format == NULL) | 405 | if (format == NULL) |
406 | #ifndef ENABLE_SELINUX | ||
375 | format = (flags & OPT_TERSE | 407 | format = (flags & OPT_TERSE |
376 | ? "%n %i %l %t %s %b %f %a %c %d\n" | 408 | ? "%n %i %l %t %s %b %f %a %c %d\n" |
377 | : " File: \"%n\"\n" | 409 | : " File: \"%n\"\n" |
@@ -379,9 +411,27 @@ static int do_statfs(char const *filename, char const *format) | |||
379 | "Block size: %-10s\n" | 411 | "Block size: %-10s\n" |
380 | "Blocks: Total: %-10b Free: %-10f Available: %a\n" | 412 | "Blocks: Total: %-10b Free: %-10f Available: %a\n" |
381 | "Inodes: Total: %-10c Free: %d"); | 413 | "Inodes: Total: %-10c Free: %d"); |
382 | print_it(format, filename, print_statfs, &statfsbuf); | 414 | print_it(format, filename, print_statfs, &statfsbuf USE_SELINUX(, scontext)); |
383 | #else | 415 | #else |
384 | 416 | format = (flags & OPT_TERSE | |
417 | ? (flags & OPT_SELINUX ? "%n %i %l %t %s %b %f %a %c %d %C\n": | ||
418 | "%n %i %l %t %s %b %f %a %c %d\n") | ||
419 | : (flags & OPT_SELINUX ? | ||
420 | " File: \"%n\"\n" | ||
421 | " ID: %-8i Namelen: %-7l Type: %T\n" | ||
422 | "Block size: %-10s\n" | ||
423 | "Blocks: Total: %-10b Free: %-10f Available: %a\n" | ||
424 | "Inodes: Total: %-10c Free: %d" | ||
425 | " S_context: %C\n": | ||
426 | " File: \"%n\"\n" | ||
427 | " ID: %-8i Namelen: %-7l Type: %T\n" | ||
428 | "Block size: %-10s\n" | ||
429 | "Blocks: Total: %-10b Free: %-10f Available: %a\n" | ||
430 | "Inodes: Total: %-10c Free: %d\n") | ||
431 | ); | ||
432 | print_it(format, filename, print_statfs, &statfsbuf USE_SELINUX(, scontext)); | ||
433 | #endif /* SELINUX */ | ||
434 | #else /* FEATURE_STAT_FORMAT */ | ||
385 | format = (flags & OPT_TERSE | 435 | format = (flags & OPT_TERSE |
386 | ? "%s %llx %lu " | 436 | ? "%s %llx %lu " |
387 | : " File: \"%s\"\n" | 437 | : " File: \"%s\"\n" |
@@ -396,6 +446,7 @@ static int do_statfs(char const *filename, char const *format) | |||
396 | else | 446 | else |
397 | printf("Type: %s\n", human_fstype(statfsbuf.f_type)); | 447 | printf("Type: %s\n", human_fstype(statfsbuf.f_type)); |
398 | 448 | ||
449 | #if !ENABLE_SELINUX | ||
399 | format = (flags & OPT_TERSE | 450 | format = (flags & OPT_TERSE |
400 | ? "%lu %ld %ld %ld %ld %ld\n" | 451 | ? "%lu %ld %ld %ld %ld %ld\n" |
401 | : "Block size: %-10lu\n" | 452 | : "Block size: %-10lu\n" |
@@ -408,8 +459,31 @@ static int do_statfs(char const *filename, char const *format) | |||
408 | (intmax_t) (statfsbuf.f_bavail), | 459 | (intmax_t) (statfsbuf.f_bavail), |
409 | (intmax_t) (statfsbuf.f_files), | 460 | (intmax_t) (statfsbuf.f_files), |
410 | (intmax_t) (statfsbuf.f_ffree)); | 461 | (intmax_t) (statfsbuf.f_ffree)); |
411 | #endif | 462 | #else |
463 | format = (flags & OPT_TERSE | ||
464 | ? (flags & OPT_SELINUX ? "%lu %ld %ld %ld %ld %ld %C\n": | ||
465 | "%lu %ld %ld %ld %ld %ld\n") | ||
466 | : (flags & OPT_SELINUX ? | ||
467 | "Block size: %-10lu\n" | ||
468 | "Blocks: Total: %-10jd Free: %-10jd Available: %jd\n" | ||
469 | "Inodes: Total: %-10jd Free: %jd" | ||
470 | "S_context: %C\n": | ||
471 | "Block size: %-10lu\n" | ||
472 | "Blocks: Total: %-10jd Free: %-10jd Available: %jd\n" | ||
473 | "Inodes: Total: %-10jd Free: %jd\n")); | ||
474 | printf(format, | ||
475 | (unsigned long int) (statfsbuf.f_bsize), | ||
476 | (intmax_t) (statfsbuf.f_blocks), | ||
477 | (intmax_t) (statfsbuf.f_bfree), | ||
478 | (intmax_t) (statfsbuf.f_bavail), | ||
479 | (intmax_t) (statfsbuf.f_files), | ||
480 | (intmax_t) (statfsbuf.f_ffree), | ||
481 | scontext); | ||
412 | 482 | ||
483 | if (scontext) | ||
484 | freecon(scontext); | ||
485 | #endif | ||
486 | #endif /* FEATURE_STAT_FORMAT */ | ||
413 | return 1; | 487 | return 1; |
414 | } | 488 | } |
415 | 489 | ||
@@ -417,7 +491,16 @@ static int do_statfs(char const *filename, char const *format) | |||
417 | static int do_stat(char const *filename, char const *format) | 491 | static int do_stat(char const *filename, char const *format) |
418 | { | 492 | { |
419 | struct stat statbuf; | 493 | struct stat statbuf; |
420 | 494 | #if ENABLE_SELINUX | |
495 | security_context_t scontext = NULL; | ||
496 | if (flags & OPT_SELINUX) { | ||
497 | if ((flags & OPT_DEREFERENCE ? lgetfilecon(filename, scontext): | ||
498 | getfilecon(filename, scontext))< 0) { | ||
499 | bb_perror_msg (filename); | ||
500 | return 0; | ||
501 | } | ||
502 | } | ||
503 | #endif | ||
421 | if ((flags & OPT_DEREFERENCE ? stat : lstat) (filename, &statbuf) != 0) { | 504 | if ((flags & OPT_DEREFERENCE ? stat : lstat) (filename, &statbuf) != 0) { |
422 | bb_perror_msg("cannot stat '%s'", filename); | 505 | bb_perror_msg("cannot stat '%s'", filename); |
423 | return 0; | 506 | return 0; |
@@ -425,6 +508,7 @@ static int do_stat(char const *filename, char const *format) | |||
425 | 508 | ||
426 | #ifdef CONFIG_FEATURE_STAT_FORMAT | 509 | #ifdef CONFIG_FEATURE_STAT_FORMAT |
427 | if (format == NULL) { | 510 | if (format == NULL) { |
511 | #ifndef ENABLE_SELINUX | ||
428 | if (flags & OPT_TERSE) { | 512 | if (flags & OPT_TERSE) { |
429 | format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o"; | 513 | format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o"; |
430 | } else { | 514 | } else { |
@@ -445,11 +529,49 @@ static int do_stat(char const *filename, char const *format) | |||
445 | "Access: %x\n" "Modify: %y\n" "Change: %z\n"; | 529 | "Access: %x\n" "Modify: %y\n" "Change: %z\n"; |
446 | } | 530 | } |
447 | } | 531 | } |
448 | } | ||
449 | print_it(format, filename, print_stat, &statbuf); | ||
450 | #else | 532 | #else |
533 | if (flags & OPT_TERSE) { | ||
534 | format = (flags & OPT_SELINUX ? | ||
535 | "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o %C\n": | ||
536 | "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"); | ||
537 | } else { | ||
538 | if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode)) { | ||
539 | format = (flags & OPT_SELINUX ? | ||
540 | " File: \"%N\"\n" | ||
541 | " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" | ||
542 | "Device: %Dh/%dd\tInode: %-10i Links: %-5h" | ||
543 | " Device type: %t,%T\n" | ||
544 | "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" | ||
545 | " S_Context: %C\n" | ||
546 | "Access: %x\n" "Modify: %y\n" "Change: %z\n": | ||
547 | " File: \"%N\"\n" | ||
548 | " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" | ||
549 | "Device: %Dh/%dd\tInode: %-10i Links: %-5h" | ||
550 | " Device type: %t,%T\n" | ||
551 | "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" | ||
552 | "Access: %x\n" "Modify: %y\n" "Change: %z\n"); | ||
553 | } else { | ||
554 | format = (flags & OPT_SELINUX ? | ||
555 | " File: \"%N\"\n" | ||
556 | " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" | ||
557 | "Device: %Dh/%dd\tInode: %-10i Links: %h\n" | ||
558 | "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" | ||
559 | "S_Context: %C\n" | ||
560 | "Access: %x\n" "Modify: %y\n" "Change: %z\n": | ||
561 | " File: \"%N\"\n" | ||
562 | " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" | ||
563 | "Device: %Dh/%dd\tInode: %-10i Links: %h\n" | ||
564 | "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" | ||
565 | "Access: %x\n" "Modify: %y\n" "Change: %z\n"); | ||
566 | } | ||
567 | } | ||
568 | #endif | ||
569 | } | ||
570 | print_it(format, filename, print_stat, &statbuf USE_SELINUX(, scontext)); | ||
571 | #else /* FEATURE_STAT_FORMAT */ | ||
451 | if (flags & OPT_TERSE) { | 572 | if (flags & OPT_TERSE) { |
452 | printf("%s %ju %ju %lx %lu %lu %jx %ju %lu %lx %lx %lu %lu %lu %lu\n", | 573 | printf("%s %ju %ju %lx %lu %lu %jx %ju %lu %lx %lx %lu %lu %lu %lu" |
574 | SKIP_SELINUX("\n"), | ||
453 | filename, | 575 | filename, |
454 | (uintmax_t) (statbuf.st_size), | 576 | (uintmax_t) (statbuf.st_size), |
455 | (uintmax_t) statbuf.st_blocks, | 577 | (uintmax_t) statbuf.st_blocks, |
@@ -466,6 +588,12 @@ static int do_stat(char const *filename, char const *format) | |||
466 | (unsigned long int) statbuf.st_ctime, | 588 | (unsigned long int) statbuf.st_ctime, |
467 | (unsigned long int) statbuf.st_blksize | 589 | (unsigned long int) statbuf.st_blksize |
468 | ); | 590 | ); |
591 | #if ENABLE_SELINUX | ||
592 | if (flags & OPT_SELINUX) | ||
593 | printf(" %lc\n", *scontext); | ||
594 | else | ||
595 | putchar('\n'); | ||
596 | #endif | ||
469 | } else { | 597 | } else { |
470 | char *linkname = NULL; | 598 | char *linkname = NULL; |
471 | 599 | ||
@@ -499,19 +627,22 @@ static int do_stat(char const *filename, char const *format) | |||
499 | (unsigned long int) minor(statbuf.st_rdev)); | 627 | (unsigned long int) minor(statbuf.st_rdev)); |
500 | else | 628 | else |
501 | putchar('\n'); | 629 | putchar('\n'); |
502 | printf("Access: (%04lo/%10.10s) Uid: (%5lu/%8s) Gid: (%5lu/%8s)\n" | 630 | printf("Access: (%04lo/%10.10s) Uid: (%5lu/%8s) Gid: (%5lu/%8s)\n", |
503 | "Access: %s\n" "Modify: %s\n" "Change: %s\n", | ||
504 | (unsigned long int) (statbuf.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)), | 631 | (unsigned long int) (statbuf.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)), |
505 | bb_mode_string(statbuf.st_mode), | 632 | bb_mode_string(statbuf.st_mode), |
506 | (unsigned long int) statbuf.st_uid, | 633 | (unsigned long int) statbuf.st_uid, |
507 | (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN", | 634 | (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN", |
508 | (unsigned long int) statbuf.st_gid, | 635 | (unsigned long int) statbuf.st_gid, |
509 | (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN", | 636 | (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN"); |
637 | #if ENABLE_SELINUX | ||
638 | printf(" S_Context: %lc\n", *scontext); | ||
639 | #endif | ||
640 | printf("Access: %s\n" "Modify: %s\n" "Change: %s\n", | ||
510 | human_time(statbuf.st_atime), | 641 | human_time(statbuf.st_atime), |
511 | human_time(statbuf.st_mtime), | 642 | human_time(statbuf.st_mtime), |
512 | human_time(statbuf.st_ctime)); | 643 | human_time(statbuf.st_ctime)); |
513 | } | 644 | } |
514 | #endif | 645 | #endif /* FEATURE_STAT_FORMAT */ |
515 | return 1; | 646 | return 1; |
516 | } | 647 | } |
517 | 648 | ||
@@ -524,6 +655,7 @@ int stat_main(int argc, char **argv) | |||
524 | int (*statfunc)(char const *, char const *) = do_stat; | 655 | int (*statfunc)(char const *, char const *) = do_stat; |
525 | 656 | ||
526 | flags = getopt32(argc, argv, "ftL" | 657 | flags = getopt32(argc, argv, "ftL" |
658 | USE_SELINUX("Z") | ||
527 | USE_FEATURE_STAT_FORMAT("c:", &format) | 659 | USE_FEATURE_STAT_FORMAT("c:", &format) |
528 | ); | 660 | ); |
529 | 661 | ||
@@ -532,6 +664,11 @@ int stat_main(int argc, char **argv) | |||
532 | if (argc == optind) /* files */ | 664 | if (argc == optind) /* files */ |
533 | bb_show_usage(); | 665 | bb_show_usage(); |
534 | 666 | ||
667 | #if ENABLE_SELINUX | ||
668 | if (flags & OPT_SELINUX) { | ||
669 | selinux_or_die(); | ||
670 | } | ||
671 | #endif /* ENABLE_SELINUX */ | ||
535 | for (i = optind; i < argc; ++i) | 672 | for (i = optind; i < argc; ++i) |
536 | ok &= statfunc(argv[i], format); | 673 | ok &= statfunc(argv[i], format); |
537 | 674 | ||