1: /*
   2:  * list file or directory
   3:  */
   4: 
   5: #include <sys/param.h>
   6: #include <sys/stat.h>
   7: #include <sys/dir.h>
   8: #include <stdio.h>
   9: 
  10: #define NFILES  1024
  11: FILE    *pwdf, *dirf;
  12: char    stdbuf[BUFSIZ];
  13: 
  14: struct lbuf {
  15:     union {
  16:         char    lname[15];
  17:         char    *namep;
  18:     } ln;
  19:     char    ltype;
  20:     short   lnum;
  21:     short   lflags;
  22:     short   lnl;
  23:     short   luid;
  24:     short   lgid;
  25:     long    lsize;
  26:     long    lmtime;
  27: };
  28: 
  29: int aflg, dflg, lflg, sflg, tflg, uflg, iflg, fflg, gflg, cflg;
  30: int rflg    = 1;
  31: long    year;
  32: int flags;
  33: int lastuid = -1;
  34: char    tbuf[16];
  35: long    tblocks;
  36: int statreq;
  37: struct  lbuf    *flist[NFILES];
  38: struct  lbuf    **lastp = flist;
  39: struct  lbuf    **firstp = flist;
  40: char    *dotp   = ".";
  41: 
  42: char    *makename();
  43: struct  lbuf *gstat();
  44: char    *ctime();
  45: long    nblock();
  46: 
  47: #define ISARG   0100000
  48: 
  49: main(argc, argv)
  50: char *argv[];
  51: {
  52:     int i;
  53:     register struct lbuf *ep, **ep1;
  54:     register struct lbuf **slastp;
  55:     struct lbuf **epp;
  56:     struct lbuf lb;
  57:     char *t;
  58:     int compar();
  59: 
  60:     setbuf(stdout, stdbuf);
  61:     time(&lb.lmtime);
  62:     year = lb.lmtime - 6L*30L*24L*60L*60L; /* 6 months ago */
  63:     if (--argc > 0 && *argv[1] == '-') {
  64:         argv++;
  65:         while (*++*argv) switch (**argv) {
  66: 
  67:         case 'a':
  68:             aflg++;
  69:             continue;
  70: 
  71:         case 's':
  72:             sflg++;
  73:             statreq++;
  74:             continue;
  75: 
  76:         case 'd':
  77:             dflg++;
  78:             continue;
  79: 
  80:         case 'g':
  81:             gflg++;
  82:             continue;
  83: 
  84:         case 'l':
  85:             lflg++;
  86:             statreq++;
  87:             continue;
  88: 
  89:         case 'r':
  90:             rflg = -1;
  91:             continue;
  92: 
  93:         case 't':
  94:             tflg++;
  95:             statreq++;
  96:             continue;
  97: 
  98:         case 'u':
  99:             uflg++;
 100:             continue;
 101: 
 102:         case 'c':
 103:             cflg++;
 104:             continue;
 105: 
 106:         case 'i':
 107:             iflg++;
 108:             continue;
 109: 
 110:         case 'f':
 111:             fflg++;
 112:             continue;
 113: 
 114:         default:
 115:             continue;
 116:         }
 117:         argc--;
 118:     }
 119:     if (fflg) {
 120:         aflg++;
 121:         lflg = 0;
 122:         sflg = 0;
 123:         tflg = 0;
 124:         statreq = 0;
 125:     }
 126:     if(lflg) {
 127:         t = "/etc/passwd";
 128:         if(gflg)
 129:             t = "/etc/group";
 130:         pwdf = fopen(t, "r");
 131:     }
 132:     if (argc==0) {
 133:         argc++;
 134:         argv = &dotp - 1;
 135:     }
 136:     for (i=0; i < argc; i++) {
 137:         if ((ep = gstat(*++argv, 1))==NULL)
 138:             continue;
 139:         ep->ln.namep = *argv;
 140:         ep->lflags |= ISARG;
 141:     }
 142:     qsort(firstp, lastp - firstp, sizeof *lastp, compar);
 143:     slastp = lastp;
 144:     for (epp=firstp; epp<slastp; epp++) {
 145:         ep = *epp;
 146:         if (ep->ltype=='d' && dflg==0 || fflg) {
 147:             if (argc>1)
 148:                 printf("\n%s:\n", ep->ln.namep);
 149:             lastp = slastp;
 150:             readdir(ep->ln.namep);
 151:             if (fflg==0)
 152:                 qsort(slastp,lastp - slastp,sizeof *lastp,compar);
 153:             if (lflg || sflg)
 154:                 printf("total %D\n", tblocks);
 155:             for (ep1=slastp; ep1<lastp; ep1++)
 156:                 pentry(*ep1);
 157:         } else
 158:             pentry(ep);
 159:     }
 160:     exit(0);
 161: }
 162: 
 163: pentry(ap)
 164: struct lbuf *ap;
 165: {
 166:     struct { char dminor, dmajor;};
 167:     register t;
 168:     register struct lbuf *p;
 169:     register char *cp;
 170: 
 171:     p = ap;
 172:     if (p->lnum == -1)
 173:         return;
 174:     if (iflg)
 175:         printf("%5u ", p->lnum);
 176:     if (sflg)
 177:     printf("%4D ", nblock(p->lsize));
 178:     if (lflg) {
 179:         putchar(p->ltype);
 180:         pmode(p->lflags);
 181:         printf("%2d ", p->lnl);
 182:         t = p->luid;
 183:         if(gflg)
 184:             t = p->lgid;
 185:         if (getname(t, tbuf)==0)
 186:             printf("%-6.6s", tbuf);
 187:         else
 188:             printf("%-6d", t);
 189:         if (p->ltype=='b' || p->ltype=='c')
 190:             printf("%3d,%3d", major((int)p->lsize), minor((int)p->lsize));
 191:         else
 192:             printf("%7ld", p->lsize);
 193:         cp = ctime(&p->lmtime);
 194:         if(p->lmtime < year)
 195:             printf(" %-7.7s %-4.4s ", cp+4, cp+20); else
 196:             printf(" %-12.12s ", cp+4);
 197:     }
 198:     if (p->lflags&ISARG)
 199:         printf("%s\n", p->ln.namep);
 200:     else
 201:         printf("%.14s\n", p->ln.lname);
 202: }
 203: 
 204: getname(uid, buf)
 205: int uid;
 206: char buf[];
 207: {
 208:     int j, c, n, i;
 209: 
 210:     if (uid==lastuid)
 211:         return(0);
 212:     if(pwdf == NULL)
 213:         return(-1);
 214:     rewind(pwdf);
 215:     lastuid = -1;
 216:     do {
 217:         i = 0;
 218:         j = 0;
 219:         n = 0;
 220:         while((c=fgetc(pwdf)) != '\n') {
 221:             if (c==EOF)
 222:                 return(-1);
 223:             if (c==':') {
 224:                 j++;
 225:                 c = '0';
 226:             }
 227:             if (j==0)
 228:                 buf[i++] = c;
 229:             if (j==2)
 230:                 n = n*10 + c - '0';
 231:         }
 232:     } while (n != uid);
 233:     buf[i++] = '\0';
 234:     lastuid = uid;
 235:     return(0);
 236: }
 237: 
 238: long
 239: nblock(size)
 240: long size;
 241: {
 242:     return((size+1023)>>10);
 243: }
 244: 
 245: int m1[] = { 1, S_IREAD>>0, 'r', '-' };
 246: int m2[] = { 1, S_IWRITE>>0, 'w', '-' };
 247: int m3[] = { 2, S_ISUID, 's', S_IEXEC>>0, 'x', '-' };
 248: int m4[] = { 1, S_IREAD>>3, 'r', '-' };
 249: int m5[] = { 1, S_IWRITE>>3, 'w', '-' };
 250: int m6[] = { 2, S_ISGID, 's', S_IEXEC>>3, 'x', '-' };
 251: int m7[] = { 1, S_IREAD>>6, 'r', '-' };
 252: int m8[] = { 1, S_IWRITE>>6, 'w', '-' };
 253: int m9[] = { 2, S_ISVTX, 't', S_IEXEC>>6, 'x', '-' };
 254: 
 255: int *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9};
 256: 
 257: pmode(aflag)
 258: {
 259:     register int **mp;
 260: 
 261:     flags = aflag;
 262:     for (mp = &m[0]; mp < &m[sizeof(m)/sizeof(m[0])];)
 263:         select(*mp++);
 264: }
 265: 
 266: select(pairp)
 267: register int *pairp;
 268: {
 269:     register int n;
 270: 
 271:     n = *pairp++;
 272:     while (--n>=0 && (flags&*pairp++)==0)
 273:         pairp++;
 274:     putchar(*pairp);
 275: }
 276: 
 277: char *
 278: makename(dir, file)
 279: char *dir, *file;
 280: {
 281:     static char dfile[100];
 282:     register char *dp, *fp;
 283:     register int i;
 284: 
 285:     dp = dfile;
 286:     fp = dir;
 287:     while (*fp)
 288:         *dp++ = *fp++;
 289:     *dp++ = '/';
 290:     fp = file;
 291:     for (i=0; i<DIRSIZ; i++)
 292:         *dp++ = *fp++;
 293:     *dp = 0;
 294:     return(dfile);
 295: }
 296: 
 297: readdir(dir)
 298: char *dir;
 299: {
 300:     static struct direct dentry;
 301:     register int j;
 302:     register struct lbuf *ep;
 303: 
 304:     if ((dirf = fopen(dir, "r")) == NULL) {
 305:         printf("%s unreadable\n", dir);
 306:         return;
 307:     }
 308:     tblocks = 0;
 309:     for(;;) {
 310:         if (fread((char *)&dentry, sizeof(dentry), 1, dirf) != 1)
 311:             break;
 312:         if (dentry.d_ino==0
 313:          || aflg==0 && dentry.d_name[0]=='.' &&  (dentry.d_name[1]=='\0'
 314:             || dentry.d_name[1]=='.' && dentry.d_name[2]=='\0'))
 315:             continue;
 316:         ep = gstat(makename(dir, dentry.d_name), 0);
 317:         if (ep==NULL)
 318:             continue;
 319:         if (ep->lnum != -1)
 320:             ep->lnum = dentry.d_ino;
 321:         for (j=0; j<DIRSIZ; j++)
 322:             ep->ln.lname[j] = dentry.d_name[j];
 323:     }
 324:     fclose(dirf);
 325: }
 326: 
 327: struct lbuf *
 328: gstat(file, argfl)
 329: char *file;
 330: {
 331:     extern char *malloc();
 332:     struct stat statb;
 333:     register struct lbuf *rep;
 334:     static int nomocore;
 335: 
 336:     if (nomocore)
 337:         return(NULL);
 338:     rep = (struct lbuf *)malloc(sizeof(struct lbuf));
 339:     if (rep==NULL) {
 340:         fprintf(stderr, "ls: out of memory\n");
 341:         nomocore = 1;
 342:         return(NULL);
 343:     }
 344:     if (lastp >= &flist[NFILES]) {
 345:         static int msg;
 346:         lastp--;
 347:         if (msg==0) {
 348:             fprintf(stderr, "ls: too many files\n");
 349:             msg++;
 350:         }
 351:     }
 352:     *lastp++ = rep;
 353:     rep->lflags = 0;
 354:     rep->lnum = 0;
 355:     rep->ltype = '-';
 356:     if (argfl || statreq) {
 357:         if (stat(file, &statb)<0) {
 358:             printf("%s not found\n", file);
 359:             statb.st_ino = -1;
 360:             statb.st_size = 0;
 361:             statb.st_mode = 0;
 362:             if (argfl) {
 363:                 lastp--;
 364:                 return(0);
 365:             }
 366:         }
 367:         rep->lnum = statb.st_ino;
 368:         rep->lsize = statb.st_size;
 369:         switch(statb.st_mode&S_IFMT) {
 370: 
 371:         case S_IFDIR:
 372:             rep->ltype = 'd';
 373:             break;
 374: 
 375:         case S_IFBLK:
 376:             rep->ltype = 'b';
 377:             rep->lsize = statb.st_rdev;
 378:             break;
 379: 
 380:         case S_IFCHR:
 381:             rep->ltype = 'c';
 382:             rep->lsize = statb.st_rdev;
 383:             break;
 384:         }
 385:         rep->lflags = statb.st_mode & ~S_IFMT;
 386:         rep->luid = statb.st_uid;
 387:         rep->lgid = statb.st_gid;
 388:         rep->lnl = statb.st_nlink;
 389:         if(uflg)
 390:             rep->lmtime = statb.st_atime;
 391:         else if (cflg)
 392:             rep->lmtime = statb.st_ctime;
 393:         else
 394:             rep->lmtime = statb.st_mtime;
 395:         tblocks += nblock(statb.st_size);
 396:     }
 397:     return(rep);
 398: }
 399: 
 400: compar(pp1, pp2)
 401: struct lbuf **pp1, **pp2;
 402: {
 403:     register struct lbuf *p1, *p2;
 404: 
 405:     p1 = *pp1;
 406:     p2 = *pp2;
 407:     if (dflg==0) {
 408:         if (p1->lflags&ISARG && p1->ltype=='d') {
 409:             if (!(p2->lflags&ISARG && p2->ltype=='d'))
 410:                 return(1);
 411:         } else {
 412:             if (p2->lflags&ISARG && p2->ltype=='d')
 413:                 return(-1);
 414:         }
 415:     }
 416:     if (tflg) {
 417:         if(p2->lmtime == p1->lmtime)
 418:             return(0);
 419:         if(p2->lmtime > p1->lmtime)
 420:             return(rflg);
 421:         return(-rflg);
 422:     }
 423:     return(rflg * strcmp(p1->lflags&ISARG? p1->ln.namep: p1->ln.lname,
 424:                 p2->lflags&ISARG? p2->ln.namep: p2->ln.lname));
 425: }

