Annotation of coherent/d/bin/lc.c, revision 1.1.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.