Annotation of 41BSD/cmd/ls/ls.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.