Annotation of coherent/b/bin/file.c, revision 1.1

1.1     ! root        1: char _version[] = "Version 1.5";
        !             2: /*
        !             3:  * Look at a file and try to
        !             4:  * figure out its type. Knows about the various
        !             5:  * flavours of filesystem entries, object files of various
        !             6:  * types, C programs, input to one of the various flavours
        !             7:  * of text formatter, etc.
        !             8:  */
        !             9: #include <stdio.h>
        !            10: #include <sys/coherent.h>
        !            11: #include <ctype.h>
        !            12: #include <sys/stat.h>
        !            13: #include <sys/uproc.h>
        !            14: #include <n.out.h>
        !            15: #include <coff.h>
        !            16: #include <canon.h>
        !            17: #include <ar.h>
        !            18: #include <arcoff.h>
        !            19: #include <sys/core.h>
        !            20: 
        !            21: /* UNIX archive magic numbers */
        !            22: #define COFFARMAG      "!<arch>\n"
        !            23: #define COFFARMAG_RAN  "!<arch>\n/"
        !            24: #define        UARMAG  0177545         /* UNIX v7 archives */
        !            25: #define        OUARMAG 0177555         /* UNIX v6 and previous archives */
        !            26: 
        !            27: #define TYPE_LEN       120
        !            28: 
        !            29: #define COMPRESSED 0x9D1F      /* Output of "compress(1)" command.  */
        !            30: 
        !            31: #define        EXEC    (S_IEXEC|(S_IEXEC<<3)|(S_IEXEC<<6))
        !            32: 
        !            33: /*
        !            34:  * Tar header.
        !            35:  */
        !            36: struct  th_info {
        !            37:        char    th_name[100],
        !            38:                th_mode[8],
        !            39:                th_uid[8],
        !            40:                th_gid[8],
        !            41:                th_size[12],
        !            42:                th_mtime[12],
        !            43:                th_check[8],
        !            44:                th_islink,
        !            45:                th_link[100],
        !            46:                th_pad[255];
        !            47: };
        !            48: 
        !            49: /*
        !            50:  * The first BUFSIZ bytes of the
        !            51:  * file in question are read into this
        !            52:  * union. It contains members for accessing
        !            53:  * the possible file structures.
        !            54:  */
        !            55: 
        !            56: union  iobuf
        !            57: {
        !            58:        char    u_buf[BUFSIZ];          /* General data */
        !            59:        struct  ldheader u_lout;        /* L.out object file header */
        !            60:        struct  filehdr u_coff;         /* COFF object file header */
        !            61:        int     u_armag;                /* Archive number */
        !            62:        struct  th_info u_tar;          /* Tar header  */
        !            63:        struct  ch_info u_core;         /* Core header */
        !            64: };
        !            65: 
        !            66: UPROC  uProc;
        !            67: 
        !            68: union  iobuf   iobuf;
        !            69: char   *file();
        !            70: char   *textclass();
        !            71: char   *objclass();
        !            72: char   *coffclass();
        !            73: char   *dirtype();
        !            74: char   *mtype();
        !            75: char   *coffmtype();
        !            76: char   *strcat();
        !            77: 
        !            78: main(argc, argv)
        !            79: char *argv[];
        !            80: {
        !            81:        struct stat sb;
        !            82:        register char *p;
        !            83:        register int i;
        !            84:        register int estat;
        !            85: 
        !            86:        if (argc < 2) {
        !            87:                fprintf(stderr, "Usage: file name ...\n");
        !            88:                exit(1);
        !            89:        }
        !            90:        estat = 0;
        !            91:        for (i=1; i<argc; i++) {
        !            92:                p = argv[i];
        !            93:                if (stat(p, &sb) < 0) {
        !            94:                        fprintf(stderr, "file: %s: not accessible\n", p);
        !            95:                        estat = 1;
        !            96:                        continue;
        !            97:                }
        !            98:                printf("%s: %s\n", p, file(&sb, p));
        !            99:        }
        !           100:        exit(estat);
        !           101: }
        !           102: 
        !           103: /*
        !           104:  * Routine to guess filetype
        !           105:  */
        !           106: char *
        !           107: file(sbp, fn)
        !           108: struct stat *sbp;
        !           109: char *fn;
        !           110: {
        !           111:        static char buf[50];
        !           112:        unsigned short magic;
        !           113:        register int nb;
        !           114:        char type[TYPE_LEN];
        !           115:        register int fd = -1;
        !           116: 
        !           117:        if ((sbp->st_mode&S_IFMT) != S_IFREG) {
        !           118:                switch (sbp->st_mode & S_IFMT) {
        !           119:                case S_IFDIR:
        !           120:                        return (dirtype(fn));
        !           121: 
        !           122:                case S_IFBLK:
        !           123:                        sprintf(buf, "block special file %d/%d",
        !           124:                            major(sbp->st_rdev), minor(sbp->st_rdev));
        !           125:                        return (buf);
        !           126: 
        !           127:                case S_IFCHR:
        !           128:                        sprintf(buf, "character special file %d/%d",
        !           129:                            major(sbp->st_rdev), minor(sbp->st_rdev));
        !           130:                        return (buf);
        !           131: 
        !           132:                case S_IFMPB:
        !           133:                        return ("block multiplexor file");
        !           134: 
        !           135:                case S_IFMPC:
        !           136:                        return ("character multiplexor file");
        !           137: 
        !           138:                case S_IFPIP:
        !           139:                        return ("named pipe");
        !           140: 
        !           141:                default:
        !           142:                        return ("invalid filetype");
        !           143:                }
        !           144:        }
        !           145:        if ((fd = open(fn, 0)) < 0)
        !           146:                return ("unreadable");
        !           147:        if ((nb = read(fd, (char *) &iobuf, sizeof(iobuf))) < 0) {
        !           148:                extern int errno;
        !           149:                printf("nb: %d, errno: %d ", nb, errno );
        !           150:                close(fd);
        !           151:                return ("read error");
        !           152:        }
        !           153: 
        !           154:        /* file of length zero? */
        !           155:        if (nb == 0) {
        !           156:                close(fd);
        !           157:                return ("empty");
        !           158:        }
        !           159: 
        !           160:        /* l.out executable?  */
        !           161:        if (nb >= sizeof(struct ldheader)) {
        !           162:                magic = iobuf.u_lout.l_magic;
        !           163:                canint(magic);
        !           164:                if (magic == L_MAGIC) {
        !           165:                        canint(iobuf.u_lout.l_flag);
        !           166:                        canint(iobuf.u_lout.l_machine);
        !           167:                        close(fd);
        !           168:                        return (objclass(fd, &iobuf.u_lout));
        !           169:                }
        !           170:        }
        !           171: 
        !           172:        /* COFF executable?  */
        !           173:        if (nb >= sizeof(struct filehdr)) {
        !           174:                magic = iobuf.u_coff.f_magic;
        !           175:                if (ISCOFF(magic)) {
        !           176:                        close(fd);
        !           177:                        return (coffclass(&iobuf.u_coff));
        !           178:                }
        !           179:        }
        !           180: 
        !           181:        /* COFF archive?  */
        !           182:        if (nb >= strlen(COFFARMAG_RAN)) {
        !           183:                if (strncmp(COFFARMAG_RAN, iobuf.u_buf,
        !           184:                  strlen(COFFARMAG_RAN)) == 0) {
        !           185:                        close(fd);
        !           186:                        return("COFF archive (ranlib)");
        !           187:                }
        !           188:                if ( strncmp(COFFARMAG, iobuf.u_buf, strlen(COFFARMAG)) == 0) {
        !           189:                        close(fd);
        !           190:                        return("COFF archive");
        !           191:                }
        !           192:        }
        !           193: 
        !           194:        /* {v7 tar} archive?  */
        !           195:        if (nb >= sizeof(struct th_info)) {
        !           196:                if (    tar_path(iobuf.u_tar.th_name, 100) &&
        !           197:                        tar_oct(iobuf.u_tar.th_mode, 8) &&
        !           198:                        tar_dec(iobuf.u_tar.th_uid, 8) &&
        !           199:                        tar_dec(iobuf.u_tar.th_gid, 8) &&
        !           200:                        tar_dec(iobuf.u_tar.th_size, 12) &&
        !           201:                        tar_dec(iobuf.u_tar.th_mtime, 12) &&
        !           202:                        strlen(iobuf.u_tar.th_pad) < 8 ) {
        !           203: 
        !           204:                        type[0] ='\0';
        !           205:                        if ( '\0' != iobuf.u_tar.th_pad[0]) {
        !           206:                                strcpy(type, iobuf.u_tar.th_pad);
        !           207:                        } else {
        !           208:                                strcpy(type, "v7 tar");
        !           209:                        }
        !           210: 
        !           211:                        strcat(type, " archive");
        !           212:                        close(fd);
        !           213:                        return(type);
        !           214:                } /* if looks like a tar header.  */
        !           215:        }
        !           216: 
        !           217:        /* core file? */
        !           218:        if (nb >= sizeof(struct ch_info)) {
        !           219:                struct ch_info * cip = & iobuf.u_core;
        !           220:                int offset = cip->ch_info_len + cip->ch_uproc_offset;
        !           221:                int lsought, readed;
        !           222: 
        !           223:                magic = cip->ch_magic;
        !           224:                if (magic != CORE_MAGIC)
        !           225:                        ;       /* bad magic for core file */
        !           226:                else if (offset != (lsought = lseek(fd, offset, 0)))
        !           227:                        ;       /* can't seek far enough to find UPROC */
        !           228:                else if (sizeof(UPROC) !=
        !           229:                  (readed = read(fd, &uProc, sizeof(UPROC))))
        !           230:                        ;       /* can't read UPROC */
        !           231:                else {
        !           232:                        sprintf(type, "core file from \"%.10s\" uproc (v%04X)",
        !           233:                          uProc.u_comm, uProc.u_version);
        !           234:                        close(fd);
        !           235:                        return(type);
        !           236:                }
        !           237:        }
        !           238: 
        !           239:        /* Archive or compress'ed file?  */
        !           240:        if (nb >= sizeof (short)) {
        !           241:                magic = iobuf.u_armag;
        !           242:                canint(magic);
        !           243:                if (magic == ARMAG) {
        !           244:                        close(fd);
        !           245:                        return ("l.out archive");
        !           246:                }
        !           247:                if (magic == UARMAG) {
        !           248:                        close(fd);
        !           249:                        return ("seventh edition archive");
        !           250:                }
        !           251:                if (magic == OUARMAG) {
        !           252:                        close(fd);
        !           253:                        return ("sixth edition archive");
        !           254:                }
        !           255:                if (magic == COMPRESSED){
        !           256:                        sprintf(type, "%d bit compressed file",
        !           257:                          (int) (0x7f & iobuf.u_buf[2]));
        !           258:                        close(fd);
        !           259:                        return(type);
        !           260:                }
        !           261:        }
        !           262: 
        !           263:        if (hasnonascii((unsigned char *) &iobuf, nb)) {
        !           264:                close(fd);
        !           265:                return ("binary data");
        !           266:        }
        !           267:        if (sbp->st_mode & EXEC) {
        !           268:                if (strncmp(iobuf.u_buf, "#!", 2) == 0) {
        !           269:                        sprintf(type, "%s script",
        !           270:                          strtok(&(iobuf.u_buf[2]), " \t\n"));
        !           271:                        close(fd);
        !           272:                        return(type);
        !           273:                } else {
        !           274:                        close(fd);
        !           275:                        return ("commands");
        !           276:                }
        !           277:        }
        !           278:        close(fd);
        !           279:        return textclass((unsigned char *) &iobuf, nb);
        !           280: }
        !           281: 
        !           282: /*
        !           283:  * Return the type of the directory.
        !           284:  * Currently, only "s.*" is recognised as SCCS directory.
        !           285:  */
        !           286: char *
        !           287: dirtype(dn)
        !           288: register char *dn;
        !           289: {
        !           290:        register char *cp;
        !           291: 
        !           292:        for (cp = dn; *cp; cp++)
        !           293:                ;
        !           294:        while (cp > dn)
        !           295:                if (*--cp == '/') {
        !           296:                        cp++;
        !           297:                        break;
        !           298:                }
        !           299:        if (cp[0]=='s' && cp[1]=='.')
        !           300:                return ("SCCS directory");
        !           301: 
        !           302:        if (strcmp(cp, "RCS") == 0)
        !           303:                return ("RCS directory");
        !           304:                
        !           305:        return ("directory");
        !           306: }
        !           307: 
        !           308: /*
        !           309:  * Return true if there ar characters
        !           310:  * in the buffer that do not look like good
        !           311:  * ascii characters.
        !           312:  * This routine knows that ascii is a seven
        !           313:  * bit code.
        !           314:  */
        !           315: hasnonascii(bp, nb)
        !           316: register unsigned char *bp;
        !           317: register nb;
        !           318: {
        !           319:        while (nb--) {
        !           320:                if (!isascii(*bp))
        !           321:                        return (1);
        !           322:                if (!(isprint(*bp) || isspace(*bp) || *bp=='\b' || *bp=='\a'))
        !           323:                        return (1);
        !           324:                bp++;
        !           325:        }
        !           326:        return (0);
        !           327: }
        !           328: 
        !           329: /*
        !           330:  * Classify the first `nb'
        !           331:  * bytes of a text file.
        !           332:  */
        !           333: char *
        !           334: textclass(bp, nb)
        !           335: register unsigned char *bp;
        !           336: register nb;
        !           337: {
        !           338:        register int c;
        !           339:        int nlf = 1;
        !           340:        int nlbrace;
        !           341:        int nrbrace;
        !           342:        int nsharps;
        !           343:        int nsemi;
        !           344:        int xmail;
        !           345:        char *sbp = bp;
        !           346: 
        !           347:        nlbrace = 0;
        !           348:        nrbrace = 0;
        !           349:        nsharps = 0;
        !           350:        nsemi = 0;
        !           351:        xmail = 0;
        !           352:        while (nb--) {
        !           353:                c = *bp++;
        !           354:                if (c=='.' && strncmp(bp, "globl", 5)==0)
        !           355:                        return ("assembler");
        !           356:                if (nlf) {
        !           357:                        if (c == '.')
        !           358:                                return ("nroff, tbl or eqn input");
        !           359:                        else if (c == ':')
        !           360:                                return ("commands");
        !           361:                        else if (c == '#')
        !           362:                                ++nsharps;
        !           363:                        else if (c=='%')
        !           364:                                if (*bp=='%' || *bp=='{' || *bp=='}')
        !           365:                                        return ("yacc or lex input");
        !           366:                }
        !           367:                if (c == '{')
        !           368:                        ++nlbrace;
        !           369:                else if (c == '}')
        !           370:                        ++nrbrace;
        !           371:                if (c == '\n') {
        !           372:                        nlf = 1;
        !           373:                        if (bp[-2] == ';')
        !           374:                                nsemi++;
        !           375:                        if (((bp-sbp) % 22) == 0) {
        !           376:                                if (bp[-2]==' ' || bp[-2]=='!')
        !           377:                                        xmail++;
        !           378:                        } else
        !           379:                                xmail = 0;
        !           380:                } else
        !           381:                        nlf = 0;
        !           382:        }
        !           383:        if (xmail)
        !           384:                return ("xmail encoded text");
        !           385:        if ((nsharps || nsemi) && (nlbrace || nrbrace))
        !           386:                return ("C program");
        !           387:        return ("probably text");
        !           388: }
        !           389: 
        !           390: /*
        !           391:  * Figure out the type of an l.out
        !           392:  * object file. Tag it with the machine
        !           393:  * id if not for the machine upon which the
        !           394:  * command is running.
        !           395:  */
        !           396: char *
        !           397: objclass(fd, lhp)
        !           398: register struct ldheader *lhp;
        !           399: {
        !           400:        static char type[TYPE_LEN];
        !           401:        register char *mch;
        !           402:        struct ldsym lds;
        !           403:        register fsize_t stbase;
        !           404:        register i;
        !           405: 
        !           406:        type[0] = '\0';
        !           407:        if ((lhp->l_flag&LF_32) != 0)
        !           408:                strcat(type, "32 bit ");
        !           409:        if ((lhp->l_flag&LF_SLIB) != 0)
        !           410:                strcat(type, "shared library ");
        !           411:        if ((lhp->l_flag&LF_SLREF) != 0)
        !           412:                strcat(type, "libref ");
        !           413:        if ((lhp->l_flag&LF_SHR) != 0)
        !           414:                strcat(type, "shared ");
        !           415:        if ((lhp->l_flag&LF_SEP) != 0)
        !           416:                strcat(type, "separate ");
        !           417:        if ((lhp->l_flag&LF_KER) != 0) {
        !           418:                register unsigned ssize;
        !           419: 
        !           420:                ssize = sizeof (lds);
        !           421:                if ((lhp->l_flag & LF_32) == 0) {
        !           422:                        stbase = sizeof(*lhp) - 2*sizeof(int);
        !           423:                        ssize -= sizeof (int);
        !           424:                } else {
        !           425:                        canshort(lhp->l_tbase);
        !           426:                        stbase = lhp->l_tbase;
        !           427:                }
        !           428:                for (i=L_SHRI; i<L_SYM; ++i)
        !           429:                        if (i!=L_BSSI && i!=L_BSSD) {
        !           430:                                cansize(lhp->l_ssize[i]);
        !           431:                                stbase += lhp->l_ssize[i];
        !           432:                        }
        !           433:                lseek(fd, stbase, 0);
        !           434:                cansize(lhp->l_ssize[L_SYM]);
        !           435:                while (lhp->l_ssize[L_SYM] != 0) {
        !           436:                        if (read(fd, &lds, ssize) != ssize)
        !           437:                                break;
        !           438:                        canshort(lds.ls_type);
        !           439:                        if (strncmp(lds.ls_id, "conftab_", NCPLN) == 0
        !           440:                        && (lds.ls_type&LR_SEG) != L_REF)
        !           441:                                break;
        !           442:                        lhp->l_ssize[L_SYM] -= ssize;
        !           443:                }
        !           444:                strcat(type, lhp->l_ssize[L_SYM]==0?"kernel ":"driver ");
        !           445:        }
        !           446:        strcat(type, "executable");
        !           447:        if ((lhp->l_flag&LF_NRB) == 0)
        !           448:                strcat(type, " with relocation");
        !           449:        if ((mch = mtype(lhp->l_machine)) == NULL)
        !           450:                mch = "Unknown machine type";
        !           451:        sprintf(type, "%s (%s)", type, mch);
        !           452:        return (type);
        !           453: }
        !           454: 
        !           455: /*
        !           456:  * Figure out the type of a coff
        !           457:  * object file. Tag it with the machine
        !           458:  * id if not for the machine upon which the
        !           459:  * command is running.
        !           460:  */
        !           461: char *
        !           462: coffclass(chp)
        !           463: register struct filehdr *chp;
        !           464: {
        !           465:        static char type[TYPE_LEN];
        !           466:        register char *mch;
        !           467: 
        !           468:        sprintf(type, "COFF ");
        !           469:        if ((chp->f_flags&F_MINMAL) != 0)
        !           470:                strcat(type, "minimal ");
        !           471: #ifdef COFF_H_FIXED
        !           472:        if ((chp->f_flags&F_UPDATE) != 0)
        !           473:                strcat(type, "update ");
        !           474:        if ((chp->f_flags&F_SWABD) != 0)
        !           475:                strcat(type, "swapped bytes ");
        !           476:        if ((chp->f_flags&F_PATCH) != 0)
        !           477:                strcat(type, "patch ");
        !           478:        if ((chp->f_flags&F_NODF) != 0)
        !           479:                strcat(type, "no decision ");
        !           480: #else /* COFF_H_FIXED */
        !           481:        if ((chp->f_flags&F_AR32WR) == 0)
        !           482:                strcat(type, "non i80x86 byte order ");
        !           483: #endif /* COFF_H_FIXED */
        !           484:        if ((chp->f_flags&F_EXEC) != 0){
        !           485:                if ((chp->f_flags&F_LSYMS) != 0)
        !           486:                        strcat(type, "stripped ");
        !           487:                strcat(type, "executable ");
        !           488:        } else {
        !           489:                strcat(type, "object ");
        !           490:                if ((chp->f_flags&F_RELFLG) != 0)
        !           491:                        strcat(type, "stripped relocation ");
        !           492:                if ((chp->f_flags&F_LSYMS) != 0)
        !           493:                        strcat(type, "stripped local symbols ");
        !           494:        }
        !           495: 
        !           496:        if ((mch = coffmtype(chp->f_magic)) == NULL)
        !           497:                mch = "Unknown machine type";
        !           498:        sprintf(type, "%s(%s) ", type, mch);
        !           499: 
        !           500:        return (type);
        !           501: }
        !           502: 
        !           503: 
        !           504: /*
        !           505:  * Identify a COFF executable.
        !           506:  */
        !           507: char *
        !           508: coffmtype(magic)
        !           509:        unsigned short magic;
        !           510: {
        !           511:        switch ((unsigned) magic) {
        !           512: 
        !           513: #ifdef COFF_H_FIXED
        !           514:        case IAPX16:
        !           515:        case IAPX16TV:
        !           516:        case IAPX20:
        !           517:        case IAPX20TV:
        !           518:                return("iAPX");
        !           519: 
        !           520:        case B16MAGIC:
        !           521:        case BTVMAGIC:
        !           522:                return("Intel Basic-16");
        !           523: 
        !           524:        case X86MAGIC:
        !           525:        case XTVMAGIC:
        !           526:                return("Intel x86");
        !           527: 
        !           528:        case I286SMAGIC:
        !           529:                return("Intel 286");
        !           530: 
        !           531:        case I386MAGIC:
        !           532:                return("Intel 386");
        !           533: 
        !           534:        case N3BMAGIC:
        !           535:        case NTVMAGIC:
        !           536:                return("New 3B");
        !           537: 
        !           538:        case WE32MAGIC:
        !           539:        case RBOMAGIC:
        !           540:        case MTVMAGIC:
        !           541:                return("MAC-32, 3515, 3B5");
        !           542: 
        !           543:        case VAXWRMAGIC:
        !           544:        case VAXROMAGIC:
        !           545:                return("VAX 11/780 or /750");
        !           546: 
        !           547:        case 0401:
        !           548:        case 0405:
        !           549:        case 0407:
        !           550:        case 0410:
        !           551:        case 0411:
        !           552:        case 0437:
        !           553:                return("pdp11");
        !           554: 
        !           555:        case MC68MAGIC:
        !           556:        case MC68TVMAGIC:
        !           557:        case M68MAGIC:
        !           558:        case M68TVMAGIC:
        !           559:                return("Motorola 680xx");
        !           560: 
        !           561:        /* case I286LMAGIC: */
        !           562:        case MC68KPGMAGIC:
        !           563:                return("UNIX PC or iAPX 286");
        !           564: 
        !           565:        case U370WRMAGIC:
        !           566:        case U370ROMAGIC:
        !           567:                return("IBM 370");
        !           568: 
        !           569:        case AMDWRMAGIC:
        !           570:        case AMDROMAGIC:
        !           571:                return("Amdahl 470/580");
        !           572: 
        !           573: #else /* COFF_H_FIXED */
        !           574:        case C_386_MAGIC:
        !           575:                return("Intel 386");
        !           576: #endif /* COFF_H_FIXED */
        !           577: 
        !           578:        default:
        !           579:                return(NULL);
        !           580: 
        !           581:        }
        !           582: } /* coffmtype() */
        !           583: 
        !           584: /*
        !           585:  * Decide if character array 'str' of length 'len' is an acceptable tar
        !           586:  * octal field.  Returns TRUE if it is acceptable, FALSE otherwise.
        !           587:  */
        !           588: int
        !           589: tar_oct(str, len)
        !           590: char *str;
        !           591: int len;
        !           592: {
        !           593:        for (; len > 0; --len, ++str) {
        !           594:                if (*str != '\0' && *str != ' ' &&
        !           595:                    !('0' <= *str && *str <= '7')) {
        !           596:                        break;
        !           597:                }
        !           598:        }
        !           599: 
        !           600:        return(0 == len);
        !           601: } /* tar_oct() */
        !           602: 
        !           603: /*
        !           604:  * Decide if character array 'str' of length 'len' is an acceptable tar
        !           605:  * decimal field.  Returns TRUE if it is acceptable, FALSE otherwise.
        !           606:  */
        !           607: int
        !           608: tar_dec(str, len)
        !           609: char *str;
        !           610: int len;
        !           611: {
        !           612:        for (; len > 0; --len, ++str) {
        !           613:                if (*str != '\0' && *str != ' ' &&
        !           614:                    !isdigit(*str)) {
        !           615:                        break;
        !           616:                }
        !           617:        }
        !           618: 
        !           619:        return(0 == len);
        !           620: } /* tar_dec() */
        !           621: 
        !           622: /*
        !           623:  * Decide if character array 'str' of length 'len' is an acceptable tar
        !           624:  * path type field.  Returns TRUE if it is acceptable, FALSE otherwise.
        !           625:  */
        !           626: int
        !           627: tar_path(str, len)
        !           628: char *str;
        !           629: int len;
        !           630: {
        !           631:        for (; len > 0; --len, ++str) {
        !           632:                if (*str != '\0' && *str != ' ' &&
        !           633:                    !isprint(*str)) {
        !           634:                        break;
        !           635:                }
        !           636:        }
        !           637: 
        !           638:        return(0 == len);
        !           639: } /* tar_path() */

unix.superglobalmegacorp.com

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