SRI-NOSC/s1/ls/ls.c

Compare this file to the similar file:
Show the results in this format:

#include "../h/iobuf.h"

#define GROUPS 1              /* define for std bell groups */
/*
 * list file or directory
 */

#define NUIDB   50      /* 50 uid name slots */

struct	suids	{
	int	f_uid;
	int	f_count;
	char    f_lnam[10];
} uidbuf[NUIDB];

struct	iobuf inf;

struct { char low; char high; };

struct ibuf {
	int	idev;
	int	inum;
	int	iflags;
	char	inl;
	char	iuid;
	char	igid;
	char	isize0;
	int	isize;
	int	iaddr[8];
	long	iatime;
	long	imtime;
};

struct lbuf {
	char	lname[14];
	int	lnum;
	int	lflags;
#ifdef GROUPS
	int     uid:8;
	int     gid:8;
#endif
#ifndef GROUPS
	int     uid;
#endif
	char	lnl;
	char	lsize0;
	int	lsize;
	long	lmtime;
} bentry;

struct lbufx {
	char	*namep;
};

int     aflg, bflg, dflg, fflg, gflg, iflg, lflg;
int     sflg, tflg, uflg, xflg, dotflg;
int	hflgx, hflg 1;
int	bsbflg, bsbsiz, bsbnum, bsbwhf, namsiz, lnlsiz;
int     fout,   dirflg;
int	rflg	1;
int	flags;
int	tblocks, tblox;
int	statreq;
struct	lbuf	*lastp	&end;
struct	lbuf	*rlastp	&end;
char	*dotp	".";
long	nowtime;

#define	IFMT	060000
#define	DIR	0100000
#define	CHR	020000
#define	BLK	040000
#define STICKY  IFMT
#define	ISARG	01000
#define	LARGE	010000
#define	SUID	04000
#define	SGID	02000
#define	ROWN	0400
#define	WOWN	0200
#define	XOWN	0100
#define	RGRP	040
#define	WGRP	020
#define	XGRP	010
#define	ROTH	04
#define	WOTH	02
#define	XOTH	01

main(argc, argv)
char **argv;
{
	int i, j, k, l, m;
	register struct lbuf *ep, *ep1;
	register struct lbuf *slastp;
	struct lbuf lb;
	char *cp, myname;
	int compar();
	extern end;

	time(&nowtime);
	fout = dup(1);
	bsbnum = 4;
	bsbflg++;
	/* get first char of name called by; d--> '-l' implied */
	cp = argv[0];
	myname = *cp;
	while (*cp)
		if (*cp++ == '/') myname = *cp;
	if (myname == 'd') {
		lflg++;	/* called via 'directory' */
		statreq++;
	}
	if (--argc > 0 && *argv[1] == '-') {
		argv++;
		while (*++*argv) switch (**argv) {
		case '.':
			dotflg++;
			continue;

		case 'a':
			aflg++;
			continue;

		case 'b':
			bflg++;
			statreq++;
			continue;

		case 'd':
			dflg++;
			continue;

		case 'f':
			fflg++;
			continue;

		case 'g':
			gflg++;
			continue;

		case 'h':
			hflg = -hflg;
			continue;

		case 'i':
			iflg++;
			continue;

		case 'l':
			lflg++;
			statreq++;
			continue;

		case 'p':
			bsbflg = 0;
			continue;

		case 'r':
			rflg = -1;
			continue;

		case 's':
			sflg++;
			statreq++;
			continue;

		case 't':
			tflg++;
			statreq++;
			continue;

		case 'u':
			uflg++;
			continue;

		case 'x':
			xflg = xflg? -xflg: -1;
			continue;

		default:
			printf("Unknown switch: %c\n", **argv);
			goto leave;
		}
		argc--;
	}
	if (fflg) {
		aflg++;
		lflg = 0;
		sflg = 0;
		tflg = 0;
		statreq = 0;
	}
	if(iflg || sflg || lflg) bsbflg = 0;
	if (argc==0) {
		argc++;
		argv = &dotp - 1;
	}
	namsiz = 4;
	for (i=0; i < argc; i++) {
		if ((ep = gstat(*++argv, 1))==0)
			continue;
		ep->namep = *argv;
		ep->lflags =| ISARG;
		if(length(*argv) > bsbsiz)
			bsbsiz = length(*argv);
	}
	qsort(&end, lastp - &end, 28, compar);
	if(!dirflg && bsbflg) {
		blkdsp(&end, lastp);
		goto leave;
	}
	slastp = lastp;
	for (ep = &end; ep<slastp; ep++) {
		if (ep->lflags&DIR && dflg==0 || fflg) {
			if (argc>1)
				printf("\n%s:\n", ep->namep);
			namsiz = 4;
			hflgx = 0;
			lnlsiz = 0;
			bsbsiz = 0;
			lastp = slastp;
			tblocks = nblock(ep->lsize0, ep->lsize);
			readdir(ep->namep);
			if (fflg==0)
				qsort(slastp, lastp - slastp, 28, compar);
			if (statreq)
				printf("total %d\n", tblocks);
			if(!bsbflg)
				for (ep1=slastp; ep1<lastp; ep1++)
					pentry(ep1);
			else
				blkdsp(slastp, lastp);
		} else {
			if(argc == 1)
				if(hflg == 1)
					hflg = 0;
				else
					hflg = 1;
			pentry(ep);
		}
	}
leave:	flush();
}

