Annotation of 43BSDReno/contrib/ansi/ansitape.c, revision 1.1.1.1

1.1       root        1: #include <sys/types.h>
                      2: #include <sys/time.h>
                      3: #include <sys/mtio.h>
                      4: #include <sys/ioctl.h>
                      5: #include <sys/file.h>
                      6: #include <sys/stat.h>
                      7: #include <a.out.h>
                      8: #include <stdio.h>
                      9: #include <ctype.h>
                     10: 
                     11: char *malloc();
                     12: static void rewind();
                     13: long lseek();
                     14: int wflag;
                     15: int xflag;
                     16: int tflag;
                     17: int cflag;
                     18: int vflag;
                     19: int dflag;
                     20: int fflag;
                     21: int totalreadfiles = 0 ;
                     22: int totalreadblocks = 0 ;
                     23: int totalreadlines = 0 ;
                     24: int totalreadchars = 0 ;
                     25: int totalwritefiles = 0 ;
                     26: int totalwriteblocks = 0 ;
                     27: int totalwritelines = 0 ;
                     28: int totalwritechars = 0 ;
                     29: 
                     30: main(argc,argv)
                     31:        int argc;
                     32:        char *argv[];
                     33: {
                     34:        struct tm *tm;
                     35:        long timetemp,time();
                     36:        int year;
                     37:        int day;
                     38:        char *tapename;
                     39:        char *filename;
                     40:        char *namelist=NULL;
                     41:        char *device = "/dev/rmt12";
                     42:        int tape;
                     43:        int file;
                     44:        int filenum;
                     45:        int argnum;
                     46:        char line[1001];
                     47:        char vmsname[1000];
                     48:        char unixname[1000];
                     49:        FILE *names;
                     50:        int count;
                     51:        int tmp;
                     52:        char blockchar;
                     53:        int blocksize=2048;
                     54:        int recordsize=1;
                     55: 
                     56:        char *key;
                     57: 
                     58:        timetemp = time((long *)NULL);
                     59:        tm = localtime(&timetemp);
                     60:        year = tm->tm_year;
                     61:        day = tm->tm_yday;
                     62:        tapename = malloc(10);
                     63:        gethostname(tapename,6);
                     64:        tapename[7]='\0';
                     65: 
                     66:        /* parse command line */
                     67:        if (argc < 2)
                     68:                usage();
                     69: 
                     70:        argv++;
                     71:        argc--;
                     72:        /* loop through first argument (key) */
                     73:        argc--;
                     74:        for (key = *argv++; *key; key++) 
                     75:                switch(*key) {
                     76: 
                     77:                case 'f':
                     78:                        if (*argv == NULL || argc <1) {
                     79:                                fprintf(stderr,
                     80:                        "ansitape: 'f' option requires tape name \n");
                     81:                                usage();
                     82:                        }
                     83:                        device = *argv++;
                     84:                        argc--;
                     85:                        break;
                     86: 
                     87:                case 'n':
                     88:                        if (*argv == NULL || argc <1) {
                     89:                                fprintf(stderr,
                     90:                        "ansitape: 'n' option requires file name\n");
                     91:                                usage();
                     92:                        }
                     93:                        namelist = *argv++;
                     94:                        argc--;
                     95:                        break;
                     96: 
                     97:                case 'l':
                     98:                        if (*argv == NULL || argc<1) {
                     99:                                fprintf(stderr,
                    100:                        "ansitape: 'l' option requires label\n");
                    101:                                usage();
                    102:                        }
                    103:                        tapename = *argv++;
                    104:                        argc--;
                    105:                        break;
                    106: 
                    107:                case 'F':
                    108:                        if(*argv == NULL) {
                    109:                                fprintf(stderr, 
                    110:                "ansitape: 'F' options requires recordsize and blocksize specifiers.\n"
                    111:                                                );
                    112:                                usage();
                    113:                        }
                    114:                        tmp = sscanf(*argv++," %d%c ",&recordsize,&blockchar);
                    115:                        argc--;
                    116:                        if(tmp<1) { 
                    117:                                fprintf(stderr,"illegal recordsize: recordsize set to 80\n");
                    118:                                recordsize=80;
                    119:                        } else if(tmp>1) {
                    120:                                if(blockchar == 'b') recordsize *= 512;
                    121:                                if(blockchar == 'k') recordsize *= 1024;
                    122:                        }
                    123: 
                    124:                        if (*argv == NULL) {
                    125:                                fprintf(stderr,
                    126:                        "ansitape: 'F' option requires blocksize specifier \n");
                    127:                                usage();
                    128:                        }
                    129:                        tmp = sscanf(*argv++," %d%c ",&blocksize,&blockchar);
                    130:                        argc--;
                    131:                        if(tmp<1) { 
                    132:                                fprintf(stderr,"illegal blocksize: blocksize set to 2048\n");
                    133:                                blocksize=2048;
                    134:                        } else if(tmp>1) {
                    135:                                if(blockchar == 'b') blocksize *= 512;
                    136:                                if(blockchar == 'k') blocksize *= 1024;
                    137:                        }
                    138:                        if(blocksize <18) blocksize=18;
                    139:                        if(blocksize >62*1024) blocksize=62*1024;
                    140:                        fflag++;
                    141:                        break;
                    142: 
                    143:                case 'b':
                    144:                        if (*argv == NULL) {
                    145:                                fprintf(stderr,
                    146:                        "ansitape: 'b' option requires blocksize specifier \n");
                    147:                                usage();
                    148:                        }
                    149:                        tmp = sscanf(*argv++," %d%c ",&blocksize,&blockchar);
                    150:                        argc--;
                    151:                        if(tmp<1) { 
                    152:                                fprintf(stderr,"illegal blocksize: blocksize set to 2048\n");
                    153:                                blocksize=2048;
                    154:                        } else if(tmp>1) {
                    155:                                if(blockchar == 'b') blocksize *= 512;
                    156:                                if(blockchar == 'k') blocksize *= 1024;
                    157:                        }
                    158:                        if(blocksize <18) blocksize=18;
                    159:                        if(blocksize >62*1024) blocksize=62*1024;
                    160:                        break;
                    161: 
                    162:                case 'c':
                    163:                        cflag++;
                    164:                        wflag++;
                    165:                        break;
                    166: 
                    167:                case 'r':
                    168:                        /*I know, this should be rflag, but I just don't like r for write*/
                    169:                        wflag++;
                    170:                        break;
                    171: 
                    172:                case 'v':
                    173:                        vflag++;
                    174:                        break;
                    175: 
                    176:                case 'x':
                    177:                        xflag++;
                    178:                        break;
                    179: 
                    180:                case 't':
                    181:                        tflag++;
                    182:                        break;
                    183: 
                    184:                case '-':
                    185:                        break;
                    186: 
                    187:                default:
                    188:                        fprintf(stderr, "ansitape: %c: unknown option\n", *key);
                    189:                        usage();
                    190:                }
                    191: 
                    192:        if (!wflag && !xflag && !tflag)
                    193:                usage();
                    194: 
                    195:        tape = open(device,wflag?O_RDWR:O_RDONLY,NULL);
                    196:        if(tape<0) {
                    197:                perror(device);
                    198:                fprintf(stderr,"tape not accessable - check if drive online and write ring present\n");
                    199:                exit(1);
                    200:        }
                    201:        rewind(tape);
                    202:        filenum=1;
                    203:        casefix(tapename);
                    204: 
                    205:        if(cflag) { 
                    206:                writevol(tapename,tape);
                    207:        } else {
                    208:                getvol(tapename,tape);
                    209:                while(1) {
                    210:                        /* read files */
                    211:                        if( readfile(tape,argc,argv) ) break;
                    212:                        filenum++;
                    213:                }
                    214:                backspace(tape);
                    215:        }
                    216: 
                    217:        if(wflag) {
                    218:                if(namelist) {
                    219:                        if(*namelist == '-') {
                    220:                                names = stdin;
                    221:                        } else {
                    222:                                names=fopen(namelist,"r");
                    223:                                if(names == NULL) {
                    224:                                        fprintf(stderr,"unable to open namelist file - no files added to tape\n");
                    225:                                }
                    226:                        }
                    227:                        while(1) {
                    228:                                fgets(line,1000,names);
                    229:                                if(feof(names)) break;
                    230:                                count = sscanf(line,"%s %s",unixname,vmsname);
                    231:                                if(count<1) continue; /* blank line */
                    232:                                if(count==1) strcpy(vmsname,unixname);
                    233:                                casefix(vmsname);
                    234:                                if(filecheck(&file,unixname)) continue;
                    235:                                writefile(tape,file,vmsname,tapename,filenum,year,day,blocksize,
                    236:                                                recordsize);
                    237:                                filenum++;
                    238:                                close(file);
                    239:                        }
                    240:                } else {
                    241:                        for(argnum=0;argnum<argc;argnum++) {
                    242:                                filename = argv[argnum];
                    243:                                if(filecheck(&file,filename)) continue;
                    244:                                casefix(filename);
                    245:                                writefile(tape,file,filename,tapename,filenum,year,day,
                    246:                                                blocksize,recordsize);
                    247:                                filenum++;
                    248:                                close(file);
                    249:                        }
                    250:                }
                    251:                writetm(tape);
                    252:                writetm(tape);
                    253:                writetm(tape);
                    254:                writetm(tape);
                    255:        }
                    256:        rewind(tape);
                    257:        close(tape);
                    258:        if(vflag && (tflag || xflag)) {
                    259:                fprintf(stdout," read  %d files in %d blocks (%d lines, %d chars)\n",
                    260:                        totalreadfiles,totalreadblocks,totalreadlines,totalreadchars);
                    261:        }
                    262:        if(vflag && wflag) {
                    263:                fprintf(stdout," wrote  %d files in %d blocks (%d lines, %d chars)\n",
                    264:                        totalwritefiles,totalwriteblocks,totalwritelines,totalwritechars);
                    265:        }
                    266:        return(0);
                    267: }
                    268: usage() {
                    269:        fprintf(stderr,
                    270:                        "ansitape: usage: ansitape -{rxtc}[flnvb] [filename] [label] [filename] [blocksize] [files]\n");
                    271:        exit(1);
                    272: }
                    273: 
                    274: writefile(tape,file,filename,tapename,filenum,year,day,blocksize,recordsize)
                    275:        int tape;
                    276:        int file;
                    277:        char *filename;
                    278:        char *tapename;
                    279:        int filenum;
                    280:        int year;
                    281:        int day;
                    282:        int blocksize;
                    283:        int recordsize;
                    284: 
                    285: {
                    286:        int blocks;
                    287:        writehdr1(tape,filename,tapename,filenum,year,day);
                    288:        writehdr2(tape,blocksize,recordsize);
                    289:        writehdr3(tape);
                    290:        writetm(tape);
                    291:        writedata(tape,file,filename,&blocks,blocksize,recordsize);
                    292:        writetm(tape);
                    293:        writeeof1(tape,filename,tapename,filenum,year,day,blocks);
                    294:        writeeof2(tape,blocksize,recordsize);
                    295:        writeeof3(tape);
                    296:        writetm(tape);
                    297:        totalwritefiles++;
                    298: }
                    299: 
                    300: writedata(tape,file,filename,blocks,blocksize,recsize)
                    301:        int tape;
                    302:        int file;
                    303:        char *filename;
                    304:        int *blocks;
                    305:        int blocksize;
                    306:        int recsize;
                    307: {
                    308: char *ibuf;
                    309: char *ibufstart;
                    310: char *obuf;
                    311: char *obufstart;
                    312: char *endibuf;
                    313: char *endobuf;
                    314: int got;
                    315: int i;
                    316: char *j;
                    317: int numchar = 0 ;
                    318: int numline = 0 ;
                    319: int numblock = 0;
                    320: int success;
                    321: 
                    322:        ibufstart = ibuf = malloc((unsigned)(blocksize<4096?8200:(2*blocksize+10)));
                    323:        obufstart = obuf = malloc((unsigned)(blocksize+10));
                    324:        endobuf = obuf + blocksize;
                    325:        endibuf = ibuf;
                    326: 
                    327: 
                    328:        i=0;
                    329:        if (!fflag) {
                    330:                while(1) {
                    331:                        if(ibuf+i>=endibuf) {   /* end of input buffer */
                    332:                                strncpy(ibufstart,ibuf,endibuf-ibuf); /* copy leftover to start */
                    333:                                ibuf = ibufstart+(endibuf-ibuf);        /* point to end of valid data */
                    334:                                got = read(file,ibuf,blocksize<4096?4096:2*blocksize);  /* read in a chunk */
                    335:                                endibuf = ibuf + got;
                    336:                                ibuf = ibufstart;       /* point to beginning of data */
                    337:                                if(got == 0) { /* end of input */
                    338:                                        if(ibuf==ibufstart){ /* no leftovers */
                    339:                                                break; /* done */
                    340:                                        } else {
                    341:                                                ibuf[i]='\n'; /* fake extra newline */
                    342:                                        }
                    343:                                }
                    344:                        }
                    345: 
                    346:                        if(obuf+i+4 > endobuf) {  /* end of output buffer */
                    347:                                if(i>blocksize-4) { 
                    348:                                        printf("record exceeds blocksize - file truncated\n");
                    349:                                        break;
                    350:                                }
                    351:                                /* filled up output record - have to fill,output,restart*/
                    352:                                for(j=obuf;j<endobuf;j++) {
                    353:                                        *j = '^';
                    354:                                }
                    355:                                success = write(tape,obufstart,blocksize);
                    356:                                if(success != blocksize) {
                    357:                                        perror("tape");
                    358:                                        fprintf(stderr," hard write error:  write aborted\n");
                    359:                                        rewind(tape);
                    360:                                        exit(1);
                    361:                                }
                    362:                                obuf=obufstart;
                    363:                                numchar -= i;
                    364:                                i=0;
                    365:                                numblock++;
                    366:                                continue;
                    367:                        }
                    368: 
                    369:                        if(ibuf[i] == '\n') { /* end of line */
                    370:                                obuf[0] = ((i+4)/1000) + '0';
                    371:                                obuf[1] = (((i+4)/100)%10) + '0';
                    372:                                obuf[2] = (((i+4)/10)%10) + '0';
                    373:                                obuf[3] = (((i+4)/1)%10) + '0';
                    374:                                obuf += (4+i); /* size + strlen */
                    375:                                ibuf += (1+i); /* newline + strlen */
                    376:                                i=0;
                    377:                                numline++;
                    378:                                continue; /* back to the top */
                    379:                        }
                    380: 
                    381:                        obuf[i+4]=ibuf[i];
                    382:                        numchar++;
                    383:                        i++;
                    384: 
                    385:                }
                    386:                /* exited - write last record and go for lunch */
                    387:                if(obuf != obufstart) {
                    388:                        for(j=obuf;j<endobuf;j++) {
                    389:                                *j = '^';
                    390:                        }
                    391:                        success = write(tape,obufstart,blocksize);
                    392:                        if(success != blocksize) {
                    393:                                perror("tape");
                    394:                                fprintf(stderr," hard write error:  write aborted\n");
                    395:                                rewind(tape);
                    396:                                exit(1);
                    397:                        }
                    398:                        numblock++;
                    399:                }
                    400:         } else {
                    401:                fflush(stdout);
                    402:                while(1) {
                    403:                        /* writing an 'F' format tape */
                    404:                        got = read(file,ibuf,recsize+1);
                    405:                        if(got == 0) {
                    406:                                /* end of input */
                    407:                                if(obuf<=obufstart) {
                    408:                                        break; /* done */
                    409:                                } else {
                    410:                                        /* no more data, so force the record out */
                    411:                                        recsize = blocksize+1;
                    412:                                }
                    413:                        } else if(got != recsize+1) {
                    414:                                printf("short read: filled\n");
                    415:                        } else if( *(ibuf+recsize) != '\n') {
                    416:                                printf("corrupted record - write aborted\b");
                    417:                                rewind(tape);
                    418:                                exit(1);
                    419:                        }
                    420:                        if(obuf+recsize >endobuf) {
                    421:                                /*would overflow output buffer, so fill up old buffer */
                    422:                                for(j=obuf;j<endobuf;j++) {
                    423:                                        *j = '^';
                    424:                                }
                    425:                                /* and write it */
                    426:                                success = write(tape,obufstart,blocksize);
                    427:                                if(success != blocksize) {
                    428:                                        perror("tape");
                    429:                                        fprintf(stderr," hard write error:   write aborted\n");
                    430:                                        rewind(tape);
                    431:                                        exit(1);
                    432:                                }
                    433:                                obuf=obufstart;
                    434:                                numblock++;
                    435:                        }
                    436:                        bcopy(ibuf,obuf,recsize);
                    437:                        obuf+=got-1;
                    438:                        numline++;
                    439:                        numchar += recsize;
                    440:                }
                    441:                numchar -= recsize;
                    442:                numline--;
                    443:        }
                    444:        free(ibufstart);
                    445:        free(obufstart);
                    446:        if(vflag) {
                    447:                fprintf(stdout,"r - %s:  %d lines (%d chars) in %d tape blocks\n",
                    448:                                filename,numline,numchar,numblock);
                    449:        }
                    450:        totalwritechars += numchar;
                    451:        totalwritelines += numline;
                    452:        totalwriteblocks += numblock;
                    453:        *blocks = numblock;
                    454: }
                    455: 
                    456: writetm(tape)
                    457:        int tape;
                    458: {
                    459:        struct mtop mtop;
                    460:        mtop.mt_op = MTWEOF;
                    461:        mtop.mt_count = 1;
                    462:        ioctl(tape,MTIOCTOP,&mtop);
                    463: }
                    464: 
                    465: void
                    466: static rewind(tape)
                    467:        int tape;
                    468: {
                    469:        struct mtop mtop;
                    470:        mtop.mt_op = MTREW;
                    471:        mtop.mt_count = 1;
                    472:        ioctl(tape,MTIOCTOP,&mtop);
                    473: }
                    474: 
                    475: skipfile(tape)
                    476:        int tape;
                    477: {
                    478:        struct mtop mtop;
                    479:        mtop.mt_op = MTFSF;
                    480:        mtop.mt_count = 1;
                    481:        ioctl(tape,MTIOCTOP,&mtop);
                    482: }
                    483: 
                    484: backspace(tape)
                    485:        int tape;
                    486: {
                    487:        struct mtop mtop;
                    488:        mtop.mt_op = MTBSF;
                    489:        mtop.mt_count = 1;
                    490:        ioctl(tape,MTIOCTOP,&mtop);
                    491: }
                    492: 
                    493: writehdr1(tape,filename,tapename,filenum,year,day)
                    494:        int tape;
                    495:        char *filename;
                    496:        char *tapename;
                    497:        int filenum;
                    498:        int year;
                    499:        int day;
                    500: {
                    501:        char buf[81];
                    502:        sprintf(buf,
                    503: "HDR1%-17.17s%-6.6s0001%4.4d000101 %2.2d%3.3d %2.2d%3.3d 000000DECFILE11A          "
                    504:                ,filename,tapename,filenum,year,day,year,day);
                    505:        write(tape,buf,80);
                    506: }
                    507: 
                    508: writeeof1(tape,filename,tapename,filenum,year,day,blocks)
                    509:        int tape;
                    510:        char *filename;
                    511:        char *tapename;
                    512:        int filenum;
                    513:        int year;
                    514:        int day;
                    515:        int blocks;
                    516: {
                    517:        char buf[81];
                    518:        sprintf(buf,
                    519: "EOF1%-17.17s%-6.6s0001%4.4d000101 %2.2d%3.3d %2.2d%3.3d %6.6dDECFILE11A          "
                    520:                ,filename,tapename,filenum,year,day,year,day,blocks);
                    521:        write(tape,buf,80);
                    522: }
                    523: 
                    524: writehdr2(tape,blocksize,recordsize)
                    525:        int tape;
                    526:        int blocksize;
                    527:        int recordsize;
                    528: {
                    529:        char buf[81];
                    530:        sprintf(buf,"HDR2%c%5.5d%5.5d%35.35s00%28.28s",fflag?'F':'D',
                    531:                        blocksize,recordsize," "," ");
                    532:        write(tape,buf,80);
                    533: }
                    534: 
                    535: writeeof2(tape,blocksize,recordsize)
                    536:        int tape;
                    537:        int blocksize;
                    538:        int recordsize;
                    539: {
                    540:        char buf[81];
                    541:        sprintf(buf,"EOF2%c%5.5d%5.5d%35.35s00%28.28s",fflag?'F':'D',
                    542:                        blocksize,recordsize," "," ");
                    543:        write(tape,buf,80);
                    544: }
                    545: 
                    546: writehdr3(tape)
                    547:        int tape;
                    548: {
                    549:        char buf[81];
                    550:        sprintf(buf, "HDR3%76.76s"," ");
                    551:        write(tape,buf,80);
                    552: }
                    553: 
                    554: writeeof3(tape)
                    555:        int tape;
                    556: {
                    557:        char buf[81];
                    558:        sprintf(buf, "EOF3%76.76s"," ");
                    559:        write(tape,buf,80);
                    560: }
                    561: 
                    562: writevol(tapename,tape)
                    563:        int tape;
                    564:        char *tapename;
                    565: {
                    566:        char buf[81];
                    567:        sprintf(buf,"VOL1%-6.6s %26.26sD%cC%10.10s1%28.28s3",tapename," ",'%'," "," ");
                    568:        write(tape,buf,80);
                    569:        if(vflag) {
                    570:                fprintf(stdout," tape labeled %-6.6s\n",tapename);
                    571:        }
                    572: }
                    573: 
                    574: getvol(tapename,tape)
                    575:        int tape;
                    576:        char *tapename;
                    577: {
                    578:        char buf[81];
                    579:        read(tape,buf,80);
                    580:        sscanf(buf,"VOL1%6s",tapename);
                    581:        if(vflag) {
                    582:                fprintf(stdout," tape was labeled %-6.6s\n",tapename);
                    583:        }
                    584: }
                    585: 
                    586: casefix(string)
                    587:     register char *string;
                    588: {
                    589:     while(*string) {
                    590:         if(islower(*string)) {
                    591:             *string = toupper(*string);
                    592:         }
                    593:         string++;
                    594:     }
                    595: }
                    596: 
                    597: int
                    598: readfile(tape,argc,argv)
                    599:        int tape;
                    600:        int argc;
                    601:        char *argv[];
                    602: {
                    603: char buf[80];
                    604: char mode;
                    605: char filename[18];
                    606: FILE *file;
                    607: int extract;
                    608: char *ibuf;
                    609: char *ibufstart;
                    610: char *endibuf;
                    611: char *fixpoint;
                    612: int size;
                    613: int numblock = 0 ;
                    614: int numchar = 0 ;
                    615: int numline = 0 ;
                    616: int argnum;
                    617: int ok;
                    618: int blocksize;
                    619: int recordsize;
                    620: 
                    621:        if(!(read(tape,buf,80))) return(1); /* no hdr record, so second eof */
                    622:        sscanf(buf,"HDR1%17s",filename);
                    623:        read(tape,buf,80);
                    624:        sscanf(buf,"HDR2%c%5d%5d",&mode,&blocksize,&recordsize);
                    625:        blocksize = blocksize>recordsize?blocksize:recordsize;
                    626:        skipfile(tape); /* throw away rest of header(s) - not interesting */
                    627:        ibufstart=ibuf=malloc((unsigned)(blocksize+10));
                    628:        endibuf=ibufstart+blocksize;
                    629:        extract=0;
                    630:        if(tflag || xflag) {
                    631:                ok=0;
                    632:                if(!argc) {
                    633:                        ok=1;
                    634:                } else for(argnum=0;argnum<argc;argnum++) {
                    635:                        casefix(argv[argnum]);
                    636:                        if(!strcmp(filename,argv[argnum])) {
                    637:                                ok=1;
                    638:                                break;
                    639:                        }
                    640:                }
                    641:                if(mode == 'D') {
                    642:                        if(xflag && ok) {
                    643:                                file = fopen(filename,"w");
                    644:                                if(file == NULL) {
                    645:                                        perror(filename);
                    646:                                } else {
                    647:                                        extract = 1;
                    648:                                }
                    649:                        }
                    650:                        while(size=read(tape,ibufstart,blocksize)) {
                    651:                                if(size != blocksize) {
                    652:                                        /*
                    653:                                         * somebody's brain damaged program leaves
                    654:                                         * short blocks on the tape - fill them up to size
                    655:                                         * (this is work THEY should have done before writing
                    656:                                         * their undersized blocks)
                    657:                                         */
                    658:                                        for(fixpoint=ibufstart+size;fixpoint<endibuf;fixpoint++) {
                    659:                                                *fixpoint='^';
                    660:                                        }
                    661:                                }
                    662:                                numblock++;
                    663:                                ibuf = ibufstart;
                    664:                                while(strncmp("^^^^",ibuf,4)) {
                    665: #define getsize(a) ((a[0]-'0')*1000)+((a[1]-'0')*100)+((a[2]-'0')*10)+(a[3]-'0')
                    666: #define bad(a) (!(isdigit(ibuf[a])))
                    667:                                        if(bad(0) || bad(1) || bad(2) || bad(3)) {
                    668:                                                fprintf(stderr, "error:  bad record length field - file may be corrupted, skipping\n");
                    669:                                                break;
                    670:                                        }
                    671:                                        size = getsize(ibuf);
                    672:                                        if(extract) {
                    673:                                                fwrite(ibuf+4,sizeof(char),size-4,file);
                    674:                                                fwrite("\n",1,1,file);
                    675:                                        }
                    676:                                        ibuf += (size);
                    677:                                        numline++;
                    678:                                        numchar += (size-4);
                    679:                                        if(ibuf > endibuf+1) {
                    680:                                                fprintf(stderr,"error:  bad tape records(s) - file may be corrupted\n");
                    681:                                                break;
                    682:                                        }
                    683:                                        if(ibuf>endibuf-4) break;
                    684:                                }
                    685:                        }
                    686:                        if(extract) {
                    687:                                fclose(file);
                    688:                        }
                    689:                } else if (mode == 'F') {
                    690:                        if(xflag && ok) {
                    691:                                file = fopen(filename,"w");
                    692:                                if(file == NULL) {
                    693:                                        perror(filename);
                    694:                                } else {
                    695:                                        extract = 1;
                    696:                                }
                    697:                        }
                    698:                        while(read(tape,ibufstart,blocksize)) {
                    699:                                numblock++;
                    700:                                ibuf = ibufstart;
                    701:                                while(ibuf+recordsize <= endibuf) {
                    702:                                        if(extract) {
                    703:                                                fwrite(ibuf,sizeof(char),recordsize,file);
                    704:                                                fwrite("\n",1,1,file);
                    705:                                        }
                    706:                                        ibuf += recordsize;
                    707:                                        numline++;
                    708:                                        numchar += recordsize;
                    709:                                }
                    710:                        }
                    711:                        if(extract) {
                    712:                                fclose(file);
                    713:                        }
                    714:                } else {
                    715:                        fprintf(stderr,"unknown record mode (%c) - file %s skipped\n",
                    716:                                        mode,filename);
                    717:                        skipfile(tape); /* throw away actual file */
                    718:                }
                    719:        } else {
                    720:                /* not interested in contents of file, so move fast */
                    721:                skipfile(tape);
                    722:        }
                    723:        skipfile(tape); /* throw away eof stuff - not interesting */
                    724:        totalreadchars += numchar;
                    725:        totalreadlines += numline;
                    726:        totalreadblocks += numblock;
                    727:        totalreadfiles ++;
                    728:        if(xflag && vflag && ok) {
                    729:                fprintf(stdout,"x - %s:  %d lines (%d chars) in %d tape blocks\n",
                    730:                                filename,numline,numchar,numblock);
                    731:        } else if(tflag && ok) {
                    732:                fprintf(stdout,"t - %s:  %d lines (%d chars) in %d tape blocks\n",
                    733:                                filename,numline,numchar,numblock);
                    734:        }
                    735:        free(ibufstart);
                    736:        return(0);
                    737: }
                    738: 
                    739: filecheck(file,name)
                    740:        int *file;
                    741:        char *name;
                    742: 
                    743: {
                    744: 
                    745:        struct stat buf;
                    746:        struct exec sample;
                    747: 
                    748:        stat(name,&buf);
                    749:        if ((buf.st_mode & S_IFDIR)==S_IFDIR) { 
                    750:                fprintf(stderr,"%s: directory - skipped\n",name);
                    751:                return(1);
                    752:        }
                    753:        if ((buf.st_mode & S_IFCHR)==S_IFCHR) { 
                    754:                fprintf(stderr,"%s: character device - skipped\n",name);
                    755:                return(1);
                    756:        }
                    757:        if ((buf.st_mode & S_IFBLK)==S_IFBLK) {
                    758:                fprintf(stderr,"%s: block device - skipped\n",name);
                    759:                return(1);
                    760:        }
                    761:        if ((buf.st_mode & S_IFLNK)==S_IFLNK) {
                    762:                fprintf(stderr,"%s: symbolic link - skipped\n",name);
                    763:                return(1);
                    764:        }
                    765:        if ((buf.st_mode & S_IFSOCK)==S_IFSOCK) {
                    766:                fprintf(stderr,"%s: socket - skipped\n",name);
                    767:                return(1);
                    768:        }
                    769:        *file = open(name,O_RDONLY,NULL);
                    770:        if(*file <0) { 
                    771:                perror(name);
                    772:                return(1);
                    773:        }
                    774:        if(read(*file,&sample,sizeof(struct exec))>= sizeof(struct exec)) {
                    775:                if(!(N_BADMAG(sample))) {
                    776:                        /* executable */
                    777:                        /* the format requires either fixed blocked records,
                    778:                         * or variable format records with each record remaining
                    779:                         * entirely within a tape block - this limits the
                    780:                         * distance between \n's to 2044 bytes, something
                    781:                         * which is VERY rarely true of executables, so
                    782:                         * we don't even try with them....
                    783:                         */
                    784:                        close(*file);
                    785:                        fprintf(stderr,"%s: executable - skipped\n",name);
                    786:                        return(1);
                    787:                }
                    788:        }
                    789:        /* either couldn't read sizeof(struct exec) or wasn't executable */
                    790:        /* so we assume it is a reasonable file until proven otherwise */
                    791:        lseek(*file,0l,0);
                    792:        return(0);
                    793: }

unix.superglobalmegacorp.com

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