Cover V03, I03
Article
Figure 1
Figure 2
Listing 1
Listing 10
Listing 11
Listing 12
Listing 13
Listing 14
Listing 2
Listing 3
Listing 4
Listing 5
Listing 6
Listing 7
Listing 8
Listing 9

may94.tar


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 */