xref: /original-bsd/contrib/ansi/ansitape.c (revision e59fb703)
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 }
794