xref: /original-bsd/contrib/ansi/ansitape.c (revision a9c19d04)
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 void rewind();
13 int wflag;
14 int xflag;
15 int tflag;
16 int cflag;
17 int vflag;
18 int dflag;
19 int fflag;
20 int totalreadfiles = 0 ;
21 int totalreadblocks = 0 ;
22 int totalreadlines = 0 ;
23 int totalreadchars = 0 ;
24 int totalwritefiles = 0 ;
25 int totalwriteblocks = 0 ;
26 int totalwritelines = 0 ;
27 int totalwritechars = 0 ;
28 
29 main(argc,argv)
30 	int argc;
31 	char *argv[];
32 {
33 	struct tm *tm;
34 	long timetemp;
35 	int year;
36 	int day;
37 	char *tapename;
38 	char *filename;
39 	char *namelist=NULL;
40 	char *device = "/dev/rmt12";
41 	int tape;
42 	int file;
43 	int filenum;
44 	int argnum;
45 	char line[1001];
46 	char vmsname[1000];
47 	char unixname[1000];
48 	FILE *names;
49 	int count;
50 	int tmp;
51 	char blockchar;
52 	int blocksize=2048;
53 	int recordsize=1;
54 
55 	char *key;
56 
57 	timetemp = time(0);
58 	tm = localtime(&timetemp);
59 	year = tm->tm_year;
60 	day = tm->tm_yday;
61 	tapename = malloc(10);
62 	gethostname(tapename,6);
63 	tapename[7]='\0';
64 
65 	/* parse command line */
66 	if (argc < 2)
67 		usage();
68 
69 	argv++;
70 	argc--;
71 	/* loop through first argument (key) */
72 	argc--;
73 	for (key = *argv++; *key; key++)
74 		switch(*key) {
75 
76 		case 'f':
77 			if (*argv == NULL || argc <1) {
78 				fprintf(stderr,
79 			"ansitape: 'f' option requires tape name \n");
80 				usage();
81 			}
82 			device = *argv++;
83 			argc--;
84 			break;
85 
86 		case 'n':
87 			if (*argv == NULL || argc <1) {
88 				fprintf(stderr,
89 			"ansitape: 'n' option requires file name\n");
90 				usage();
91 			}
92 			namelist = *argv++;
93 			argc--;
94 			break;
95 
96 		case 'l':
97 			if (*argv == NULL || argc<1) {
98 				fprintf(stderr,
99 			"ansitape: 'l' option requires label\n");
100 				usage();
101 			}
102 			tapename = *argv++;
103 			argc--;
104 			break;
105 
106 		case 'F':
107 			if(*argv == NULL) {
108 				fprintf(stderr,
109 		"ansitape: 'F' options requires recordsize and blocksize specifiers.\n"
110 						);
111 				usage();
112 			}
113 			tmp = sscanf(*argv++," %d%c ",&recordsize,&blockchar);
114 			argc--;
115 			if(tmp<1) {
116 				fprintf(stderr,"illegal recordsize: recordsize set to 80\n");
117 				recordsize=80;
118 			} else if(tmp>1) {
119 				if(blockchar == 'b') recordsize *= 512;
120 				if(blockchar == 'k') recordsize *= 1024;
121 			}
122 
123 			if (*argv == NULL) {
124 				fprintf(stderr,
125 			"ansitape: 'F' option requires blocksize specifier \n");
126 				usage();
127 			}
128 			tmp = sscanf(*argv++," %d%c ",&blocksize,&blockchar);
129 			argc--;
130 			if(tmp<1) {
131 				fprintf(stderr,"illegal blocksize: blocksize set to 2048\n");
132 				blocksize=2048;
133 			} else if(tmp>1) {
134 				if(blockchar == 'b') blocksize *= 512;
135 				if(blockchar == 'k') blocksize *= 1024;
136 			}
137 			if(blocksize <18) blocksize=18;
138 			if(blocksize >62*1024) blocksize=62*1024;
139 			fflag++;
140 			break;
141 
142 		case 'b':
143 			if (*argv == NULL) {
144 				fprintf(stderr,
145 			"ansitape: 'b' option requires blocksize specifier \n");
146 				usage();
147 			}
148 			tmp = sscanf(*argv++," %d%c ",&blocksize,&blockchar);
149 			argc--;
150 			if(tmp<1) {
151 				fprintf(stderr,"illegal blocksize: blocksize set to 2048\n");
152 				blocksize=2048;
153 			} else if(tmp>1) {
154 				if(blockchar == 'b') blocksize *= 512;
155 				if(blockchar == 'k') blocksize *= 1024;
156 			}
157 			if(blocksize <18) blocksize=18;
158 			if(blocksize >62*1024) blocksize=62*1024;
159 			break;
160 
161 		case 'c':
162 			cflag++;
163 			wflag++;
164 			break;
165 
166 		case 'r':
167 			/*I know, this should be rflag, but I just don't like r for write*/
168 			wflag++;
169 			break;
170 
171 		case 'v':
172 			vflag++;
173 			break;
174 
175 		case 'x':
176 			xflag++;
177 			break;
178 
179 		case 't':
180 			tflag++;
181 			break;
182 
183 		case '-':
184 			break;
185 
186 		default:
187 			fprintf(stderr, "ansitape: %c: unknown option\n", *key);
188 			usage();
189 		}
190 
191 	if (!wflag && !xflag && !tflag)
192 		usage();
193 
194 	tape = open(device,wflag?O_RDWR:O_RDONLY,NULL);
195 	if(tape<0) {
196 		perror(device);
197 		printf(stderr,"tape not accessable - check if drive online and write ring present\n");
198 		exit(1);
199 	}
200 	rewind(tape);
201 	filenum=1;
202 	casefix(tapename);
203 
204 	if(cflag) {
205 		writevol(tapename,tape);
206 	} else {
207 		getvol(tapename,tape);
208 		while(1) {
209 			/* read files */
210 			if( readfile(tape,argc,argv) ) break;
211 			filenum++;
212 		}
213 		backspace(tape);
214 	}
215 
216 	if(wflag) {
217 		if(namelist) {
218 			if(*namelist == '-') {
219 				names = stdin;
220 			} else {
221 				names=fopen(namelist,"r");
222 				if(names == NULL) {
223 					fprintf(stderr,"unable to open namelist file - no files added to tape\n");
224 				}
225 			}
226 			while(1) {
227 				fgets(line,1000,names);
228 				if(feof(names)) break;
229 				count = sscanf(line,"%s %s",unixname,vmsname);
230 				if(count<1) continue; /* blank line */
231 				if(count==1) strcpy(vmsname,unixname);
232 				casefix(vmsname);
233 				if(filecheck(&file,unixname)) continue;
234 				writefile(tape,file,vmsname,tapename,filenum,year,day,blocksize,
235 						recordsize);
236 				filenum++;
237 				close(file);
238 			}
239 		} else {
240 			for(argnum=0;argnum<argc;argnum++) {
241 				filename = argv[argnum];
242 				if(filecheck(&file,filename)) continue;
243 				casefix(filename);
244 				writefile(tape,file,filename,tapename,filenum,year,day,
245 						blocksize,recordsize);
246 				filenum++;
247 				close(file);
248 			}
249 		}
250 		writetm(tape);
251 		writetm(tape);
252 		writetm(tape);
253 		writetm(tape);
254 	}
255 	rewind(tape);
256 	close(tape);
257 	if(vflag && (tflag || xflag)) {
258 		fprintf(stdout," read  %d files in %d blocks (%d lines, %d chars)\n",
259 			totalreadfiles,totalreadblocks,totalreadlines,totalreadchars);
260 	}
261 	if(vflag && wflag) {
262 		fprintf(stdout," wrote  %d files in %d blocks (%d lines, %d chars)\n",
263 			totalwritefiles,totalwriteblocks,totalwritelines,totalwritechars);
264 	}
265 }
266 usage() {
267 	fprintf(stderr,
268 			"ansitape: usage: ansitape -{rxtc}[flnvb] [filename] [label] [filename] [blocksize] [files]\n");
269 	exit();
270 }
271 
272 writefile(tape,file,filename,tapename,filenum,year,day,blocksize,recordsize)
273 	int tape;
274 	int file;
275 	char *filename;
276 	char *tapename;
277 	int filenum;
278 	int year;
279 	int day;
280 	int blocksize;
281 	int recordsize;
282 
283 {
284 	int blocks;
285 	writehdr1(tape,filename,tapename,filenum,year,day);
286 	writehdr2(tape,blocksize,recordsize);
287 	writehdr3(tape);
288 	writetm(tape);
289 	writedata(tape,file,filename,&blocks,blocksize,recordsize);
290 	writetm(tape);
291 	writeeof1(tape,filename,tapename,filenum,year,day,blocks);
292 	writeeof2(tape,blocksize,recordsize);
293 	writeeof3(tape);
294 	writetm(tape);
295 	totalwritefiles++;
296 }
297 
298 writedata(tape,file,filename,blocks,blocksize,recsize)
299 	int tape;
300 	int file;
301 	char *filename;
302 	int *blocks;
303 	int blocksize;
304 	int recsize;
305 {
306 char *ibuf;
307 char *ibufstart;
308 char *obuf;
309 char *obufstart;
310 char sizebuf[5];
311 char *endibuf;
312 char *endobuf;
313 int got;
314 int i;
315 char *j;
316 int numchar = 0 ;
317 int numline = 0 ;
318 int numblock = 0;
319 int success;
320 
321 	ibufstart = ibuf = malloc(blocksize<4096?8200:(2*blocksize+10));
322 	obufstart = obuf = malloc(blocksize+10);
323 	endobuf = obuf + blocksize;
324 	endibuf = ibuf;
325 
326 
327 	i=0;
328 	if (!fflag) {
329 		while(1) {
330 			if(ibuf+i>=endibuf) {	/* end of input buffer */
331 				strncpy(ibufstart,ibuf,endibuf-ibuf); /* copy leftover to start */
332 				ibuf = ibufstart+(endibuf-ibuf);	/* point to end of valid data */
333 				got = read(file,ibuf,blocksize<4096?4096:2*blocksize);	/* read in a chunk */
334 				endibuf = ibuf + got;
335 				ibuf = ibufstart;	/* point to beginning of data */
336 				if(got == 0) { /* end of input */
337 					if(ibuf==ibufstart){ /* no leftovers */
338 						break; /* done */
339 					} else {
340 						ibuf[i]='\n'; /* fake extra newline */
341 					}
342 				}
343 			}
344 
345 			if(obuf+i+4 > endobuf) {  /* end of output buffer */
346 				if(i>blocksize-4) {
347 					printf("record exceeds blocksize - file truncated\n");
348 					break;
349 				}
350 				/* filled up output record - have to fill,output,restart*/
351 				for(j=obuf;j<endobuf;j++) {
352 					*j = '^';
353 				}
354 				success = write(tape,obufstart,blocksize);
355 				if(success != blocksize) {
356 					perror("tape");
357 					fprintf(stderr," hard write error:  write aborted\n");
358 					rewind(tape);
359 					exit(1);
360 				}
361 				obuf=obufstart;
362 				numchar -= i;
363 				i=0;
364 				numblock++;
365 				continue;
366 			}
367 
368 			if(ibuf[i] == '\n') { /* end of line */
369 				/*sprintf(sizebuf,"%4.4d",i+4); /* make length string */
370 				/*strncpy(obuf,sizebuf,4); /* put in length field */
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 				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 				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 					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 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%56810.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 i;
614 int size;
615 int numblock = 0 ;
616 int numchar = 0 ;
617 int numline = 0 ;
618 int argnum;
619 int ok;
620 int blocksize;
621 int recordsize;
622 int writeblock;
623 
624 	if(!(read(tape,buf,80))) return(1); /* no hdr record, so second eof */
625 	sscanf(buf,"HDR1%17s",filename);
626 	read(tape,buf,80);
627 	sscanf(buf,"HDR2%c%5d%5d",&mode,&blocksize,&recordsize);
628 	blocksize = blocksize>recordsize?blocksize:recordsize;
629 	skipfile(tape); /* throw away rest of header(s) - not interesting */
630 	ibufstart=ibuf=malloc(blocksize+10);
631 	endibuf=ibufstart+blocksize;
632 	extract=0;
633 	if(tflag || xflag) {
634 		ok=0;
635 		if(!argc) {
636 			ok=1;
637 		} else for(argnum=0;argnum<argc;argnum++) {
638 			casefix(argv[argnum]);
639 			if(!strcmp(filename,argv[argnum])) {
640 				ok=1;
641 				break;
642 			}
643 		}
644 		if(mode == 'D') {
645 			if(xflag && ok) {
646 				file = fopen(filename,"w");
647 				if(file == NULL) {
648 					perror(filename);
649 				} else {
650 					extract = 1;
651 				}
652 			}
653 			while(size=read(tape,ibufstart,blocksize)) {
654 				if(size != blocksize) {
655 					/*
656 					 * somebody's brain damaged program leaves
657 					 * short blocks on the tape - fill them up to size
658 					 * (this is work THEY should have done before writing
659 					 * their undersized blocks)
660 					 */
661 					for(fixpoint=ibufstart+size;fixpoint<endibuf;fixpoint++) {
662 						*fixpoint='^';
663 					}
664 				}
665 				numblock++;
666 				ibuf = ibufstart;
667 				while(strncmp("^^^^",ibuf,4)) {
668 #define getsize(a) ((a[0]-'0')*1000)+((a[1]-'0')*100)+((a[2]-'0')*10)+(a[3]-'0')
669 #define bad(a) (!(isdigit(ibuf[a])))
670 					if(bad(0) || bad(1) || bad(2) || bad(3)) {
671 						fprintf(stderr, "error:  bad record length field - file may be corrupted, skipping\n");
672 						break;
673 					}
674 					size = getsize(ibuf);
675 					if(extract) {
676 						fwrite(ibuf+4,sizeof(char),size-4,file);
677 						fwrite("\n",1,1,file);
678 					}
679 					ibuf += (size);
680 					numline++;
681 					numchar += (size-4);
682 					if(ibuf > endibuf+1) {
683 						fprintf(stderr,"error:  bad tape records(s) - file may be corrupted\n");
684 						break;
685 					}
686 					if(ibuf>endibuf-4) break;
687 				}
688 			}
689 			if(extract) {
690 				fclose(file);
691 			}
692 		} else if (mode == 'F') {
693 			if(xflag && ok) {
694 				file = fopen(filename,"w");
695 				if(file == NULL) {
696 					perror(filename);
697 				} else {
698 					extract = 1;
699 				}
700 			}
701 			while(read(tape,ibufstart,blocksize)) {
702 				numblock++;
703 				ibuf = ibufstart;
704 				while(ibuf+recordsize <= endibuf) {
705 					if(extract) {
706 						fwrite(ibuf,sizeof(char),recordsize,file);
707 						fwrite("\n",1,1,file);
708 					}
709 					ibuf += recordsize;
710 					numline++;
711 					numchar += recordsize;
712 				}
713 			}
714 			if(extract) {
715 				fclose(file);
716 			}
717 		} else {
718 			fprintf(stderr,"unknown record mode (%c) - file %s skipped\n",
719 					mode,filename);
720 			skipfile(tape);	/* throw away actual file */
721 		}
722 	} else {
723 		/* not interested in contents of file, so move fast */
724 		skipfile(tape);
725 	}
726 	skipfile(tape); /* throw away eof stuff - not interesting */
727 	totalreadchars += numchar;
728 	totalreadlines += numline;
729 	totalreadblocks += numblock;
730 	totalreadfiles ++;
731 	if(xflag && vflag && ok) {
732 		fprintf(stdout,"x - %s:  %d lines (%d chars) in %d tape blocks\n",
733 				filename,numline,numchar,numblock);
734 	} else if(tflag && ok) {
735 		fprintf(stdout,"t - %s:  %d lines (%d chars) in %d tape blocks\n",
736 				filename,numline,numchar,numblock);
737 	}
738 	free(ibufstart);
739 	return(0);
740 }
741 
742 filecheck(file,name)
743 	int *file;
744 	char *name;
745 
746 {
747 
748 	struct stat buf;
749 	struct exec sample;
750 
751 	stat(name,&buf);
752 	if ((buf.st_mode & S_IFDIR)==S_IFDIR) {
753 		fprintf(stderr,"%s: directory - skipped\n",name);
754 		return(1);
755 	}
756 	if ((buf.st_mode & S_IFCHR)==S_IFCHR) {
757 		fprintf(stderr,"%s: character device - skipped\n",name);
758 		return(1);
759 	}
760 	if ((buf.st_mode & S_IFBLK)==S_IFBLK) {
761 		fprintf(stderr,"%s: block device - skipped\n",name);
762 		return(1);
763 	}
764 	if ((buf.st_mode & S_IFLNK)==S_IFLNK) {
765 		fprintf(stderr,"%s: symbolic link - skipped\n",name);
766 		return(1);
767 	}
768 	if ((buf.st_mode & S_IFSOCK)==S_IFSOCK) {
769 		fprintf(stderr,"%s: socket - skipped\n",name);
770 		return(1);
771 	}
772 	*file = open(name,O_RDONLY,NULL);
773 	if(*file <0) {
774 		perror(name);
775 		return(1);
776 	}
777 	if(read(*file,&sample,sizeof(struct exec))>= sizeof(struct exec)) {
778 		if(!(N_BADMAG(sample))) {
779 			/* executable */
780 			/* the format requires either fixed blocked records,
781 			 * or variable format records with each record remaining
782 			 * entirely within a tape block - this limits the
783 			 * distance between \n's to 2044 bytes, something
784 			 * which is VERY rarely true of executables, so
785 			 * we don't even try with them....
786 			 */
787 			close(*file);
788 			fprintf(stderr,"%s: executable - skipped\n",name);
789 			return(1);
790 		}
791 	}
792 	/* either couldn't read sizeof(struct exec) or wasn't executable */
793 	/* so we assume it is a reasonable file until proven otherwise */
794 	lseek(*file,0l,0);
795 	return(0);
796 }
797