pentry(ap)
struct lbuf *ap;
{
	char tbuf[16];
	struct { char dminor, dmajor;};
	register struct lbuf *p;
	register char *cp;
	long longtime;

/*      longtime = 60l*60l*24l*30l*10l;  /* 10 months of seconds */
	longtime = 25920000l;
	p = ap;
	if (p->lnum == -1)
		return;
	if(hflg > 0 && !hflgx)
		header();
	if (iflg)
		printf("%5d ", p->lnum);
	if (lflg) {
		pmode(p->lflags);
		if(lnlsiz)
			printf("%*d", lnlsiz+1, p->lnl&0377);
		if(cp = getl(p->uid))
			printf(" %-*.15s", namsiz, cp);
		else
			printf(" %-*d", namsiz, p->uid);
#ifdef GROUPS
		if(gflg)
			printf(" %3d", p->gid);
#endif
		if (p->lflags&IFMT && (p->lflags&IFMT) != IFMT) {
			printf("%3d,%3d", p->lsize.dmajor&0377,
			    p->lsize.dminor&0377);
			if(sflg)
				printf("  (0)");
		} else {
			printf("%7s", locv(p->lsize0, p->lsize));
			if (sflg)
				printf("%5d", nblock(p->lsize0, p->lsize));
		}
		cp = ctime(&p->lmtime)+4;
		if((nowtime - p->lmtime) > longtime)
			printf(" %-6.6s '%-4.2s ",cp,cp+18);
		else
			printf(" %-12.12s ",cp);
	}
	if (p->lflags&ISARG)
		printf("%s\n", p->namep);
	else
		printf("%.14s\n", p->lname);
}

nblock(size0, size)
char *size0, *size;
{
	register int n;

	n = ldiv(size0, size, 512);
	if (size&0777)
		n++;
	if (n>8)
		n =+ (n+255)/256;
	return(n);
}

int     m0[] { 4, STICKY, 'S', DIR, 'd', BLK, 'b', CHR, 'c', '-'};
int	m1[] { 1, ROWN, 'r', '-' };
int	m2[] { 1, WOWN, 'w', '-' };
int	m3[] { 2, SUID, 's', XOWN, 'x', '-' };
#ifdef GROUPS
int	m4[] { 1, RGRP, 'r', '-' };
int	m5[] { 1, WGRP, 'w', '-' };
int     m6[] { 2, SGID, 's', XGRP, 'x', '-' };
#endif
int	m7[] { 1, ROTH, 'r', '-' };
int	m8[] { 1, WOTH, 'w', '-' };
int	m9[] { 1, XOTH, 'x', '-' };

int	*m[] { m0, m1, m2, m3,
#ifdef GROUPS
		m4, m5, m6,
#endif
		m7, m8, m9};

pmode(aflag)
{
	register int **mp;

	flags = aflag;
	for (mp = &m[0]; mp < &m + 1;)
		select(*mp++);
}

