Annotation of coherent/d/bin/lc.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * List files in categories (and columns)
        !             3:  */
        !             4: 
        !             5: #include <stdio.h>
        !             6: #include <sys/stat.h>
        !             7: #include <sys/dir.h>
        !             8: 
        !             9: #define        WIDTH   79              /* Default line width */
        !            10: #define        GAP     1               /* Minimum gap between columns */
        !            11: #define        INDENT1 4               /* Indent for multiple directories */
        !            12: #define        INDENT2 4               /* Indent for files in a category */
        !            13: #define        NFNAME  400             /* Maximum a filename can expand to */
        !            14: 
        !            15: int    oneflag;                /* One per line */
        !            16: int    aflag;                  /* Do all entries, including `.' and `..' */
        !            17: int    bflag;                  /* Do block special */
        !            18: int    cflag;                  /* Do character special */
        !            19: int    dflag;                  /* Do directories */
        !            20: int    fflag;                  /* Do regular files */
        !            21: int    mflag;                  /* Do multiplexor files */
        !            22: int    pflag;                  /* Do pipes */
        !            23: int    allflag = 1;            /* Do all types */
        !            24: int    ndir;
        !            25: int    printed = 0;            /* Set when we have printed something */
        !            26: int    maxwidth;               /* Maximum width of a filename */
        !            27: int    lwidth = WIDTH-INDENT2;
        !            28: 
        !            29: struct stat    sb;
        !            30: char   iobuf[BUFSIZ];
        !            31: char   obuf[BUFSIZ];
        !            32: char   fname[NFNAME];
        !            33: 
        !            34: typedef        struct  ENTRY   {
        !            35:        struct  ENTRY   *e_fp;
        !            36:        char    e_name[DIRSIZ];
        !            37: }      ENTRY;
        !            38: 
        !            39: ENTRY  *files, *dirs, *blocks, *chars, *pipes, *mults;
        !            40: 
        !            41: main(argc, argv)
        !            42: char *argv[];
        !            43: {
        !            44:        register char *ap;
        !            45:        register int i;
        !            46:        register int estat = 0;
        !            47: 
        !            48:        while (argc>1 && *argv[1]=='-') {
        !            49:                for (ap = &argv[1][1]; *ap!='\0'; ap++)
        !            50:                        switch (*ap) {
        !            51:                        case 'f':
        !            52:                                fflag = 1;
        !            53:                                allflag = 0;
        !            54:                                break;
        !            55: 
        !            56:                        case 'd':
        !            57:                                dflag = 1;
        !            58:                                allflag = 0;
        !            59:                                break;
        !            60: 
        !            61:                        case 'm':
        !            62:                                mflag = 1;
        !            63:                                allflag = 0;
        !            64:                                break;
        !            65: 
        !            66:                        case 'b':
        !            67:                                bflag = 1;
        !            68:                                allflag = 0;
        !            69:                                break;
        !            70: 
        !            71:                        case 'c':
        !            72:                                cflag = 1;
        !            73:                                allflag = 0;
        !            74:                                break;
        !            75: 
        !            76:                        case 'p':
        !            77:                                pflag = 1;
        !            78:                                allflag = 0;
        !            79:                                break;
        !            80: 
        !            81:                        case '1':
        !            82:                                oneflag = 1;
        !            83:                                break;
        !            84: 
        !            85:                        case 'a':
        !            86:                                aflag = 1;
        !            87:                                break;
        !            88: 
        !            89:                        default:
        !            90:                                usage();
        !            91:                        }
        !            92:                argv++;
        !            93:                argc--;
        !            94:        }
        !            95:        if (allflag)
        !            96:                fflag = dflag = cflag = bflag = mflag = pflag = 1;
        !            97:        setbuf(stdout, obuf);
        !            98:        if (argc < 2) {
        !            99:                ndir = 1;
        !           100:                estat = lc(".");
        !           101:        } else {
        !           102:                if (argc > 2)
        !           103:                        lwidth -= INDENT1;
        !           104:                ndir = argc-1;
        !           105:                for (i=1; i<argc; i++) {
        !           106:                        estat |= lc(argv[i]);
        !           107:                        fflush(stdout);
        !           108:                }
        !           109:        }
        !           110:        exit(estat);
        !           111: }
        !           112: 
        !           113: /*
        !           114:  * Do `lc' on a single name.
        !           115:  */
        !           116: lc(name)
        !           117: char *name;
        !           118: {
        !           119:        char *type;
        !           120: 
        !           121:        if (stat(name, &sb) < 0) {
        !           122:                fprintf(stderr, "%s: not found\n", name);
        !           123:                return (1);
        !           124:        }
        !           125:        switch (sb.st_mode & S_IFMT) {
        !           126:        case S_IFDIR:
        !           127:                return (lcdir(name));
        !           128: 
        !           129:        case S_IFREG:
        !           130:                type = "file";
        !           131:                break;
        !           132: 
        !           133:        case S_IFBLK:
        !           134:                type = "block special file";
        !           135:                break;
        !           136: 
        !           137:        case S_IFCHR:
        !           138:                type = "character special file";
        !           139:                break;
        !           140: 
        !           141:        case S_IFMPB:
        !           142:        case S_IFMPC:
        !           143:                type = "multiplexed file";
        !           144:                break;
        !           145: 
        !           146:        case S_IFPIP:
        !           147:                type = "pipe";
        !           148:                break;
        !           149: 
        !           150:        default:
        !           151:                printf("%s: unknown file type\n", name);
        !           152:                return (1);
        !           153:        }
        !           154:        printf("%s: %s\n", name, type);
        !           155:        return (0);
        !           156: }
        !           157: 
        !           158: /*
        !           159:  * Process one directory.
        !           160:  */
        !           161: lcdir(dname)
        !           162: char *dname;
        !           163: {
        !           164:        register struct direct *dp;
        !           165:        register int nb;
        !           166:        register int fd;
        !           167: 
        !           168:        clearlist(&files);
        !           169:        clearlist(&dirs);
        !           170:        clearlist(&blocks);
        !           171:        clearlist(&chars);
        !           172:        clearlist(&pipes);
        !           173:        clearlist(&mults);
        !           174:        maxwidth = 0;
        !           175:        if (ndir > 1) {
        !           176:                if (printed)
        !           177:                        putchar('\n');
        !           178:                printf("%s:\n", dname);
        !           179:        }
        !           180:        printed = 0;
        !           181:        if ((fd = open(dname, 0)) < 0) {
        !           182:                fprintf(stderr, "Cannot open directory `%s'\n", dname);
        !           183:                return (1);
        !           184:        }
        !           185:        while ((nb = read(fd, iobuf, BUFSIZ)) > 0)
        !           186:                for (dp = iobuf; dp < &iobuf[nb]; dp++) {
        !           187:                        if (dp->d_ino == 0)
        !           188:                                continue;
        !           189:                        doentry(dname, dp);
        !           190:                }
        !           191:        close(fd);
        !           192:        prnames();
        !           193:        if (nb < 0) {
        !           194:                fprintf(stderr, "%s: directory read error\n", dname);
        !           195:                return (1);
        !           196:        }
        !           197:        return (0);
        !           198: }
        !           199: 
        !           200: /*
        !           201:  * Do a stat on one filename in the
        !           202:  * indicated directory.
        !           203:  * and then sort into the appropriate table.
        !           204:  */
        !           205: doentry(dirname, dp)
        !           206: char *dirname;
        !           207: struct direct *dp;
        !           208: {
        !           209:        int width = 0;
        !           210: 
        !           211:        {
        !           212:                register char *p = dp->d_name;
        !           213: 
        !           214:                if (!aflag
        !           215:                 && *p++=='.' && (*p=='\0' || (*p++=='.' && *p=='\0')))
        !           216:                        return (0);
        !           217:        } {
        !           218:                register char *p1, *p2;
        !           219:                register unsigned n = DIRSIZ;
        !           220: 
        !           221:                p1 = fname;
        !           222:                p2 = dirname;
        !           223:                while (*p1++ = *p2++)
        !           224:                        ;
        !           225:                p1--;
        !           226:                if (*p1 != '/')
        !           227:                        *p1++ = '/';
        !           228:                p2 = dp->d_name;
        !           229:                do {
        !           230:                        if (*p2 == '\0')
        !           231:                                break;
        !           232:                        width++;
        !           233:                        *p1++ = *p2++;
        !           234:                } while (--n);
        !           235:                *p1 = '\0';
        !           236:        }
        !           237:        if (width > maxwidth)
        !           238:                maxwidth = width;
        !           239:        if (stat(fname, &sb) < 0) {
        !           240:                prindent("%.*s: cannot stat\n", DIRSIZ, dp->d_name);
        !           241:                return (1);
        !           242:        } {
        !           243:                register ENTRY *ep;
        !           244:                register ENTRY **list;
        !           245: 
        !           246:                if ((ep = (ENTRY *)malloc(sizeof (ENTRY))) == NULL) {
        !           247:                        fprintf(stderr, "Out of memory\n");
        !           248:                        exit (1);
        !           249:                }
        !           250:                strncpy(ep->e_name, dp->d_name, DIRSIZ);
        !           251:                switch (sb.st_mode & S_IFMT) {
        !           252:                case S_IFREG:
        !           253:                        list = &files;
        !           254:                        break;
        !           255: 
        !           256:                case S_IFDIR:
        !           257:                        list = &dirs;
        !           258:                        break;
        !           259: 
        !           260:                case S_IFBLK:
        !           261:                        list = &blocks;
        !           262:                        break;
        !           263: 
        !           264:                case S_IFCHR:
        !           265:                        list = &chars;
        !           266:                        break;
        !           267: 
        !           268:                case S_IFMPC:
        !           269:                case S_IFMPB:
        !           270:                        list = &mults;
        !           271:                        break;
        !           272: 
        !           273:                case S_IFPIP:
        !           274:                        list = &pipes;
        !           275:                        break;
        !           276: 
        !           277:                default:
        !           278:                        prindent("%.*s: unknown file type\n", DIRSIZ,
        !           279:                            dp->d_name);
        !           280:                        return (1);
        !           281:                }
        !           282:                addlist(list, ep);
        !           283:        }
        !           284:        return (0);
        !           285: }
        !           286: 
        !           287: /*
        !           288:  * Add an entry to the list.
        !           289:  * Sort the list at insertion time
        !           290:  * into lexicographic order.
        !           291:  */
        !           292: addlist(lpp, ep)
        !           293: ENTRY **lpp;
        !           294: ENTRY *ep;
        !           295: {
        !           296:        register ENTRY *rp;
        !           297:        register ENTRY *pp;
        !           298: 
        !           299:        for (pp=NULL, rp=*lpp; rp!=NULL; pp=rp, rp=rp->e_fp)
        !           300:                if (strncmp(ep->e_name, rp->e_name, DIRSIZ) <= 0)
        !           301:                        break;
        !           302:        if (pp == NULL) {
        !           303:                ep->e_fp = *lpp;
        !           304:                *lpp = ep;
        !           305:        } else {
        !           306:                ep->e_fp = pp->e_fp;
        !           307:                pp->e_fp = ep;
        !           308:        }
        !           309: }
        !           310: 
        !           311: /*
        !           312:  * Clear out the list, a pointer to which is
        !           313:  * the argument.
        !           314:  */
        !           315: clearlist(lpp)
        !           316: ENTRY **lpp;
        !           317: {
        !           318:        register ENTRY *rp, *op;
        !           319: 
        !           320:        rp = *lpp;
        !           321:        while (rp != NULL) {
        !           322:                op = rp;
        !           323:                rp = rp->e_fp;
        !           324:                free(op);
        !           325:        }
        !           326:        *lpp = NULL;
        !           327: }
        !           328: 
        !           329: /*
        !           330:  * Print out the appropriate names.
        !           331:  */
        !           332: prnames()
        !           333: {
        !           334:        if (dflag)
        !           335:                prtype(dirs, "Directories");
        !           336:        if (fflag)
        !           337:                prtype(files, "Files");
        !           338:        if (cflag)
        !           339:                prtype(chars, "Character special files");
        !           340:        if (bflag)
        !           341:                prtype(blocks, "Block special files");
        !           342:        if (pflag)
        !           343:                prtype(pipes, "Pipes");
        !           344:        if (mflag)
        !           345:                prtype(mults, "Multiplexed files");
        !           346: }
        !           347: 
        !           348: /*
        !           349:  * Print out one type of files
        !           350:  */
        !           351: prtype(list, type)
        !           352: ENTRY *list;
        !           353: char *type;
        !           354: {
        !           355:        register char *cp;
        !           356:        register ENTRY *ep;
        !           357:        register int n;
        !           358:        register int i;
        !           359:        int npl;
        !           360: 
        !           361:        if (list == NULL)
        !           362:                return;
        !           363:        if (printed)
        !           364:                putchar('\n');
        !           365:        if(!oneflag)
        !           366:                prindent("%s:\n", type);
        !           367:        if (oneflag)
        !           368:                npl = 1;
        !           369:        else
        !           370:                npl = lwidth/(maxwidth+GAP);
        !           371:        ep = list;
        !           372:        i = 0;
        !           373:        for (ep = list; ep != NULL; ep = ep->e_fp) {
        !           374:                if (!oneflag && (i == 0)) {
        !           375:                        printf("%*s", INDENT2, "");
        !           376:                        prindent("");
        !           377:                }
        !           378:                n = DIRSIZ;
        !           379:                for (cp=ep->e_name; *cp!='\0' && n; n--)
        !           380:                        putchar(*cp++);
        !           381:                if (++i!=npl && ep->e_fp!=NULL) {
        !           382:                        n -= DIRSIZ-GAP-maxwidth;
        !           383:                        while (n-- > 0)
        !           384:                                putchar(' ');
        !           385:                } else {
        !           386:                        i = 0;
        !           387:                        putchar('\n');
        !           388:                }
        !           389:        }
        !           390: }
        !           391: 
        !           392: /*
        !           393:  * Print a line with possible indent.
        !           394:  */
        !           395: /* VARARGS */
        !           396: prindent(x)
        !           397: {
        !           398:        if (ndir > 1)
        !           399:                printf("%*s", INDENT1, "");
        !           400:        printf("%r", &x);
        !           401:        printed = 1;
        !           402: }
        !           403: 
        !           404: usage()
        !           405: {
        !           406:        fprintf(stderr, "Usage: lc [-afdcbp] [-1] [name ...]\n");
        !           407:        exit(1);
        !           408: }

unix.superglobalmegacorp.com

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