X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=coreutils%2Fstat.c;h=5996268ef582843d76d74eb3f2f148e22458c675;hb=9bd8d0c23e867238bad53b04a029f71db9b88c3f;hp=397e395d85c71414fc4283137eadea4b1596515c;hpb=0e6ab01c5a525fc0e298d44f4573a4f8972406f2;p=oweals%2Fbusybox.git diff --git a/coreutils/stat.c b/coreutils/stat.c index 397e395d8..5996268ef 100644 --- a/coreutils/stat.c +++ b/coreutils/stat.c @@ -13,17 +13,15 @@ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ -#include "busybox.h" +#include "libbb.h" /* vars to control behavior */ -#define OPT_FILESYS (1<<0) -#define OPT_TERSE (1<<1) -#define OPT_DEREFERENCE (1<<2) -#define OPT_SELINUX (1<<3) +#define OPT_FILESYS (1 << 0) +#define OPT_TERSE (1 << 1) +#define OPT_DEREFERENCE (1 << 2) +#define OPT_SELINUX (1 << 3) -static char buf[sizeof("YYYY-MM-DD HH:MM:SS.000000000")]; - -static char const * file_type(struct stat const *st) +static const char *file_type(const struct stat *st) { /* See POSIX 1003.1-2001 XCU Table 4-8 lines 17093-17107 * for some of these formats. @@ -46,7 +44,7 @@ static char const * file_type(struct stat const *st) return "weird file"; } -static char const *human_time(time_t t) +static const char *human_time(time_t t) { /* Old static char *str; @@ -56,8 +54,12 @@ static char const *human_time(time_t t) */ /* coreutils 6.3 compat: */ + /*static char buf[sizeof("YYYY-MM-DD HH:MM:SS.000000000")] ALIGN1;*/ +#define buf bb_common_bufsiz1 + strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S.000000000", localtime(&t)); return buf; +#undef buf } /* Return the type of the specified file system. @@ -65,12 +67,11 @@ static char const *human_time(time_t t) * Others have statfs.f_fstypename[MFSNAMELEN]. (NetBSD 1.5.2) * Still others have neither and have to get by with f_type (Linux). */ -static char const *human_fstype(long f_type) +static const char *human_fstype(uint32_t f_type) { - int i; - const struct types { - long type; - const char * const fs; + static const struct types { + uint32_t type; + const char *const fs; } humantypes[] = { { 0xADFF, "affs" }, { 0x1Cd1, "devpts" }, @@ -109,67 +110,80 @@ static char const *human_fstype(long f_type) { 0x62656572, "sysfs" }, { 0, "UNKNOWN" } }; - for (i=0; humantypes[i].type; ++i) + + int i; + + for (i = 0; humantypes[i].type; ++i) if (humantypes[i].type == f_type) break; return humantypes[i].fs; } -#ifdef CONFIG_FEATURE_STAT_FORMAT +#if ENABLE_FEATURE_STAT_FORMAT +static void strcatc(char *str, char c) +{ + int len = strlen(str); + str[len++] = c; + str[len] = '\0'; +} + +static void printfs(char *pformat, const char *msg) +{ + strcatc(pformat, 's'); + printf(pformat, msg); +} + /* print statfs info */ -static void print_statfs(char *pformat, const size_t buf_len, const char m, - const char * const filename, void const *data - USE_SELINUX(, security_context_t scontext)) +static void print_statfs(char *pformat, const char m, + const char *const filename, const void *data + USE_SELINUX(, security_context_t scontext)) { - struct statfs const *statfsbuf = data; + const struct statfs *statfsbuf = data; if (m == 'n') { - strncat(pformat, "s", buf_len); - printf(pformat, filename); + printfs(pformat, filename); } else if (m == 'i') { - strncat(pformat, "Lx", buf_len); + strcat(pformat, "Lx"); printf(pformat, statfsbuf->f_fsid); } else if (m == 'l') { - strncat(pformat, "lu", buf_len); + strcat(pformat, "lu"); printf(pformat, statfsbuf->f_namelen); } else if (m == 't') { - strncat(pformat, "lx", buf_len); - printf(pformat, (unsigned long int) (statfsbuf->f_type)); /* no equiv */ + strcat(pformat, "lx"); + printf(pformat, (unsigned long) (statfsbuf->f_type)); /* no equiv */ } else if (m == 'T') { - strncat(pformat, "s", buf_len); - printf(pformat, human_fstype(statfsbuf->f_type)); + printfs(pformat, human_fstype(statfsbuf->f_type)); } else if (m == 'b') { - strncat(pformat, "jd", buf_len); + strcat(pformat, "jd"); printf(pformat, (intmax_t) (statfsbuf->f_blocks)); } else if (m == 'f') { - strncat(pformat, "jd", buf_len); + strcat(pformat, "jd"); printf(pformat, (intmax_t) (statfsbuf->f_bfree)); } else if (m == 'a') { - strncat(pformat, "jd", buf_len); + strcat(pformat, "jd"); printf(pformat, (intmax_t) (statfsbuf->f_bavail)); } else if (m == 's' || m == 'S') { - strncat(pformat, "lu", buf_len); - printf(pformat, (unsigned long int) (statfsbuf->f_bsize)); + strcat(pformat, "lu"); + printf(pformat, (unsigned long) (statfsbuf->f_bsize)); } else if (m == 'c') { - strncat(pformat, "jd", buf_len); + strcat(pformat, "jd"); printf(pformat, (intmax_t) (statfsbuf->f_files)); } else if (m == 'd') { - strncat(pformat, "jd", buf_len); + strcat(pformat, "jd"); printf(pformat, (intmax_t) (statfsbuf->f_ffree)); #if ENABLE_SELINUX } else if (m == 'C' && (option_mask32 & OPT_SELINUX)) { - strncat(pformat, "s", buf_len); - printf(scontext); + printfs(pformat, scontext); #endif } else { - strncat(pformat, "c", buf_len); + strcatc(pformat, 'c'); printf(pformat, m); } } /* print stat info */ -static void print_stat(char *pformat, const size_t buf_len, const char m, - const char * const filename, void const *data - USE_SELINUX(, security_context_t scontext)) +static void print_stat(char *pformat, const char m, + const char *const filename, const void *data + USE_SELINUX(, security_context_t scontext)) { #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) struct stat *statbuf = (struct stat *) data; @@ -177,131 +191,118 @@ static void print_stat(char *pformat, const size_t buf_len, const char m, struct group *gw_ent; if (m == 'n') { - strncat(pformat, "s", buf_len); - printf(pformat, filename); + printfs(pformat, filename); } else if (m == 'N') { - strncat(pformat, "s", buf_len); + strcatc(pformat, 's'); if (S_ISLNK(statbuf->st_mode)) { char *linkname = xmalloc_readlink_or_warn(filename); - if (linkname == NULL) { - bb_perror_msg("cannot read symbolic link '%s'", filename); + if (linkname == NULL) return; - } /*printf("\"%s\" -> \"%s\"", filename, linkname); */ printf(pformat, filename); printf(" -> "); printf(pformat, linkname); + free(linkname); } else { printf(pformat, filename); } } else if (m == 'd') { - strncat(pformat, "ju", buf_len); + strcat(pformat, "ju"); printf(pformat, (uintmax_t) statbuf->st_dev); } else if (m == 'D') { - strncat(pformat, "jx", buf_len); + strcat(pformat, "jx"); printf(pformat, (uintmax_t) statbuf->st_dev); } else if (m == 'i') { - strncat(pformat, "ju", buf_len); + strcat(pformat, "ju"); printf(pformat, (uintmax_t) statbuf->st_ino); } else if (m == 'a') { - strncat(pformat, "lo", buf_len); - printf(pformat, (unsigned long int) (statbuf->st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO))); + strcat(pformat, "lo"); + printf(pformat, (unsigned long) (statbuf->st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO))); } else if (m == 'A') { - strncat(pformat, "s", buf_len); - printf(pformat, bb_mode_string(statbuf->st_mode)); + printfs(pformat, bb_mode_string(statbuf->st_mode)); } else if (m == 'f') { - strncat(pformat, "lx", buf_len); - printf(pformat, (unsigned long int) statbuf->st_mode); + strcat(pformat, "lx"); + printf(pformat, (unsigned long) statbuf->st_mode); } else if (m == 'F') { - strncat(pformat, "s", buf_len); - printf(pformat, file_type(statbuf)); + printfs(pformat, file_type(statbuf)); } else if (m == 'h') { - strncat(pformat, "lu", buf_len); - printf(pformat, (unsigned long int) statbuf->st_nlink); + strcat(pformat, "lu"); + printf(pformat, (unsigned long) statbuf->st_nlink); } else if (m == 'u') { - strncat(pformat, "lu", buf_len); - printf(pformat, (unsigned long int) statbuf->st_uid); + strcat(pformat, "lu"); + printf(pformat, (unsigned long) statbuf->st_uid); } else if (m == 'U') { - strncat(pformat, "s", buf_len); setpwent(); pw_ent = getpwuid(statbuf->st_uid); - printf(pformat, (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN"); + printfs(pformat, (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN"); } else if (m == 'g') { - strncat(pformat, "lu", buf_len); - printf(pformat, (unsigned long int) statbuf->st_gid); + strcat(pformat, "lu"); + printf(pformat, (unsigned long) statbuf->st_gid); } else if (m == 'G') { - strncat(pformat, "s", buf_len); setgrent(); gw_ent = getgrgid(statbuf->st_gid); - printf(pformat, (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN"); + printfs(pformat, (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN"); } else if (m == 't') { - strncat(pformat, "lx", buf_len); - printf(pformat, (unsigned long int) major(statbuf->st_rdev)); + strcat(pformat, "lx"); + printf(pformat, (unsigned long) major(statbuf->st_rdev)); } else if (m == 'T') { - strncat(pformat, "lx", buf_len); - printf(pformat, (unsigned long int) minor(statbuf->st_rdev)); + strcat(pformat, "lx"); + printf(pformat, (unsigned long) minor(statbuf->st_rdev)); } else if (m == 's') { - strncat(pformat, "ju", buf_len); + strcat(pformat, "ju"); printf(pformat, (uintmax_t) (statbuf->st_size)); } else if (m == 'B') { - strncat(pformat, "lu", buf_len); - printf(pformat, (unsigned long int) 512); //ST_NBLOCKSIZE + strcat(pformat, "lu"); + printf(pformat, (unsigned long) 512); //ST_NBLOCKSIZE } else if (m == 'b') { - strncat(pformat, "ju", buf_len); + strcat(pformat, "ju"); printf(pformat, (uintmax_t) statbuf->st_blocks); } else if (m == 'o') { - strncat(pformat, "lu", buf_len); - printf(pformat, (unsigned long int) statbuf->st_blksize); + strcat(pformat, "lu"); + printf(pformat, (unsigned long) statbuf->st_blksize); } else if (m == 'x') { - strncat(pformat, "s", buf_len); - printf(pformat, human_time(statbuf->st_atime)); + printfs(pformat, human_time(statbuf->st_atime)); } else if (m == 'X') { - strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len); - printf(pformat, (unsigned long int) statbuf->st_atime); + strcat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu"); + printf(pformat, (unsigned long) statbuf->st_atime); } else if (m == 'y') { - strncat(pformat, "s", buf_len); - printf(pformat, human_time(statbuf->st_mtime)); + printfs(pformat, human_time(statbuf->st_mtime)); } else if (m == 'Y') { - strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len); - printf(pformat, (unsigned long int) statbuf->st_mtime); + strcat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu"); + printf(pformat, (unsigned long) statbuf->st_mtime); } else if (m == 'z') { - strncat(pformat, "s", buf_len); - printf(pformat, human_time(statbuf->st_ctime)); + printfs(pformat, human_time(statbuf->st_ctime)); } else if (m == 'Z') { - strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len); - printf(pformat, (unsigned long int) statbuf->st_ctime); + strcat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu"); + printf(pformat, (unsigned long) statbuf->st_ctime); #if ENABLE_SELINUX } else if (m == 'C' && (option_mask32 & OPT_SELINUX)) { - strncat(pformat, "s", buf_len); - printf(pformat, scontext); + printfs(pformat, scontext); #endif } else { - strncat(pformat, "c", buf_len); + strcatc(pformat, 'c'); printf(pformat, m); } } -static void print_it(char const *masterformat, char const *filename, - void (*print_func) (char *, size_t, char, char const *, void const * - USE_SELINUX(, security_context_t scontext)), - void const *data USE_SELINUX(, security_context_t scontext) ) +static void print_it(const char *masterformat, const char *filename, + void (*print_func) (char*, char, const char*, const void* USE_SELINUX(, security_context_t scontext)), + const void *data + USE_SELINUX(, security_context_t scontext) ) { - char *b; - - /* create a working copy of the format string */ + /* Create a working copy of the format string */ char *format = xstrdup(masterformat); - /* Add 2 to accomodate our conversion of the stat '%s' format string * to the printf '%llu' one. */ - size_t n_alloc = strlen(format) + 2 + 1; - char *dest = xmalloc(n_alloc); + char *dest = xmalloc(strlen(format) + 2 + 1); + char *b; b = format; while (b) { size_t len; char *p = strchr(b, '%'); if (!p) { - /* coreutils 6.3 always print at the end */ + /* coreutils 6.3 always prints at the end */ /*fputs(b, stdout);*/ puts(b); break; @@ -309,10 +310,11 @@ static void print_it(char const *masterformat, char const *filename, *p++ = '\0'; fputs(b, stdout); + /* dest = "%" */ len = strspn(p, "#-+.I 0123456789"); dest[0] = '%'; memcpy(dest + 1, p, len); - dest[1 + len] = 0; + dest[1 + len] = '\0'; p += len; b = p + 1; @@ -321,10 +323,11 @@ static void print_it(char const *masterformat, char const *filename, b = NULL; /* fall through */ case '%': - putchar('%'); + bb_putchar('%'); break; default: - print_func(dest, n_alloc, *p, filename, data USE_SELINUX(,scontext)); + /* Completes "%" with specifier and printfs */ + print_func(dest, *p, filename, data USE_SELINUX(,scontext)); break; } } @@ -335,15 +338,18 @@ static void print_it(char const *masterformat, char const *filename, #endif /* Stat the file system and print what we find. */ -static bool do_statfs(char const *filename, char const *format) +static bool do_statfs(const char *filename, const char *format) { struct statfs statfsbuf; #if ENABLE_SELINUX security_context_t scontext = NULL; if (option_mask32 & OPT_SELINUX) { - if ((option_mask32 & OPT_DEREFERENCE ? lgetfilecon(filename, scontext): - getfilecon(filename, scontext))< 0) { + if ((option_mask32 & OPT_DEREFERENCE + ? lgetfilecon(filename, &scontext) + : getfilecon(filename, &scontext) + ) < 0 + ) { bb_perror_msg(filename); return 0; } @@ -354,9 +360,9 @@ static bool do_statfs(char const *filename, char const *format) return 0; } -#ifdef CONFIG_FEATURE_STAT_FORMAT - if (format == NULL) -#ifndef ENABLE_SELINUX +#if ENABLE_FEATURE_STAT_FORMAT + if (format == NULL) { +#if !ENABLE_SELINUX format = (option_mask32 & OPT_TERSE ? "%n %i %l %t %s %b %f %a %c %d\n" : " File: \"%n\"\n" @@ -364,9 +370,8 @@ static bool do_statfs(char const *filename, char const *format) "Block size: %-10s\n" "Blocks: Total: %-10b Free: %-10f Available: %a\n" "Inodes: Total: %-10c Free: %d"); - print_it(format, filename, print_statfs, &statfsbuf USE_SELINUX(, scontext)); #else - format = (option_mask32 & OPT_TERSE + format = (option_mask32 & OPT_TERSE ? (option_mask32 & OPT_SELINUX ? "%n %i %l %t %s %b %f %a %c %d %C\n": "%n %i %l %t %s %b %f %a %c %d\n") : (option_mask32 & OPT_SELINUX ? @@ -382,8 +387,9 @@ static bool do_statfs(char const *filename, char const *format) "Blocks: Total: %-10b Free: %-10f Available: %a\n" "Inodes: Total: %-10c Free: %d\n") ); - print_it(format, filename, print_statfs, &statfsbuf USE_SELINUX(, scontext)); #endif /* SELINUX */ + } + print_it(format, filename, print_statfs, &statfsbuf USE_SELINUX(, scontext)); #else /* FEATURE_STAT_FORMAT */ format = (option_mask32 & OPT_TERSE ? "%s %llx %lu " @@ -395,7 +401,7 @@ static bool do_statfs(char const *filename, char const *format) statfsbuf.f_namelen); if (option_mask32 & OPT_TERSE) - printf("%lx ", (unsigned long int) (statfsbuf.f_type)); + printf("%lx ", (unsigned long) (statfsbuf.f_type)); else printf("Type: %s\n", human_fstype(statfsbuf.f_type)); @@ -406,7 +412,7 @@ static bool do_statfs(char const *filename, char const *format) "Blocks: Total: %-10jd Free: %-10jd Available: %jd\n" "Inodes: Total: %-10jd Free: %jd\n"); printf(format, - (unsigned long int) (statfsbuf.f_bsize), + (unsigned long) (statfsbuf.f_bsize), (intmax_t) (statfsbuf.f_blocks), (intmax_t) (statfsbuf.f_bfree), (intmax_t) (statfsbuf.f_bavail), @@ -425,7 +431,7 @@ static bool do_statfs(char const *filename, char const *format) "Blocks: Total: %-10jd Free: %-10jd Available: %jd\n" "Inodes: Total: %-10jd Free: %jd\n")); printf(format, - (unsigned long int) (statfsbuf.f_bsize), + (unsigned long) (statfsbuf.f_bsize), (intmax_t) (statfsbuf.f_blocks), (intmax_t) (statfsbuf.f_bfree), (intmax_t) (statfsbuf.f_bavail), @@ -441,16 +447,19 @@ static bool do_statfs(char const *filename, char const *format) } /* stat the file and print what we find */ -static bool do_stat(char const *filename, char const *format) +static bool do_stat(const char *filename, const char *format) { struct stat statbuf; #if ENABLE_SELINUX security_context_t scontext = NULL; if (option_mask32 & OPT_SELINUX) { - if ((option_mask32 & OPT_DEREFERENCE ? lgetfilecon(filename, scontext): - getfilecon(filename, scontext))< 0) { - bb_perror_msg (filename); + if ((option_mask32 & OPT_DEREFERENCE + ? lgetfilecon(filename, &scontext) + : getfilecon(filename, &scontext) + ) < 0 + ) { + bb_perror_msg(filename); return 0; } } @@ -460,9 +469,9 @@ static bool do_stat(char const *filename, char const *format) return 0; } -#ifdef CONFIG_FEATURE_STAT_FORMAT +#if ENABLE_FEATURE_STAT_FORMAT if (format == NULL) { -#ifndef ENABLE_SELINUX +#if !ENABLE_SELINUX if (option_mask32 & OPT_TERSE) { format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o"; } else { @@ -529,24 +538,24 @@ static bool do_stat(char const *filename, char const *format) filename, (uintmax_t) (statbuf.st_size), (uintmax_t) statbuf.st_blocks, - (unsigned long int) statbuf.st_mode, - (unsigned long int) statbuf.st_uid, - (unsigned long int) statbuf.st_gid, + (unsigned long) statbuf.st_mode, + (unsigned long) statbuf.st_uid, + (unsigned long) statbuf.st_gid, (uintmax_t) statbuf.st_dev, (uintmax_t) statbuf.st_ino, - (unsigned long int) statbuf.st_nlink, - (unsigned long int) major(statbuf.st_rdev), - (unsigned long int) minor(statbuf.st_rdev), - (unsigned long int) statbuf.st_atime, - (unsigned long int) statbuf.st_mtime, - (unsigned long int) statbuf.st_ctime, - (unsigned long int) statbuf.st_blksize + (unsigned long) statbuf.st_nlink, + (unsigned long) major(statbuf.st_rdev), + (unsigned long) minor(statbuf.st_rdev), + (unsigned long) statbuf.st_atime, + (unsigned long) statbuf.st_mtime, + (unsigned long) statbuf.st_ctime, + (unsigned long) statbuf.st_blksize ); #if ENABLE_SELINUX if (option_mask32 & OPT_SELINUX) printf(" %lc\n", *scontext); else - putchar('\n'); + bb_putchar('\n'); #endif } else { char *linkname = NULL; @@ -569,24 +578,24 @@ static bool do_stat(char const *filename, char const *format) "Device: %jxh/%jud\tInode: %-10ju Links: %-5lu", (uintmax_t) (statbuf.st_size), (uintmax_t) statbuf.st_blocks, - (unsigned long int) statbuf.st_blksize, + (unsigned long) statbuf.st_blksize, file_type(&statbuf), (uintmax_t) statbuf.st_dev, (uintmax_t) statbuf.st_dev, (uintmax_t) statbuf.st_ino, - (unsigned long int) statbuf.st_nlink); + (unsigned long) statbuf.st_nlink); if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode)) printf(" Device type: %lx,%lx\n", - (unsigned long int) major(statbuf.st_rdev), - (unsigned long int) minor(statbuf.st_rdev)); + (unsigned long) major(statbuf.st_rdev), + (unsigned long) minor(statbuf.st_rdev)); else - putchar('\n'); + bb_putchar('\n'); printf("Access: (%04lo/%10.10s) Uid: (%5lu/%8s) Gid: (%5lu/%8s)\n", - (unsigned long int) (statbuf.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)), + (unsigned long) (statbuf.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)), bb_mode_string(statbuf.st_mode), - (unsigned long int) statbuf.st_uid, + (unsigned long) statbuf.st_uid, (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN", - (unsigned long int) statbuf.st_gid, + (unsigned long) statbuf.st_gid, (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN"); #if ENABLE_SELINUX printf(" S_Context: %lc\n", *scontext); @@ -600,15 +609,15 @@ static bool do_stat(char const *filename, char const *format) return 1; } -int stat_main(int argc, char **argv); +int stat_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int stat_main(int argc, char **argv) { char *format = NULL; int i; int ok = 1; - bool (*statfunc)(char const *, char const *) = do_stat; + bool (*statfunc)(const char *, const char *) = do_stat; - getopt32(argc, argv, "ftL" + getopt32(argv, "ftL" USE_SELINUX("Z") USE_FEATURE_STAT_FORMAT("c:", &format) );