select(pairp)
int *pairp;
{
	register int n, *ap;

	ap = pairp;
	n = *ap++;
	while (--n >= 0 && (flags&*ap) != *ap++)
		ap++;
	putchar(*ap);
}

makename(dir, file)
char *dir, *file;
{
	static char dfile[100];
	register char *dp, *fp;
	register int i;

	dp = dfile;
	fp = dir;
	while (*fp)
		*dp++ = *fp++;
	*dp++ = '/';
	fp = file;
	for (i=0; i<14; i++)
		*dp++ = *fp++;
	*dp = 0;
	return(dfile);
}

readdir(dir)
char *dir;
{
	static struct {
		int	dinode;
		char	dname[14];
	} dentry;
	register char *p;
	register int j;
	register struct lbuf *ep;

	if (fopen(dir, &inf) < 0) {
		printf("%s unreadable\n", dir);
		return;
	}
	for(;;) {
		p = &dentry;
		for (j=0; j<16; j++)
			*p++ = getc(&inf);
		if (dentry.dinode==0
		 || aflg==0 && dentry.dname[0]=='.')
			continue;
		if (dentry.dinode == -1)
			break;
		ep = gstat(makename(dir, dentry.dname), xflg);
		if((xflg < 0 && (ep->lflags&DIR)==0) ||
		   (xflg > 0 && (ep->lflags&DIR)) ||
		   (dotflg && any('.', dentry.dname))) {
			lastp--;
			tblocks =- tblox;
			continue;
		}
		if (ep->lnum != -1)
			ep->lnum = dentry.dinode;
		for (j=0; j<14; j++)
			if(!(ep->lname[j] = dentry.dname[j])) {
				if(bsbsiz < j) bsbsiz = j;
				goto fiddlestix;
			}
			bsbsiz = 14;
fiddlestix: ;
	}
	close(inf.b_fildes);
}

gstat(file, argfl)
char *file;
{
	struct ibuf statb;
	register int i;
	register struct lbuf *rep;

	if (lastp+1 >= rlastp) {
		sbrk(512);
		rlastp.idev =+ 512;
	}
	rep = lastp;
	lastp++;
	rep->lflags = 0;
	rep->lnum = 0;
	if (argfl || statreq) {
		if (stat(file, &statb)<0) {
			printf("%s not found\n", file);
			statb.inum = -1;
			statb.isize0 = 0;
			statb.isize = 0;
			statb.iflags = 0;
			if (argfl) {
				lastp--;
				return(0);
			}
		}
		rep->lnum = statb.inum;
		rep->lflags = statb.iflags& ~(IFMT|DIR|ISARG);
		switch(statb.iflags& (IFMT|ISARG)) {
		case 040000: rep->lflags =| DIR; dirflg++; break;
		case 020000: rep->lflags =| CHR; break;
		case 060000: rep->lflags =| BLK; break;
		case 001000: rep->lflags =| STICKY; break;
		}
#ifndef GROUPS
		rep->uid.high = statb.iuid;
		rep->uid.low = statb.igid;
#endif
#ifdef GROUPS
		rep->uid = statb.iuid;
		rep->gid = statb.igid;
#endif
	/*      getl(rep->uid);         /* get name lengths */
		namsiz = 8;             /* rand hack !!!!!!!*/
		rep->lnl = statb.inl;
		if((i = decsiz(statb.inl&0377)) > lnlsiz && statb.inl != 1)
			lnlsiz = i;
		rep->lsize0 = statb.isize0;
		rep->lsize = statb.isize;
		if (rep->lflags&IFMT && (rep->lflags&IFMT) != IFMT && lflg)
			rep->lsize = statb.iaddr[0];
		rep->lmtime = statb.imtime;
		if(uflg) {
			rep->lmtime = statb.iatime;
		}
		tblox = nblock(statb.isize0, statb.isize);
		tblocks =+ tblox;
	}
	return(rep);
}

compar(ap1, ap2)
struct lbuf *ap1, *ap2;
{
	register struct lbuf *p1, *p2;
	register int i;
	int j, lim;
	struct { char *charp;};

