le.c
Peter da Silva
peter at baylor.UUCP
Fri Aug 16 03:02:06 AEST 1985
Having recieved numerous (well, 2) requests for "le", here's the source offered
without comment. 4.2 people will undoubtedly have to patch it to handle the
crufty new directories, but I have done that for a descendent of this (a visual
shell) and it's no hassle. V7 people rejoice: it runs under that venerable
system. I have never tried to convert it ro its descendents fo SIII/SV, so
let me know what luck you have.
---- le.c -----
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/dir.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#define D_DEV 01
#define D_INO 02
#define D_MODE 04
#define D_LINKS 010
#define D_UID 020
#define D_GID 040
#define D_RDEV 0100
#define D_SIZE 0200
#define D_ATIME 0400
#define D_MTIME 01000
#define D_CTIME 02000
#define D_SMODE 04000
#define D_SUID 010000
#define D_SGID 020000
#define FALSE 0
#define TRUE 1
#define MAXENTS 512
#define MAXID 64
struct entry {
struct direct e_dir;
char filler;
struct stat e_stat;
} entries[MAXENTS];
int nentries;
char *errname;
extern int errno;
int xerrno;
char *tab=" ";
long maxsize;
char sizstr[2][10] = {"%6lu%s","%6s%s"};
int dohead=0, dodir=1;
int flags = D_MODE|D_LINKS|D_UID|D_SIZE|D_MTIME;
char *emesg[3]={
"No such error",
#define TOO_MANY 1
"Too many directory entries",
0
};
getdir(dir)
char *dir;
{
int entcmp();
char *nameof();
FILE *fp;
int valid;
if(!(fp = fopen(dir, "r"))) {
errname=dir;
return FALSE;
}
maxsize=0L;
for(nentries=0;
nentries<MAXENTS &&
fread(&entries[nentries].e_dir,
sizeof entries[nentries].e_dir, 1, fp)>0;
nentries += valid) {
if(valid=entries[nentries].e_dir.d_ino?1:0) {
entries[nentries].filler=0;
if(stat(nameof(entries[nentries].e_dir.d_name, dir),
&entries[nentries].e_stat
)==-1
) {
fclose(fp);
errname=nameof(entries[nentries].e_dir.d_name,
dir);
return FALSE;
}
if(entries[nentries].e_stat.st_size>maxsize)
maxsize=entries[nentries].e_stat.st_size;
}
}
if(nentries>=MAXENTS) {
errno=0;
xerrno=TOO_MANY;
errname=dir;
return FALSE;
}
fclose(fp);
qsort(entries, nentries, sizeof(struct entry), entcmp);
setsize(maxsize);
return TRUE;
}
setsize(size)
long size;
{
char tmp[32];
int siz;
sprintf(tmp, "%lu", size);
siz=strlen(tmp);
if(siz<6) siz=6;
sprintf(sizstr[0], "%%%dlu%%s", siz);
sprintf(sizstr[1], "%%%ds%%s", siz);
if(dohead) {
header();
dohead=0;
}
}
char *
nameof(name, dir)
char *name, *dir;
{
char nambuf[BUFSIZ];
if(!dir[0])
return name;
if(dir[0]=='.' && !dir[1])
return name;
else if(dir[0]=='/' && !dir[1]) {
sprintf(nambuf, "/%s", name);
return nambuf;
} else {
sprintf(nambuf, "%s/%s", dir, name);
return nambuf;
}
}
pname(name)
char *name;
{
int len = 0;
for(;*name; name++)
if(*name<' ') { printf("^%c", *name+'@'); len+=2; }
else if(*name=='\0177') { printf("^?"); len+=2; }
else if(*name>'\0177') { printf("\\%03o", *name); len += 4; }
else { putchar(*name); len++; }
return len;
}
entcmp(e1, e2)
struct entry *e1, *e2;
{
return strcmp(e1->e_dir.d_name, e2->e_dir.d_name);
}
fdump(dir)
char *dir;
{
struct stat sbuf;
if(stat(dir, &sbuf)==-1) {
errname=dir;
return FALSE;
} else
if(dodir && (sbuf.st_mode&S_IFMT)==S_IFDIR) {
if(getdir(dir))
return dump(dir);
else
return FALSE;
} else {
setsize(sbuf.st_size);
statout(dir, &sbuf, ".");
return TRUE;
}
}
dump(dir)
char *dir;
{
int i, j;
int chars;
if(flags==0) {
for(i=0; i<=nentries/5; i++) {
chars = 0;
for(j=0; j<5; j++) {
if(i+j*nentries/5<nentries)
chars +=
pname(entries[i+j*nentries/5].e_dir.d_name);
if(chars<8) { putchar('\t'); chars=8; }
if(chars<16) { putchar('\t'); chars=16; }
else { putchar(' '); chars++; }
chars %= 16;
}
putchar('\n');
}
}
else for(i=0; i<nentries; i++)
statout(entries[i].e_dir.d_name,
&entries[i].e_stat, dir);
return TRUE;
}
statout(name, sbuf, dir)
char *name;
struct stat *sbuf;
char *dir;
{
char *u_name(), *g_name();
if(flags&D_DEV)
printf("%3d,%3d%s",
major(sbuf->st_dev),
minor(sbuf->st_dev),
tab);
if(flags&D_RDEV)
printf("%3d,%3d%s",
major(sbuf->st_rdev),
minor(sbuf->st_rdev),
tab);
if(flags&D_INO)
printf("%5u%s", sbuf->st_ino, tab);
if(flags&D_SMODE)
printf("%6o%s", sbuf->st_mode, tab);
if(flags&D_MODE) {
int mode = sbuf->st_mode;
if((mode&S_IFMT)==S_IFCHR) putchar('c');
else if((mode&S_IFMT)==S_IFBLK) putchar('b');
else if((mode&S_IFMT)==S_IFDIR) putchar('d');
else if((mode&S_IFMT)==S_IFREG) putchar('-');
else putchar('?');
triad((mode>>6)&7, mode&S_ISUID, 's');
triad((mode>>3)&7, mode&S_ISGID, 's');
triad(mode&7, mode&S_ISVTX, 't');
printf("%s", tab);
}
if(flags&D_LINKS)
printf("%3u%s", sbuf->st_nlink, tab);
if(flags&D_SUID)
printf("%3d%s", sbuf->st_uid, tab);
if(flags&D_UID)
printf("%-8s%s", u_name(sbuf->st_uid), tab);
if(flags&D_SGID)
printf("%3d%s", sbuf->st_gid, tab);
if(flags&D_GID)
printf("%-8s%s", g_name(sbuf->st_gid), tab);
if(flags&D_SIZE)
printf(sizstr[0], sbuf->st_size, tab);
if((flags&~(D_ATIME|D_MTIME|D_CTIME)) &&
(flags&(D_ATIME|D_MTIME|D_CTIME))) putchar(' ');
if(flags&D_ATIME)
printime(&sbuf->st_atime);
if(flags&D_MTIME)
printime(&sbuf->st_mtime);
if(flags&D_CTIME)
printime(&sbuf->st_ctime);
pname(nameof(name, dir));
putchar('\n');
}
struct idtab {
int id_id;
char id_name[10];
} u_list[MAXID], g_list[MAXID];
int u_ptr=0, g_ptr=0;
char *
u_name(uid)
int uid;
{
int i;
struct passwd *pwptr, *getpwuid();
for(i=0; i<u_ptr; i++)
if(u_list[i].id_id==uid)
return u_list[i].id_name;
u_list[u_ptr].id_id=uid;
if(pwptr=getpwuid(uid)) {
for(i=0; pwptr->pw_name[i]>' '; i++)
u_list[u_ptr].id_name[i]=pwptr->pw_name[i];
u_list[u_ptr].id_name[i]=0;
} else
sprintf(u_list[u_ptr].id_name, "%d", uid);
return u_list[u_ptr++].id_name;
}
char *
g_name(gid)
int gid;
{
int i;
struct group *grptr, *getgrgid();
for(i=0; i<g_ptr; i++)
if(g_list[i].id_id==gid)
return g_list[i].id_name;
g_list[g_ptr].id_id=gid;
if(grptr=getgrgid(gid)) {
for(i=0; grptr->gr_name[i]>' '; i++)
g_list[g_ptr].id_name[i]=grptr->gr_name[i];
g_list[g_ptr].id_name[i]=0;
} else
sprintf(g_list[g_ptr].id_name, "%d", gid);
return g_list[g_ptr++].id_name;
}
printime(clock)
long *clock;
{
struct tm *tmbuf, *localtime();
static char *months[12]= {
"Jan","Feb","Mar","Apr","May","Jun",
"Jul","Aug","Sep","Oct","Nov","Dec"
};
tmbuf=localtime(clock);
printf("%2d %3s %02d %2d:%02d %s",
tmbuf->tm_mday,
months[tmbuf->tm_mon],
tmbuf->tm_year,
tmbuf->tm_hour,
tmbuf->tm_min,
tab);
}
header()
{
if(flags&D_DEV)
printf("%7s%s", "IDev", tab);
if(flags&D_RDEV)
printf("%7s%s", "Rdev", tab);
if(flags&D_INO)
printf("%5s%s", "Inode", tab);
if(flags&D_SMODE)
printf("%6s%s", "Mode", tab);
if(flags&D_MODE)
printf("%-10s%s", "Long mode", tab);
if(flags&D_LINKS)
printf("%3s%s", "Lnx", tab);
if(flags&D_SUID)
printf("%3s%s", "UID", tab);
if(flags&D_UID)
printf("%-8s%s", "User", tab);
if(flags&D_SGID)
printf("%3s%s", "GID", tab);
if(flags&D_GID)
printf("%-8s%s", "Group", tab);
if(flags&D_SIZE)
printf(sizstr[1], "Size", tab);
if((flags&~(D_ATIME|D_MTIME|D_CTIME)) &&
(flags&(D_ATIME|D_MTIME|D_CTIME))) putchar(' ');
if(flags&D_ATIME)
printf("%-16s%s", "Access time", tab);
if(flags&D_MTIME)
printf("%-16s%s", "Modify time", tab);
if(flags&D_CTIME)
printf("%-16s%s", "Inode time", tab);
if(flags)
printf("%s\n", "File name");
}
triad(bits, special, code)
int bits, special;
char code;
{
if(bits&4) putchar('r');
else putchar('-');
if(bits&2) putchar('w');
else putchar('-');
if(special) putchar(code);
else if(bits&1) putchar('x');
else putchar('-');
}
main(ac, av)
int ac;
char **av;
{
int i, j;
int exit_status = 0;
int filed=0;
for(i=1; i<ac; i++) {
if(av[i][0]=='-')
for(j=1; av[i][j]; j++)
switch(av[i][j]) {
case 'T':
if(av[i][j+1])
tab = &av[i][++j];
else
tab = &av[++i][j=0];
while(av[i][j]) j++;
j--;
break;
case 'N': flags = 0; break;
case 'A': flags = -1; break;
case 'D': dodir=!dodir; break;
case 'd': flags ^= D_DEV; break;
case 'i': flags ^= D_INO; break;
case 'm': flags ^= D_MODE; break;
case 'M': flags ^= D_SMODE; break;
case 'l': flags ^= D_LINKS; break;
case 'u': flags ^= D_UID; break;
case 'U': flags ^= D_SUID; break;
case 'g': flags ^= D_GID; break;
case 'G': flags ^= D_SGID; break;
case 'r': flags ^= D_RDEV; break;
case 's': flags ^= D_SIZE; break;
case 'a': flags ^= D_ATIME; break;
case 't': flags ^= D_MTIME; break;
case 'c': flags ^= D_CTIME; break;
case 'h': dohead=!dohead; break;
case 'H': header(); break;
default:
printf("Unknown option -%c.\n", av[i][j]);
printf("\tUsage %s [-A|-N] [-diMmlUuGgrsatc] [-Ttab] [-Hh] [-D] [file]...\n", av[0]);
break;
}
else {
filed=1;
if(!fdump(av[i])) {
fperror(av[0], errname);
exit_status=errno?errno:(-xerrno);
}
}
}
if(!filed)
if(!fdump(".")) {
fperror(av[0], errname);
exit_status=errno;
}
if(dohead) header();
exit(exit_status);
}
fperror(prog, file)
char *prog, *file;
{
fprintf(stderr, "%s -- ", prog);
if(errno)
perror(file);
else
fprintf(stderr, "%s: %s\n", file, emesg[xerrno]);
}
--
Peter da Silva (the mad Australian)
UUCP: ...!shell!neuro1!{hyd-ptd,baylor,datafac}!peter
MCI: PDASILVA; CIS: 70216,1076
More information about the Comp.sources.unix
mailing list