|
|
1.1 ! root 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("%5d ", 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+511)>>9); ! 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: struct stat statb; ! 332: register struct lbuf *rep; ! 333: static int nomocore; ! 334: ! 335: if (nomocore) ! 336: return(NULL); ! 337: rep = (struct lbuf *)malloc(sizeof(struct lbuf)); ! 338: if (rep==NULL) { ! 339: fprintf(stderr, "ls: out of memory\n"); ! 340: nomocore = 1; ! 341: return(NULL); ! 342: } ! 343: if (lastp >= &flist[NFILES]) { ! 344: static int msg; ! 345: lastp--; ! 346: if (msg==0) { ! 347: fprintf(stderr, "ls: too many files\n"); ! 348: msg++; ! 349: } ! 350: } ! 351: *lastp++ = rep; ! 352: rep->lflags = 0; ! 353: rep->lnum = 0; ! 354: rep->ltype = '-'; ! 355: if (argfl || statreq) { ! 356: if (stat(file, &statb)<0) { ! 357: printf("%s not found\n", file); ! 358: statb.st_ino = -1; ! 359: statb.st_size = 0; ! 360: statb.st_mode = 0; ! 361: if (argfl) { ! 362: lastp--; ! 363: return(0); ! 364: } ! 365: } ! 366: rep->lnum = statb.st_ino; ! 367: rep->lsize = statb.st_size; ! 368: switch(statb.st_mode&S_IFMT) { ! 369: ! 370: case S_IFDIR: ! 371: rep->ltype = 'd'; ! 372: break; ! 373: ! 374: case S_IFBLK: ! 375: rep->ltype = 'b'; ! 376: rep->lsize = statb.st_rdev; ! 377: break; ! 378: ! 379: case S_IFCHR: ! 380: rep->ltype = 'c'; ! 381: rep->lsize = statb.st_rdev; ! 382: break; ! 383: } ! 384: rep->lflags = statb.st_mode & ~S_IFMT; ! 385: rep->luid = statb.st_uid; ! 386: rep->lgid = statb.st_gid; ! 387: rep->lnl = statb.st_nlink; ! 388: if(uflg) ! 389: rep->lmtime = statb.st_atime; ! 390: else if (cflg) ! 391: rep->lmtime = statb.st_ctime; ! 392: else ! 393: rep->lmtime = statb.st_mtime; ! 394: tblocks += nblock(statb.st_size); ! 395: } ! 396: return(rep); ! 397: } ! 398: ! 399: compar(pp1, pp2) ! 400: struct lbuf **pp1, **pp2; ! 401: { ! 402: register struct lbuf *p1, *p2; ! 403: ! 404: p1 = *pp1; ! 405: p2 = *pp2; ! 406: if (dflg==0) { ! 407: if (p1->lflags&ISARG && p1->ltype=='d') { ! 408: if (!(p2->lflags&ISARG && p2->ltype=='d')) ! 409: return(1); ! 410: } else { ! 411: if (p2->lflags&ISARG && p2->ltype=='d') ! 412: return(-1); ! 413: } ! 414: } ! 415: if (tflg) { ! 416: if(p2->lmtime == p1->lmtime) ! 417: return(0); ! 418: if(p2->lmtime > p1->lmtime) ! 419: return(rflg); ! 420: return(-rflg); ! 421: } ! 422: return(rflg * strcmp(p1->lflags&ISARG? p1->ln.namep: p1->ln.lname, ! 423: p2->lflags&ISARG? p2->ln.namep: p2->ln.lname)); ! 424: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.