Defined functions

compar defined in line 400; used 3 times
getname defined in line 204; used 1 times
gstat defined in line 327; used 3 times
main defined in line 49; never used
makename defined in line 277; used 2 times
nblock defined in line 238; used 3 times
pentry defined in line 163; used 2 times
pmode defined in line 257; used 1 times
readdir defined in line 297; used 1 times
select defined in line 266; used 1 times

Defined variables

aflg defined in line 29; used 3 times
cflg defined in line 29; used 2 times
dflg defined in line 29; used 3 times
dotp defined in line 40; used 1 times
fflg defined in line 29; used 4 times
firstp defined in line 39; used 3 times
flags defined in line 32; used 2 times
flist defined in line 37; used 3 times
gflg defined in line 29; used 3 times
iflg defined in line 29; used 2 times
lastp defined in line 38; used 11 times
lastuid defined in line 33; used 3 times
lflg defined in line 29; used 5 times
m defined in line 255; used 4 times
  • in line 262(4)
m1 defined in line 245; used 1 times
m2 defined in line 246; used 1 times
m3 defined in line 247; used 1 times
m4 defined in line 248; used 1 times
m5 defined in line 249; used 1 times
m6 defined in line 250; used 1 times
m7 defined in line 251; used 1 times
m8 defined in line 252; used 1 times
m9 defined in line 253; used 1 times
rflg defined in line 30; used 4 times
sflg defined in line 29; used 4 times
statreq defined in line 36; used 5 times
stdbuf defined in line 12; used 1 times
  • in line 60
tblocks defined in line 35; used 3 times
tbuf defined in line 34; used 2 times
tflg defined in line 29; used 3 times
uflg defined in line 29; used 2 times
year defined in line 31; used 2 times

Defined struct's

lbuf defined in line 14; used 34 times

Defined macros

ISARG defined in line 47; used 7 times
NFILES defined in line 10; used 2 times
Last modified: 1983-05-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1507
Valid CSS Valid XHTML 1.0 Strict