home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Source Code 1992 March
/
Source_Code_CD-ROM_Walnut_Creek_March_1992.iso
/
unix_c
/
filemgmt
/
stat.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-03-21
|
8KB
|
298 lines
28-Dec-85 04:10:43-MST,7958;000000000001
Return-Path: <unix-sources-request@BRL.ARPA>
Received: from BRL-TGR.ARPA by SIMTEL20.ARPA with TCP; Sat 28 Dec 85 04:10:33-MST
Received: from usenet by TGR.BRL.ARPA id a020626; 28 Dec 85 5:43 EST
From: Wombat <rsk@pucc-j.ARPA>
Newsgroups: net.sources
Subject: Updated version of stat.c
Message-ID: <680@pucc-j>
Date: 27 Dec 85 19:48:29 GMT
Keywords: stat, inode, ls
To: unix-sources@BRL-TGR.ARPA
This is a revision of an earlier posting; it incorporates several improvements
and bug fixes as noted in the opening comments. Additional bug fixes and
changes *to the author*, please.
/*
* Stat.c Dump out inode info in nice form. pur-ee!rsk
* Original version by someone at Purdue in the days of v6;
* this one by Rsk for modern times. (4.2, V)
*
* Bug fix for setuid bit misplacement, and modifications
* for System V by Bill Stoll, whuxlm!wws.
*
* Masscomp (and system V) mods by Stan Barber, neuro1!sob.
*
* Bug fix for setuid bit and flag mods, and for
* misplaced include of time.h, okstate!zap.
* Note: I left SINCE as a compile-time option; it
* probably shouldn't even be there. ---Rsk
*
* (void)'s added to make lint happy, pur-ee!rsk.
*
* Still doesn't run under 2.9; to be fixed soon.
*
*
* Vanilla version is for system V.
* Define BSD42 for 4.2bsd version.
* Define SINCE for "elapsed time" since inode times.
* Define MASSCOMP for those machines; this implies system V.
*/
#ifdef MASSCOMP
#undef BSD42
#endif MASSCOMP
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <ctype.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
#define FAIL -1 /* Failure return code from call */
#define OKAY 0 /* Success return code from call */
struct stat Sbuf; /* for return values from stat() call */
char *ctime(); /* Time conversion */
struct passwd *getpwuid(); /* User entry */
struct passwd *pwent; /* User structure */
struct group *getgrgid(); /* Group entry */
struct group *grent; /* Group structure */
char Mode[10]; /* File protection mode */
#define LBUFSIZ 256 /* Length for symbolic link translation buffer */
char Lbuf[LBUFSIZ]; /* Symbolic link translation buffer */
main(argc, argv)
int argc;
char *argv[];
{
int i;
i = 1;
if(argc == 1) {
(void) fprintf(stderr,"Usage: stat file1 [file2 ...]\n");
exit(1);
}
do {
(void) stat_it(argv[i]);
if( (argc > 1) && (i < (argc-1)) )
(void) printf("\n");
}
while(++i < argc);
exit(0);
}
/*
* stat_it() - Actually stat and format results from file.
* exit - OKAY if no problems encountered
* FAIL if couldn't open or other nastiness
*
*/
stat_it(filename)
char *filename;
{
int count;
#ifdef BSD42
if( lstat(filename,&Sbuf) == FAIL) {
(void) fprintf(stderr,"Can't lstat %s\n",filename);
return(FAIL);
}
#else BSD42
if( stat(filename,&Sbuf) == FAIL) {
(void) fprintf(stderr,"Can't stat %s\n",filename);
return(FAIL);
}
#endif BSD42
#ifdef BSD42
if( (Sbuf.st_mode & S_IFMT) == S_IFLNK) {
if( (count=readlink(filename,Lbuf,LBUFSIZ)) == FAIL) {
(void) fprintf(stderr,"Can't readlink %s\n", filename);
return(FAIL);
}
if( count < LBUFSIZ)
Lbuf[count] = '\0';
(void) printf(" File: \"%s\" -> \"%s\"\n",filename,Lbuf);
}
else
#endif BSD42
(void) printf(" File: \"%s\"\n", filename);
(void) printf(" Size: %-10d", Sbuf.st_size);
#ifdef BSD42
(void) printf(" Allocated Blocks: %-10ld", Sbuf.st_blocks);
#endif BSD42
(void) printf(" Filetype: ");
switch( Sbuf.st_mode & S_IFMT) {
case S_IFDIR: (void) printf("Directory\n");
break;
case S_IFCHR: (void) printf("Character Device\n");
break;
case S_IFBLK: (void) printf("Block Device\n");
break;
case S_IFREG: (void) printf("Regular File\n");
break;
#ifdef BSD42
case S_IFLNK: (void) printf("Symbolic Link\n");
break;
case S_IFSOCK: (void) printf("Socket\n");
break;
#else BSD42
case S_IFIFO: (void) printf("Fifo File\n");
break;
#endif BSD42
#ifdef MASSCOMP
case S_IFCTG: (void) printf("Contiguous File\n");
break;
#endif MASSCOMP
default : (void) printf("Unknown\n");
}
(void) strcpy(Mode,"----------");
if(Sbuf.st_mode & (S_IEXEC>>6)) /* Other execute */
Mode[9] = 'x';
if(Sbuf.st_mode & (S_IWRITE>>6)) /* Other write */
Mode[8] = 'w';
if(Sbuf.st_mode & (S_IREAD>>6)) /* Other read */
Mode[7] = 'r';
if(Sbuf.st_mode & (S_IEXEC>>3)) /* Group execute */
Mode[6] = 'x';
if(Sbuf.st_mode & (S_IWRITE>>3)) /* Group write */
Mode[5] = 'w';
if(Sbuf.st_mode & (S_IREAD>>3)) /* Group read */
Mode[4] = 'r';
if(Sbuf.st_mode & S_IEXEC) /* User execute */
Mode[3] = 'x';
if(Sbuf.st_mode & S_IWRITE) /* User write */
Mode[2] = 'w';
if(Sbuf.st_mode & S_IREAD) /* User read */
Mode[1] = 'r';
if(Sbuf.st_mode & S_ISVTX) /* Sticky bit */
Mode[9] = 't';
if(Sbuf.st_mode & S_ISGID) /* Set group id */
Mode[6] = 's';
if(Sbuf.st_mode & S_ISUID) /* Set user id */
Mode[3] = 's';
switch( Sbuf.st_mode & S_IFMT) {
case S_IFDIR: Mode[0] = 'd';
break;
case S_IFCHR: Mode[0] = 'c';
break;
case S_IFBLK: Mode[0] = 'b';
break;
case S_IFREG: Mode[0] = '-';
break;
#ifdef BSD42
case S_IFLNK: Mode[0] = 'l';
break;
case S_IFSOCK: Mode[0] = 's';
break;
#else BSD42
case S_IFIFO: Mode[0] = 'f';
break;
#endif BSD42
#ifdef MASSCOMP
case S_IFCTG: Mode[0] = 'C';
break;
#endif MASSCOMP
default : Mode[0] = '?';
}
(void) printf(" Mode: (%04o/%s)", Sbuf.st_mode&07777,Mode);
(void) setpwent();
if( (pwent = getpwuid(Sbuf.st_uid)) == NULL) {
(void) fprintf(stderr,"getpwuid() failed\n");
exit(1);
}
(void) printf(" Uid: (%5d/%8s)", Sbuf.st_uid, pwent->pw_name);
(void) setgrent();
if( (grent = getgrgid(Sbuf.st_gid)) == NULL) {
(void) fprintf(stderr,"getgrgid() failed\n");
exit(1);
}
(void) printf(" Gid: (%5d/%8s)\n", Sbuf.st_gid, grent->gr_name);
(void) printf("Device: %-5d", Sbuf.st_dev);
(void) printf(" Inode: %-10d", Sbuf.st_ino);
(void) printf("Links: %-5d", Sbuf.st_nlink);
/* Only meaningful if file is device */
if( ( (Sbuf.st_mode & S_IFMT) == S_IFCHR)
|| ( (Sbuf.st_mode & S_IFMT) == S_IFBLK) )
(void) printf(" Device type: %d\n",Sbuf.st_rdev);
else
(void) printf("\n");
/* The %.24s strips the newline from the ctime() string */
#ifdef SINCE
(void) printf("Access: %.24s",ctime(&Sbuf.st_atime));
(void) tsince(Sbuf.st_atime);
(void) printf("Modify: %.24s",ctime(&Sbuf.st_mtime));
(void) tsince(Sbuf.st_mtime);
(void) printf("Change: %.24s",ctime(&Sbuf.st_ctime));
(void) tsince(Sbuf.st_ctime);
#else SINCE
(void) printf("Access: %s",ctime(&Sbuf.st_atime));
(void) printf("Modify: %s",ctime(&Sbuf.st_mtime));
(void) printf("Change: %s",ctime(&Sbuf.st_ctime));
#endif SINCE
/*
* Should I put this in somewhere? No.
*
* printf("Optimal Blocksize: %ld\n", Sbuf.st_blksize);
*/
return(OKAY);
}
#ifdef SINCE
tsince(time_sec)
long time_sec;
{
long time_buf;
long d_since; /* days elapsed since time */
long h_since; /* hours elapsed since time */
long m_since; /* minutes elapsed since time */
long s_since; /* seconds elapsed since time */
(void) time(&time_buf);
if(time_sec > time_buf) {
(void) fprintf(stderr,"Time going backwards\n");
exit(1);
}
s_since = time_buf - time_sec;
d_since = s_since / 86400l ;
s_since -= d_since * 86400l ;
h_since = s_since / 3600l ;
s_since -= h_since * 3600l ;
m_since = s_since / 60l ;
s_since -= m_since * 60l ;
(void) printf("(%05ld.%02ld:%02ld:%02ld)\n",d_since,h_since,m_since,s_since);
return(OKAY);
}
#endif SINCE
--
Rich Kulawiec pur-ee!rsk purdue-!rsk rsk@purdue-asc.arpa rsk@asc.purdue.edu