aboutsummaryrefslogtreecommitdiff
path: root/coreutils/stat.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-03-10 16:58:49 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-03-10 16:58:49 +0000
commit49622d784672bf2f7b2fe80589714cdef5adde0c (patch)
tree892bb79b0ef031d729e688d6be4950f6d17f13b9 /coreutils/stat.c
parent4eb8b936cb0aeb27c3e12f9a93fc43aa1e9668f5 (diff)
downloadbusybox-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.c169
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
20static long flags; 22static long flags;
21 23
22static char const *file_type(struct stat const *st) 24static 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 */
116static void print_statfs(char *pformat, size_t buf_len, char m, 118static 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 */
175static void print_stat(char *pformat, size_t buf_len, char m, 186static 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
311static void print_it(char const *masterformat, char const *filename, 331static 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)
417static int do_stat(char const *filename, char const *format) 491static 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