home *** CD-ROM | disk | FTP | other *** search
- /*
- * list file or directory
- */
-
- #include <sys/param.h>
- #include <sys/stat.h>
- #include <sys/dir.h>
- #include <stdio.h>
-
- #define NFILES 1024
- FILE *pwdf, *dirf;
- char stdbuf[BUFSIZ];
-
- struct lbuf {
- union {
- char lname[15];
- char *namep;
- } ln;
- char ltype;
- short lnum;
- short lflags;
- short lnl;
- short luid;
- short lgid;
- long lsize;
- long lmtime;
- };
-
- int aflg, dflg, lflg, sflg, tflg, uflg, iflg, fflg, gflg, cflg;
- int rflg = 1;
- long year;
- int flags;
- int lastuid = -1;
- char tbuf[16];
- long tblocks;
- int statreq;
- struct lbuf *flist[NFILES];
- struct lbuf **lastp = flist;
- struct lbuf **firstp = flist;
- char *dotp = ".";
-
- char *makename();
- struct lbuf *gstat();
- char *ctime();
- long nblock();
-
- #define ISARG 0100000
-
- main(argc, argv)
- char *argv[];
- {
- int i;
- register struct lbuf *ep, **ep1;
- register struct lbuf **slastp;
- struct lbuf **epp;
- struct lbuf lb;
- char *t;
- int compar();
-
- setbuf(stdout, stdbuf);
- time(&lb.lmtime);
- year = lb.lmtime - 6L*30L*24L*60L*60L; /* 6 months ago */
- if (--argc > 0 && *argv[1] == '-') {
- argv++;
- while (*++*argv) switch (**argv) {
-
- case 'a':
- aflg++;
- continue;
-
- case 's':
- sflg++;
- statreq++;
- continue;
-
- case 'd':
- dflg++;
- continue;
-
- case 'g':
- gflg++;
- continue;
-
- case 'l':
- lflg++;
- statreq++;
- continue;
-
- case 'r':
- rflg = -1;
- continue;
-
- case 't':
- tflg++;
- statreq++;
- continue;
-
- case 'u':
- uflg++;
- continue;
-
- case 'c':
- cflg++;
- continue;
-
- case 'i':
- iflg++;
- continue;
-
- case 'f':
- fflg++;
- continue;
-
- default:
- continue;
- }
- argc--;
- }
- if (fflg) {
- aflg++;
- lflg = 0;
- sflg = 0;
- tflg = 0;
- statreq = 0;
- }
- if(lflg) {
- t = "/etc/passwd";
- if(gflg)
- t = "/etc/group";
- pwdf = fopen(t, "r");
- }
- if (argc==0) {
- argc++;
- argv = &dotp - 1;
- }
- for (i=0; i < argc; i++) {
- if ((ep = gstat(*++argv, 1))==NULL)
- continue;
- ep->ln.namep = *argv;
- ep->lflags |= ISARG;
- }
- qsort(firstp, lastp - firstp, sizeof *lastp, compar);
- slastp = lastp;
- for (epp=firstp; epp<slastp; epp++) {
- ep = *epp;
- if (ep->ltype=='d' && dflg==0 || fflg) {
- if (argc>1)
- printf("\n%s:\n", ep->ln.namep);
- lastp = slastp;
- readdir(ep->ln.namep);
- if (fflg==0)
- qsort(slastp,lastp - slastp,sizeof *lastp,compar);
- if (lflg || sflg)
- printf("total %D\n", tblocks);
- for (ep1=slastp; ep1<lastp; ep1++)
- pentry(*ep1);
- } else
- pentry(ep);
- }
- exit(0);
- }
-
- pentry(ap)
- struct lbuf *ap;
- {
- struct { char dminor, dmajor;};
- register t;
- register struct lbuf *p;
- register char *cp;
-
- p = ap;
- if (p->lnum == -1)
- return;
- if (iflg)
- printf("%5u ", p->lnum);
- if (sflg)
- printf("%4D ", nblock(p->lsize));
- if (lflg) {
- putchar(p->ltype);
- pmode(p->lflags);
- printf("%2d ", p->lnl);
- t = p->luid;
- if(gflg)
- t = p->lgid;
- if (getname(t, tbuf)==0)
- printf("%-6.6s", tbuf);
- else
- printf("%-6d", t);
- if (p->ltype=='b' || p->ltype=='c')
- printf("%3d,%3d", major((int)p->lsize), minor((int)p->lsize));
- else
- printf("%7ld", p->lsize);
- cp = ctime(&p->lmtime);
- if(p->lmtime < year)
- printf(" %-7.7s %-4.4s ", cp+4, cp+20); else
- printf(" %-12.12s ", cp+4);
- }
- if (p->lflags&ISARG)
- printf("%s\n", p->ln.namep);
- else
- printf("%.14s\n", p->ln.lname);
- }
-
- getname(uid, buf)
- int uid;
- char buf[];
- {
- int j, c, n, i;
-
- if (uid==lastuid)
- return(0);
- if(pwdf == NULL)
- return(-1);
- rewind(pwdf);
- lastuid = -1;
- do {
- i = 0;
- j = 0;
- n = 0;
- while((c=fgetc(pwdf)) != '\n') {
- if (c==EOF)
- return(-1);
- if (c==':') {
- j++;
- c = '0';
- }
- if (j==0)
- buf[i++] = c;
- if (j==2)
- n = n*10 + c - '0';
- }
- } while (n != uid);
- buf[i++] = '\0';
- lastuid = uid;
- return(0);
- }
-
- long
- nblock(size)
- long size;
- {
- return((size+511)>>9);
- }
-
- int m1[] = { 1, S_IREAD>>0, 'r', '-' };
- int m2[] = { 1, S_IWRITE>>0, 'w', '-' };
- int m3[] = { 2, S_ISUID, 's', S_IEXEC>>0, 'x', '-' };
- int m4[] = { 1, S_IREAD>>3, 'r', '-' };
- int m5[] = { 1, S_IWRITE>>3, 'w', '-' };
- int m6[] = { 2, S_ISGID, 's', S_IEXEC>>3, 'x', '-' };
- int m7[] = { 1, S_IREAD>>6, 'r', '-' };
- int m8[] = { 1, S_IWRITE>>6, 'w', '-' };
- int m9[] = { 2, S_ISVTX, 't', S_IEXEC>>6, 'x', '-' };
-
- int *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9};
-
- pmode(aflag)
- {
- register int **mp;
-
- flags = aflag;
- for (mp = &m[0]; mp < &m[sizeof(m)/sizeof(m[0])];)
- select(*mp++);
- }
-
- select(pairp)
- register int *pairp;
- {
- register int n;
-
- n = *pairp++;
- while (--n>=0 && (flags&*pairp++)==0)
- pairp++;
- putchar(*pairp);
- }
-
- char *
- 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<DIRSIZ; i++)
- *dp++ = *fp++;
- *dp = 0;
- return(dfile);
- }
-
- readdir(dir)
- char *dir;
- {
- static struct direct dentry;
- register int j;
- register struct lbuf *ep;
-
- if ((dirf = fopen(dir, "r")) == NULL) {
- printf("%s unreadable\n", dir);
- return;
- }
- tblocks = 0;
- for(;;) {
- if (fread((char *)&dentry, sizeof(dentry), 1, dirf) != 1)
- break;
- if (dentry.d_ino==0
- || aflg==0 && dentry.d_name[0]=='.' && (dentry.d_name[1]=='\0'
- || dentry.d_name[1]=='.' && dentry.d_name[2]=='\0'))
- continue;
- ep = gstat(makename(dir, dentry.d_name), 0);
- if (ep==NULL)
- continue;
- if (ep->lnum != -1)
- ep->lnum = dentry.d_ino;
- for (j=0; j<DIRSIZ; j++)
- ep->ln.lname[j] = dentry.d_name[j];
- }
- fclose(dirf);
- }
-
- struct lbuf *
- gstat(file, argfl)
- char *file;
- {
- extern char *malloc();
- struct stat statb;
- register struct lbuf *rep;
- static int nomocore;
-
- if (nomocore)
- return(NULL);
- rep = (struct lbuf *)malloc(sizeof(struct lbuf));
- if (rep==NULL) {
- fprintf(stderr, "ls: out of memory\n");
- nomocore = 1;
- return(NULL);
- }
- if (lastp >= &flist[NFILES]) {
- static int msg;
- lastp--;
- if (msg==0) {
- fprintf(stderr, "ls: too many files\n");
- msg++;
- }
- }
- *lastp++ = rep;
- rep->lflags = 0;
- rep->lnum = 0;
- rep->ltype = '-';
- if (argfl || statreq) {
- if (stat(file, &statb)<0) {
- printf("%s not found\n", file);
- statb.st_ino = -1;
- statb.st_size = 0;
- statb.st_mode = 0;
- if (argfl) {
- lastp--;
- return(0);
- }
- }
- rep->lnum = statb.st_ino;
- rep->lsize = statb.st_size;
- switch(statb.st_mode&S_IFMT) {
-
- case S_IFDIR:
- rep->ltype = 'd';
- break;
-
- case S_IFBLK:
- rep->ltype = 'b';
- rep->lsize = statb.st_rdev;
- break;
-
- case S_IFCHR:
- rep->ltype = 'c';
- rep->lsize = statb.st_rdev;
- break;
- }
- rep->lflags = statb.st_mode & ~S_IFMT;
- rep->luid = statb.st_uid;
- rep->lgid = statb.st_gid;
- rep->lnl = statb.st_nlink;
- if(uflg)
- rep->lmtime = statb.st_atime;
- else if (cflg)
- rep->lmtime = statb.st_ctime;
- else
- rep->lmtime = statb.st_mtime;
- tblocks += nblock(statb.st_size);
- }
- return(rep);
- }
-
- compar(pp1, pp2)
- struct lbuf **pp1, **pp2;
- {
- register struct lbuf *p1, *p2;
-
- p1 = *pp1;
- p2 = *pp2;
- if (dflg==0) {
- if (p1->lflags&ISARG && p1->ltype=='d') {
- if (!(p2->lflags&ISARG && p2->ltype=='d'))
- return(1);
- } else {
- if (p2->lflags&ISARG && p2->ltype=='d')
- return(-1);
- }
- }
- if (tflg) {
- if(p2->lmtime == p1->lmtime)
- return(0);
- if(p2->lmtime > p1->lmtime)
- return(rflg);
- return(-rflg);
- }
- return(rflg * strcmp(p1->lflags&ISARG? p1->ln.namep: p1->ln.lname,
- p2->lflags&ISARG? p2->ln.namep: p2->ln.lname));
- }
-