From: CSRG Date: Thu, 10 Dec 1987 10:02:22 +0000 (-0800) Subject: BSD 4_3_Tahoe development X-Git-Tag: BSD-4_3_Net_1^2~283 X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/commitdiff_plain/f32f758bce196c63fcaddd89cea9d59f1cc1af32 BSD 4_3_Tahoe development Work on file usr/src/new/ansi/ansitape.c Synthesized-from: CSRG/cd2/4.3tahoe --- diff --git a/usr/src/new/ansi/ansitape.c b/usr/src/new/ansi/ansitape.c new file mode 100644 index 0000000000..eac0268e34 --- /dev/null +++ b/usr/src/new/ansi/ansitape.c @@ -0,0 +1,793 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *malloc(); +static void rewind(); +long lseek(); +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); + } + 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=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;jendobuf) { + /*would overflow output buffer, so fill up old buffer */ + for(j=obuf;jrecordsize?blocksize:recordsize; + skipfile(tape); /* throw away rest of header(s) - not interesting */ + ibufstart=ibuf=malloc((unsigned)(blocksize+10)); + endibuf=ibufstart+blocksize; + extract=0; + if(tflag || xflag) { + ok=0; + if(!argc) { + ok=1; + } else for(argnum=0;argnum endibuf+1) { + fprintf(stderr,"error: bad tape records(s) - file may be corrupted\n"); + break; + } + if(ibuf>endibuf-4) break; + } + } + if(extract) { + fclose(file); + } + } else if (mode == 'F') { + if(xflag && ok) { + file = fopen(filename,"w"); + if(file == NULL) { + perror(filename); + } else { + extract = 1; + } + } + while(read(tape,ibufstart,blocksize)) { + numblock++; + ibuf = ibufstart; + while(ibuf+recordsize <= endibuf) { + if(extract) { + fwrite(ibuf,sizeof(char),recordsize,file); + fwrite("\n",1,1,file); + } + ibuf += recordsize; + numline++; + numchar += recordsize; + } + } + if(extract) { + fclose(file); + } + } else { + fprintf(stderr,"unknown record mode (%c) - file %s skipped\n", + mode,filename); + skipfile(tape); /* throw away actual file */ + } + } else { + /* not interested in contents of file, so move fast */ + skipfile(tape); + } + skipfile(tape); /* throw away eof stuff - not interesting */ + totalreadchars += numchar; + totalreadlines += numline; + totalreadblocks += numblock; + totalreadfiles ++; + if(xflag && vflag && ok) { + fprintf(stdout,"x - %s: %d lines (%d chars) in %d tape blocks\n", + filename,numline,numchar,numblock); + } else if(tflag && ok) { + fprintf(stdout,"t - %s: %d lines (%d chars) in %d tape blocks\n", + filename,numline,numchar,numblock); + } + free(ibufstart); + return(0); +} + +filecheck(file,name) + int *file; + char *name; + +{ + + struct stat buf; + struct exec sample; + + stat(name,&buf); + if ((buf.st_mode & S_IFDIR)==S_IFDIR) { + fprintf(stderr,"%s: directory - skipped\n",name); + return(1); + } + if ((buf.st_mode & S_IFCHR)==S_IFCHR) { + fprintf(stderr,"%s: character device - skipped\n",name); + return(1); + } + if ((buf.st_mode & S_IFBLK)==S_IFBLK) { + fprintf(stderr,"%s: block device - skipped\n",name); + return(1); + } + if ((buf.st_mode & S_IFLNK)==S_IFLNK) { + fprintf(stderr,"%s: symbolic link - skipped\n",name); + return(1); + } + if ((buf.st_mode & S_IFSOCK)==S_IFSOCK) { + fprintf(stderr,"%s: socket - skipped\n",name); + return(1); + } + *file = open(name,O_RDONLY,NULL); + if(*file <0) { + perror(name); + return(1); + } + if(read(*file,&sample,sizeof(struct exec))>= sizeof(struct exec)) { + if(!(N_BADMAG(sample))) { + /* executable */ + /* the format requires either fixed blocked records, + * or variable format records with each record remaining + * entirely within a tape block - this limits the + * distance between \n's to 2044 bytes, something + * which is VERY rarely true of executables, so + * we don't even try with them.... + */ + close(*file); + fprintf(stderr,"%s: executable - skipped\n",name); + return(1); + } + } + /* either couldn't read sizeof(struct exec) or wasn't executable */ + /* so we assume it is a reasonable file until proven otherwise */ + lseek(*file,0l,0); + return(0); +}