Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/coreutils/stat.c
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/coreutils/stat.c
r1765 r2725 11 11 * Taken from coreutils and turned into a busybox applet by Mike Frysinger 12 12 * 13 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.13 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 14 14 */ 15 16 15 #include "libbb.h" 17 16 18 /* vars to control behavior */ 19 #define OPT_FILESYS (1<<0) 20 #define OPT_TERSE (1<<1) 21 #define OPT_DEREFERENCE (1<<2) 22 #define OPT_SELINUX (1<<3) 23 24 static char buf[sizeof("YYYY-MM-DD HH:MM:SS.000000000")] ALIGN1; 25 26 static char const * file_type(struct stat const *st) 17 #define OPT_FILESYS (1 << 0) 18 #define OPT_TERSE (1 << 1) 19 #define OPT_DEREFERENCE (1 << 2) 20 #define OPT_SELINUX (1 << 3) 21 22 #if ENABLE_FEATURE_STAT_FORMAT 23 typedef bool (*statfunc_ptr)(const char *, const char *); 24 #else 25 typedef bool (*statfunc_ptr)(const char *); 26 #endif 27 28 static const char *file_type(const struct stat *st) 27 29 { 28 30 /* See POSIX 1003.1-2001 XCU Table 4-8 lines 17093-17107 … … 47 49 } 48 50 49 static c har const*human_time(time_t t)51 static const char *human_time(time_t t) 50 52 { 51 53 /* Old … … 57 59 /* coreutils 6.3 compat: */ 58 60 61 /*static char buf[sizeof("YYYY-MM-DD HH:MM:SS.000000000")] ALIGN1;*/ 62 #define buf bb_common_bufsiz1 63 59 64 strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S.000000000", localtime(&t)); 60 65 return buf; 66 #undef buf 61 67 } 62 68 … … 66 72 * Still others have neither and have to get by with f_type (Linux). 67 73 */ 68 static char const *human_fstype(long f_type) 69 { 70 int i; 74 static const char *human_fstype(uint32_t f_type) 75 { 71 76 static const struct types { 72 longtype;77 uint32_t type; 73 78 const char *const fs; 74 79 } humantypes[] = { … … 110 115 { 0, "UNKNOWN" } 111 116 }; 117 118 int i; 119 112 120 for (i = 0; humantypes[i].type; ++i) 113 121 if (humantypes[i].type == f_type) … … 116 124 } 117 125 126 /* "man statfs" says that statfsbuf->f_fsid is a mess */ 127 /* coreutils treats it as an array of ints, most significant first */ 128 static unsigned long long get_f_fsid(const struct statfs *statfsbuf) 129 { 130 const unsigned *p = (const void*) &statfsbuf->f_fsid; 131 unsigned sz = sizeof(statfsbuf->f_fsid) / sizeof(unsigned); 132 unsigned long long r = 0; 133 134 do 135 r = (r << (sizeof(unsigned)*8)) | *p++; 136 while (--sz > 0); 137 return r; 138 } 139 118 140 #if ENABLE_FEATURE_STAT_FORMAT 141 static void strcatc(char *str, char c) 142 { 143 int len = strlen(str); 144 str[len++] = c; 145 str[len] = '\0'; 146 } 147 148 static void printfs(char *pformat, const char *msg) 149 { 150 strcatc(pformat, 's'); 151 printf(pformat, msg); 152 } 153 119 154 /* print statfs info */ 120 static void print_statfs(char *pformat, const size_t buf_len, const char m,121 const char *const filename, void const*data122 USE_SELINUX(, security_context_t scontext))123 { 124 struct statfs const*statfsbuf = data;155 static void FAST_FUNC print_statfs(char *pformat, const char m, 156 const char *const filename, const void *data 157 IF_SELINUX(, security_context_t scontext)) 158 { 159 const struct statfs *statfsbuf = data; 125 160 if (m == 'n') { 126 strncat(pformat, "s", buf_len); 127 printf(pformat, filename); 161 printfs(pformat, filename); 128 162 } else if (m == 'i') { 129 str ncat(pformat, "Lx", buf_len);130 printf(pformat, statfsbuf->f_fsid);163 strcat(pformat, "llx"); 164 printf(pformat, get_f_fsid(statfsbuf)); 131 165 } else if (m == 'l') { 132 str ncat(pformat, "lu", buf_len);133 printf(pformat, statfsbuf->f_namelen);166 strcat(pformat, "lu"); 167 printf(pformat, (unsigned long) statfsbuf->f_namelen); 134 168 } else if (m == 't') { 135 str ncat(pformat, "lx", buf_len);136 printf(pformat, (unsigned long) (statfsbuf->f_type)); /* no equiv */169 strcat(pformat, "lx"); 170 printf(pformat, (unsigned long) statfsbuf->f_type); /* no equiv */ 137 171 } else if (m == 'T') { 138 strncat(pformat, "s", buf_len); 139 printf(pformat, human_fstype(statfsbuf->f_type)); 172 printfs(pformat, human_fstype(statfsbuf->f_type)); 140 173 } else if (m == 'b') { 141 str ncat(pformat, "jd", buf_len);142 printf(pformat, ( intmax_t) (statfsbuf->f_blocks));174 strcat(pformat, "llu"); 175 printf(pformat, (unsigned long long) statfsbuf->f_blocks); 143 176 } else if (m == 'f') { 144 str ncat(pformat, "jd", buf_len);145 printf(pformat, ( intmax_t) (statfsbuf->f_bfree));177 strcat(pformat, "llu"); 178 printf(pformat, (unsigned long long) statfsbuf->f_bfree); 146 179 } else if (m == 'a') { 147 str ncat(pformat, "jd", buf_len);148 printf(pformat, ( intmax_t) (statfsbuf->f_bavail));180 strcat(pformat, "llu"); 181 printf(pformat, (unsigned long long) statfsbuf->f_bavail); 149 182 } else if (m == 's' || m == 'S') { 150 str ncat(pformat, "lu", buf_len);151 printf(pformat, (unsigned long) (statfsbuf->f_bsize));183 strcat(pformat, "lu"); 184 printf(pformat, (unsigned long) statfsbuf->f_bsize); 152 185 } else if (m == 'c') { 153 str ncat(pformat, "jd", buf_len);154 printf(pformat, ( intmax_t) (statfsbuf->f_files));186 strcat(pformat, "llu"); 187 printf(pformat, (unsigned long long) statfsbuf->f_files); 155 188 } else if (m == 'd') { 156 str ncat(pformat, "jd", buf_len);157 printf(pformat, ( intmax_t) (statfsbuf->f_ffree));158 # if ENABLE_SELINUX189 strcat(pformat, "llu"); 190 printf(pformat, (unsigned long long) statfsbuf->f_ffree); 191 # if ENABLE_SELINUX 159 192 } else if (m == 'C' && (option_mask32 & OPT_SELINUX)) { 160 strncat(pformat, "s", buf_len); 161 printf(scontext); 162 #endif 193 printfs(pformat, scontext); 194 # endif 163 195 } else { 164 str ncat(pformat, "c", buf_len);196 strcatc(pformat, 'c'); 165 197 printf(pformat, m); 166 198 } … … 168 200 169 201 /* print stat info */ 170 static void print_stat(char *pformat, const size_t buf_len, const char m,171 const char *const filename, void const*data172 USE_SELINUX(, security_context_t scontext))202 static void FAST_FUNC print_stat(char *pformat, const char m, 203 const char *const filename, const void *data 204 IF_SELINUX(, security_context_t scontext)) 173 205 { 174 206 #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) … … 178 210 179 211 if (m == 'n') { 180 strncat(pformat, "s", buf_len); 181 printf(pformat, filename); 212 printfs(pformat, filename); 182 213 } else if (m == 'N') { 183 str ncat(pformat, "s", buf_len);214 strcatc(pformat, 's'); 184 215 if (S_ISLNK(statbuf->st_mode)) { 185 216 char *linkname = xmalloc_readlink_or_warn(filename); 186 if (linkname == NULL) { 187 bb_perror_msg("cannot read symbolic link '%s'", filename); 217 if (linkname == NULL) 188 218 return; 189 } 190 /*printf("\"%s\" -> \"%s\"", filename, linkname); */ 191 printf(pformat, filename); 192 printf(" -> "); 193 printf(pformat, linkname); 219 printf("'%s' -> '%s'", filename, linkname); 220 free(linkname); 194 221 } else { 195 222 printf(pformat, filename); 196 223 } 197 224 } else if (m == 'd') { 198 str ncat(pformat, "ju", buf_len);199 printf(pformat, (u intmax_t) statbuf->st_dev);225 strcat(pformat, "llu"); 226 printf(pformat, (unsigned long long) statbuf->st_dev); 200 227 } else if (m == 'D') { 201 str ncat(pformat, "jx", buf_len);202 printf(pformat, (u intmax_t) statbuf->st_dev);228 strcat(pformat, "llx"); 229 printf(pformat, (unsigned long long) statbuf->st_dev); 203 230 } else if (m == 'i') { 204 str ncat(pformat, "ju", buf_len);205 printf(pformat, (u intmax_t) statbuf->st_ino);231 strcat(pformat, "llu"); 232 printf(pformat, (unsigned long long) statbuf->st_ino); 206 233 } else if (m == 'a') { 207 str ncat(pformat, "lo", buf_len);234 strcat(pformat, "lo"); 208 235 printf(pformat, (unsigned long) (statbuf->st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO))); 209 236 } else if (m == 'A') { 210 strncat(pformat, "s", buf_len); 211 printf(pformat, bb_mode_string(statbuf->st_mode)); 237 printfs(pformat, bb_mode_string(statbuf->st_mode)); 212 238 } else if (m == 'f') { 213 str ncat(pformat, "lx", buf_len);239 strcat(pformat, "lx"); 214 240 printf(pformat, (unsigned long) statbuf->st_mode); 215 241 } else if (m == 'F') { 216 strncat(pformat, "s", buf_len); 217 printf(pformat, file_type(statbuf)); 242 printfs(pformat, file_type(statbuf)); 218 243 } else if (m == 'h') { 219 str ncat(pformat, "lu", buf_len);244 strcat(pformat, "lu"); 220 245 printf(pformat, (unsigned long) statbuf->st_nlink); 221 246 } else if (m == 'u') { 222 str ncat(pformat, "lu", buf_len);247 strcat(pformat, "lu"); 223 248 printf(pformat, (unsigned long) statbuf->st_uid); 224 249 } else if (m == 'U') { 225 strncat(pformat, "s", buf_len);226 setpwent();227 250 pw_ent = getpwuid(statbuf->st_uid); 228 printf (pformat, (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN");251 printfs(pformat, (pw_ent != NULL) ? pw_ent->pw_name : "UNKNOWN"); 229 252 } else if (m == 'g') { 230 str ncat(pformat, "lu", buf_len);253 strcat(pformat, "lu"); 231 254 printf(pformat, (unsigned long) statbuf->st_gid); 232 255 } else if (m == 'G') { 233 strncat(pformat, "s", buf_len);234 setgrent();235 256 gw_ent = getgrgid(statbuf->st_gid); 236 printf (pformat, (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN");257 printfs(pformat, (gw_ent != NULL) ? gw_ent->gr_name : "UNKNOWN"); 237 258 } else if (m == 't') { 238 str ncat(pformat, "lx", buf_len);259 strcat(pformat, "lx"); 239 260 printf(pformat, (unsigned long) major(statbuf->st_rdev)); 240 261 } else if (m == 'T') { 241 str ncat(pformat, "lx", buf_len);262 strcat(pformat, "lx"); 242 263 printf(pformat, (unsigned long) minor(statbuf->st_rdev)); 243 264 } else if (m == 's') { 244 str ncat(pformat, "ju", buf_len);245 printf(pformat, (u intmax_t) (statbuf->st_size));265 strcat(pformat, "llu"); 266 printf(pformat, (unsigned long long) statbuf->st_size); 246 267 } else if (m == 'B') { 247 str ncat(pformat, "lu", buf_len);268 strcat(pformat, "lu"); 248 269 printf(pformat, (unsigned long) 512); //ST_NBLOCKSIZE 249 270 } else if (m == 'b') { 250 str ncat(pformat, "ju", buf_len);251 printf(pformat, (u intmax_t) statbuf->st_blocks);271 strcat(pformat, "llu"); 272 printf(pformat, (unsigned long long) statbuf->st_blocks); 252 273 } else if (m == 'o') { 253 str ncat(pformat, "lu", buf_len);274 strcat(pformat, "lu"); 254 275 printf(pformat, (unsigned long) statbuf->st_blksize); 255 276 } else if (m == 'x') { 256 strncat(pformat, "s", buf_len); 257 printf(pformat, human_time(statbuf->st_atime)); 277 printfs(pformat, human_time(statbuf->st_atime)); 258 278 } else if (m == 'X') { 259 strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len); 260 printf(pformat, (unsigned long) statbuf->st_atime); 279 strcat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu"); 280 /* note: (unsigned long) would be wrong: 281 * imagine (unsigned long64)int32 */ 282 printf(pformat, (long) statbuf->st_atime); 261 283 } else if (m == 'y') { 262 strncat(pformat, "s", buf_len); 263 printf(pformat, human_time(statbuf->st_mtime)); 284 printfs(pformat, human_time(statbuf->st_mtime)); 264 285 } else if (m == 'Y') { 265 str ncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len);266 printf(pformat, ( unsignedlong) statbuf->st_mtime);286 strcat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu"); 287 printf(pformat, (long) statbuf->st_mtime); 267 288 } else if (m == 'z') { 268 strncat(pformat, "s", buf_len); 269 printf(pformat, human_time(statbuf->st_ctime)); 289 printfs(pformat, human_time(statbuf->st_ctime)); 270 290 } else if (m == 'Z') { 271 str ncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len);272 printf(pformat, ( unsignedlong) statbuf->st_ctime);273 # if ENABLE_SELINUX291 strcat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu"); 292 printf(pformat, (long) statbuf->st_ctime); 293 # if ENABLE_SELINUX 274 294 } else if (m == 'C' && (option_mask32 & OPT_SELINUX)) { 275 strncat(pformat, "s", buf_len); 276 printf(pformat, scontext); 277 #endif 295 printfs(pformat, scontext); 296 # endif 278 297 } else { 279 str ncat(pformat, "c", buf_len);298 strcatc(pformat, 'c'); 280 299 printf(pformat, m); 281 300 } 282 301 } 283 302 284 static void print_it(char const *masterformat, char const *filename, 285 void (*print_func) (char *, size_t, char, char const *, void const * 286 USE_SELINUX(, security_context_t scontext)), 287 void const *data USE_SELINUX(, security_context_t scontext) ) 288 { 289 char *b; 290 291 /* create a working copy of the format string */ 303 static void print_it(const char *masterformat, 304 const char *filename, 305 void FAST_FUNC (*print_func)(char*, char, const char*, const void* IF_SELINUX(, security_context_t scontext)), 306 const void *data 307 IF_SELINUX(, security_context_t scontext)) 308 { 309 /* Create a working copy of the format string */ 292 310 char *format = xstrdup(masterformat); 293 294 311 /* Add 2 to accomodate our conversion of the stat '%s' format string 295 312 * to the printf '%llu' one. */ 296 size_t n_alloc = strlen(format) + 2 + 1;297 char * dest = xmalloc(n_alloc);313 char *dest = xmalloc(strlen(format) + 2 + 1); 314 char *b; 298 315 299 316 b = format; 300 317 while (b) { 318 /* Each iteration finds next %spec, 319 * prints preceding string and handles found %spec 320 */ 301 321 size_t len; 302 322 char *p = strchr(b, '%'); 303 323 if (!p) { 304 /* coreutils 6.3 always print <cr>at the end */324 /* coreutils 6.3 always prints newline at the end */ 305 325 /*fputs(b, stdout);*/ 306 326 puts(b); 307 327 break; 308 328 } 309 *p++ = '\0'; 329 330 /* dest = "%<modifiers>" */ 331 len = 1 + strspn(p + 1, "#-+.I 0123456789"); 332 memcpy(dest, p, len); 333 dest[len] = '\0'; 334 335 /* print preceding string */ 336 *p = '\0'; 310 337 fputs(b, stdout); 311 338 312 len = strspn(p, "#-+.I 0123456789");313 dest[0] = '%';314 memcpy(dest + 1, p, len);315 dest[1 + len] = 0;316 339 p += len; 317 318 340 b = p + 1; 319 341 switch (*p) { … … 322 344 /* fall through */ 323 345 case '%': 324 putchar('%');346 bb_putchar('%'); 325 347 break; 326 348 default: 327 print_func(dest, n_alloc, *p, filename, data USE_SELINUX(,scontext)); 349 /* Completes "%<modifiers>" with specifier and printfs */ 350 print_func(dest, *p, filename, data IF_SELINUX(,scontext)); 328 351 break; 329 352 } … … 333 356 free(dest); 334 357 } 335 #endif 358 #endif /* FEATURE_STAT_FORMAT */ 336 359 337 360 /* Stat the file system and print what we find. */ 338 static bool do_statfs(char const *filename, char const *format) 361 #if !ENABLE_FEATURE_STAT_FORMAT 362 #define do_statfs(filename, format) do_statfs(filename) 363 #endif 364 static bool do_statfs(const char *filename, const char *format) 339 365 { 340 366 struct statfs statfsbuf; 367 #if !ENABLE_FEATURE_STAT_FORMAT 368 const char *format; 369 #endif 341 370 #if ENABLE_SELINUX 342 371 security_context_t scontext = NULL; … … 354 383 #endif 355 384 if (statfs(filename, &statfsbuf) != 0) { 356 bb_perror_msg("can not read file system information for '%s'", filename);385 bb_perror_msg("can't read file system information for '%s'", filename); 357 386 return 0; 358 387 } 359 388 360 389 #if ENABLE_FEATURE_STAT_FORMAT 361 if (format == NULL) 362 # if !ENABLE_SELINUX390 if (format == NULL) { 391 # if !ENABLE_SELINUX 363 392 format = (option_mask32 & OPT_TERSE 364 393 ? "%n %i %l %t %s %b %f %a %c %d\n" … … 368 397 "Blocks: Total: %-10b Free: %-10f Available: %a\n" 369 398 "Inodes: Total: %-10c Free: %d"); 370 print_it(format, filename, print_statfs, &statfsbuf USE_SELINUX(, scontext)); 371 #else 372 format = (option_mask32 & OPT_TERSE 399 # else 400 format = (option_mask32 & OPT_TERSE 373 401 ? (option_mask32 & OPT_SELINUX ? "%n %i %l %t %s %b %f %a %c %d %C\n": 374 402 "%n %i %l %t %s %b %f %a %c %d\n") … … 386 414 "Inodes: Total: %-10c Free: %d\n") 387 415 ); 388 print_it(format, filename, print_statfs, &statfsbuf USE_SELINUX(, scontext)); 389 #endif /* SELINUX */ 416 # endif /* SELINUX */ 417 } 418 print_it(format, filename, print_statfs, &statfsbuf IF_SELINUX(, scontext)); 390 419 #else /* FEATURE_STAT_FORMAT */ 391 420 format = (option_mask32 & OPT_TERSE 392 421 ? "%s %llx %lu " 393 422 : " File: \"%s\"\n" 394 " ID: %-8 Lx Namelen: %-7lu ");423 " ID: %-8llx Namelen: %-7lu "); 395 424 printf(format, 396 425 filename, 397 statfsbuf.f_fsid,426 get_f_fsid(&statfsbuf), 398 427 statfsbuf.f_namelen); 399 428 400 429 if (option_mask32 & OPT_TERSE) 401 printf("%lx ", (unsigned long) (statfsbuf.f_type));430 printf("%lx ", (unsigned long) statfsbuf.f_type); 402 431 else 403 432 printf("Type: %s\n", human_fstype(statfsbuf.f_type)); 404 433 405 # if !ENABLE_SELINUX434 # if !ENABLE_SELINUX 406 435 format = (option_mask32 & OPT_TERSE 407 ? "%lu %l d %ld %ld %ld %ld\n"436 ? "%lu %llu %llu %llu %llu %llu\n" 408 437 : "Block size: %-10lu\n" 409 "Blocks: Total: %-10 jd Free: %-10jd Available: %jd\n"410 "Inodes: Total: %-10 jd Free: %jd\n");438 "Blocks: Total: %-10llu Free: %-10llu Available: %llu\n" 439 "Inodes: Total: %-10llu Free: %llu\n"); 411 440 printf(format, 412 (unsigned long) (statfsbuf.f_bsize),413 ( intmax_t) (statfsbuf.f_blocks),414 ( intmax_t) (statfsbuf.f_bfree),415 ( intmax_t) (statfsbuf.f_bavail),416 ( intmax_t) (statfsbuf.f_files),417 ( intmax_t) (statfsbuf.f_ffree));418 # else441 (unsigned long) statfsbuf.f_bsize, 442 (unsigned long long) statfsbuf.f_blocks, 443 (unsigned long long) statfsbuf.f_bfree, 444 (unsigned long long) statfsbuf.f_bavail, 445 (unsigned long long) statfsbuf.f_files, 446 (unsigned long long) statfsbuf.f_ffree); 447 # else 419 448 format = (option_mask32 & OPT_TERSE 420 ? (option_mask32 & OPT_SELINUX ? "%lu %ld %ld %ld %ld %ld %C\n": 421 "%lu %ld %ld %ld %ld %ld\n") 422 : (option_mask32 & OPT_SELINUX ? 423 "Block size: %-10lu\n" 424 "Blocks: Total: %-10jd Free: %-10jd Available: %jd\n" 425 "Inodes: Total: %-10jd Free: %jd" 426 "S_context: %C\n": 427 "Block size: %-10lu\n" 428 "Blocks: Total: %-10jd Free: %-10jd Available: %jd\n" 429 "Inodes: Total: %-10jd Free: %jd\n")); 449 ? (option_mask32 & OPT_SELINUX ? "%lu %llu %llu %llu %llu %llu %C\n" : "%lu %llu %llu %llu %llu %llu\n") 450 : (option_mask32 & OPT_SELINUX 451 ? "Block size: %-10lu\n" 452 "Blocks: Total: %-10llu Free: %-10llu Available: %llu\n" 453 "Inodes: Total: %-10llu Free: %llu" 454 "S_context: %C\n" 455 : "Block size: %-10lu\n" 456 "Blocks: Total: %-10llu Free: %-10llu Available: %llu\n" 457 "Inodes: Total: %-10llu Free: %llu\n" 458 ) 459 ); 430 460 printf(format, 431 (unsigned long) (statfsbuf.f_bsize),432 (intmax_t) (statfsbuf.f_blocks),433 (intmax_t) (statfsbuf.f_bfree),434 (intmax_t) (statfsbuf.f_bavail),435 (intmax_t) (statfsbuf.f_files),436 (intmax_t) (statfsbuf.f_ffree),461 (unsigned long) statfsbuf.f_bsize, 462 (unsigned long long) statfsbuf.f_blocks, 463 (unsigned long long) statfsbuf.f_bfree, 464 (unsigned long long) statfsbuf.f_bavail, 465 (unsigned long long) statfsbuf.f_files, 466 (unsigned long long) statfsbuf.f_ffree, 437 467 scontext); 438 468 439 469 if (scontext) 440 470 freecon(scontext); 441 # endif442 #endif 471 # endif 472 #endif /* FEATURE_STAT_FORMAT */ 443 473 return 1; 444 474 } 445 475 446 476 /* stat the file and print what we find */ 447 static bool do_stat(char const *filename, char const *format) 477 #if !ENABLE_FEATURE_STAT_FORMAT 478 #define do_stat(filename, format) do_stat(filename) 479 #endif 480 static bool do_stat(const char *filename, const char *format) 448 481 { 449 482 struct stat statbuf; … … 463 496 #endif 464 497 if ((option_mask32 & OPT_DEREFERENCE ? stat : lstat) (filename, &statbuf) != 0) { 465 bb_perror_msg("can not stat '%s'", filename);498 bb_perror_msg("can't stat '%s'", filename); 466 499 return 0; 467 500 } … … 469 502 #if ENABLE_FEATURE_STAT_FORMAT 470 503 if (format == NULL) { 471 # if !ENABLE_SELINUX504 # if !ENABLE_SELINUX 472 505 if (option_mask32 & OPT_TERSE) { 473 506 format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o"; … … 475 508 if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode)) { 476 509 format = 477 " File: \"%N\"\n"510 " File: %N\n" 478 511 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" 479 512 "Device: %Dh/%dd\tInode: %-10i Links: %-5h" … … 483 516 } else { 484 517 format = 485 " File: \"%N\"\n"518 " File: %N\n" 486 519 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" 487 520 "Device: %Dh/%dd\tInode: %-10i Links: %h\n" … … 490 523 } 491 524 } 492 # else525 # else 493 526 if (option_mask32 & OPT_TERSE) { 494 527 format = (option_mask32 & OPT_SELINUX ? … … 498 531 if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode)) { 499 532 format = (option_mask32 & OPT_SELINUX ? 500 " File: \"%N\"\n"533 " File: %N\n" 501 534 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" 502 535 "Device: %Dh/%dd\tInode: %-10i Links: %-5h" … … 505 538 " S_Context: %C\n" 506 539 "Access: %x\n" "Modify: %y\n" "Change: %z\n": 507 " File: \"%N\"\n"540 " File: %N\n" 508 541 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" 509 542 "Device: %Dh/%dd\tInode: %-10i Links: %-5h" … … 513 546 } else { 514 547 format = (option_mask32 & OPT_SELINUX ? 515 " File: \"%N\"\n"548 " File: %N\n" 516 549 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" 517 550 "Device: %Dh/%dd\tInode: %-10i Links: %h\n" … … 519 552 "S_Context: %C\n" 520 553 "Access: %x\n" "Modify: %y\n" "Change: %z\n": 521 " File: \"%N\"\n"554 " File: %N\n" 522 555 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" 523 556 "Device: %Dh/%dd\tInode: %-10i Links: %h\n" … … 526 559 } 527 560 } 528 # endif529 } 530 print_it(format, filename, print_stat, &statbuf USE_SELINUX(, scontext));561 # endif 562 } 563 print_it(format, filename, print_stat, &statbuf IF_SELINUX(, scontext)); 531 564 #else /* FEATURE_STAT_FORMAT */ 532 565 if (option_mask32 & OPT_TERSE) { 533 printf("%s % ju %ju %lx %lu %lu %jx %ju %lu %lx %lx %lu %lu %lu %lu"534 SKIP_SELINUX("\n"),566 printf("%s %llu %llu %lx %lu %lu %llx %llu %lu %lx %lx %lu %lu %lu %lu" 567 IF_NOT_SELINUX("\n"), 535 568 filename, 536 (u intmax_t) (statbuf.st_size),537 (u intmax_t) statbuf.st_blocks,569 (unsigned long long) statbuf.st_size, 570 (unsigned long long) statbuf.st_blocks, 538 571 (unsigned long) statbuf.st_mode, 539 572 (unsigned long) statbuf.st_uid, 540 573 (unsigned long) statbuf.st_gid, 541 (u intmax_t) statbuf.st_dev,542 (u intmax_t) statbuf.st_ino,574 (unsigned long long) statbuf.st_dev, 575 (unsigned long long) statbuf.st_ino, 543 576 (unsigned long) statbuf.st_nlink, 544 577 (unsigned long) major(statbuf.st_rdev), … … 549 582 (unsigned long) statbuf.st_blksize 550 583 ); 551 # if ENABLE_SELINUX584 # if ENABLE_SELINUX 552 585 if (option_mask32 & OPT_SELINUX) 553 586 printf(" %lc\n", *scontext); 554 587 else 555 putchar('\n');556 # endif588 bb_putchar('\n'); 589 # endif 557 590 } else { 558 591 char *linkname = NULL; 559 560 592 struct passwd *pw_ent; 561 593 struct group *gw_ent; 562 setgrent(); 594 563 595 gw_ent = getgrgid(statbuf.st_gid); 564 setpwent();565 596 pw_ent = getpwuid(statbuf.st_uid); 566 597 567 598 if (S_ISLNK(statbuf.st_mode)) 568 599 linkname = xmalloc_readlink_or_warn(filename); 569 if (linkname) 570 printf(" File: \"%s\" -> \"%s\"\n", filename, linkname); 571 else 572 printf(" File: \"%s\"\n", filename); 573 574 printf(" Size: %-10ju\tBlocks: %-10ju IO Block: %-6lu %s\n" 575 "Device: %jxh/%jud\tInode: %-10ju Links: %-5lu", 576 (uintmax_t) (statbuf.st_size), 577 (uintmax_t) statbuf.st_blocks, 600 if (linkname) { 601 printf(" File: '%s' -> '%s'\n", filename, linkname); 602 free(linkname); 603 } else { 604 printf(" File: '%s'\n", filename); 605 } 606 607 printf(" Size: %-10llu\tBlocks: %-10llu IO Block: %-6lu %s\n" 608 "Device: %llxh/%llud\tInode: %-10llu Links: %-5lu", 609 (unsigned long long) statbuf.st_size, 610 (unsigned long long) statbuf.st_blocks, 578 611 (unsigned long) statbuf.st_blksize, 579 612 file_type(&statbuf), 580 (u intmax_t) statbuf.st_dev,581 (u intmax_t) statbuf.st_dev,582 (u intmax_t) statbuf.st_ino,613 (unsigned long long) statbuf.st_dev, 614 (unsigned long long) statbuf.st_dev, 615 (unsigned long long) statbuf.st_ino, 583 616 (unsigned long) statbuf.st_nlink); 584 617 if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode)) … … 587 620 (unsigned long) minor(statbuf.st_rdev)); 588 621 else 589 putchar('\n');622 bb_putchar('\n'); 590 623 printf("Access: (%04lo/%10.10s) Uid: (%5lu/%8s) Gid: (%5lu/%8s)\n", 591 624 (unsigned long) (statbuf.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)), 592 625 bb_mode_string(statbuf.st_mode), 593 626 (unsigned long) statbuf.st_uid, 594 (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN",627 (pw_ent != NULL) ? pw_ent->pw_name : "UNKNOWN", 595 628 (unsigned long) statbuf.st_gid, 596 (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN"); 629 (gw_ent != NULL) ? gw_ent->gr_name : "UNKNOWN"); 630 # if ENABLE_SELINUX 631 printf(" S_Context: %lc\n", *scontext); 632 # endif 633 printf("Access: %s\n", human_time(statbuf.st_atime)); 634 printf("Modify: %s\n", human_time(statbuf.st_mtime)); 635 printf("Change: %s\n", human_time(statbuf.st_ctime)); 636 } 637 #endif /* FEATURE_STAT_FORMAT */ 638 return 1; 639 } 640 641 int stat_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 642 int stat_main(int argc UNUSED_PARAM, char **argv) 643 { 644 IF_FEATURE_STAT_FORMAT(char *format = NULL;) 645 int i; 646 int ok; 647 unsigned opts; 648 statfunc_ptr statfunc = do_stat; 649 650 opt_complementary = "-1"; /* min one arg */ 651 opts = getopt32(argv, "ftL" 652 IF_SELINUX("Z") 653 IF_FEATURE_STAT_FORMAT("c:", &format) 654 ); 655 if (opts & OPT_FILESYS) /* -f */ 656 statfunc = do_statfs; 597 657 #if ENABLE_SELINUX 598 printf(" S_Context: %lc\n", *scontext); 599 #endif 600 printf("Access: %s\n" "Modify: %s\n" "Change: %s\n", 601 human_time(statbuf.st_atime), 602 human_time(statbuf.st_mtime), 603 human_time(statbuf.st_ctime)); 604 } 605 #endif /* FEATURE_STAT_FORMAT */ 606 return 1; 607 } 608 609 int stat_main(int argc, char **argv); 610 int stat_main(int argc, char **argv) 611 { 612 char *format = NULL; 613 int i; 614 int ok = 1; 615 bool (*statfunc)(char const *, char const *) = do_stat; 616 617 getopt32(argv, "ftL" 618 USE_SELINUX("Z") 619 USE_FEATURE_STAT_FORMAT("c:", &format) 620 ); 621 622 if (option_mask32 & OPT_FILESYS) /* -f */ 623 statfunc = do_statfs; 624 if (argc == optind) /* files */ 625 bb_show_usage(); 626 627 #if ENABLE_SELINUX 628 if (option_mask32 & OPT_SELINUX) { 658 if (opts & OPT_SELINUX) { 629 659 selinux_or_die(); 630 660 } 631 #endif /* ENABLE_SELINUX */ 632 for (i = optind; i < argc; ++i) 633 ok &= statfunc(argv[i], format); 661 #endif 662 ok = 1; 663 argv += optind; 664 for (i = 0; argv[i]; ++i) 665 ok &= statfunc(argv[i] IF_FEATURE_STAT_FORMAT(, format)); 634 666 635 667 return (ok ? EXIT_SUCCESS : EXIT_FAILURE);
Note:
See TracChangeset
for help on using the changeset viewer.