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

Defined functions

compar defined in line 429; used 3 times
getname defined in line 213; used 1 times
gstat defined in line 336; used 3 times
main defined in line 52; never used
makename defined in line 286; used 2 times
nblock defined in line 247; used 3 times
pentry defined in line 166; used 2 times
pmode defined in line 266; used 1 times
readdir defined in line 306; used 1 times
savestr defined in line 457; used 2 times
select defined in line 275; used 1 times

Defined variables

aflg defined in line 32; used 3 times
cflg defined in line 32; used 2 times
dflg defined in line 32; used 3 times
dotp defined in line 43; used 1 times
fflg defined in line 32; used 4 times
firstp defined in line 42; used 3 times
flags defined in line 35; used 2 times
flist defined in line 40; used 3 times
gflg defined in line 32; used 3 times
iflg defined in line 32; used 2 times
lastp defined in line 41; used 11 times
lastuid defined in line 36; used 3 times
lflg defined in line 32; used 7 times
m defined in line 264; used 4 times
  • in line 271(4)
m1 defined in line 254; used 1 times
m2 defined in line 255; used 1 times
m3 defined in line 256; used 1 times
m4 defined in line 257; used 1 times
m5 defined in line 258; used 1 times
m6 defined in line 259; used 1 times
m7 defined in line 260; used 1 times
m8 defined in line 261; used 1 times
m9 defined in line 262; used 1 times
rflg defined in line 33; used 4 times
sflg defined in line 32; used 4 times
statreq defined in line 39; used 5 times
stdbuf defined in line 12; used 1 times
  • in line 63
tblocks defined in line 38; used 3 times
tbuf defined in line 37; used 2 times
tflg defined in line 32; used 3 times
uflg defined in line 32; used 2 times
year defined in line 34; used 2 times

Defined struct's

lbuf defined in line 14; used 34 times

Defined macros

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