12841Swnj /*
22841Swnj  * pxheader - program to sit in front of interpreter code to make shell mods
32841Swnj  *	      unnecessary to make Pascal obj's look like real programs.
42841Swnj  *
52841Swnj  * This program lives in /usr/lib/px_header
62841Swnj  * Bill Joy UCB February 6, 1978
72841Swnj  */
82841Swnj 
9*2948Smckusic static char sccsid[] = "@(#)px_header.c 1.2 03/06/81";
102841Swnj 
11*2948Smckusic #include <stdio.h>
12*2948Smckusic #include <sys/types.h>
13*2948Smckusic #include <a.out.h>
14*2948Smckusic #include "whoami.h"
15*2948Smckusic #include "objfmt.h"
16*2948Smckusic 
172841Swnj #define	ETXTBSY	26
182841Swnj #define	ADDR_LC	HEADER_BYTES - sizeof (struct exec) - sizeof (struct pxhdr)
192841Swnj 
20*2948Smckusic extern	errno;
21*2948Smckusic 
222841Swnj main(argc, argv)
232841Swnj 	register int argc;
242841Swnj 	register char *argv[];
252841Swnj {
262841Swnj 	register int i, j;
272841Swnj 	register unsigned short *ip;
282841Swnj 	char *largv[512];
292841Swnj 	int pv[2];
302841Swnj 
312841Swnj 	if (argc > 510) {
322841Swnj 		error("Too many arguments.\n");
332841Swnj 		exit(1);
342841Swnj 	}
352841Swnj 	largv[0] = argv[0];
362841Swnj 	largv[1] = "-";
372841Swnj 	for (i = 1; i < argc; i++)
382841Swnj 		largv[i + 1] = argv[i];
392841Swnj 	largv[argc + 1] = 0;
402841Swnj 	pipe(pv);
412841Swnj 	i = fork();
422841Swnj 	if (i == -1)
432841Swnj 		error("Try again.\n");
442841Swnj 	if (i == 0) {
452841Swnj 		close(pv[0]);
46*2948Smckusic 		ip = (unsigned short *)(ADDR_LC);
47*2948Smckusic 		i = ((struct pxhdr *)(ip))->objsize + sizeof(struct pxhdr);
482841Swnj 		while (i != 0) {
492841Swnj 			j = (i > 0 && i < BUFSIZ) ? i : BUFSIZ;
502841Swnj 			write(pv[1], ip, j);
512841Swnj 			ip += BUFSIZ / sizeof ( unsigned short );
522841Swnj 			i -= j;
532841Swnj 		}
542841Swnj 		exit(1);
552841Swnj 	}
562841Swnj 	close(pv[1]);
572841Swnj 	if (pv[0] != 3) {
582841Swnj 		close(3);
592841Swnj 		dup(pv[0]);
602841Swnj 		close(pv[0]);
612841Swnj 	}
622841Swnj 	for (;;) {
632841Swnj 		execv(PX_INTRP, largv);
642841Swnj 		if (errno != ETXTBSY)
652841Swnj 			break;
662841Swnj 		sleep(2);
672841Swnj 	}
682841Swnj 	error("Px not found.\n");
692841Swnj }
702841Swnj 
712841Swnj error(cp)
722841Swnj 	register char *cp;
732841Swnj {
742841Swnj 	register int i;
752841Swnj 	register char *dp;
762841Swnj 
772841Swnj 	dp = cp;
782841Swnj 	i = 0;
792841Swnj 	while (*dp++)
802841Swnj 		i++;
812841Swnj 	write(2, cp, i);
822841Swnj 	exit(1);
832841Swnj }
842841Swnj 
852841Swnj exit(i)
862841Swnj {
872841Swnj 	_exit(i);
882841Swnj }
89