1: # 2: /* 3: * list file or directory 4: */ 5: 6: struct { 7: int fdes; 8: int nleft; 9: char *nextc; 10: char buff[512]; 11: } inf; 12: 13: struct ibuf { 14: int idev; 15: int inum; 16: int iflags; 17: char inl; 18: char iuid; 19: char igid; 20: char isize0; 21: int isize; 22: int iaddr[8]; 23: char *iatime[2]; 24: char *imtime[2]; 25: }; 26: 27: struct lbuf { 28: char lname[15]; 29: int lnum; 30: int lflags; 31: char lnl; 32: char luid; 33: char lgid; 34: char lsize0; 35: int lsize; 36: char *lmtime[2]; 37: }; 38: 39: struct lbufx { 40: char *namep; 41: }; 42: 43: int aflg, dflg, lflg, sflg, tflg, uflg, iflg, fflg, gflg; 44: int fout; 45: int rflg 1; 46: char *year; 47: int flags; 48: int uidfil -1; 49: int lastuid -1; 50: char tbuf[16]; 51: int tblocks; 52: int statreq; 53: struct lbuf *lastp &end; 54: struct lbuf *rlastp &end; 55: char *dotp "."; 56: 57: #define IFMT 060000 58: #define DIR 0100000 59: #define CHR 020000 60: #define BLK 040000 61: #define ISARG 01000 62: #define LARGE 010000 63: #define STXT 010000 64: #define SUID 04000 65: #define SGID 02000 66: #define ROWN 0400 67: #define WOWN 0200 68: #define XOWN 0100 69: #define RGRP 040 70: #define WGRP 020 71: #define XGRP 010 72: #define ROTH 04 73: #define WOTH 02 74: #define XOTH 01 75: #define RSTXT 01000 76: 77: main(argc, argv) 78: char **argv; 79: { 80: int i, j; 81: extern struct lbuf end; 82: register struct lbuf *ep, *ep1; 83: register struct lbuf *slastp; 84: struct lbuf lb; 85: int t; 86: int compar(); 87: 88: fout = dup(1); 89: time(lb.lmtime); 90: year = lb.lmtime[0] - 245; /* 6 months ago */ 91: if (--argc > 0 && *argv[1] == '-') { 92: argv++; 93: while (*++*argv) switch (**argv) { 94: case 'a': 95: aflg++; 96: continue; 97: 98: case 's': 99: sflg++; 100: statreq++; 101: continue; 102: 103: case 'd': 104: dflg++; 105: continue; 106: 107: case 'g': 108: gflg++; 109: continue; 110: 111: case 'l': 112: lflg++; 113: statreq++; 114: continue; 115: 116: case 'r': 117: rflg = -1; 118: continue; 119: 120: case 't': 121: tflg++; 122: statreq++; 123: continue; 124: 125: case 'u': 126: uflg++; 127: continue; 128: 129: case 'i': 130: iflg++; 131: continue; 132: 133: case 'f': 134: fflg++; 135: continue; 136: 137: default: 138: continue; 139: } 140: argc--; 141: } 142: if (fflg) { 143: aflg++; 144: lflg = 0; 145: sflg = 0; 146: tflg = 0; 147: statreq = 0; 148: } 149: if(lflg) { 150: t = "/etc/passwd"; 151: if(gflg) 152: t = "/etc/group"; 153: uidfil = open(t, 0); 154: } 155: if (argc==0) { 156: argc++; 157: argv = &dotp - 1; 158: } 159: for (i=0; i < argc; i++) { 160: if ((ep = gstat(*++argv, 1))==0) 161: continue; 162: ep->namep = *argv; 163: ep->lflags =| ISARG; 164: } 165: qsort(&end, lastp - &end, sizeof *lastp, compar); 166: slastp = lastp; 167: for (ep = &end; ep<slastp; ep++) { 168: if (ep->lflags&DIR && dflg==0 || fflg) { 169: if (argc>1) 170: printf("\n%s:\n", ep->namep); 171: lastp = slastp; 172: readdir(ep->namep); 173: if (fflg==0) 174: qsort(slastp,lastp - slastp,sizeof *lastp,compar); 175: if (statreq) 176: printf("total %d\n", tblocks); 177: for (ep1=slastp; ep1<lastp; ep1++) 178: pentry(ep1); 179: } else 180: pentry(ep); 181: } 182: flush(); 183: } 184: 185: pentry(ap) 186: struct lbuf *ap; 187: { 188: struct { char dminor, dmajor;}; 189: register t; 190: register struct lbuf *p; 191: register char *cp; 192: 193: p = ap; 194: if (p->lnum == -1) 195: return; 196: if (iflg) 197: printf("%5d ", p->lnum); 198: if (lflg) { 199: pmode(p->lflags); 200: printf("%2d ", p->lnl); 201: t = p->luid; 202: if(gflg) 203: t = p->lgid; 204: t =& 0377; 205: if (getname(t, tbuf)==0) 206: printf("%-6.6s", tbuf); 207: else 208: printf("%-6d", t); 209: if (p->lflags & (BLK|CHR)) 210: printf("%3d,%3d", p->lsize.dmajor&0377, 211: p->lsize.dminor&0377); 212: else 213: printf("%7s", locv(p->lsize0, p->lsize)); 214: cp = ctime(p->lmtime); 215: if(p->lmtime[0] < year) 216: printf(" %-7.7s %-4.4s ", cp+4, cp+20); else 217: printf(" %-12.12s ", cp+4); 218: } else if (sflg) 219: printf("%4d ", nblock(p->lsize0, p->lsize)); 220: if (p->lflags&ISARG) 221: printf("%s\n", p->namep); 222: else 223: printf("%.14s\n", p->lname); 224: } 225: 226: getname(uid, buf) 227: int uid; 228: char buf[]; 229: { 230: int j, c, n, i; 231: 232: if (uid==lastuid) 233: return(0); 234: inf.fdes = uidfil; 235: seek(inf.fdes, 0, 0); 236: inf.nleft = 0; 237: lastuid = -1; 238: do { 239: i = 0; 240: j = 0; 241: n = 0; 242: while((c=getc(&inf)) != '\n') { 243: if (c<0) 244: return(-1); 245: if (c==':') { 246: j++; 247: c = '0'; 248: } 249: if (j==0) 250: buf[i++] = c; 251: if (j==2) 252: n = n*10 + c - '0'; 253: } 254: } while (n != uid); 255: buf[i++] = '\0'; 256: lastuid = uid; 257: return(0); 258: } 259: 260: nblock(size0, size) 261: char *size0, *size; 262: { 263: register int n; 264: 265: n = ldiv(size0, size, 512); 266: if (size&0777) 267: n++; 268: if (n>8) 269: n =+ (n+255)/256; 270: return(n); 271: } 272: 273: int m0[] { 3, DIR, 'd', BLK, 'b', CHR, 'c', '-'}; 274: int m1[] { 1, ROWN, 'r', '-' }; 275: int m2[] { 1, WOWN, 'w', '-' }; 276: int m3[] { 2, SUID, 's', XOWN, 'x', '-' }; 277: int m4[] { 1, RGRP, 'r', '-' }; 278: int m5[] { 1, WGRP, 'w', '-' }; 279: int m6[] { 2, SGID, 's', XGRP, 'x', '-' }; 280: int m7[] { 1, ROTH, 'r', '-' }; 281: int m8[] { 1, WOTH, 'w', '-' }; 282: int m9[] { 1, XOTH, 'x', '-' }; 283: int m10[] { 1, STXT, 't', ' ' }; 284: 285: int *m[] { m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10}; 286: 287: pmode(aflag) 288: { 289: register int **mp; 290: 291: flags = aflag; 292: for (mp = &m[0]; mp < &m[11];) 293: select(*mp++); 294: } 295: 296: select(pairp) 297: int *pairp; 298: { 299: register int n, *ap; 300: 301: ap = pairp; 302: n = *ap++; 303: while (--n>=0 && (flags&*ap++)==0) 304: ap++; 305: putchar(*ap); 306: } 307: 308: makename(dir, file) 309: char *dir, *file; 310: { 311: static char dfile[100]; 312: register char *dp, *fp; 313: register int i; 314: 315: dp = dfile; 316: fp = dir; 317: while (*fp) 318: *dp++ = *fp++; 319: *dp++ = '/'; 320: fp = file; 321: for (i=0; i<14; i++) 322: *dp++ = *fp++; 323: *dp = 0; 324: return(dfile); 325: } 326: 327: readdir(dir) 328: char *dir; 329: { 330: static struct { 331: int dinode; 332: char dname[14]; 333: } dentry; 334: register char *p; 335: register int j; 336: register struct lbuf *ep; 337: 338: if (fopen(dir, &inf) < 0) { 339: printf("%s unreadable\n", dir); 340: return; 341: } 342: tblocks = 0; 343: for(;;) { 344: p = &dentry; 345: for (j=0; j<16; j++) 346: *p++ = getc(&inf); 347: if (dentry.dinode==0 348: || aflg==0 && dentry.dname[0]=='.') 349: continue; 350: if (dentry.dinode == -1) 351: break; 352: ep = gstat(makename(dir, dentry.dname), 0); 353: if (ep->lnum != -1) 354: ep->lnum = dentry.dinode; 355: for (j=0; j<14; j++) 356: ep->lname[j] = dentry.dname[j]; 357: } 358: close(inf.fdes); 359: } 360: 361: gstat(file, argfl) 362: char *file; 363: { 364: struct ibuf statb; 365: register struct lbuf *rep; 366: 367: if (lastp+1 >= rlastp) { 368: sbrk(512); 369: rlastp.idev =+ 512; 370: } 371: rep = lastp; 372: lastp++; 373: rep->lflags = 0; 374: rep->lnum = 0; 375: if (argfl || statreq) { 376: if (stat(file, &statb)<0) { 377: printf("%s not found\n", file); 378: statb.inum = -1; 379: statb.isize0 = 0; 380: statb.isize = 0; 381: statb.iflags = 0; 382: if (argfl) { 383: lastp--; 384: return(0); 385: } 386: } 387: rep->lnum = statb.inum; 388: statb.iflags =& ~DIR; 389: if ((statb.iflags&IFMT) == 060000) { 390: statb.iflags =& ~020000; 391: } else if ((statb.iflags&IFMT)==040000) { 392: statb.iflags =& ~IFMT; 393: statb.iflags =| DIR; 394: } 395: statb.iflags =& ~ LARGE; 396: if (statb.iflags & RSTXT) 397: statb.iflags =| STXT; 398: statb.iflags =& ~ RSTXT; 399: rep->lflags = statb.iflags; 400: rep->luid = statb.iuid; 401: rep->lgid = statb.igid; 402: rep->lnl = statb.inl; 403: rep->lsize0 = statb.isize0; 404: rep->lsize = statb.isize; 405: if (rep->lflags & (BLK|CHR) && lflg) 406: rep->lsize = statb.iaddr[0]; 407: rep->lmtime[0] = statb.imtime[0]; 408: rep->lmtime[1] = statb.imtime[1]; 409: if(uflg) { 410: rep->lmtime[0] = statb.iatime[0]; 411: rep->lmtime[1] = statb.iatime[1]; 412: } 413: tblocks =+ nblock(statb.isize0, statb.isize); 414: } 415: return(rep); 416: } 417: 418: compar(ap1, ap2) 419: struct lbuf *ap1, *ap2; 420: { 421: register struct lbuf *p1, *p2; 422: register int i; 423: int j; 424: struct { char *charp;}; 425: 426: p1 = ap1; 427: p2 = ap2; 428: if (dflg==0) { 429: if ((p1->lflags&(DIR|ISARG)) == (DIR|ISARG)) { 430: if ((p2->lflags&(DIR|ISARG)) != (DIR|ISARG)) 431: return(1); 432: } else { 433: if ((p2->lflags&(DIR|ISARG)) == (DIR|ISARG)) 434: return(-1); 435: } 436: } 437: if (tflg) { 438: i = 0; 439: if (p2->lmtime[0] > p1->lmtime[0]) 440: i++; 441: else if (p2->lmtime[0] < p1->lmtime[0]) 442: i--; 443: else if (p2->lmtime[1] > p1->lmtime[1]) 444: i++; 445: else if (p2->lmtime[1] < p1->lmtime[1]) 446: i--; 447: return(i*rflg); 448: } 449: if (p1->lflags&ISARG) 450: p1 = p1->namep; 451: else 452: p1 = p1->lname; 453: if (p2->lflags&ISARG) 454: p2 = p2->namep; 455: else 456: p2 = p2->lname; 457: for (;;) 458: if ((j = *p1.charp++ - *p2.charp++) || p1.charp[-1]==0) 459: return(rflg*j); 460: return(0); 461: }