aboutsummaryrefslogtreecommitdiff
path: root/coreutils/stat.c
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2005-04-23 06:26:38 +0000
committerMike Frysinger <vapier@gentoo.org>2005-04-23 06:26:38 +0000
commit9b5f71ec029776e21bda6c4c61e6b463fd3a2314 (patch)
tree962bf98157f322d70e5c0fdd7fce5ef6865bbd3d /coreutils/stat.c
parent84ab267e226407ee402eff10aaf8239ed684de77 (diff)
downloadbusybox-w32-9b5f71ec029776e21bda6c4c61e6b463fd3a2314.tar.gz
busybox-w32-9b5f71ec029776e21bda6c4c61e6b463fd3a2314.tar.bz2
busybox-w32-9b5f71ec029776e21bda6c4c61e6b463fd3a2314.zip
stat implementation based upon coreutils
Diffstat (limited to 'coreutils/stat.c')
-rw-r--r--coreutils/stat.c599
1 files changed, 599 insertions, 0 deletions
diff --git a/coreutils/stat.c b/coreutils/stat.c
new file mode 100644
index 000000000..e386d75a0
--- /dev/null
+++ b/coreutils/stat.c
@@ -0,0 +1,599 @@
1/*
2 * stat -- display file or file system status
3 *
4 * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation.
5 * Copyright (C) 2005 by Erik Andersen <andersen@codepoet.org>
6 * Copyright (C) 2005 by Mike Frysinger <vapier@gentoo.org>
7 *
8 * Written by Michael Meskes
9 * Taken from coreutils and turned into a busybox applet by Mike Frysinger
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27#include <stdio.h>
28#include <sys/types.h>
29#include <pwd.h>
30#include <grp.h>
31#include <sys/vfs.h>
32#include <time.h>
33#include <getopt.h>
34#include <sys/stat.h>
35#include <string.h>
36#include "busybox.h"
37
38/* vars to control behavior */
39static int follow_links = 0;
40static int terse = 0;
41
42static char const *file_type(struct stat const *st)
43{
44 /* See POSIX 1003.1-2001 XCU Table 4-8 lines 17093-17107
45 * for some of these formats.
46 * To keep diagnostics grammatical in English, the
47 * returned string must start with a consonant.
48 */
49 if (S_ISREG(st->st_mode)) return st->st_size == 0 ? "regular empty file" : "regular file";
50 if (S_ISDIR(st->st_mode)) return "directory";
51 if (S_ISBLK(st->st_mode)) return "block special file";
52 if (S_ISCHR(st->st_mode)) return "character special file";
53 if (S_ISFIFO(st->st_mode)) return "fifo";
54 if (S_ISLNK(st->st_mode)) return "symbolic link";
55 if (S_ISSOCK(st->st_mode)) return "socket";
56 if (S_TYPEISMQ(st)) return "message queue";
57 if (S_TYPEISSEM(st)) return "semaphore";
58 if (S_TYPEISSHM(st)) return "shared memory object";
59#ifdef S_TYPEISTMO
60 if (S_TYPEISTMO(st)) return "typed memory object";
61#endif
62 return "weird file";
63}
64
65static char const *human_time(time_t t)
66{
67 static char *str;
68 str = ctime(&t);
69 str[strlen(str)-1] = '\0';
70 return str;
71}
72
73/* Return the type of the specified file system.
74 * Some systems have statfvs.f_basetype[FSTYPSZ]. (AIX, HP-UX, and Solaris)
75 * Others have statfs.f_fstypename[MFSNAMELEN]. (NetBSD 1.5.2)
76 * Still others have neither and have to get by with f_type (Linux).
77 */
78static char const *human_fstype(long f_type)
79{
80#define S_MAGIC_AFFS 0xADFF
81#define S_MAGIC_DEVPTS 0x1CD1
82#define S_MAGIC_EXT 0x137D
83#define S_MAGIC_EXT2_OLD 0xEF51
84#define S_MAGIC_EXT2 0xEF53
85#define S_MAGIC_JFS 0x3153464a
86#define S_MAGIC_XFS 0x58465342
87#define S_MAGIC_HPFS 0xF995E849
88#define S_MAGIC_ISOFS 0x9660
89#define S_MAGIC_ISOFS_WIN 0x4000
90#define S_MAGIC_ISOFS_R_WIN 0x4004
91#define S_MAGIC_MINIX 0x137F
92#define S_MAGIC_MINIX_30 0x138F
93#define S_MAGIC_MINIX_V2 0x2468
94#define S_MAGIC_MINIX_V2_30 0x2478
95#define S_MAGIC_MSDOS 0x4d44
96#define S_MAGIC_FAT 0x4006
97#define S_MAGIC_NCP 0x564c
98#define S_MAGIC_NFS 0x6969
99#define S_MAGIC_PROC 0x9fa0
100#define S_MAGIC_SMB 0x517B
101#define S_MAGIC_XENIX 0x012FF7B4
102#define S_MAGIC_SYSV4 0x012FF7B5
103#define S_MAGIC_SYSV2 0x012FF7B6
104#define S_MAGIC_COH 0x012FF7B7
105#define S_MAGIC_UFS 0x00011954
106#define S_MAGIC_XIAFS 0x012FD16D
107#define S_MAGIC_NTFS 0x5346544e
108#define S_MAGIC_TMPFS 0x1021994
109#define S_MAGIC_REISERFS 0x52654973
110#define S_MAGIC_CRAMFS 0x28cd3d45
111#define S_MAGIC_ROMFS 0x7275
112#define S_MAGIC_RAMFS 0x858458f6
113#define S_MAGIC_SQUASHFS 0x73717368
114#define S_MAGIC_SYSFS 0x62656572
115 switch (f_type) {
116 case S_MAGIC_AFFS: return "affs";
117 case S_MAGIC_DEVPTS: return "devpts";
118 case S_MAGIC_EXT: return "ext";
119 case S_MAGIC_EXT2_OLD: return "ext2";
120 case S_MAGIC_EXT2: return "ext2/ext3";
121 case S_MAGIC_JFS: return "jfs";
122 case S_MAGIC_XFS: return "xfs";
123 case S_MAGIC_HPFS: return "hpfs";
124 case S_MAGIC_ISOFS: return "isofs";
125 case S_MAGIC_ISOFS_WIN: return "isofs";
126 case S_MAGIC_ISOFS_R_WIN: return "isofs";
127 case S_MAGIC_MINIX: return "minix";
128 case S_MAGIC_MINIX_30: return "minix (30 char.)";
129 case S_MAGIC_MINIX_V2: return "minix v2";
130 case S_MAGIC_MINIX_V2_30: return "minix v2 (30 char.)";
131 case S_MAGIC_MSDOS: return "msdos";
132 case S_MAGIC_FAT: return "fat";
133 case S_MAGIC_NCP: return "novell";
134 case S_MAGIC_NFS: return "nfs";
135 case S_MAGIC_PROC: return "proc";
136 case S_MAGIC_SMB: return "smb";
137 case S_MAGIC_XENIX: return "xenix";
138 case S_MAGIC_SYSV4: return "sysv4";
139 case S_MAGIC_SYSV2: return "sysv2";
140 case S_MAGIC_COH: return "coh";
141 case S_MAGIC_UFS: return "ufs";
142 case S_MAGIC_XIAFS: return "xia";
143 case S_MAGIC_NTFS: return "ntfs";
144 case S_MAGIC_TMPFS: return "tmpfs";
145 case S_MAGIC_REISERFS: return "reiserfs";
146 case S_MAGIC_CRAMFS: return "cramfs";
147 case S_MAGIC_ROMFS: return "romfs";
148 case S_MAGIC_RAMFS: return "ramfs";
149 case S_MAGIC_SQUASHFS: return "squashfs";
150 case S_MAGIC_SYSFS: return "sysfs";
151 default: {
152 static char buf[sizeof("UNKNOWN (0x%lx)") - 3
153 + (sizeof(f_type) * CHAR_BIT + 3) / 4];
154 sprintf(buf, "UNKNOWN (0x%lx)", f_type);
155 return buf;
156 }
157 }
158}
159
160#ifdef CONFIG_FEATURE_STAT_FORMAT
161/* print statfs info */
162static void print_statfs(char *pformat, size_t buf_len, char m,
163 char const *filename, void const *data)
164{
165 struct statfs const *statfsbuf = data;
166
167 switch (m) {
168 case 'n':
169 strncat(pformat, "s", buf_len);
170 printf(pformat, filename);
171 break;
172 case 'i':
173 strncat(pformat, "Lx", buf_len);
174 printf(pformat, statfsbuf->f_fsid);
175 break;
176 case 'l':
177 strncat(pformat, "lu", buf_len);
178 printf(pformat, statfsbuf->f_namelen);
179 break;
180 case 't':
181 strncat(pformat, "lx", buf_len);
182 printf(pformat, (unsigned long int) (statfsbuf->f_type)); /* no equiv. */
183 break;
184 case 'T':
185 strncat(pformat, "s", buf_len);
186 printf(pformat, human_fstype(statfsbuf->f_type));
187 break;
188 case 'b':
189 strncat(pformat, "ld", buf_len);
190 printf(pformat, (intmax_t) (statfsbuf->f_blocks));
191 break;
192 case 'f':
193 strncat(pformat, "ld", buf_len);
194 printf(pformat, (intmax_t) (statfsbuf->f_bfree));
195 break;
196 case 'a':
197 strncat(pformat, "ld", buf_len);
198 printf(pformat, (intmax_t) (statfsbuf->f_bavail));
199 break;
200 case 's':
201 strncat(pformat, "lu", buf_len);
202 printf(pformat, (unsigned long int) (statfsbuf->f_bsize));
203 break;
204 case 'S': {
205 unsigned long int frsize = statfsbuf->f_frsize;
206 if (!frsize)
207 frsize = statfsbuf->f_bsize;
208 strncat(pformat, "lu", buf_len);
209 printf(pformat, frsize);
210 break;
211 }
212 case 'c':
213 strncat(pformat, "ld", buf_len);
214 printf(pformat, (intmax_t) (statfsbuf->f_files));
215 break;
216 case 'd':
217 strncat(pformat, "ld", buf_len);
218 printf(pformat, (intmax_t) (statfsbuf->f_ffree));
219 break;
220 default:
221 strncat(pformat, "c", buf_len);
222 printf(pformat, m);
223 break;
224 }
225}
226
227/* print stat info */
228static void print_stat(char *pformat, size_t buf_len, char m,
229 char const *filename, void const *data)
230{
231#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
232 struct stat *statbuf = (struct stat *) data;
233 struct passwd *pw_ent;
234 struct group *gw_ent;
235
236 switch (m) {
237 case 'n':
238 strncat(pformat, "s", buf_len);
239 printf(pformat, filename);
240 break;
241 case 'N':
242 strncat(pformat, "s", buf_len);
243 if (S_ISLNK(statbuf->st_mode)) {
244 char *linkname = xreadlink(filename);
245 if (linkname == NULL) {
246 bb_perror_msg("cannot read symbolic link '%s'", filename);
247 return;
248 }
249 /*printf("\"%s\" -> \"%s\"", filename, linkname); */
250 printf(pformat, filename);
251 printf(" -> ");
252 printf(pformat, linkname);
253 } else {
254 printf(pformat, filename);
255 }
256 break;
257 case 'd':
258 strncat(pformat, "lu", buf_len);
259 printf(pformat, (uintmax_t) statbuf->st_dev);
260 break;
261 case 'D':
262 strncat(pformat, "lx", buf_len);
263 printf(pformat, (uintmax_t) statbuf->st_dev);
264 break;
265 case 'i':
266 strncat(pformat, "lu", buf_len);
267 printf(pformat, (uintmax_t) statbuf->st_ino);
268 break;
269 case 'a':
270 strncat(pformat, "lo", buf_len);
271 printf(pformat, (unsigned long int) (statbuf->st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)));
272 break;
273 case 'A':
274 strncat(pformat, "s", buf_len);
275 printf(pformat, bb_mode_string(statbuf->st_mode));
276 break;
277 case 'f':
278 strncat(pformat, "lx", buf_len);
279 printf(pformat, (unsigned long int) statbuf->st_mode);
280 break;
281 case 'F':
282 strncat(pformat, "s", buf_len);
283 printf(pformat, file_type(statbuf));
284 break;
285 case 'h':
286 strncat(pformat, "lu", buf_len);
287 printf(pformat, (unsigned long int) statbuf->st_nlink);
288 break;
289 case 'u':
290 strncat(pformat, "lu", buf_len);
291 printf(pformat, (unsigned long int) statbuf->st_uid);
292 break;
293 case 'U':
294 strncat(pformat, "s", buf_len);
295 setpwent();
296 pw_ent = getpwuid(statbuf->st_uid);
297 printf(pformat, (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN");
298 break;
299 case 'g':
300 strncat(pformat, "lu", buf_len);
301 printf(pformat, (unsigned long int) statbuf->st_gid);
302 break;
303 case 'G':
304 strncat(pformat, "s", buf_len);
305 setgrent();
306 gw_ent = getgrgid(statbuf->st_gid);
307 printf(pformat, (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN");
308 break;
309 case 't':
310 strncat(pformat, "lx", buf_len);
311 printf(pformat, (unsigned long int) major(statbuf->st_rdev));
312 break;
313 case 'T':
314 strncat(pformat, "lx", buf_len);
315 printf(pformat, (unsigned long int) minor(statbuf->st_rdev));
316 break;
317 case 's':
318 strncat(pformat, "lu", buf_len);
319 printf(pformat, (uintmax_t) (statbuf->st_size));
320 break;
321 case 'B':
322 strncat(pformat, "lu", buf_len);
323 printf(pformat, (unsigned long int) 512); //ST_NBLOCKSIZE
324 break;
325 case 'b':
326 strncat(pformat, "lu", buf_len);
327 printf(pformat, (uintmax_t) statbuf->st_blocks);
328 break;
329 case 'o':
330 strncat(pformat, "lu", buf_len);
331 printf(pformat, (unsigned long int) statbuf->st_blksize);
332 break;
333 case 'x':
334 strncat(pformat, "s", buf_len);
335 printf(pformat, human_time(statbuf->st_atime));
336 break;
337 case 'X':
338 strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len);
339 printf(pformat, (unsigned long int) statbuf->st_atime);
340 break;
341 case 'y':
342 strncat(pformat, "s", buf_len);
343 printf(pformat, human_time(statbuf->st_mtime));
344 break;
345 case 'Y':
346 strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len);
347 printf(pformat, (unsigned long int) statbuf->st_mtime);
348 break;
349 case 'z':
350 strncat(pformat, "s", buf_len);
351 printf(pformat, human_time(statbuf->st_ctime));
352 break;
353 case 'Z':
354 strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len);
355 printf(pformat, (unsigned long int) statbuf->st_ctime);
356 break;
357 default:
358 strncat(pformat, "c", buf_len);
359 printf(pformat, m);
360 break;
361 }
362}
363
364static void print_it(char const *masterformat, char const *filename,
365 void (*print_func) (char *, size_t, char, char const *, void const *),
366 void const *data)
367{
368 char *b;
369
370 /* create a working copy of the format string */
371 char *format = bb_xstrdup(masterformat);
372
373 /* Add 2 to accommodate our conversion of the stat `%s' format string
374 * to the printf `%llu' one. */
375 size_t n_alloc = strlen(format) + 2 + 1;
376 char *dest = xmalloc(n_alloc);
377
378 b = format;
379 while (b) {
380 char *p = strchr(b, '%');
381 if (p != NULL) {
382 size_t len;
383 *p++ = '\0';
384 fputs(b, stdout);
385
386 len = strspn(p, "#-+.I 0123456789");
387 dest[0] = '%';
388 memcpy(dest + 1, p, len);
389 dest[1 + len] = 0;
390 p += len;
391
392 b = p + 1;
393 switch (*p) {
394 case '\0':
395 b = NULL;
396 /* fall through */
397 case '%':
398 putchar('%');
399 break;
400 default:
401 print_func(dest, n_alloc, *p, filename, data);
402 break;
403 }
404
405 } else {
406 fputs(b, stdout);
407 b = NULL;
408 }
409 }
410
411 free(format);
412 free(dest);
413}
414#endif
415
416/* Stat the file system and print what we find. */
417static int do_statfs(char const *filename, char const *format)
418{
419 struct statfs statfsbuf;
420
421 if (statfs(filename, &statfsbuf) != 0) {
422 bb_perror_msg("cannot read file system information for '%s'", filename);
423 return 0;
424 }
425
426#ifdef CONFIG_FEATURE_STAT_FORMAT
427 if (format == NULL)
428 format = (terse
429 ? "%n %i %l %t %s %S %b %f %a %c %d\n"
430 : " File: \"%n\"\n"
431 " ID: %-8i Namelen: %-7l Type: %T\n"
432 "Block size: %-10s Fundamental block size: %S\n"
433 "Blocks: Total: %-10b Free: %-10f Available: %a\n"
434 "Inodes: Total: %-10c Free: %d\n");
435 print_it(format, filename, print_statfs, &statfsbuf);
436#else
437
438 format = (terse
439 ? "%s %Lx %lu "
440 : " File: \"%s\"\n"
441 " ID: %-8Lx Namelen: %-7lu ");
442 printf(format,
443 filename,
444 statfsbuf.f_fsid,
445 statfsbuf.f_namelen);
446
447 if (terse)
448 printf("%lx ", (unsigned long int) (statfsbuf.f_type));
449 else
450 printf("Type: %s\n", human_fstype(statfsbuf.f_type));
451
452 format = (terse
453 ? "%lu %lu %ld %ld %ld %ld %ld\n"
454 : "Block size: %-10lu Fundamental block size: %lu\n"
455 "Blocks: Total: %-10ld Free: %-10ld Available: %ld\n"
456 "Inodes: Total: %-10ld Free: %ld\n");
457 printf(format,
458 (unsigned long int) (statfsbuf.f_bsize),
459 statfsbuf.f_frsize ? statfsbuf.f_frsize : statfsbuf.f_bsize,
460 (intmax_t) (statfsbuf.f_blocks),
461 (intmax_t) (statfsbuf.f_bfree),
462 (intmax_t) (statfsbuf.f_bavail),
463 (intmax_t) (statfsbuf.f_files),
464 (intmax_t) (statfsbuf.f_ffree));
465#endif
466
467 return 1;
468}
469
470/* stat the file and print what we find */
471static int do_stat(char const *filename, char const *format)
472{
473 struct stat statbuf;
474
475 if ((follow_links ? stat : lstat) (filename, &statbuf) != 0) {
476 bb_perror_msg("cannot stat '%s'", filename);
477 return 0;
478 }
479
480#ifdef CONFIG_FEATURE_STAT_FORMAT
481 if (format == NULL) {
482 if (terse) {
483 format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n";
484 } else {
485 if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode)) {
486 format =
487 " File: \"%N\"\n"
488 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
489 "Device: %Dh/%dd\tInode: %-10i Links: %-5h"
490 " Device type: %t,%T\n"
491 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
492 "Access: %x\n" "Modify: %y\n" "Change: %z\n";
493 } else {
494 format =
495 " File: \"%N\"\n"
496 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
497 "Device: %Dh/%dd\tInode: %-10i Links: %h\n"
498 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
499 "Access: %x\n" "Modify: %y\n" "Change: %z\n";
500 }
501 }
502 }
503 print_it(format, filename, print_stat, &statbuf);
504#else
505 if (terse) {
506 printf("%s %lu %lu %lx %lu %lu %lx %lu %lu %lx %lx %lu %lu %lu %lu\n",
507 filename,
508 (uintmax_t) (statbuf.st_size),
509 (uintmax_t) statbuf.st_blocks,
510 (unsigned long int) statbuf.st_mode,
511 (unsigned long int) statbuf.st_uid,
512 (unsigned long int) statbuf.st_gid,
513 (uintmax_t) statbuf.st_dev,
514 (uintmax_t) statbuf.st_ino,
515 (unsigned long int) statbuf.st_nlink,
516 (unsigned long int) major(statbuf.st_rdev),
517 (unsigned long int) minor(statbuf.st_rdev),
518 (unsigned long int) statbuf.st_atime,
519 (unsigned long int) statbuf.st_mtime,
520 (unsigned long int) statbuf.st_ctime,
521 (unsigned long int) statbuf.st_blksize
522 );
523 } else {
524 char *linkname = NULL;
525
526 struct passwd *pw_ent;
527 struct group *gw_ent;
528 setgrent();
529 gw_ent = getgrgid(statbuf.st_gid);
530 setpwent();
531 pw_ent = getpwuid(statbuf.st_uid);
532
533 if (S_ISLNK(statbuf.st_mode))
534 linkname = xreadlink(filename);
535 if (linkname)
536 printf(" File: \"%s\" -> \"%s\"\n", filename, linkname);
537 else
538 printf(" File: \"%s\"\n", filename);
539
540 printf(" Size: %-10lu\tBlocks: %-10lu IO Block: %-6lu %s\n"
541 "Device: %lxh/%lud\tInode: %-10lu Links: %-5lu",
542 (uintmax_t) (statbuf.st_size),
543 (uintmax_t) statbuf.st_blocks,
544 (unsigned long int) statbuf.st_blksize,
545 file_type(&statbuf),
546 (uintmax_t) statbuf.st_dev,
547 (uintmax_t) statbuf.st_dev,
548 (uintmax_t) statbuf.st_ino,
549 (unsigned long int) statbuf.st_nlink);
550 if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode))
551 printf(" Device type: %lx,%lx\n",
552 (unsigned long int) major(statbuf.st_rdev),
553 (unsigned long int) minor(statbuf.st_rdev));
554 else
555 putchar('\n');
556 printf("Access: (%04lo/%10.10s) Uid: (%5lu/%8s) Gid: (%5lu/%8s)\n"
557 "Access: %s\n" "Modify: %s\n" "Change: %s\n",
558 (unsigned long int) (statbuf.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)),
559 bb_mode_string(statbuf.st_mode),
560 (unsigned long int) statbuf.st_uid,
561 (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN",
562 (unsigned long int) statbuf.st_gid,
563 (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN",
564 human_time(statbuf.st_atime),
565 human_time(statbuf.st_mtime),
566 human_time(statbuf.st_ctime));
567 }
568#endif
569 return 1;
570}
571
572int stat_main(int argc, char **argv)
573{
574 int i;
575 char *format = NULL;
576 int ok = 1;
577 long flags;
578 int (*statfunc)(char const *, char const *) = do_stat;
579
580 flags = bb_getopt_ulflags(argc, argv, "fLlt"
581#ifdef CONFIG_FEATURE_STAT_FORMAT
582 "c:", &format
583#endif
584 );
585
586 if (flags & 1) /* -f */
587 statfunc = do_statfs;
588 if (flags & 2 || flags & 4) /* -L, -l */
589 follow_links = 1;
590 if (flags & 8) /* -t */
591 terse = 1;
592 if (argc == optind) /* files */
593 bb_show_usage();
594
595 for (i = optind; i < argc; ++i)
596 ok &= statfunc(argv[i], format);
597
598 return (ok ? EXIT_SUCCESS : EXIT_FAILURE);
599}