📄 ansitape.c
字号:
#include <sys/types.h>#include <sys/time.h>#include <sys/mtio.h>#include <sys/ioctl.h>#include <sys/file.h>#include <sys/stat.h>#include <a.out.h>#include <stdio.h>#include <ctype.h>#include <unistd.h>char *malloc();static void ansi_rewind();int wflag;int xflag;int tflag;int cflag;int vflag;int dflag;int fflag;int totalreadfiles = 0 ;int totalreadblocks = 0 ;int totalreadlines = 0 ;int totalreadchars = 0 ;int totalwritefiles = 0 ;int totalwriteblocks = 0 ;int totalwritelines = 0 ;int totalwritechars = 0 ;main(argc,argv) int argc; char *argv[];{ struct tm *tm; long timetemp,time(); int year; int day; char *tapename; char *filename; char *namelist=NULL; char *device = "/dev/rmt12"; int tape; int file; int filenum; int argnum; char line[1001]; char vmsname[1000]; char unixname[1000]; FILE *names; int count; int tmp; char blockchar; int blocksize=2048; int recordsize=1; char *key; timetemp = time((long *)NULL); tm = localtime(&timetemp); year = tm->tm_year; day = tm->tm_yday; tapename = malloc(10); gethostname(tapename,6); tapename[7]='\0'; /* parse command line */ if (argc < 2) usage(); argv++; argc--; /* loop through first argument (key) */ argc--; for (key = *argv++; *key; key++) switch(*key) { case 'f': if (*argv == NULL || argc <1) { fprintf(stderr, "ansitape: 'f' option requires tape name \n"); usage(); } device = *argv++; argc--; break; case 'n': if (*argv == NULL || argc <1) { fprintf(stderr, "ansitape: 'n' option requires file name\n"); usage(); } namelist = *argv++; argc--; break; case 'l': if (*argv == NULL || argc<1) { fprintf(stderr, "ansitape: 'l' option requires label\n"); usage(); } tapename = *argv++; argc--; break; case 'F': if(*argv == NULL) { fprintf(stderr, "ansitape: 'F' options requires recordsize and blocksize specifiers.\n" ); usage(); } tmp = sscanf(*argv++," %d%c ",&recordsize,&blockchar); argc--; if(tmp<1) { fprintf(stderr,"illegal recordsize: recordsize set to 80\n"); recordsize=80; } else if(tmp>1) { if(blockchar == 'b') recordsize *= 512; if(blockchar == 'k') recordsize *= 1024; } if (*argv == NULL) { fprintf(stderr, "ansitape: 'F' option requires blocksize specifier \n"); usage(); } tmp = sscanf(*argv++," %d%c ",&blocksize,&blockchar); argc--; if(tmp<1) { fprintf(stderr,"illegal blocksize: blocksize set to 2048\n"); blocksize=2048; } else if(tmp>1) { if(blockchar == 'b') blocksize *= 512; if(blockchar == 'k') blocksize *= 1024; } if(blocksize <18) blocksize=18; if(blocksize >62*1024) blocksize=62*1024; fflag++; break; case 'b': if (*argv == NULL) { fprintf(stderr, "ansitape: 'b' option requires blocksize specifier \n"); usage(); } tmp = sscanf(*argv++," %d%c ",&blocksize,&blockchar); argc--; if(tmp<1) { fprintf(stderr,"illegal blocksize: blocksize set to 2048\n"); blocksize=2048; } else if(tmp>1) { if(blockchar == 'b') blocksize *= 512; if(blockchar == 'k') blocksize *= 1024; } if(blocksize <18) blocksize=18; if(blocksize >62*1024) blocksize=62*1024; break; case 'c': cflag++; wflag++; break; case 'r': /*I know, this should be rflag, but I just don't like r for write*/ wflag++; break; case 'v': vflag++; break; case 'x': xflag++; break; case 't': tflag++; break; case '-': break; default: fprintf(stderr, "ansitape: %c: unknown option\n", *key); usage(); } if (!wflag && !xflag && !tflag) usage(); tape = open(device,wflag?O_RDWR:O_RDONLY,NULL); if(tape<0) { perror(device); fprintf(stderr,"tape not accessable - check if drive online and write ring present\n"); exit(1); } ansi_rewind(tape); filenum=1; casefix(tapename); if(cflag) { writevol(tapename,tape); } else { getvol(tapename,tape); while(1) { /* read files */ if( readfile(tape,argc,argv) ) break; filenum++; } backspace(tape); } if(wflag) { if(namelist) { if(*namelist == '-') { names = stdin; } else { names=fopen(namelist,"r"); if(names == NULL) { fprintf(stderr,"unable to open namelist file - no files added to tape\n"); } } while(1) { fgets(line,1000,names); if(feof(names)) break; count = sscanf(line,"%s %s",unixname,vmsname); if(count<1) continue; /* blank line */ if(count==1) strcpy(vmsname,unixname); casefix(vmsname); if(filecheck(&file,unixname)) continue; writefile(tape,file,vmsname,tapename,filenum,year,day,blocksize, recordsize); filenum++; close(file); } } else { for(argnum=0;argnum<argc;argnum++) { filename = argv[argnum]; if(filecheck(&file,filename)) continue; casefix(filename); writefile(tape,file,filename,tapename,filenum,year,day, blocksize,recordsize); filenum++; close(file); } } writetm(tape); writetm(tape); writetm(tape); writetm(tape); } ansi_rewind(tape); close(tape); if(vflag && (tflag || xflag)) { fprintf(stdout," read %d files in %d blocks (%d lines, %d chars)\n", totalreadfiles,totalreadblocks,totalreadlines,totalreadchars); } if(vflag && wflag) { fprintf(stdout," wrote %d files in %d blocks (%d lines, %d chars)\n", totalwritefiles,totalwriteblocks,totalwritelines,totalwritechars); } return(0);}usage() { fprintf(stderr, "ansitape: usage: ansitape -{rxtc}[flnvb] [filename] [label] [filename] [blocksize] [files]\n"); exit(1);}writefile(tape,file,filename,tapename,filenum,year,day,blocksize,recordsize) int tape; int file; char *filename; char *tapename; int filenum; int year; int day; int blocksize; int recordsize;{ int blocks; writehdr1(tape,filename,tapename,filenum,year,day); writehdr2(tape,blocksize,recordsize); writehdr3(tape); writetm(tape); writedata(tape,file,filename,&blocks,blocksize,recordsize); writetm(tape); writeeof1(tape,filename,tapename,filenum,year,day,blocks); writeeof2(tape,blocksize,recordsize); writeeof3(tape); writetm(tape); totalwritefiles++;}writedata(tape,file,filename,blocks,blocksize,recsize) int tape; int file; char *filename; int *blocks; int blocksize; int recsize;{char *ibuf;char *ibufstart;char *obuf;char *obufstart;char *endibuf;char *endobuf;int got;int i;char *j;int numchar = 0 ;int numline = 0 ;int numblock = 0;int success; ibufstart = ibuf = malloc((unsigned)(blocksize<4096?8200:(2*blocksize+10))); obufstart = obuf = malloc((unsigned)(blocksize+10)); endobuf = obuf + blocksize; endibuf = ibuf; i=0; if (!fflag) { while(1) { if(ibuf+i>=endibuf) { /* end of input buffer */ strncpy(ibufstart,ibuf,endibuf-ibuf); /* copy leftover to start */ ibuf = ibufstart+(endibuf-ibuf); /* point to end of valid data */ got = read(file,ibuf,blocksize<4096?4096:2*blocksize); /* read in a chunk */ endibuf = ibuf + got; ibuf = ibufstart; /* point to beginning of data */ if(got == 0) { /* end of input */ if(ibuf==ibufstart){ /* no leftovers */ break; /* done */ } else { ibuf[i]='\n'; /* fake extra newline */ } } } if(obuf+i+4 > endobuf) { /* end of output buffer */ if(i>blocksize-4) { printf("record exceeds blocksize - file truncated\n"); break; } /* filled up output record - have to fill,output,restart*/ for(j=obuf;j<endobuf;j++) { *j = '^'; } success = write(tape,obufstart,blocksize); if(success != blocksize) { perror("tape"); fprintf(stderr," hard write error: write aborted\n"); ansi_rewind(tape); exit(1); } obuf=obufstart; numchar -= i; i=0; numblock++; continue; } if(ibuf[i] == '\n') { /* end of line */ obuf[0] = ((i+4)/1000) + '0'; obuf[1] = (((i+4)/100)%10) + '0'; obuf[2] = (((i+4)/10)%10) + '0'; obuf[3] = (((i+4)/1)%10) + '0'; obuf += (4+i); /* size + strlen */ ibuf += (1+i); /* newline + strlen */ i=0; numline++; continue; /* back to the top */ } obuf[i+4]=ibuf[i]; numchar++; i++; } /* exited - write last record and go for lunch */ if(obuf != obufstart) { for(j=obuf;j<endobuf;j++) { *j = '^'; } success = write(tape,obufstart,blocksize); if(success != blocksize) { perror("tape"); fprintf(stderr," hard write error: write aborted\n"); ansi_rewind(tape); exit(1); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -