summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2001-11-26 11:04:49 +0000
committerJim Meyering <jim@meyering.net>2001-11-26 11:04:49 +0000
commita927d9b0ae73c0be7153ff15d782e2e669f85602 (patch)
tree418afa50614073be3c4b433d3381e858795ca6b7 /src
parent0099b7b26e601368173b84e872788838541c70fe (diff)
downloadcoreutils-a927d9b0ae73c0be7153ff15d782e2e669f85602.tar.xz
*** empty log message ***
Diffstat (limited to 'src')
-rw-r--r--src/stat.c368
1 files changed, 368 insertions, 0 deletions
diff --git a/src/stat.c b/src/stat.c
new file mode 100644
index 000000000..e65242c14
--- /dev/null
+++ b/src/stat.c
@@ -0,0 +1,368 @@
+#include <config.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#ifdef HAVE_SYS_SYSMACROS_H
+# include <sys/sysmacros.h>
+#endif
+#include <pwd.h>
+#include <grp.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/vfs.h>
+
+#include <getopt.h>
+#include "error.h"
+#include "filemode.h"
+#include "fs.h"
+#include "quotearg.h"
+#include "system.h"
+#include "xreadlink.h"
+
+#define PROGRAM_NAME "stat"
+
+#define AUTHORS "Michael Meskes"
+
+static struct option const long_options[] = {
+ {"link", no_argument, 0, 'l'},
+ {"filesystem", no_argument, 0, 'f'},
+ {"terse", no_argument, 0, 't'},
+ {GETOPT_HELP_OPTION_DECL},
+ {GETOPT_VERSION_OPTION_DECL},
+ {NULL, 0, NULL, 0}
+};
+
+static char *program_name;
+
+/* stat the filesystem and print what we find */
+static void
+do_statfs (char const *filename, int terse)
+{
+ struct statfs statfsbuf;
+
+ if (statfs (filename, &statfsbuf) == -1)
+ {
+ error (0, errno, "%s", quotearg_colon (filename));
+ return;
+ }
+
+ if (terse != 0)
+ {
+#ifdef __USE_FILE_OFFSET64
+# define STATFSFMT "%s %x %x %lu %lx %lld %lld %lld %ld %lld %lld\n"
+#else
+# define STATFSFMT "%s %x %x %d %x %ld %ld %ld %d %ld %ld\n"
+#endif
+ printf (STATFSFMT,
+ filename,
+ statfsbuf.f_fsid.__val[0],
+ statfsbuf.f_fsid.__val[1],
+ statfsbuf.f_namelen,
+ statfsbuf.f_type,
+ statfsbuf.f_blocks,
+ statfsbuf.f_bfree,
+ statfsbuf.f_bavail,
+ statfsbuf.f_bsize, statfsbuf.f_files, statfsbuf.f_ffree);
+
+ return;
+ }
+
+ printf (" File: \"%s\"\n", filename);
+#ifdef __USE_FILE_OFFSET64
+ printf (" ID: %-8x %-8x Namelen: %-7ld Type: ",
+ statfsbuf.f_fsid.__val[0],
+ statfsbuf.f_fsid.__val[1], statfsbuf.f_namelen);
+#else
+ printf (" ID: %-8x %-8x Namelen: %-7d Type: ",
+ statfsbuf.f_fsid.__val[0],
+ statfsbuf.f_fsid.__val[1], statfsbuf.f_namelen);
+#endif
+
+ switch (statfsbuf.f_type)
+ {
+ case AFFS_SUPER_MAGIC:
+ printf ("AFFS\n");
+ break;
+ case EXT_SUPER_MAGIC:
+ printf ("EXT\n");
+ break;
+ case EXT2_OLD_SUPER_MAGIC:
+ printf ("EXT2\n");
+ break;
+ case EXT2_SUPER_MAGIC:
+ printf ("EXT2\n");
+ break;
+ case HPFS_SUPER_MAGIC:
+ printf ("HPFS\n");
+ break;
+ case ISOFS_SUPER_MAGIC:
+ printf ("ISOFS\n");
+ break;
+ case MINIX_SUPER_MAGIC:
+ printf ("MINIX\n");
+ case MINIX_SUPER_MAGIC2:
+ printf ("MINIX (30 char.)\n");
+ break;
+ case MINIX2_SUPER_MAGIC:
+ printf ("MINIX V2\n");
+ break;
+ case MINIX2_SUPER_MAGIC2:
+ printf ("MINIX V2 (30 char.)\n");
+ break;
+ case MSDOS_SUPER_MAGIC:
+ printf ("MSDOS\n");
+ break;
+ case NCP_SUPER_MAGIC:
+ printf ("NOVELL\n");
+ break;
+ case NFS_SUPER_MAGIC:
+ printf ("NFS\n");
+ break;
+ case PROC_SUPER_MAGIC:
+ printf ("PROC\n");
+ break;
+ case SMB_SUPER_MAGIC:
+ printf ("SMB\n");
+ break;
+ case XENIX_SUPER_MAGIC:
+ printf ("XENIX\n");
+ break;
+ case SYSV4_SUPER_MAGIC:
+ printf ("SYSV4\n");
+ break;
+ case SYSV2_SUPER_MAGIC:
+ printf ("SYSV2\n");
+ break;
+ case COH_SUPER_MAGIC:
+ printf ("COH\n");
+ break;
+ case UFS_MAGIC:
+ printf ("UFS\n");
+ break;
+ case _XIAFS_SUPER_MAGIC:
+ printf ("XIA\n");
+ break;
+ case NTFS_SUPER_MAGIC:
+ printf ("NTFS\n");
+ break;
+ case TMPFS_MAGIC:
+ printf ("TMPFS\n");
+ break;
+ case REISERFS_MAGIC:
+ printf ("TMPFS\n");
+ break;
+ default:
+#ifdef __USE_FILE_OFFSET64
+ printf ("UNKNOWN (0x%lx)\n", statfsbuf.f_type);
+#else
+ printf ("UNKNOWN (0x%x)\n", statfsbuf.f_type);
+#endif
+ }
+#ifdef __USE_FILE_OFFSET64
+ printf
+ ("Blocks: Total: %-10lld Free: %-10lld Available: %-10lld Size:%ld \n",
+ statfsbuf.f_blocks, statfsbuf.f_bfree, statfsbuf.f_bavail,
+ statfsbuf.f_bsize);
+ printf ("Inodes: Total: %-10lld Free: %-10lld\n", statfsbuf.f_files,
+ statfsbuf.f_ffree);
+#else
+ printf ("Blocks: Total: %-10ld Free: %-10ld Available: %-10ld Size:%d\n",
+ statfsbuf.f_blocks,
+ statfsbuf.f_bfree, statfsbuf.f_bavail, statfsbuf.f_bsize);
+ printf ("Inodes: Total: %-10ld Free: %-10ld\n",
+ statfsbuf.f_files, statfsbuf.f_ffree);
+#endif
+}
+
+/* stat the file and print what we find */
+static void
+do_stat (char const *filename, int follow_links, int terse)
+{
+ struct stat statbuf;
+ int err = (follow_links
+ ? stat (filename, &statbuf)
+ : lstat (filename, &statbuf));
+ char modebuf[11];
+ struct passwd *pw_ent;
+ struct group *gw_ent;
+
+ if (err == -1)
+ {
+ error (0, errno, "%s", quotearg_colon (filename));
+ return;
+ }
+
+ if (terse != 0)
+ {
+ printf ("%s %u %u %x %d %d %x %d %d %x %x %d %d %d %d\n",
+ filename,
+ (unsigned int) statbuf.st_size,
+ (unsigned int) statbuf.st_blocks,
+ statbuf.st_mode,
+ statbuf.st_uid,
+ statbuf.st_gid,
+ (int) statbuf.st_dev,
+ (int) statbuf.st_ino,
+ (int) statbuf.st_nlink,
+ major (statbuf.st_rdev),
+ minor (statbuf.st_rdev),
+ (int) statbuf.st_atime,
+ (int) statbuf.st_mtime,
+ (int) statbuf.st_ctime, (int) statbuf.st_blksize);
+ return;
+ }
+
+ if (S_ISLNK (statbuf.st_mode))
+ {
+ char *linkname = xreadlink (filename);
+ if (linkname)
+ printf (" File: \"%s\" -> \"%s\"\n", filename, linkname);
+
+ free (linkname);
+ if (linkname == NULL)
+ {
+ error (0, errno, _("cannot read symbolic link %s"),
+ quotearg_colon (filename));
+ return;
+ }
+
+ }
+ else
+ printf (" File: \"%s\"\n", filename);
+
+ printf (" Size: %-10u\tBlocks: %-10u IO Block: %-6d ",
+ (unsigned int) statbuf.st_size,
+ (unsigned int) statbuf.st_blocks, (int) statbuf.st_blksize);
+
+ switch (statbuf.st_mode & S_IFMT)
+ {
+ case S_IFDIR:
+ printf ("Directory\n");
+ break;
+ case S_IFCHR:
+ printf ("Character Device\n");
+ break;
+ case S_IFBLK:
+ printf ("Block Device\n");
+ break;
+ case S_IFREG:
+ printf ("Regular File\n");
+ break;
+ case S_IFLNK:
+ printf ("Symbolic Link\n");
+ break;
+ case S_IFSOCK:
+ printf ("Socket\n");
+ break;
+ case S_IFIFO:
+ printf ("Fifo File\n");
+ break;
+ default:
+ printf ("Unknown\n");
+ }
+
+ printf ("Device: %xh/%dd\tInode: %-10d Links: %-5d",
+ (int) statbuf.st_dev,
+ (int) statbuf.st_dev, (int) statbuf.st_ino, (int) statbuf.st_nlink);
+
+ if (S_ISBLK (statbuf.st_mode) || S_ISCHR (statbuf.st_mode))
+ printf (" Device type: %x,%x\n",
+ major (statbuf.st_rdev), minor (statbuf.st_rdev));
+ else
+ printf ("\n");
+
+ mode_string (statbuf.st_mode, modebuf);
+ modebuf[10] = 0;
+ printf ("Access: (%04o/%10.10s)", statbuf.st_mode & 07777, modebuf);
+
+ setpwent ();
+ setgrent ();
+ pw_ent = getpwuid (statbuf.st_uid);
+ gw_ent = getgrgid (statbuf.st_gid);
+ printf (" Uid: (%5d/%8s) Gid: (%5d/%8s)\n",
+ statbuf.st_uid,
+ (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN",
+ statbuf.st_gid, (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN");
+
+ printf ("Access: %s", ctime (&statbuf.st_atime));
+ printf ("Modify: %s", ctime (&statbuf.st_mtime));
+ printf ("Change: %s\n", ctime (&statbuf.st_ctime));
+}
+
+void
+usage (int status)
+{
+ if (status != 0)
+ fprintf (stderr, _("Try %s --help' for more information.\n"),
+ program_name);
+ else
+ {
+ printf (_("Usage: %s [OPTION] FILE...\n"), program_name);
+ fputs (_("\
+Display file or filesystem status.\n\
+\n\
+ -l, --link follow links\n\
+ -f, --filesystem display filesystem status instead of file status\n\
+ -t, --terse print the information in terse form\n\
+"), stdout);
+ fputs (_("\
+ --help display this help and exit\n\
+ --version output version information and exit\n\
+"), stdout);
+ puts (_("\nReport bugs to <bug-fileutils@gnu.org>."));
+ }
+ exit (status);
+}
+
+int
+main (int argc, char **argv)
+{
+ int c;
+ int i;
+ int follow_links = 0;
+ int fs = 0;
+ int terse = 0;
+
+ program_name = argv[0];
+ setlocale (LC_ALL, "");
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ atexit (close_stdout);
+ while ((c = getopt_long (argc, argv, "lft", long_options, NULL)) != -1)
+ {
+ switch (c)
+ {
+ case 'l':
+ follow_links = 1;
+ break;
+ case 'f':
+ fs = 1;
+ break;
+ case 't':
+ terse = 1;
+ break;
+ case_GETOPT_HELP_CHAR;
+
+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
+
+ default:
+ usage (EXIT_FAILURE);
+ }
+ }
+
+ if (argc == optind)
+ {
+ error (0, 0, _("too few arguments"));
+ usage (EXIT_FAILURE);
+ }
+
+ for (i = optind; i < argc; i++)
+ {
+ if (fs == 0)
+ do_stat (argv[i], follow_links, terse);
+ else
+ do_statfs (argv[i], terse);
+ }
+
+ exit (EXIT_SUCCESS);
+}