Listing 1: stat.c
/* stat.c */
/* Copyright 1994 by Steven G. Isaacson */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <time.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
static char Sccsid[]="@(#) stat.c 01/31/94 stevei";
char *h[] = {
" - Read filenames from stdin",
" -F [filename] file containing list of filenames",
" -x Default output: mode nlink uid gid size mtime name",
" -n Print name",
" -p Look up user and group names (default prints uid and gid)",
" -i Inode number",
" -d ID of device containing a directory entry for this file",
" -D ID of device: defined for character/block special files",
" -l Number of links",
" -u User ID of the file's owner",
" -g Group ID of the file's group",
" -s File size in bytes",
" -o File mode [see mknod(2)] -O decimal value",
" -a Time of last access -A decimal value",
" -m Time of last data modification -M decimal value",
" -c Time of last file status 'change' -C decimal value",
" -t Show all three times",
" -w Print no extra white space",
#ifdef S_IFLNK
" -L Print symbolic link name",
#endif
" -h This help page",
'\0' };
char *usage_str="usage: stat [-args] [filename(s)|-]";
int mode=FALSE; /* o */
int mode_dec=FALSE; /* O */
int ino=FALSE; /* i */
int dev=FALSE; /* d */
int rdev=FALSE; /* D */
int nlink=FALSE; /* l */
int uid=FALSE; /* u */
int gid=FALSE; /* q */
int size=FALSE; /* s */
int atime=FALSE; /* a */
int Atime=FALSE; /* a */
int mtime=FALSE; /* m */
int Mtime=FALSE; /* m */
int xctime=FALSE; /* c */
int xCtime=FALSE; /* c */
int name=FALSE; /* n */
int lkupname=FALSE; /* p */
int symlnkname=FALSE; /* L */
int showt=FALSE; /* t */
int nwht=FALSE; /* w */
#define DEFAULT_OUTPUT mode=nlink=uid=gid=size=\
mtime=name=lkupname=TRUE;
main(argc, argv)
int argc;
char *argv[];
{
int i;
extern int optind;
extern char *optarg;
char *options="oOidDlugsaAmMcCxhn?F:Lptw";
int c, errflg=0;
char stdinfn[256];
FILE *stdinfp;
stdinfn[0] = '\0';
if (argc == 1) {
fprintf(stderr, "%s\n", usage_str);
exit(1);
}
/* default same as -x */
if ( argv[1][0] != '-' || (argv[1][0] == '-' && ! argv[1][1]) )
DEFAULT_OUTPUT ;
while ((c=getopt(argc, argv, options)) != EOF) {
switch (c) {
case 'x':
DEFAULT_OUTPUT ;
break;
case 'L':
symlnkname=TRUE;
break;
case 'o':
mode=TRUE;
break;
case 'O':
mode_dec=TRUE;
break;
case 't':
showt=TRUE;
break;
case 'i':
ino=TRUE;
break;
case 'd':
dev=TRUE;
break;
case 'D':
rdev=TRUE;
break;
case 'l':
nlink=TRUE;
break;
case 'u':
uid=TRUE;
break;
case 'g':
gid=TRUE;
break;
case 's':
size=TRUE;
break;
case 'a':
atime=TRUE;
break;
case 'A':
Atime=TRUE;
break;
case 'm':
mtime=TRUE;
break;
case 'M':
Mtime=TRUE;
break;
case 'c':
xctime=TRUE;
break;
case 'C':
xCtime=TRUE;
break;
case 'n':
name=TRUE;
break;
case 'p':
lkupname=TRUE;
break;
case 'F':
strcpy(stdinfn, optarg);
break;
case 'w':
nwht=TRUE;
break;
case '?':
case 'h':
default:
errflg++;
break;
}
if (errflg) {
help();
exit(0);
}
}
if (stdinfn[0]) {
/* input is coming from a file */
if ((stdinfp = fopen(stdinfn, "r")) == NULL) {
fprintf ( stderr,
"*** could not open: %s\n", stdinfn );
exit ( 2 );
}
stat_input(stdinfp);
}
else {
/* input is coming from the command-line or
stdin */
for (i=optind; i < argc; i++) {
if ( argv[i][0] == '-' )
stat_input(stdin);
else
stat_fn(argv[i]);
}
}
exit(0);
}
/* ================================================= */
/* display help page */
help()
{
int i;
fprintf(stderr, "%s\n", usage_str);
for (i=0; h[i]; i++)
fprintf(stderr, "%s\n", h[i]);
fprintf(stderr, "\n");
}
/* ================================================= */
/* get the list of files to stat from a file. */
#define MAX_FN 1024
stat_input(fp)
FILE *fp;
{
char buf[MAX_FN], *retval;
while ((retval=fgets(buf, MAX_FN, fp)) != (char *)EOF
&& retval != NULL ) {
buf[strlen(buf) - 1] = '\0';
stat_fn(buf);
}
}
/* ================================================= */
/* make the stat (or lstat) system call. */
#define SYM_LN_BUF 256
stat_fn(fn)
char *fn;
{
struct stat sbuf;
struct passwd *ppass;
struct group *pgroup;
char *pc;
int cc;
char buf[SYM_LN_BUF];
#ifdef S_IFLNK
if ( lstat(fn, &sbuf )) {
#else
if ( stat(fn, &sbuf )) {
#endif
perror(fn);
return;
}
if (mode) {
#ifdef S_IFLNK
if ((sbuf.st_mode & S_IFMT) == S_IFLNK)
/* symbolic link */
printf("l");
#else
if ( FALSE )
;
#endif
else if ((sbuf.st_mode & S_IFMT) == S_IFDIR)
/* directory */
printf("d");
else if ((sbuf.st_mode & S_IFMT) == S_IFCHR)
/* character special device */
printf("c");
else if ((sbuf.st_mode & S_IFMT) == S_IFBLK)
/* block special device */
printf("b");
else if ((sbuf.st_mode & S_IFMT) == S_IFREG)
/* regular file */
printf("-");
else if ((sbuf.st_mode & S_IFMT) == S_IFIFO)
/* fifo */
printf("p");
#ifdef S_INSHD
else if ((sbuf.st_mode & S_IFMT) == S_INSHD)
/* shared memory */
printf("m");
#endif
#ifdef S_IFNAM
else if ((sbuf.st_mode & S_IFMT) == S_IFNAM)
/* name special entry */
printf("n");
#endif
#ifdef S_INSEM
else if ((sbuf.st_mode & S_IFMT) == S_INSEM)
/* semaphore */
printf("s");
#endif
#ifdef S_IFSOCK
else if ((sbuf.st_mode & S_IFMT) == S_IFSOCK)
/* socket */
printf("s");
#endif
else
/* don't know! */
printf("?");
if ((sbuf.st_mode & S_IREAD) == S_IREAD)
/* 00400 */ printf("r");
else
printf("-");
if ((sbuf.st_mode & S_IWRITE) == S_IWRITE )
/* 00200 */ printf("w");
else
printf("-");
if ((sbuf.st_mode & S_IEXEC) == S_IEXEC &&
(sbuf.st_mode & S_ISUID) == S_ISUID)
/* 00100 */ printf("s");
else if ((sbuf.st_mode & S_IEXEC) == S_IEXEC)
printf("x");
else
printf("-");
if ((sbuf.st_mode & 00040) == 00040)
/* 00400 */ printf("r");
else
printf("-");
if ((sbuf.st_mode & 00020) == 00020)
/* 00200 */ printf("w");
else
printf("-");
if ((sbuf.st_mode & 00010) == 00010 &&
(sbuf.st_mode & S_ISGID) == S_ISGID)
printf("s");
else if ((sbuf.st_mode & 00010) == 00010)
/* 00100 */ printf("x");
else
printf("-");
if ((sbuf.st_mode & 00004) == 00004)
/* 00400 */ printf("r");
else
printf("-");
if ((sbuf.st_mode & 00002) == 00002)
/* 00200 */ printf("w");
else
printf("-");
if ((sbuf.st_mode & 00001) == 00001)
/* 00100 */ printf("x");
else
printf("-");
printf(" ");
}
if (mode_dec) printf("%hu ", sbuf.st_mode);
if (ino) printf("%d ", sbuf.st_ino);
if (dev)
printf("%d,%d ",
major(sbuf.st_dev), minor(sbuf.st_dev));
if (rdev)
printf("%d,%d ",
major(sbuf.st_rdev), minor(sbuf.st_rdev));
if (nlink) {
nwht ? printf("%d ", sbuf.st_nlink) :
printf("%2d ", sbuf.st_nlink);
}
if (uid) {
if (lkupname) {
ppass=(struct passwd *)getpwuid(sbuf.st_uid);
if ( ppass ) {
nwht ? printf("%s ", ppass->pw_name) :
printf("%-8s ", ppass->pw_name);
}
else
printf("%d ", sbuf.st_uid);
}
else
printf("%d ", sbuf.st_uid);
}
if (gid) {
if (lkupname) {
pgroup=(struct group *)getgrgid(sbuf.st_gid);
if (pgroup) {
nwht ? printf("%s ", pgroup->gr_name) :
printf("%-8s ", pgroup->gr_name);
}
else
printf("%d ", sbuf.st_gid);
}
else
printf("%d ", sbuf.st_gid);
}
if (size) {
nwht ? printf("%d ", sbuf.st_size) :
printf("%8d ", sbuf.st_size);
}
if (atime) { /* time of last access */
pc=ctime(&sbuf.st_atime);
pc[strlen(pc) - 1]='\0';
printf("%s ", pc);
}
if (Atime) printf("%d ", sbuf.st_atime);
if (mtime) { /* time of last data modification */
pc=ctime(&sbuf.st_mtime);
pc[strlen(pc) - 1]='\0';
printf("%s ", pc);
}
if (Mtime) printf("%d ", sbuf.st_mtime);
if (xctime) { /* time of last file status 'change' */
pc=ctime(&sbuf.st_ctime);
pc[strlen(pc) - 1]='\0';
printf("%s ", pc);
}
if (xCtime) printf("%d ", sbuf.st_ctime);
if (name)
printf("%s", fn);
#ifdef S_IFLNK
if (symlnkname) {
cc=readlink(fn, buf, SYM_LN_BUF);
buf[cc]='\0';
printf(" -> %s", buf);
}
#endif
if (showt) {
printf("\n");
pc=ctime(&sbuf.st_atime);
pc[strlen(pc) - 1]='\0';
printf("access time: %s\n", pc);
pc=ctime(&sbuf.st_mtime);
pc[strlen(pc) - 1]='\0';
printf(" mod time: %s\n", pc);
pc=ctime(&sbuf.st_ctime);
pc[strlen(pc) - 1]='\0';
printf("change time: %s", pc);
}
printf("\n");
}
/* End of File */
|