Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10.2 9/5/84; site baylor.UUCP
Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!think!harvard!seismo!ut-sally!ut-ngp!shell!neuro1!baylor!peter
From: peter@baylor.UUCP (Peter da Silva)
Newsgroups: net.sources
Subject: le.c
Message-ID: <401@baylor.UUCP>
Date: Thu, 15-Aug-85 13:02:06 EDT
Article-I.D.: baylor.401
Posted: Thu Aug 15 13:02:06 1985
Date-Received: Tue, 20-Aug-85 08:33:25 EDT
Distribution: net
Organization: Ancient Illuminated Seers of Bavaria
Lines: 468

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 
#include 
#include 
#include 
#include 
#include 
#include 

#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;
	    nentries0;
	    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/5st_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; ipw_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; igr_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