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