	p1 = ap1;
	p2 = ap2;
	if (dflg==0) {
		if ((p1->lflags&(DIR|ISARG)) == (DIR|ISARG)) {
			if ((p2->lflags&(DIR|ISARG)) != (DIR|ISARG))
				return(1);
		} else {
			if ((p2->lflags&(DIR|ISARG)) == (DIR|ISARG))
				return(-1);
		}
	}
	if (tflg) {
		i = 0;
		if(p2->lmtime > p1->lmtime)
			i++;
		else if(p2->lmtime < p1->lmtime)
			i--;
		return(i*rflg);
	}
	if(bflg)
		return(sizcmp(p1,p2)*rflg);
	if(p1->lflags & ISARG) {
		p1 = p1->namep;  p2 = p2->namep;
		lim = 256;
	} else {
		p1 = p1->lname;  p2 = p2->lname;
		lim = 14;
	}
	for (i=0; i<lim; i++)
		if ((j = *p1.charp++ - *p2.charp++) || p1.charp[-1]==0)
			return(rflg*j);
	return(0);
}


getl(uid)
{
	register struct suids *u, *small;
	register int i;
	char *cp, *np;

	small = &uidbuf[0];
	for(u = &uidbuf; u < &uidbuf[NUIDB]; u++) {
		if(u->f_uid == 0) {
			small = u;
			break;
		}
		if(u->f_uid == uid+1) {
			u->f_count++;
			i = length(u->f_lnam);
			if(i > namsiz)
				namsiz = i;
			return(u->f_lnam);
		}
		if(u->f_count < small->f_count)
			small = u;
	}
	cp = getlogn(uid);
	if(*cp) {
		np = small->f_lnam;
		i = 0;
		while(*np++ = *cp++)
			i++;
		if(i > namsiz)
			namsiz = i;
		small->f_uid = uid+1;
		small->f_count = 1;
		return(small->f_lnam);
	}
	return(0);
}

decsiz(num)
{
	register int i;

	i = 1;
	while(num =/ 10) i++;
	return(i);
}

header()
{
	hflgx++;
	if(iflg) printf("Inode ");
	if(lflg) {
		printf("%-*s", sizeof m/sizeof m[0], "t prot");
		if(lnlsiz) printf("%*s", lnlsiz+1, "ln");
		printf(" %-*s", namsiz+1, "owner");
#ifdef GROUPS
		if(gflg)
			printf("grp ");
#endif
		printf(" bytes ");
		if(sflg)
			printf("blks ");
		if(!uflg)
			printf("  modified   ");
		else
			printf("  accessed   ");
	}
	if(iflg || lflg || sflg)
		printf("name\n");
}

length(str)
{
	register char *cp;
	register int i;

	cp = str;
	i = 0;
	while(*cp++) ++i;
	return(i);
}


blkdsp(base, last)
struct lbuf *base, *last;
{
	register struct lbuf *ep1;
	int i,j,k,l,mmm;

	bsbnum = 79/(bsbsiz+1);
/*      bsbnum = (sgbuf.sg_clim?
		 (sgbuf.sg_clim&0377)-1:71)
		 /(bsbsiz+1);
 */     ep1 = base;
	i = (last-base);
	l = (i + bsbnum -1) / bsbnum;
	for(j = 0; j < l; j++) {
	    for(mmm = 0; mmm < bsbnum; mmm++) {
		k = (mmm * l) + j;
		if(k >= i)
		    continue;
		if((mmm+1)*l+j >= i)
		    printf("%s",gname(&ep1[k]));
		else
		    printf("%-*s ",bsbsiz,gname(&ep1[k]));
	    }
	    printf("\n");
	}
}

gname(lbp)
struct lbuf *lbp;
{
	register struct lbuf *lp;

	lp = lbp;
	if(lp->lflags & ISARG)
		return(lp->namep);
	lp->lname[14] = 0;
	return(&lp->lname[0]);
}


sizcmp(p1,p2)
struct lbuf *p1, *p2;
{
	long l1, l2;
	struct { int long0, long1; };

	l1.long0 = p1->lsize0 & 0377;
	l1.long1 = p1->lsize;
	l2.long0 = p2->lsize0 & 0377;
	l2.long1 = p2->lsize;
	if(l1 > l2)
		return(-1);
	if(l1 < l2)
		return(1);
	return(0);
}