(du invocation): Describe new option: -0, --null.
[coreutils.git] / src / stat.c
blob8b988165393d4046d4147caa3c95229f117f6490
1 /* stat.c -- display file or filesystem status
2 Copyright (C) 2001, 2002, 2003 Free Software Foundation.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 Written by Michael Meskes. */
20 #include <config.h>
22 #include <stdio.h>
23 #include <sys/types.h>
24 #include <pwd.h>
25 #include <grp.h>
26 #if HAVE_SYS_STATVFS_H && HAVE_STRUCT_STATVFS_F_BASETYPE
27 # include <sys/statvfs.h>
28 #elif HAVE_SYS_VFS_H
29 # include <sys/vfs.h>
30 #elif HAVE_SYS_MOUNT_H && HAVE_SYS_PARAM_H
31 /* NOTE: freebsd5.0 needs sys/param.h and sys/mount.h for statfs.
32 It does have statvfs.h, but shouldn't use it, since it doesn't
33 HAVE_STRUCT_STATVFS_F_BASETYPE. So find a clean way to fix it. */
34 /* NetBSD 1.5.2 needs these, for the declaration of struct statfs. */
35 # include <sys/param.h>
36 # include <sys/mount.h>
37 # if HAVE_NETINET_IN_H && HAVE_NFS_NFS_CLNT_H && HAVE_NFS_VFS_H
38 /* Ultrix 4.4 needs these for the declaration of struct statfs. */
39 # include <netinet/in.h>
40 # include <nfs/nfs_clnt.h>
41 # include <nfs/vfs.h>
42 # endif
43 #endif
45 #include "system.h"
47 #include "error.h"
48 #include "filemode.h"
49 #include "file-type.h"
50 #include "fs.h"
51 #include "getopt.h"
52 #include "quote.h"
53 #include "quotearg.h"
54 #include "strftime.h"
55 #include "xreadlink.h"
57 #define NAMEMAX_FORMAT PRIuMAX
59 #if HAVE_STRUCT_STATVFS_F_BASETYPE
60 # define STRUCT_STATVFS struct statvfs
61 # define HAVE_STRUCT_STATXFS_F_TYPE HAVE_STRUCT_STATVFS
62 # if HAVE_STRUCT_STATVFS_F_NAMEMAX
63 # define SB_F_NAMEMAX(S) ((uintmax_t) ((S)->f_namemax))
64 # endif
65 #else
66 # define STRUCT_STATVFS struct statfs
67 # define HAVE_STRUCT_STATXFS_F_TYPE HAVE_STRUCT_STATFS
68 # if HAVE_STRUCT_STATFS_F_NAMELEN
69 # define SB_F_NAMEMAX(S) ((uintmax_t) ((S)->f_namelen))
70 # endif
71 #endif
73 #ifndef SB_F_NAMEMAX
74 /* NetBSD 1.5.2 has neither f_namemax nor f_namelen. */
75 # define SB_F_NAMEMAX(S) "*"
76 # undef NAMEMAX_FORMAT
77 # define NAMEMAX_FORMAT "s"
78 #endif
80 #if HAVE_STRUCT_STATVFS_F_BASETYPE
81 # define STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME f_basetype
82 #else
83 # if HAVE_STRUCT_STATFS_F_FSTYPENAME
84 # define STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME f_fstypename
85 # endif
86 #endif
88 #define PROGRAM_NAME "stat"
90 #define AUTHORS "Michael Meskes"
92 static struct option const long_options[] = {
93 {"link", no_argument, 0, 'l'}, /* deprecated. FIXME: remove in 2003 */
94 {"dereference", no_argument, 0, 'L'},
95 {"format", required_argument, 0, 'c'},
96 {"filesystem", no_argument, 0, 'f'},
97 {"terse", no_argument, 0, 't'},
98 {GETOPT_HELP_OPTION_DECL},
99 {GETOPT_VERSION_OPTION_DECL},
100 {NULL, 0, NULL, 0}
103 /* Nonzero means we should exit with EXIT_FAILURE upon completion. */
104 static int G_fail;
106 char *program_name;
108 /* Return the type of the specified file system.
109 Some systems have statfvs.f_basetype[FSTYPSZ]. (AIX, HP-UX, and Solaris)
110 Others have statfs.f_fstypename[MFSNAMELEN]. (NetBSD 1.5.2)
111 Still others have neither and have to get by with f_type (Linux). */
112 static char *
113 human_fstype (STRUCT_STATVFS const *statfsbuf)
115 #ifdef STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME
116 /* Cast away the `const' attribute. */
117 return (char *) statfsbuf->STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME;
118 #else
119 char const *type;
120 switch (statfsbuf->f_type)
122 # if defined __linux__
124 /* IMPORTANT NOTE: Each of the following `case S_MAGIC_...:'
125 statements must be followed by a hexadecimal constant in
126 a comment. The S_MAGIC_... name and constant are automatically
127 combined to produce the #define directives in fs.h. */
129 case S_MAGIC_AFFS: /* 0xADFF */
130 type = "affs";
131 break;
132 case S_MAGIC_DEVPTS: /* 0x1CD1 */
133 type = "devpts";
134 break;
135 case S_MAGIC_EXT: /* 0x137D */
136 type = "ext";
137 break;
138 case S_MAGIC_EXT2_OLD: /* 0xEF51 */
139 type = "ext2";
140 break;
141 case S_MAGIC_EXT2: /* 0xEF53 */
142 type = "ext2/ext3";
143 break;
144 case S_MAGIC_HPFS: /* 0xF995E849 */
145 type = "hpfs";
146 break;
147 case S_MAGIC_ISOFS: /* 0x9660 */
148 type = "isofs";
149 break;
150 case S_MAGIC_ISOFS_WIN: /* 0x4000 */
151 type = "isofs";
152 break;
153 case S_MAGIC_ISOFS_R_WIN: /* 0x4004 */
154 type = "isofs";
155 break;
156 case S_MAGIC_MINIX: /* 0x137F */
157 type = "minix";
158 break;
159 case S_MAGIC_MINIX_30: /* 0x138F */
160 type = "minix (30 char.)";
161 break;
162 case S_MAGIC_MINIX_V2: /* 0x2468 */
163 type = "minix v2";
164 break;
165 case S_MAGIC_MINIX_V2_30: /* 0x2478 */
166 type = "minix v2 (30 char.)";
167 break;
168 case S_MAGIC_MSDOS: /* 0x4d44 */
169 type = "msdos";
170 break;
171 case S_MAGIC_FAT: /* 0x4006 */
172 type = "fat";
173 break;
174 case S_MAGIC_NCP: /* 0x564c */
175 type = "novell";
176 break;
177 case S_MAGIC_NFS: /* 0x6969 */
178 type = "nfs";
179 break;
180 case S_MAGIC_PROC: /* 0x9fa0 */
181 type = "proc";
182 break;
183 case S_MAGIC_SMB: /* 0x517B */
184 type = "smb";
185 break;
186 case S_MAGIC_XENIX: /* 0x012FF7B4 */
187 type = "xenix";
188 break;
189 case S_MAGIC_SYSV4: /* 0x012FF7B5 */
190 type = "sysv4";
191 break;
192 case S_MAGIC_SYSV2: /* 0x012FF7B6 */
193 type = "sysv2";
194 break;
195 case S_MAGIC_COH: /* 0x012FF7B7 */
196 type = "coh";
197 break;
198 case S_MAGIC_UFS: /* 0x00011954 */
199 type = "ufs";
200 break;
201 case S_MAGIC_XIAFS: /* 0x012FD16D */
202 type = "xia";
203 break;
204 case S_MAGIC_NTFS: /* 0x5346544e */
205 type = "ntfs";
206 break;
207 case S_MAGIC_TMPFS: /* 0x1021994 */
208 type = "tmpfs";
209 break;
210 case S_MAGIC_REISERFS: /* 0x52654973 */
211 type = "reiserfs";
212 break;
213 case S_MAGIC_CRAMFS: /* 0x28cd3d45 */
214 type = "cramfs";
215 break;
216 case S_MAGIC_ROMFS: /* 0x7275 */
217 type = "romfs";
218 break;
219 # elif __GNU__
220 case FSTYPE_UFS:
221 type = "ufs";
222 break;
223 case FSTYPE_NFS:
224 type = "nfs";
225 break;
226 case FSTYPE_GFS:
227 type = "gfs";
228 break;
229 case FSTYPE_LFS:
230 type = "lfs";
231 break;
232 case FSTYPE_SYSV:
233 type = "sysv";
234 break;
235 case FSTYPE_FTP:
236 type = "ftp";
237 break;
238 case FSTYPE_TAR:
239 type = "tar";
240 break;
241 case FSTYPE_AR:
242 type = "ar";
243 break;
244 case FSTYPE_CPIO:
245 type = "cpio";
246 break;
247 case FSTYPE_MSLOSS:
248 type = "msloss";
249 break;
250 case FSTYPE_CPM:
251 type = "cpm";
252 break;
253 case FSTYPE_HFS:
254 type = "hfs";
255 break;
256 case FSTYPE_DTFS:
257 type = "dtfs";
258 break;
259 case FSTYPE_GRFS:
260 type = "grfs";
261 break;
262 case FSTYPE_TERM:
263 type = "term";
264 break;
265 case FSTYPE_DEV:
266 type = "dev";
267 break;
268 case FSTYPE_PROC:
269 type = "proc";
270 break;
271 case FSTYPE_IFSOCK:
272 type = "ifsock";
273 break;
274 case FSTYPE_AFS:
275 type = "afs";
276 break;
277 case FSTYPE_DFS:
278 type = "dfs";
279 break;
280 case FSTYPE_PROC9:
281 type = "proc9";
282 break;
283 case FSTYPE_SOCKET:
284 type = "socket";
285 break;
286 case FSTYPE_MISC:
287 type = "misc";
288 break;
289 case FSTYPE_EXT2FS:
290 type = "ext2/ext3";
291 break;
292 case FSTYPE_HTTP:
293 type = "http";
294 break;
295 case FSTYPE_MEMFS:
296 type = "memfs";
297 break;
298 case FSTYPE_ISO9660:
299 type = "iso9660";
300 break;
301 # endif
302 default:
303 type = NULL;
304 break;
307 if (type)
308 return (char *) type;
311 static char buf[sizeof "UNKNOWN (0x%x)" - 2
312 + 2 * sizeof (statfsbuf->f_type)];
313 sprintf (buf, "UNKNOWN (0x%x)", statfsbuf->f_type);
314 return buf;
316 #endif
319 static char *
320 human_access (struct stat const *statbuf)
322 static char modebuf[11];
323 mode_string (statbuf->st_mode, modebuf);
324 modebuf[10] = 0;
325 return modebuf;
328 static char *
329 human_time (time_t const *t)
331 static char str[80];
332 struct tm *tm = localtime (t);
333 if (tm == NULL)
335 G_fail = 1;
336 return (char *) _("*** invalid date/time ***");
338 nstrftime (str, sizeof str, "%Y-%m-%d %H:%M:%S.%N %z", tm, 0, 0);
339 return str;
342 /* print statfs info */
343 static void
344 print_statfs (char *pformat, char m, char const *filename,
345 void const *data)
347 STRUCT_STATVFS const *statfsbuf = data;
349 switch (m)
351 case 'n':
352 strcat (pformat, "s");
353 printf (pformat, filename);
354 break;
356 case 'i':
357 #if HAVE_STRUCT_STATXFS_F_FSID___VAL
358 strcat (pformat, "x %-8x");
359 printf (pformat, statfsbuf->f_fsid.__val[0], /* u_long */
360 statfsbuf->f_fsid.__val[1]);
361 #else
362 strcat (pformat, "Lx");
363 printf (pformat, statfsbuf->f_fsid);
364 #endif
365 break;
367 case 'l':
368 strcat (pformat, NAMEMAX_FORMAT);
369 printf (pformat, SB_F_NAMEMAX (statfsbuf));
370 break;
371 case 't':
372 #if HAVE_STRUCT_STATXFS_F_TYPE
373 strcat (pformat, "lx");
374 printf (pformat, (long int) (statfsbuf->f_type)); /* no equiv. */
375 #else
376 fputc ('*', stdout);
377 #endif
378 break;
379 case 'T':
380 strcat (pformat, "s");
381 printf (pformat, human_fstype (statfsbuf));
382 break;
383 case 'b':
384 strcat (pformat, PRIdMAX);
385 printf (pformat, (intmax_t) (statfsbuf->f_blocks));
386 break;
387 case 'f':
388 strcat (pformat, PRIdMAX);
389 printf (pformat, (intmax_t) (statfsbuf->f_bfree));
390 break;
391 case 'a':
392 strcat (pformat, PRIdMAX);
393 printf (pformat, (intmax_t) (statfsbuf->f_bavail));
394 break;
395 case 's':
396 strcat (pformat, "ld");
397 printf (pformat, (long int) (statfsbuf->f_bsize));
398 break;
399 case 'c':
400 strcat (pformat, PRIdMAX);
401 printf (pformat, (intmax_t) (statfsbuf->f_files));
402 break;
403 case 'd':
404 strcat (pformat, PRIdMAX);
405 printf (pformat, (intmax_t) (statfsbuf->f_ffree));
406 break;
408 default:
409 strcat (pformat, "c");
410 printf (pformat, m);
411 break;
415 /* print stat info */
416 static void
417 print_stat (char *pformat, char m, char const *filename, void const *data)
419 struct stat *statbuf = (struct stat *) data;
420 struct passwd *pw_ent;
421 struct group *gw_ent;
423 switch (m)
425 case 'n':
426 strcat (pformat, "s");
427 printf (pformat, filename);
428 break;
429 case 'N':
430 strcat (pformat, "s");
431 if (S_ISLNK (statbuf->st_mode))
433 char *linkname = xreadlink (filename);
434 if (linkname == NULL)
436 error (0, errno, _("cannot read symbolic link %s"),
437 quote (filename));
438 return;
440 /*printf("\"%s\" -> \"%s\"", filename, linkname); */
441 printf (pformat, quote (filename));
442 printf (" -> ");
443 printf (pformat, quote (linkname));
445 else
447 printf (pformat, quote (filename));
449 break;
450 case 'd':
451 strcat (pformat, "d");
452 printf (pformat, (int) statbuf->st_dev);
453 break;
454 case 'D':
455 strcat (pformat, "x");
456 printf (pformat, (int) statbuf->st_dev);
457 break;
458 case 'i':
459 strcat (pformat, "d");
460 printf (pformat, (int) statbuf->st_ino);
461 break;
462 case 'a':
463 strcat (pformat, "o");
464 printf (pformat, statbuf->st_mode & 07777);
465 break;
466 case 'A':
467 strcat (pformat, "s");
468 printf (pformat, human_access (statbuf));
469 break;
470 case 'f':
471 strcat (pformat, "x");
472 printf (pformat, statbuf->st_mode);
473 break;
474 case 'F':
475 strcat (pformat, "s");
476 printf (pformat, file_type (statbuf));
477 break;
478 case 'h':
479 strcat (pformat, "d");
480 printf (pformat, (int) statbuf->st_nlink);
481 break;
482 case 'u':
483 strcat (pformat, "d");
484 printf (pformat, statbuf->st_uid);
485 break;
486 case 'U':
487 strcat (pformat, "s");
488 setpwent ();
489 pw_ent = getpwuid (statbuf->st_uid);
490 printf (pformat, (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN");
491 break;
492 case 'g':
493 strcat (pformat, "d");
494 printf (pformat, statbuf->st_gid);
495 break;
496 case 'G':
497 strcat (pformat, "s");
498 setgrent ();
499 gw_ent = getgrgid (statbuf->st_gid);
500 printf (pformat, (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN");
501 break;
502 case 't':
503 strcat (pformat, "x");
504 printf (pformat, major (statbuf->st_rdev));
505 break;
506 case 'T':
507 strcat (pformat, "x");
508 printf (pformat, minor (statbuf->st_rdev));
509 break;
510 case 's':
511 strcat (pformat, PRIuMAX);
512 printf (pformat, (uintmax_t) (statbuf->st_size));
513 break;
514 case 'B':
515 strcat (pformat, "u");
516 printf (pformat, (unsigned int) ST_NBLOCKSIZE);
517 break;
518 case 'b':
519 strcat (pformat, "u");
520 printf (pformat, (unsigned int) ST_NBLOCKS (*statbuf));
521 break;
522 case 'o':
523 strcat (pformat, "d");
524 printf (pformat, (int) statbuf->st_blksize);
525 break;
526 case 'x':
527 strcat (pformat, "s");
528 printf (pformat, human_time (&(statbuf->st_atime)));
529 break;
530 case 'X':
531 strcat (pformat, "d");
532 printf (pformat, (int) statbuf->st_atime);
533 break;
534 case 'y':
535 strcat (pformat, "s");
536 printf (pformat, human_time (&(statbuf->st_mtime)));
537 break;
538 case 'Y':
539 strcat (pformat, "d");
540 printf (pformat, (int) statbuf->st_mtime);
541 break;
542 case 'z':
543 strcat (pformat, "s");
544 printf (pformat, human_time (&(statbuf->st_ctime)));
545 break;
546 case 'Z':
547 strcat (pformat, "d");
548 printf (pformat, (int) statbuf->st_ctime);
549 break;
550 default:
551 strcat (pformat, "c");
552 printf (pformat, m);
553 break;
557 static void
558 print_it (char const *masterformat, char const *filename,
559 void (*print_func) (char *, char, char const *, void const *),
560 void const *data)
562 char *b;
564 /* create a working copy of the format string */
565 char *format = xstrdup (masterformat);
567 char *dest = xmalloc (strlen (format) + 1);
569 b = format;
570 while (b)
572 char *p = strchr (b, '%');
573 if (p != NULL)
575 size_t len;
576 *p++ = '\0';
577 fputs (b, stdout);
579 len = strspn (p, "#-+.I 0123456789");
580 dest[0] = '%';
581 memcpy (dest + 1, p, len);
582 dest[1 + len] = 0;
583 p += len;
585 b = p + 1;
586 switch (*p)
588 case '\0':
589 b = NULL;
590 /* fall through */
591 case '%':
592 putchar ('%');
593 break;
594 default:
595 print_func (dest, *p, filename, data);
596 break;
599 else
601 fputs (b, stdout);
602 b = NULL;
605 free (format);
606 free (dest);
607 fputc ('\n', stdout);
610 /* stat the filesystem and print what we find */
611 static void
612 do_statfs (char const *filename, int terse, char const *format)
614 STRUCT_STATVFS statfsbuf;
615 int i = statfs (filename, &statfsbuf);
617 if (i == -1)
619 error (0, errno, _("cannot read file system information for %s"),
620 quote (filename));
621 return;
624 if (format == NULL)
626 format = (terse
627 ? "%n %i %l %t %b %f %a %s %c %d"
628 : " File: \"%n\"\n"
629 " ID: %-8i Namelen: %-7l Type: %T\n"
630 "Blocks: Total: %-10b Free: %-10f Available: %-10a Size: %s\n"
631 "Inodes: Total: %-10c Free: %-10d");
634 print_it (format, filename, print_statfs, &statfsbuf);
637 /* stat the file and print what we find */
638 static void
639 do_stat (char const *filename, int follow_links, int terse,
640 char const *format)
642 struct stat statbuf;
643 int i = ((follow_links == 1)
644 ? stat (filename, &statbuf)
645 : lstat (filename, &statbuf));
647 if (i == -1)
649 error (0, errno, _("cannot stat %s"), quote (filename));
650 return;
653 if (format == NULL)
655 if (terse != 0)
657 format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o";
659 else
661 /* tmp hack to match orignal output until conditional implemented */
662 i = statbuf.st_mode & S_IFMT;
663 if (i == S_IFCHR || i == S_IFBLK)
665 format =
666 " File: %N\n"
667 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
668 "Device: %Dh/%dd\tInode: %-10i Links: %-5h"
669 " Device type: %t,%T\n"
670 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
671 "Access: %x\n" "Modify: %y\n" "Change: %z\n";
673 else
675 format =
676 " File: %N\n"
677 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
678 "Device: %Dh/%dd\tInode: %-10i Links: %h\n"
679 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
680 "Access: %x\n" "Modify: %y\n" "Change: %z\n";
684 print_it (format, filename, print_stat, &statbuf);
687 void
688 usage (int status)
690 if (status != 0)
691 fprintf (stderr, _("Try `%s --help' for more information.\n"),
692 program_name);
693 else
695 printf (_("Usage: %s [OPTION] FILE...\n"), program_name);
696 fputs (_("\
697 Display file or filesystem status.\n\
699 -f, --filesystem display filesystem status instead of file status\n\
700 -c --format=FORMAT use the specified FORMAT instead of the default\n\
701 -L, --dereference follow links\n\
702 -t, --terse print the information in terse form\n\
703 "), stdout);
704 fputs (HELP_OPTION_DESCRIPTION, stdout);
705 fputs (VERSION_OPTION_DESCRIPTION, stdout);
707 fputs (_("\n\
708 The valid format sequences for files (without --filesystem):\n\
710 %A Access rights in human readable form\n\
711 %a Access rights in octal\n\
712 %B The size in bytes of each block reported by `%b'\n\
713 %b Number of blocks allocated (see %B)\n\
714 "), stdout);
715 fputs (_("\
716 %D Device number in hex\n\
717 %d Device number in decimal\n\
718 %F File type\n\
719 %f Raw mode in hex\n\
720 %G Group name of owner\n\
721 %g Group ID of owner\n\
722 "), stdout);
723 fputs (_("\
724 %h Number of hard links\n\
725 %i Inode number\n\
726 %N Quoted File name with dereference if symbolic link\n\
727 %n File name\n\
728 %o IO block size\n\
729 %s Total size, in bytes\n\
730 %T Minor device type in hex\n\
731 %t Major device type in hex\n\
732 "), stdout);
733 fputs (_("\
734 %U User name of owner\n\
735 %u User ID of owner\n\
736 %X Time of last access as seconds since Epoch\n\
737 %x Time of last access\n\
738 %Y Time of last modification as seconds since Epoch\n\
739 %y Time of last modification\n\
740 %Z Time of last change as seconds since Epoch\n\
741 %z Time of last change\n\
743 "), stdout);
745 fputs (_("\
746 Valid format sequences for file systems:\n\
748 %a Free blocks available to non-superuser\n\
749 %b Total data blocks in file system\n\
750 %c Total file nodes in file system\n\
751 %d Free file nodes in file system\n\
752 %f Free blocks in file system\n\
753 "), stdout);
754 fputs (_("\
755 %i File System id in hex\n\
756 %l Maximum length of filenames\n\
757 %n File name\n\
758 %s Optimal transfer block size\n\
759 %T Type in human readable form\n\
760 %t Type in hex\n\
761 "), stdout);
762 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
764 exit (status);
768 main (int argc, char *argv[])
770 int c;
771 int i;
772 int follow_links = 0;
773 int fs = 0;
774 int terse = 0;
775 char *format = NULL;
777 initialize_main (&argc, &argv);
778 program_name = argv[0];
779 setlocale (LC_ALL, "");
780 bindtextdomain (PACKAGE, LOCALEDIR);
781 textdomain (PACKAGE);
783 atexit (close_stdout);
785 while ((c = getopt_long (argc, argv, "c:fLlt", long_options, NULL)) != -1)
787 switch (c)
789 case 'c':
790 format = optarg;
791 break;
793 case 'l': /* deprecated */
794 error (0, 0, _("Warning: `-l' is deprecated; use `-L' instead"));
795 /* fall through */
796 case 'L':
797 follow_links = 1;
798 break;
800 case 'f':
801 fs = 1;
802 break;
804 case 't':
805 terse = 1;
806 break;
808 case_GETOPT_HELP_CHAR;
810 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
812 default:
813 usage (EXIT_FAILURE);
817 if (argc == optind)
819 error (0, 0, _("too few arguments"));
820 usage (EXIT_FAILURE);
823 for (i = optind; i < argc; i++)
825 if (fs == 0)
826 do_stat (argv[i], follow_links, terse, format);
827 else
828 do_statfs (argv[i], terse, format);
831 exit (G_fail ? EXIT_FAILURE : EXIT_SUCCESS);