source: MondoRescue/branches/stable/mindi-busybox/coreutils/stat.c@ 1770

Last change on this file since 1770 was 1770, checked in by Bruno Cornec, 16 years ago
  • Better output for mindi-busybox revision
  • Remove dummy file created on NFS - report from Arnaud Tiger <arnaud.tiger_at_hp.com>
  • strace useful for debug
  • fix new versions for pb (2.0.0 for mindi and 1.7.2 for mindi-busybox)
  • fix build process for mindi-busybox + options used in that version (dd for label-partitions-as-necessary)
  • fix typo in label-partitions-as-necessary which doesn't seem to work
  • Update to busybox 1.7.2
  • perl is now required at restore time to support uuid swap partitions (and will be used for many other thigs

in the future for sure)

  • next mindi version will be 2.0.0 due to all the changes made in it (udev may break working distros)
  • small optimization in mindi on keyboard handling (one single find instead of multiple)
  • better interaction for USB device when launching mindi manually
  • attempt to automatically guess block disk size for ramdisk
  • fix typos in bkphw
  • Fix the remaining problem with UUID support for swap partitions
  • Updates mondoarchive man page for USB support
  • Adds preliminary Hardware support to mindi (Proliant SSSTK)
  • Tries to add udev support also for rhel4
  • Fix UUID support which was still broken.
  • Be conservative in test for the start-nfs script
  • Update config file for mindi-busybox for 1.7.2 migration
  • Try to run around a busybox bug (1.2.2 pb on inexistant links)
  • Add build content for mindi-busybox in pb
  • Remove distributions content for mindi-busybox
  • Fix a warning on inexistant raidtab
  • Solve problem on tmpfs in restore init (Problem of inexistant symlink and busybox)
  • Create MONDO_CACHE and use it everywhere + creation at start
  • Really never try to eject a USB device
  • Fix a issue with &> usage (replaced with 1> and 2>)
  • Adds magic file to depllist in order to have file working + ldd which helps for debugging issues
  • tty modes correct to avoid sh error messages
  • Use ext3 normally and not ext2 instead
  • USB device should be corrected after reading (take 1st part)
  • Adds a mount_USB_here function derived from mount_CDROM_here
  • usb detection place before /dev detection in device name at restore time
  • Fix when restoring from USB: media is asked in interactive mode
  • Adds USB support for mondorestore
  • mount_cdrom => mount_media
  • elilo.efi is now searched throughout /boot/efi and not in a fixed place as there is no standard
  • untar-and-softlink => untar (+ interface change)
  • suppress useless softlinks creation/removal in boot process
  • avoids udevd messages on groups
  • Increase # of disks to 99 as in mindi at restore time (should be a conf file parameter)
  • skip existing big file creation
  • seems to work correctly for USB mindi boot
  • Adds group and tty link to udev conf
  • Always load usb-torage (even 2.6) to initiate USB bus discovery
  • Better printing of messages
  • Attempt to fix a bug in supporting OpenSusE 10.3 kernel for initramfs (mindi may now use multiple regex for kernel initrd detection)
  • Links were not correctly done as non relative for modules in mindi
  • exclusion of modules denied now works
  • Also create modules in their ordinary place, so that classical modprobe works + copy modules.dep
  • Fix bugs for DENY_MODS handling
  • Add device /dev/console for udev
  • ide-generic should now really be excluded
  • Fix a bug in major number for tty
  • If udev then adds modprobe/insmod to rootfs
  • tty0 is also cretaed with udev
  • ide-generic put rather in DENY_MODS
  • udevd remove from deplist s handled in mindi directly
  • better default for mindi when using --usb
  • Handles dynamically linked busybox (in case we want to use it soon ;-)
  • Adds fixed devices to create for udev
  • ide-generic should not be part of the initrd when using libata v2
  • support a dynamically linked udev (case on Ubuntu 7.10 and Mandriva 2008.0 so should be quite generic) This will give incitation to move to dyn. linked binaries in the initrd which will help for other tasks (ia6 4)
  • Improvement in udev support (do not use cl options not available in busybox)
  • Udev in mindi
    • auto creation of the right links at boot time with udev-links.conf(from Mandriva 2008.0)
    • rework startup of udev as current makes kernel crash (from Mandriva 2008.0)
    • add support for 64 bits udev
  • Try to render MyInsmod silent at boot time
  • Adds udev support (mandatory for newest distributions to avoid remapping of devices in a different way as on the original system)
  • We also need vaft format support for USB boot
  • Adds libusual support (Ubuntu 7.10 needs it for USB)
  • Improve Ubuntu/Debian keyboard detection and support
  • pbinit adapted to new pb (0.8.10). Filtering of docs done in it
  • Suppress some mondo warnings and errors on USB again
  • Tries to fix lack of files in deb mindi package
  • Verify should now work for USB devices
  • More log/mesages improvement for USB support
  • - Supress g_erase_tmpdir_and_scratchdir
  • Improve some log messages for USB support
  • Try to improve install in mindi to avoid issues with isolinux.cfg not installed vene if in the pkg :-(
  • Improve mindi-busybox build
  • In conformity with pb 0.8.9
  • Add support for Ubuntu 7.10 in build process
  • Add USB Key button to Menu UI (CD streamer removed)
  • Attempt to fix error messages on tmp/scratch files at the end by removing those dir at the latest possible.
  • Fix a bug linked to the size of the -E param which could be used (Arnaud Tiger/René Ribaud).
  • Integrate ~/.pbrc content into mondorescue.pb (required project-builder >= 0.8.7)
  • Put mondorescue in conformity with new pb filtering rules
  • Add USB support at restore time (no test done yet). New start-usb script PB varibale added where useful
  • Unmounting USB device before removal of temporary scratchdir
  • Stil refining USB copy back to mondo (one command was not executed)
  • No need to have the image subdor in the csratchdir when USB.
  • umount the USB partition before attempting to use it
  • Remove useless copy from mindi to mondo at end of USB handling

(risky merge, we are raising the limits of 2 diverging branches. The status of stable is not completely sure as such. Will need lots of tests, but it's not yet done :-()
(merge -r1692:1769 $SVN_M/branches/2.2.5)

File size: 19.4 KB
RevLine 
[1770]1/* vi: set sw=4 ts=4: */
[821]2/*
3 * stat -- display file or file system status
4 *
5 * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation.
6 * Copyright (C) 2005 by Erik Andersen <andersen@codepoet.org>
7 * Copyright (C) 2005 by Mike Frysinger <vapier@gentoo.org>
[1770]8 * Copyright (C) 2006 by Yoshinori Sato <ysato@users.sourceforge.jp>
[821]9 *
10 * Written by Michael Meskes
11 * Taken from coreutils and turned into a busybox applet by Mike Frysinger
12 *
13 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
14 */
15
[1770]16#include "libbb.h"
[821]17
18/* vars to control behavior */
[1770]19#define OPT_FILESYS (1<<0)
20#define OPT_TERSE (1<<1)
21#define OPT_DEREFERENCE (1<<2)
22#define OPT_SELINUX (1<<3)
[821]23
[1770]24static char buf[sizeof("YYYY-MM-DD HH:MM:SS.000000000")] ALIGN1;
25
26static char const * file_type(struct stat const *st)
[821]27{
28 /* See POSIX 1003.1-2001 XCU Table 4-8 lines 17093-17107
29 * for some of these formats.
30 * To keep diagnostics grammatical in English, the
31 * returned string must start with a consonant.
32 */
33 if (S_ISREG(st->st_mode)) return st->st_size == 0 ? "regular empty file" : "regular file";
34 if (S_ISDIR(st->st_mode)) return "directory";
35 if (S_ISBLK(st->st_mode)) return "block special file";
36 if (S_ISCHR(st->st_mode)) return "character special file";
37 if (S_ISFIFO(st->st_mode)) return "fifo";
38 if (S_ISLNK(st->st_mode)) return "symbolic link";
39 if (S_ISSOCK(st->st_mode)) return "socket";
40 if (S_TYPEISMQ(st)) return "message queue";
41 if (S_TYPEISSEM(st)) return "semaphore";
42 if (S_TYPEISSHM(st)) return "shared memory object";
43#ifdef S_TYPEISTMO
44 if (S_TYPEISTMO(st)) return "typed memory object";
45#endif
46 return "weird file";
47}
48
49static char const *human_time(time_t t)
50{
[1770]51 /* Old
[821]52 static char *str;
53 str = ctime(&t);
54 str[strlen(str)-1] = '\0';
55 return str;
[1770]56 */
57 /* coreutils 6.3 compat: */
58
59 strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S.000000000", localtime(&t));
60 return buf;
[821]61}
62
63/* Return the type of the specified file system.
64 * Some systems have statfvs.f_basetype[FSTYPSZ]. (AIX, HP-UX, and Solaris)
65 * Others have statfs.f_fstypename[MFSNAMELEN]. (NetBSD 1.5.2)
66 * Still others have neither and have to get by with f_type (Linux).
67 */
68static char const *human_fstype(long f_type)
69{
70 int i;
71 static const struct types {
72 long type;
[1770]73 const char *const fs;
[821]74 } humantypes[] = {
75 { 0xADFF, "affs" },
76 { 0x1Cd1, "devpts" },
77 { 0x137D, "ext" },
78 { 0xEF51, "ext2" },
79 { 0xEF53, "ext2/ext3" },
80 { 0x3153464a, "jfs" },
81 { 0x58465342, "xfs" },
82 { 0xF995E849, "hpfs" },
83 { 0x9660, "isofs" },
84 { 0x4000, "isofs" },
85 { 0x4004, "isofs" },
86 { 0x137F, "minix" },
87 { 0x138F, "minix (30 char.)" },
88 { 0x2468, "minix v2" },
89 { 0x2478, "minix v2 (30 char.)" },
90 { 0x4d44, "msdos" },
91 { 0x4006, "fat" },
92 { 0x564c, "novell" },
93 { 0x6969, "nfs" },
94 { 0x9fa0, "proc" },
95 { 0x517B, "smb" },
96 { 0x012FF7B4, "xenix" },
97 { 0x012FF7B5, "sysv4" },
98 { 0x012FF7B6, "sysv2" },
99 { 0x012FF7B7, "coh" },
100 { 0x00011954, "ufs" },
101 { 0x012FD16D, "xia" },
102 { 0x5346544e, "ntfs" },
103 { 0x1021994, "tmpfs" },
104 { 0x52654973, "reiserfs" },
105 { 0x28cd3d45, "cramfs" },
106 { 0x7275, "romfs" },
107 { 0x858458f6, "romfs" },
108 { 0x73717368, "squashfs" },
109 { 0x62656572, "sysfs" },
110 { 0, "UNKNOWN" }
111 };
[1770]112 for (i = 0; humantypes[i].type; ++i)
[821]113 if (humantypes[i].type == f_type)
114 break;
115 return humantypes[i].fs;
116}
117
[1770]118#if ENABLE_FEATURE_STAT_FORMAT
[821]119/* print statfs info */
[1770]120static void print_statfs(char *pformat, const size_t buf_len, const char m,
121 const char *const filename, void const *data
122 USE_SELINUX(, security_context_t scontext))
[821]123{
124 struct statfs const *statfsbuf = data;
[1770]125 if (m == 'n') {
[821]126 strncat(pformat, "s", buf_len);
127 printf(pformat, filename);
[1770]128 } else if (m == 'i') {
[821]129 strncat(pformat, "Lx", buf_len);
130 printf(pformat, statfsbuf->f_fsid);
[1770]131 } else if (m == 'l') {
[821]132 strncat(pformat, "lu", buf_len);
133 printf(pformat, statfsbuf->f_namelen);
[1770]134 } else if (m == 't') {
[821]135 strncat(pformat, "lx", buf_len);
[1770]136 printf(pformat, (unsigned long) (statfsbuf->f_type)); /* no equiv */
137 } else if (m == 'T') {
[821]138 strncat(pformat, "s", buf_len);
139 printf(pformat, human_fstype(statfsbuf->f_type));
[1770]140 } else if (m == 'b') {
[821]141 strncat(pformat, "jd", buf_len);
142 printf(pformat, (intmax_t) (statfsbuf->f_blocks));
[1770]143 } else if (m == 'f') {
[821]144 strncat(pformat, "jd", buf_len);
145 printf(pformat, (intmax_t) (statfsbuf->f_bfree));
[1770]146 } else if (m == 'a') {
[821]147 strncat(pformat, "jd", buf_len);
148 printf(pformat, (intmax_t) (statfsbuf->f_bavail));
[1770]149 } else if (m == 's' || m == 'S') {
[821]150 strncat(pformat, "lu", buf_len);
[1770]151 printf(pformat, (unsigned long) (statfsbuf->f_bsize));
152 } else if (m == 'c') {
[821]153 strncat(pformat, "jd", buf_len);
154 printf(pformat, (intmax_t) (statfsbuf->f_files));
[1770]155 } else if (m == 'd') {
[821]156 strncat(pformat, "jd", buf_len);
157 printf(pformat, (intmax_t) (statfsbuf->f_ffree));
[1770]158#if ENABLE_SELINUX
159 } else if (m == 'C' && (option_mask32 & OPT_SELINUX)) {
160 strncat(pformat, "s", buf_len);
161 printf(scontext);
162#endif
163 } else {
[821]164 strncat(pformat, "c", buf_len);
165 printf(pformat, m);
166 }
167}
168
169/* print stat info */
[1770]170static void print_stat(char *pformat, const size_t buf_len, const char m,
171 const char *const filename, void const *data
172 USE_SELINUX(, security_context_t scontext))
[821]173{
174#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
175 struct stat *statbuf = (struct stat *) data;
176 struct passwd *pw_ent;
177 struct group *gw_ent;
178
[1770]179 if (m == 'n') {
[821]180 strncat(pformat, "s", buf_len);
181 printf(pformat, filename);
[1770]182 } else if (m == 'N') {
[821]183 strncat(pformat, "s", buf_len);
184 if (S_ISLNK(statbuf->st_mode)) {
[1770]185 char *linkname = xmalloc_readlink_or_warn(filename);
[821]186 if (linkname == NULL) {
187 bb_perror_msg("cannot read symbolic link '%s'", filename);
188 return;
189 }
190 /*printf("\"%s\" -> \"%s\"", filename, linkname); */
191 printf(pformat, filename);
192 printf(" -> ");
193 printf(pformat, linkname);
194 } else {
195 printf(pformat, filename);
196 }
[1770]197 } else if (m == 'd') {
[821]198 strncat(pformat, "ju", buf_len);
199 printf(pformat, (uintmax_t) statbuf->st_dev);
[1770]200 } else if (m == 'D') {
[821]201 strncat(pformat, "jx", buf_len);
202 printf(pformat, (uintmax_t) statbuf->st_dev);
[1770]203 } else if (m == 'i') {
[821]204 strncat(pformat, "ju", buf_len);
205 printf(pformat, (uintmax_t) statbuf->st_ino);
[1770]206 } else if (m == 'a') {
[821]207 strncat(pformat, "lo", buf_len);
[1770]208 printf(pformat, (unsigned long) (statbuf->st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)));
209 } else if (m == 'A') {
[821]210 strncat(pformat, "s", buf_len);
211 printf(pformat, bb_mode_string(statbuf->st_mode));
[1770]212 } else if (m == 'f') {
[821]213 strncat(pformat, "lx", buf_len);
[1770]214 printf(pformat, (unsigned long) statbuf->st_mode);
215 } else if (m == 'F') {
[821]216 strncat(pformat, "s", buf_len);
217 printf(pformat, file_type(statbuf));
[1770]218 } else if (m == 'h') {
[821]219 strncat(pformat, "lu", buf_len);
[1770]220 printf(pformat, (unsigned long) statbuf->st_nlink);
221 } else if (m == 'u') {
[821]222 strncat(pformat, "lu", buf_len);
[1770]223 printf(pformat, (unsigned long) statbuf->st_uid);
224 } else if (m == 'U') {
[821]225 strncat(pformat, "s", buf_len);
226 setpwent();
227 pw_ent = getpwuid(statbuf->st_uid);
228 printf(pformat, (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN");
[1770]229 } else if (m == 'g') {
[821]230 strncat(pformat, "lu", buf_len);
[1770]231 printf(pformat, (unsigned long) statbuf->st_gid);
232 } else if (m == 'G') {
[821]233 strncat(pformat, "s", buf_len);
234 setgrent();
235 gw_ent = getgrgid(statbuf->st_gid);
236 printf(pformat, (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN");
[1770]237 } else if (m == 't') {
[821]238 strncat(pformat, "lx", buf_len);
[1770]239 printf(pformat, (unsigned long) major(statbuf->st_rdev));
240 } else if (m == 'T') {
[821]241 strncat(pformat, "lx", buf_len);
[1770]242 printf(pformat, (unsigned long) minor(statbuf->st_rdev));
243 } else if (m == 's') {
[821]244 strncat(pformat, "ju", buf_len);
245 printf(pformat, (uintmax_t) (statbuf->st_size));
[1770]246 } else if (m == 'B') {
[821]247 strncat(pformat, "lu", buf_len);
[1770]248 printf(pformat, (unsigned long) 512); //ST_NBLOCKSIZE
249 } else if (m == 'b') {
[821]250 strncat(pformat, "ju", buf_len);
251 printf(pformat, (uintmax_t) statbuf->st_blocks);
[1770]252 } else if (m == 'o') {
[821]253 strncat(pformat, "lu", buf_len);
[1770]254 printf(pformat, (unsigned long) statbuf->st_blksize);
255 } else if (m == 'x') {
[821]256 strncat(pformat, "s", buf_len);
257 printf(pformat, human_time(statbuf->st_atime));
[1770]258 } else if (m == 'X') {
[821]259 strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len);
[1770]260 printf(pformat, (unsigned long) statbuf->st_atime);
261 } else if (m == 'y') {
[821]262 strncat(pformat, "s", buf_len);
263 printf(pformat, human_time(statbuf->st_mtime));
[1770]264 } else if (m == 'Y') {
[821]265 strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len);
[1770]266 printf(pformat, (unsigned long) statbuf->st_mtime);
267 } else if (m == 'z') {
[821]268 strncat(pformat, "s", buf_len);
269 printf(pformat, human_time(statbuf->st_ctime));
[1770]270 } else if (m == 'Z') {
[821]271 strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len);
[1770]272 printf(pformat, (unsigned long) statbuf->st_ctime);
273#if ENABLE_SELINUX
274 } else if (m == 'C' && (option_mask32 & OPT_SELINUX)) {
275 strncat(pformat, "s", buf_len);
276 printf(pformat, scontext);
277#endif
278 } else {
[821]279 strncat(pformat, "c", buf_len);
280 printf(pformat, m);
281 }
282}
283
284static void print_it(char const *masterformat, char const *filename,
[1770]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) )
[821]288{
289 char *b;
290
291 /* create a working copy of the format string */
[1770]292 char *format = xstrdup(masterformat);
[821]293
[1770]294 /* Add 2 to accomodate our conversion of the stat '%s' format string
295 * to the printf '%llu' one. */
[821]296 size_t n_alloc = strlen(format) + 2 + 1;
297 char *dest = xmalloc(n_alloc);
298
299 b = format;
300 while (b) {
[1770]301 size_t len;
[821]302 char *p = strchr(b, '%');
[1770]303 if (!p) {
304 /* coreutils 6.3 always print <cr> at the end */
305 /*fputs(b, stdout);*/
306 puts(b);
307 break;
308 }
309 *p++ = '\0';
310 fputs(b, stdout);
[821]311
[1770]312 len = strspn(p, "#-+.I 0123456789");
313 dest[0] = '%';
314 memcpy(dest + 1, p, len);
315 dest[1 + len] = 0;
316 p += len;
[821]317
[1770]318 b = p + 1;
319 switch (*p) {
320 case '\0':
[821]321 b = NULL;
[1770]322 /* fall through */
323 case '%':
324 putchar('%');
325 break;
326 default:
327 print_func(dest, n_alloc, *p, filename, data USE_SELINUX(,scontext));
328 break;
[821]329 }
330 }
331
332 free(format);
333 free(dest);
334}
335#endif
336
337/* Stat the file system and print what we find. */
[1770]338static bool do_statfs(char const *filename, char const *format)
[821]339{
340 struct statfs statfsbuf;
[1770]341#if ENABLE_SELINUX
342 security_context_t scontext = NULL;
[821]343
[1770]344 if (option_mask32 & OPT_SELINUX) {
345 if ((option_mask32 & OPT_DEREFERENCE
346 ? lgetfilecon(filename, &scontext)
347 : getfilecon(filename, &scontext)
348 ) < 0
349 ) {
350 bb_perror_msg(filename);
351 return 0;
352 }
353 }
354#endif
[821]355 if (statfs(filename, &statfsbuf) != 0) {
356 bb_perror_msg("cannot read file system information for '%s'", filename);
357 return 0;
358 }
359
[1770]360#if ENABLE_FEATURE_STAT_FORMAT
[821]361 if (format == NULL)
[1770]362#if !ENABLE_SELINUX
363 format = (option_mask32 & OPT_TERSE
[821]364 ? "%n %i %l %t %s %b %f %a %c %d\n"
365 : " File: \"%n\"\n"
366 " ID: %-8i Namelen: %-7l Type: %T\n"
367 "Block size: %-10s\n"
368 "Blocks: Total: %-10b Free: %-10f Available: %a\n"
[1770]369 "Inodes: Total: %-10c Free: %d");
370 print_it(format, filename, print_statfs, &statfsbuf USE_SELINUX(, scontext));
[821]371#else
[1770]372 format = (option_mask32 & OPT_TERSE
373 ? (option_mask32 & OPT_SELINUX ? "%n %i %l %t %s %b %f %a %c %d %C\n":
374 "%n %i %l %t %s %b %f %a %c %d\n")
375 : (option_mask32 & OPT_SELINUX ?
376 " File: \"%n\"\n"
377 " ID: %-8i Namelen: %-7l Type: %T\n"
378 "Block size: %-10s\n"
379 "Blocks: Total: %-10b Free: %-10f Available: %a\n"
380 "Inodes: Total: %-10c Free: %d"
381 " S_context: %C\n":
382 " File: \"%n\"\n"
383 " ID: %-8i Namelen: %-7l Type: %T\n"
384 "Block size: %-10s\n"
385 "Blocks: Total: %-10b Free: %-10f Available: %a\n"
386 "Inodes: Total: %-10c Free: %d\n")
387 );
388 print_it(format, filename, print_statfs, &statfsbuf USE_SELINUX(, scontext));
389#endif /* SELINUX */
390#else /* FEATURE_STAT_FORMAT */
391 format = (option_mask32 & OPT_TERSE
[821]392 ? "%s %llx %lu "
393 : " File: \"%s\"\n"
394 " ID: %-8Lx Namelen: %-7lu ");
395 printf(format,
396 filename,
397 statfsbuf.f_fsid,
398 statfsbuf.f_namelen);
399
[1770]400 if (option_mask32 & OPT_TERSE)
401 printf("%lx ", (unsigned long) (statfsbuf.f_type));
[821]402 else
403 printf("Type: %s\n", human_fstype(statfsbuf.f_type));
404
[1770]405#if !ENABLE_SELINUX
406 format = (option_mask32 & OPT_TERSE
[821]407 ? "%lu %ld %ld %ld %ld %ld\n"
408 : "Block size: %-10lu\n"
409 "Blocks: Total: %-10jd Free: %-10jd Available: %jd\n"
410 "Inodes: Total: %-10jd Free: %jd\n");
411 printf(format,
[1770]412 (unsigned long) (statfsbuf.f_bsize),
[821]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));
[1770]418#else
419 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"));
430 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),
437 scontext);
438
439 if (scontext)
440 freecon(scontext);
[821]441#endif
[1770]442#endif /* FEATURE_STAT_FORMAT */
[821]443 return 1;
444}
445
446/* stat the file and print what we find */
[1770]447static bool do_stat(char const *filename, char const *format)
[821]448{
449 struct stat statbuf;
[1770]450#if ENABLE_SELINUX
451 security_context_t scontext = NULL;
[821]452
[1770]453 if (option_mask32 & OPT_SELINUX) {
454 if ((option_mask32 & OPT_DEREFERENCE
455 ? lgetfilecon(filename, &scontext)
456 : getfilecon(filename, &scontext)
457 ) < 0
458 ) {
459 bb_perror_msg(filename);
460 return 0;
461 }
462 }
463#endif
464 if ((option_mask32 & OPT_DEREFERENCE ? stat : lstat) (filename, &statbuf) != 0) {
[821]465 bb_perror_msg("cannot stat '%s'", filename);
466 return 0;
467 }
468
[1770]469#if ENABLE_FEATURE_STAT_FORMAT
[821]470 if (format == NULL) {
[1770]471#if !ENABLE_SELINUX
472 if (option_mask32 & OPT_TERSE) {
473 format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o";
[821]474 } else {
475 if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode)) {
476 format =
477 " File: \"%N\"\n"
478 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
479 "Device: %Dh/%dd\tInode: %-10i Links: %-5h"
480 " Device type: %t,%T\n"
481 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
482 "Access: %x\n" "Modify: %y\n" "Change: %z\n";
483 } else {
484 format =
485 " File: \"%N\"\n"
486 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
487 "Device: %Dh/%dd\tInode: %-10i Links: %h\n"
488 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
489 "Access: %x\n" "Modify: %y\n" "Change: %z\n";
490 }
491 }
[1770]492#else
493 if (option_mask32 & OPT_TERSE) {
494 format = (option_mask32 & OPT_SELINUX ?
495 "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o %C\n":
496 "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n");
497 } else {
498 if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode)) {
499 format = (option_mask32 & OPT_SELINUX ?
500 " File: \"%N\"\n"
501 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
502 "Device: %Dh/%dd\tInode: %-10i Links: %-5h"
503 " Device type: %t,%T\n"
504 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
505 " S_Context: %C\n"
506 "Access: %x\n" "Modify: %y\n" "Change: %z\n":
507 " File: \"%N\"\n"
508 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
509 "Device: %Dh/%dd\tInode: %-10i Links: %-5h"
510 " Device type: %t,%T\n"
511 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
512 "Access: %x\n" "Modify: %y\n" "Change: %z\n");
513 } else {
514 format = (option_mask32 & OPT_SELINUX ?
515 " File: \"%N\"\n"
516 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
517 "Device: %Dh/%dd\tInode: %-10i Links: %h\n"
518 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
519 "S_Context: %C\n"
520 "Access: %x\n" "Modify: %y\n" "Change: %z\n":
521 " File: \"%N\"\n"
522 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
523 "Device: %Dh/%dd\tInode: %-10i Links: %h\n"
524 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
525 "Access: %x\n" "Modify: %y\n" "Change: %z\n");
526 }
527 }
528#endif
[821]529 }
[1770]530 print_it(format, filename, print_stat, &statbuf USE_SELINUX(, scontext));
531#else /* FEATURE_STAT_FORMAT */
532 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"),
[821]535 filename,
536 (uintmax_t) (statbuf.st_size),
537 (uintmax_t) statbuf.st_blocks,
[1770]538 (unsigned long) statbuf.st_mode,
539 (unsigned long) statbuf.st_uid,
540 (unsigned long) statbuf.st_gid,
[821]541 (uintmax_t) statbuf.st_dev,
542 (uintmax_t) statbuf.st_ino,
[1770]543 (unsigned long) statbuf.st_nlink,
544 (unsigned long) major(statbuf.st_rdev),
545 (unsigned long) minor(statbuf.st_rdev),
546 (unsigned long) statbuf.st_atime,
547 (unsigned long) statbuf.st_mtime,
548 (unsigned long) statbuf.st_ctime,
549 (unsigned long) statbuf.st_blksize
[821]550 );
[1770]551#if ENABLE_SELINUX
552 if (option_mask32 & OPT_SELINUX)
553 printf(" %lc\n", *scontext);
554 else
555 putchar('\n');
556#endif
[821]557 } else {
558 char *linkname = NULL;
559
560 struct passwd *pw_ent;
561 struct group *gw_ent;
562 setgrent();
563 gw_ent = getgrgid(statbuf.st_gid);
564 setpwent();
565 pw_ent = getpwuid(statbuf.st_uid);
566
567 if (S_ISLNK(statbuf.st_mode))
[1770]568 linkname = xmalloc_readlink_or_warn(filename);
[821]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,
[1770]578 (unsigned long) statbuf.st_blksize,
[821]579 file_type(&statbuf),
580 (uintmax_t) statbuf.st_dev,
581 (uintmax_t) statbuf.st_dev,
582 (uintmax_t) statbuf.st_ino,
[1770]583 (unsigned long) statbuf.st_nlink);
[821]584 if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode))
585 printf(" Device type: %lx,%lx\n",
[1770]586 (unsigned long) major(statbuf.st_rdev),
587 (unsigned long) minor(statbuf.st_rdev));
[821]588 else
589 putchar('\n');
[1770]590 printf("Access: (%04lo/%10.10s) Uid: (%5lu/%8s) Gid: (%5lu/%8s)\n",
591 (unsigned long) (statbuf.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)),
[821]592 bb_mode_string(statbuf.st_mode),
[1770]593 (unsigned long) statbuf.st_uid,
[821]594 (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN",
[1770]595 (unsigned long) statbuf.st_gid,
596 (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN");
597#if ENABLE_SELINUX
598 printf(" S_Context: %lc\n", *scontext);
599#endif
600 printf("Access: %s\n" "Modify: %s\n" "Change: %s\n",
[821]601 human_time(statbuf.st_atime),
602 human_time(statbuf.st_mtime),
603 human_time(statbuf.st_ctime));
604 }
[1770]605#endif /* FEATURE_STAT_FORMAT */
[821]606 return 1;
607}
608
[1770]609int stat_main(int argc, char **argv);
[821]610int stat_main(int argc, char **argv)
611{
[1770]612 char *format = NULL;
[821]613 int i;
614 int ok = 1;
[1770]615 bool (*statfunc)(char const *, char const *) = do_stat;
[821]616
[1770]617 getopt32(argv, "ftL"
618 USE_SELINUX("Z")
619 USE_FEATURE_STAT_FORMAT("c:", &format)
[821]620 );
621
[1770]622 if (option_mask32 & OPT_FILESYS) /* -f */
[821]623 statfunc = do_statfs;
624 if (argc == optind) /* files */
625 bb_show_usage();
626
[1770]627#if ENABLE_SELINUX
628 if (option_mask32 & OPT_SELINUX) {
629 selinux_or_die();
630 }
631#endif /* ENABLE_SELINUX */
[821]632 for (i = optind; i < argc; ++i)
633 ok &= statfunc(argv[i], format);
634
635 return (ok ? EXIT_SUCCESS : EXIT_FAILURE);
636}
Note: See TracBrowser for help on using the repository browser.