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 | |
| 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')
| -rw-r--r-- | coreutils/cp.c | 7 | ||||
| -rw-r--r-- | coreutils/id.c | 43 | ||||
| -rw-r--r-- | coreutils/install.c | 75 | ||||
| -rw-r--r-- | coreutils/libcoreutils/getopt_mk_fifo_nod.c | 20 | ||||
| -rw-r--r-- | coreutils/ls.c | 6 | ||||
| -rw-r--r-- | coreutils/mkdir.c | 20 | ||||
| -rw-r--r-- | coreutils/mv.c | 9 | ||||
| -rw-r--r-- | coreutils/stat.c | 169 |
8 files changed, 310 insertions, 39 deletions
diff --git a/coreutils/cp.c b/coreutils/cp.c index 7b0de477b..64cf63797 100644 --- a/coreutils/cp.c +++ b/coreutils/cp.c | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | * Mini cp implementation for busybox | 3 | * Mini cp implementation for busybox |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu> | 5 | * Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu> |
| 6 | * SELinux support by Yuichi Nakamura <ynakam@hitachisoft.jp> | ||
| 6 | * | 7 | * |
| 7 | * Licensed under GPL v2 or later, see file LICENSE in this tarball for details. | 8 | * Licensed under GPL v2 or later, see file LICENSE in this tarball for details. |
| 8 | */ | 9 | */ |
| @@ -50,6 +51,12 @@ int cp_main(int argc, char **argv) | |||
| 50 | if (flags & OPT_H) ... // deref command-line params only | 51 | if (flags & OPT_H) ... // deref command-line params only |
| 51 | */ | 52 | */ |
| 52 | 53 | ||
| 54 | #if ENABLE_SELINUX | ||
| 55 | if (flags & FILEUTILS_PRESERVE_SECURITY_CONTEXT) { | ||
| 56 | selinux_or_die(); | ||
| 57 | } | ||
| 58 | #endif | ||
| 59 | |||
| 53 | flags ^= FILEUTILS_DEREFERENCE; /* The sense of this flag was reversed. */ | 60 | flags ^= FILEUTILS_DEREFERENCE; /* The sense of this flag was reversed. */ |
| 54 | 61 | ||
| 55 | if (optind + 2 > argc) { | 62 | if (optind + 2 > argc) { |
diff --git a/coreutils/id.c b/coreutils/id.c index 963ee0566..a0364675f 100644 --- a/coreutils/id.c +++ b/coreutils/id.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | /* BB_AUDIT SUSv3 _NOT_ compliant -- option -G is not currently supported. */ | 10 | /* BB_AUDIT SUSv3 _NOT_ compliant -- option -G is not currently supported. */ |
| 11 | /* Hacked by Tito Ragusa (C) 2004 to handle usernames of whatever length and to | 11 | /* Hacked by Tito Ragusa (C) 2004 to handle usernames of whatever length and to |
| 12 | * be more similar to GNU id. | 12 | * be more similar to GNU id. |
| 13 | * -Z option support: by Yuichi Nakamura <ynakam@hitachisoft.jp> | ||
| 13 | */ | 14 | */ |
| 14 | 15 | ||
| 15 | #include "busybox.h" | 16 | #include "busybox.h" |
| @@ -17,14 +18,13 @@ | |||
| 17 | #include <unistd.h> | 18 | #include <unistd.h> |
| 18 | #include <sys/types.h> | 19 | #include <sys/types.h> |
| 19 | 20 | ||
| 20 | #ifdef CONFIG_SELINUX | ||
| 21 | #include <selinux/selinux.h> /* for is_selinux_enabled() */ | ||
| 22 | #endif | ||
| 23 | |||
| 24 | #define PRINT_REAL 1 | 21 | #define PRINT_REAL 1 |
| 25 | #define NAME_NOT_NUMBER 2 | 22 | #define NAME_NOT_NUMBER 2 |
| 26 | #define JUST_USER 4 | 23 | #define JUST_USER 4 |
| 27 | #define JUST_GROUP 8 | 24 | #define JUST_GROUP 8 |
| 25 | #if ENABLE_SELINUX | ||
| 26 | #define JUST_CONTEXT 16 | ||
| 27 | #endif | ||
| 28 | 28 | ||
| 29 | static short printf_full(unsigned int id, const char *arg, const char prefix) | 29 | static short printf_full(unsigned int id, const char *arg, const char prefix) |
| 30 | { | 30 | { |
| @@ -47,11 +47,13 @@ int id_main(int argc, char **argv) | |||
| 47 | gid_t gid; | 47 | gid_t gid; |
| 48 | unsigned long flags; | 48 | unsigned long flags; |
| 49 | short status; | 49 | short status; |
| 50 | 50 | #if ENABLE_SELINUX | |
| 51 | security_context_t scontext; | ||
| 52 | #endif | ||
| 51 | /* Don't allow -n -r -nr -ug -rug -nug -rnug */ | 53 | /* Don't allow -n -r -nr -ug -rug -nug -rnug */ |
| 52 | /* Don't allow more than one username */ | 54 | /* Don't allow more than one username */ |
| 53 | opt_complementary = "?1:?:u--g:g--u:r?ug:n?ug"; | 55 | opt_complementary = "?1:?:u--g:g--u:r?ug:n?ug" USE_SELINUX(":u--Z:Z--u:g--Z:Z--g"); |
| 54 | flags = getopt32(argc, argv, "rnug"); | 56 | flags = getopt32(argc, argv, "rnug" USE_SELINUX("Z")); |
| 55 | 57 | ||
| 56 | /* This values could be overwritten later */ | 58 | /* This values could be overwritten later */ |
| 57 | uid = geteuid(); | 59 | uid = geteuid(); |
| @@ -69,14 +71,33 @@ int id_main(int argc, char **argv) | |||
| 69 | /* in this case PRINT_REAL is the same */ | 71 | /* in this case PRINT_REAL is the same */ |
| 70 | } | 72 | } |
| 71 | 73 | ||
| 72 | if (flags & (JUST_GROUP | JUST_USER)) { | 74 | if (flags & (JUST_GROUP | JUST_USER USE_SELINUX(| JUST_CONTEXT))) { |
| 73 | /* JUST_GROUP and JUST_USER are mutually exclusive */ | 75 | /* JUST_GROUP and JUST_USER are mutually exclusive */ |
| 74 | if (flags & NAME_NOT_NUMBER) { | 76 | if (flags & NAME_NOT_NUMBER) { |
| 75 | /* bb_getpwuid and bb_getgrgid exit on failure so puts cannot segfault */ | 77 | /* bb_getpwuid and bb_getgrgid exit on failure so puts cannot segfault */ |
| 76 | puts((flags & JUST_USER) ? bb_getpwuid(NULL, uid, -1 ) : bb_getgrgid(NULL, gid, -1 )); | 78 | puts((flags & JUST_USER) ? bb_getpwuid(NULL, uid, -1 ) : bb_getgrgid(NULL, gid, -1 )); |
| 77 | } else { | 79 | } else { |
| 78 | printf("%u\n", (flags & JUST_USER) ? uid : gid); | 80 | if (flags & JUST_USER) { |
| 79 | } | 81 | printf("%u\n", uid); |
| 82 | } | ||
| 83 | if (flags & JUST_GROUP) { | ||
| 84 | printf("%u\n", gid); | ||
| 85 | } | ||
| 86 | } | ||
| 87 | |||
| 88 | #if ENABLE_SELINUX | ||
| 89 | if (flags & JUST_CONTEXT) { | ||
| 90 | selinux_or_die(); | ||
| 91 | if (argc - optind == 1) { | ||
| 92 | bb_error_msg_and_die("can't print security context when user specified"); | ||
| 93 | } | ||
| 94 | |||
| 95 | if (getcon(&scontext)) { | ||
| 96 | bb_error_msg_and_die("can't get process context"); | ||
| 97 | } | ||
| 98 | printf("%s\n", scontext); | ||
| 99 | } | ||
| 100 | #endif | ||
| 80 | /* exit */ | 101 | /* exit */ |
| 81 | fflush_stdout_and_exit(EXIT_SUCCESS); | 102 | fflush_stdout_and_exit(EXIT_SUCCESS); |
| 82 | } | 103 | } |
| @@ -88,7 +109,7 @@ int id_main(int argc, char **argv) | |||
| 88 | /* bb_getgrgid doesn't exit on failure here */ | 109 | /* bb_getgrgid doesn't exit on failure here */ |
| 89 | status |= printf_full(gid, bb_getgrgid(NULL, gid, 0), 'g'); | 110 | status |= printf_full(gid, bb_getgrgid(NULL, gid, 0), 'g'); |
| 90 | 111 | ||
| 91 | #ifdef CONFIG_SELINUX | 112 | #if ENABLE_SELINUX |
| 92 | if (is_selinux_enabled()) { | 113 | if (is_selinux_enabled()) { |
| 93 | security_context_t mysid; | 114 | security_context_t mysid; |
| 94 | const char *context; | 115 | const char *context; |
diff --git a/coreutils/install.c b/coreutils/install.c index c105addc5..83facad9d 100644 --- a/coreutils/install.c +++ b/coreutils/install.c | |||
| @@ -21,10 +21,49 @@ static const struct option install_long_options[] = { | |||
| 21 | { "group", 0, NULL, 'g' }, | 21 | { "group", 0, NULL, 'g' }, |
| 22 | { "mode", 0, NULL, 'm' }, | 22 | { "mode", 0, NULL, 'm' }, |
| 23 | { "owner", 0, NULL, 'o' }, | 23 | { "owner", 0, NULL, 'o' }, |
| 24 | #if ENABLE_SELINUX | ||
| 25 | { "context", 1, NULL, 'Z' }, | ||
| 26 | { "preserve_context", 0, NULL, 0xff }, | ||
| 27 | { "preserve-context", 0, NULL, 0xff }, | ||
| 28 | #endif | ||
| 24 | { 0, 0, 0, 0 } | 29 | { 0, 0, 0, 0 } |
| 25 | }; | 30 | }; |
| 26 | #endif | 31 | #endif |
| 27 | 32 | ||
| 33 | |||
| 34 | #if ENABLE_SELINUX | ||
| 35 | static bool use_default_selinux_context = 1; | ||
| 36 | |||
| 37 | static void setdefaultfilecon(const char *path) { | ||
| 38 | struct stat s; | ||
| 39 | security_context_t scontext = NULL; | ||
| 40 | |||
| 41 | if (!is_selinux_enabled()) { | ||
| 42 | return; | ||
| 43 | } | ||
| 44 | if (lstat(path, &s) != 0) { | ||
| 45 | return; | ||
| 46 | } | ||
| 47 | |||
| 48 | if (matchpathcon(path, s.st_mode, &scontext) < 0) { | ||
| 49 | goto out; | ||
| 50 | } | ||
| 51 | if (strcmp(scontext, "<<none>>") == 0) { | ||
| 52 | goto out; | ||
| 53 | } | ||
| 54 | |||
| 55 | if (lsetfilecon(path, scontext) < 0) { | ||
| 56 | if (errno != ENOTSUP) { | ||
| 57 | bb_perror_msg("warning: failed to change context of %s to %s", path, scontext); | ||
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 61 | out: | ||
| 62 | freecon(scontext); | ||
| 63 | } | ||
| 64 | |||
| 65 | #endif | ||
| 66 | |||
| 28 | int install_main(int argc, char **argv); | 67 | int install_main(int argc, char **argv); |
| 29 | int install_main(int argc, char **argv) | 68 | int install_main(int argc, char **argv) |
| 30 | { | 69 | { |
| @@ -37,7 +76,9 @@ int install_main(int argc, char **argv) | |||
| 37 | const char *mode_str; | 76 | const char *mode_str; |
| 38 | int copy_flags = FILEUTILS_DEREFERENCE | FILEUTILS_FORCE; | 77 | int copy_flags = FILEUTILS_DEREFERENCE | FILEUTILS_FORCE; |
| 39 | int ret = EXIT_SUCCESS, flags, i, isdir; | 78 | int ret = EXIT_SUCCESS, flags, i, isdir; |
| 40 | 79 | #if ENABLE_SELINUX | |
| 80 | security_context_t scontext; | ||
| 81 | #endif | ||
| 41 | enum { | 82 | enum { |
| 42 | OPT_CMD = 0x1, | 83 | OPT_CMD = 0x1, |
| 43 | OPT_DIRECTORY = 0x2, | 84 | OPT_DIRECTORY = 0x2, |
| @@ -46,14 +87,35 @@ int install_main(int argc, char **argv) | |||
| 46 | OPT_GROUP = 0x10, | 87 | OPT_GROUP = 0x10, |
| 47 | OPT_MODE = 0x20, | 88 | OPT_MODE = 0x20, |
| 48 | OPT_OWNER = 0x40, | 89 | OPT_OWNER = 0x40, |
| 90 | #if ENABLE_SELINUX | ||
| 91 | OPT_SET_SECURITY_CONTEXT = 0x80, | ||
| 92 | OPT_PRESERVE_SECURITY_CONTEXT = 0x100, | ||
| 93 | #endif | ||
| 49 | }; | 94 | }; |
| 50 | 95 | ||
| 51 | #if ENABLE_FEATURE_INSTALL_LONG_OPTIONS | 96 | #if ENABLE_FEATURE_INSTALL_LONG_OPTIONS |
| 52 | applet_long_options = install_long_options; | 97 | applet_long_options = install_long_options; |
| 53 | #endif | 98 | #endif |
| 54 | opt_complementary = "?:s--d:d--s"; | 99 | opt_complementary = "?:s--d:d--s" USE_SELINUX(":Z--\xff:\xff--Z"); |
| 55 | /* -c exists for backwards compatibility, its needed */ | 100 | /* -c exists for backwards compatibility, it's needed */ |
| 56 | flags = getopt32(argc, argv, "cdpsg:m:o:", &gid_str, &mode_str, &uid_str); | 101 | |
| 102 | flags = getopt32(argc, argv, "cdpsg:m:o:" USE_SELINUX("Z:"), &gid_str, &mode_str, &uid_str USE_SELINUX(, &scontext)); | ||
| 103 | |||
| 104 | #if ENABLE_SELINUX | ||
| 105 | if (flags & OPT_PRESERVE_SECURITY_CONTEXT) { | ||
| 106 | use_default_selinux_context = 0; | ||
| 107 | copy_flags |= FILEUTILS_PRESERVE_SECURITY_CONTEXT; | ||
| 108 | selinux_or_die(); | ||
| 109 | } | ||
| 110 | if (flags & OPT_SET_SECURITY_CONTEXT) { | ||
| 111 | selinux_or_die(); | ||
| 112 | if (setfscreatecon(scontext) < 0) { | ||
| 113 | bb_error_msg_and_die("setfscreatecon(%s)", scontext); // perror? | ||
| 114 | } | ||
| 115 | use_default_selinux_context = 0; | ||
| 116 | copy_flags |= FILEUTILS_SET_SECURITY_CONTEXT; | ||
| 117 | } | ||
| 118 | #endif | ||
| 57 | 119 | ||
| 58 | /* preserve access and modification time, this is GNU behaviour, BSD only preserves modification time */ | 120 | /* preserve access and modification time, this is GNU behaviour, BSD only preserves modification time */ |
| 59 | if (flags & OPT_PRESERVE_TIME) { | 121 | if (flags & OPT_PRESERVE_TIME) { |
| @@ -117,7 +179,10 @@ int install_main(int argc, char **argv) | |||
| 117 | bb_perror_msg("cannot change permissions of %s", dest); | 179 | bb_perror_msg("cannot change permissions of %s", dest); |
| 118 | ret = EXIT_FAILURE; | 180 | ret = EXIT_FAILURE; |
| 119 | } | 181 | } |
| 120 | 182 | #if ENABLE_SELINUX | |
| 183 | if (use_default_selinux_context) | ||
| 184 | setdefaultfilecon(dest); | ||
| 185 | #endif | ||
| 121 | /* Set the user and group id */ | 186 | /* Set the user and group id */ |
| 122 | if ((flags & (OPT_OWNER|OPT_GROUP)) | 187 | if ((flags & (OPT_OWNER|OPT_GROUP)) |
| 123 | && lchown(dest, uid, gid) == -1 | 188 | && lchown(dest, uid, gid) == -1 |
diff --git a/coreutils/libcoreutils/getopt_mk_fifo_nod.c b/coreutils/libcoreutils/getopt_mk_fifo_nod.c index 3a3d34118..2e0c27439 100644 --- a/coreutils/libcoreutils/getopt_mk_fifo_nod.c +++ b/coreutils/libcoreutils/getopt_mk_fifo_nod.c | |||
| @@ -30,11 +30,25 @@ mode_t getopt_mk_fifo_nod(int argc, char **argv) | |||
| 30 | { | 30 | { |
| 31 | mode_t mode = 0666; | 31 | mode_t mode = 0666; |
| 32 | char *smode = NULL; | 32 | char *smode = NULL; |
| 33 | 33 | #if ENABLE_SELINUX | |
| 34 | getopt32(argc, argv, "m:", &smode); | 34 | security_context_t scontext; |
| 35 | if(smode) { | 35 | #endif |
| 36 | int opt; | ||
| 37 | opt = getopt32(argc, argv, "m:" USE_SELINUX("Z:"), &smode USE_SELINUX(,&scontext)); | ||
| 38 | if (opt & 1) { | ||
| 36 | if (bb_parse_mode(smode, &mode)) | 39 | if (bb_parse_mode(smode, &mode)) |
| 37 | umask(0); | 40 | umask(0); |
| 38 | } | 41 | } |
| 42 | |||
| 43 | #if ENABLE_SELINUX | ||
| 44 | if (opt & 2) { | ||
| 45 | selinux_or_die(); | ||
| 46 | if (setfscreatecon(scontext)) { | ||
| 47 | bb_error_msg_and_die("cannot set default file creation context " | ||
| 48 | "to %s", scontext); | ||
| 49 | } | ||
| 50 | } | ||
| 51 | #endif | ||
| 52 | |||
| 39 | return mode; | 53 | return mode; |
| 40 | } | 54 | } |
diff --git a/coreutils/ls.c b/coreutils/ls.c index f902d382a..1c1544a34 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c | |||
| @@ -716,7 +716,8 @@ static const char ls_options[] = "Cadil1gnsxAk" | |||
| 716 | USE_FEATURE_LS_RECURSIVE("R") | 716 | USE_FEATURE_LS_RECURSIVE("R") |
| 717 | USE_FEATURE_HUMAN_READABLE("h") | 717 | USE_FEATURE_HUMAN_READABLE("h") |
| 718 | USE_SELINUX("K") | 718 | USE_SELINUX("K") |
| 719 | USE_FEATURE_AUTOWIDTH("T:w:"); | 719 | USE_FEATURE_AUTOWIDTH("T:w:") |
| 720 | USE_SELINUX("Z"); | ||
| 720 | 721 | ||
| 721 | enum { | 722 | enum { |
| 722 | LIST_MASK_TRIGGER = 0, | 723 | LIST_MASK_TRIGGER = 0, |
| @@ -769,6 +770,9 @@ static const unsigned opt_flags[] = { | |||
| 769 | #if ENABLE_FEATURE_AUTOWIDTH | 770 | #if ENABLE_FEATURE_AUTOWIDTH |
| 770 | 0, 0, /* T, w - ignored */ | 771 | 0, 0, /* T, w - ignored */ |
| 771 | #endif | 772 | #endif |
| 773 | #if ENABLE_SELINUX | ||
| 774 | LIST_MODEBITS|LIST_ID_NAME|LIST_CONTEXT, /* Z */ | ||
| 775 | #endif | ||
| 772 | (1U<<31) | 776 | (1U<<31) |
| 773 | }; | 777 | }; |
| 774 | 778 | ||
diff --git a/coreutils/mkdir.c b/coreutils/mkdir.c index 67819e784..93ded1dd5 100644 --- a/coreutils/mkdir.c +++ b/coreutils/mkdir.c | |||
| @@ -16,6 +16,9 @@ | |||
| 16 | * conjunction with -m. | 16 | * conjunction with -m. |
| 17 | */ | 17 | */ |
| 18 | 18 | ||
| 19 | /* Nov 28, 2006 Yoshinori Sato <ysato@users.sourceforge.jp>: Add SELinux Support. | ||
| 20 | */ | ||
| 21 | |||
| 19 | #include <stdlib.h> | 22 | #include <stdlib.h> |
| 20 | #include <unistd.h> | 23 | #include <unistd.h> |
| 21 | #include <getopt.h> /* struct option */ | 24 | #include <getopt.h> /* struct option */ |
| @@ -25,6 +28,9 @@ | |||
| 25 | static const struct option mkdir_long_options[] = { | 28 | static const struct option mkdir_long_options[] = { |
| 26 | { "mode", 1, NULL, 'm' }, | 29 | { "mode", 1, NULL, 'm' }, |
| 27 | { "parents", 0, NULL, 'p' }, | 30 | { "parents", 0, NULL, 'p' }, |
| 31 | #if ENABLE_SELINUX | ||
| 32 | { "context", 1, NULL, 'Z' }, | ||
| 33 | #endif | ||
| 28 | { 0, 0, 0, 0 } | 34 | { 0, 0, 0, 0 } |
| 29 | }; | 35 | }; |
| 30 | #endif | 36 | #endif |
| @@ -37,11 +43,14 @@ int mkdir_main(int argc, char **argv) | |||
| 37 | int flags = 0; | 43 | int flags = 0; |
| 38 | unsigned opt; | 44 | unsigned opt; |
| 39 | char *smode; | 45 | char *smode; |
| 46 | #if ENABLE_SELINUX | ||
| 47 | security_context_t scontext; | ||
| 48 | #endif | ||
| 40 | 49 | ||
| 41 | #if ENABLE_FEATURE_MKDIR_LONG_OPTIONS | 50 | #if ENABLE_FEATURE_MKDIR_LONG_OPTIONS |
| 42 | applet_long_options = mkdir_long_options; | 51 | applet_long_options = mkdir_long_options; |
| 43 | #endif | 52 | #endif |
| 44 | opt = getopt32(argc, argv, "m:p", &smode); | 53 | opt = getopt32(argc, argv, "m:p" USE_SELINUX("Z:"), &smode USE_SELINUX(,&scontext)); |
| 45 | if (opt & 1) { | 54 | if (opt & 1) { |
| 46 | mode = 0777; | 55 | mode = 0777; |
| 47 | if (!bb_parse_mode(smode, &mode)) { | 56 | if (!bb_parse_mode(smode, &mode)) { |
| @@ -50,6 +59,15 @@ int mkdir_main(int argc, char **argv) | |||
| 50 | } | 59 | } |
| 51 | if (opt & 2) | 60 | if (opt & 2) |
| 52 | flags |= FILEUTILS_RECUR; | 61 | flags |= FILEUTILS_RECUR; |
| 62 | #if ENABLE_SELINUX | ||
| 63 | if (opt & 4) { | ||
| 64 | selinux_or_die(); | ||
| 65 | if (setfscreatecon(scontext)) { | ||
| 66 | bb_error_msg_and_die("cannot set default file creation context " | ||
| 67 | "to %s", scontext); | ||
| 68 | } | ||
| 69 | } | ||
| 70 | #endif | ||
| 53 | 71 | ||
| 54 | if (optind == argc) { | 72 | if (optind == argc) { |
| 55 | bb_show_usage(); | 73 | bb_show_usage(); |
diff --git a/coreutils/mv.c b/coreutils/mv.c index 7d4905fc9..64cae965b 100644 --- a/coreutils/mv.c +++ b/coreutils/mv.c | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | * Mini mv implementation for busybox | 3 | * Mini mv implementation for busybox |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu> | 5 | * Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu> |
| 6 | * SELinux support by Yuichi Nakamura <ynakam@hitachisoft.jp> | ||
| 6 | * | 7 | * |
| 7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 8 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
| 8 | */ | 9 | */ |
| @@ -44,6 +45,7 @@ int mv_main(int argc, char **argv) | |||
| 44 | unsigned long flags; | 45 | unsigned long flags; |
| 45 | int dest_exists; | 46 | int dest_exists; |
| 46 | int status = 0; | 47 | int status = 0; |
| 48 | int copy_flag = 0; | ||
| 47 | 49 | ||
| 48 | #if ENABLE_FEATURE_MV_LONG_OPTIONS | 50 | #if ENABLE_FEATURE_MV_LONG_OPTIONS |
| 49 | applet_long_options = mv_long_options; | 51 | applet_long_options = mv_long_options; |
| @@ -113,8 +115,11 @@ DO_MOVE: | |||
| 113 | goto RET_1; | 115 | goto RET_1; |
| 114 | } | 116 | } |
| 115 | } | 117 | } |
| 116 | if ((copy_file(*argv, dest, | 118 | copy_flag = FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS; |
| 117 | FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS) >= 0) && | 119 | #if ENABLE_SELINUX |
| 120 | copy_flag |= FILEUTILS_PRESERVE_SECURITY_CONTEXT; | ||
| 121 | #endif | ||
| 122 | if ((copy_file(*argv, dest, copy_flag) >= 0) && | ||
| 118 | (remove_file(*argv, FILEUTILS_RECUR | FILEUTILS_FORCE) >= 0)) { | 123 | (remove_file(*argv, FILEUTILS_RECUR | FILEUTILS_FORCE) >= 0)) { |
| 119 | goto RET_0; | 124 | goto RET_0; |
| 120 | } | 125 | } |
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 | ||
