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*5639Smckusic static char sccsid[] = "@(#)px_header.c 1.3 02/01/82";
102841Swnj 
112948Smckusic #include <stdio.h>
122948Smckusic #include <sys/types.h>
132948Smckusic #include <a.out.h>
142948Smckusic #include "whoami.h"
152948Smckusic #include "objfmt.h"
162948Smckusic 
172841Swnj #define	ETXTBSY	26
182841Swnj #define	ADDR_LC	HEADER_BYTES - sizeof (struct exec) - sizeof (struct pxhdr)
19*5639Smckusic #define MAXARGS 512
202841Swnj 
212948Smckusic extern	errno;
222948Smckusic 
232841Swnj main(argc, argv)
242841Swnj 	register int argc;
252841Swnj 	register char *argv[];
262841Swnj {
27*5639Smckusic 	register int i;
28*5639Smckusic 	int codesiz, symtabsiz;
29*5639Smckusic 	register char *cp;
30*5639Smckusic 	char *largv[MAXARGS];
31*5639Smckusic 	int fd, pv[2], pid;
322841Swnj 
33*5639Smckusic 	cp = (char *)(ADDR_LC);
34*5639Smckusic 	codesiz = ((struct pxhdr *)(cp))->objsize + sizeof(struct pxhdr);
35*5639Smckusic 	symtabsiz = ((struct pxhdr *)(cp))->symtabsize;
36*5639Smckusic 	if (argc > MAXARGS - 3)
37*5639Smckusic 		error(2, "Too many arguments.\n");
38*5639Smckusic 	if (symtabsiz != 0) {
39*5639Smckusic 		largv[0] = "pxhdr";
40*5639Smckusic 		largv[1] = "/tmp/px00000";
41*5639Smckusic 		cp = &largv[1][11];
42*5639Smckusic 		for (i = getpid(); i > 0; i /= 10)
43*5639Smckusic 			*cp-- = '0' + i % 10;
44*5639Smckusic 		fd = creat(largv[1], 0444);
45*5639Smckusic 		if (fd < 0)
46*5639Smckusic 			error(3, "Cannot create /tmp file\n");
47*5639Smckusic 		for (i = 0; i < argc; i++)
48*5639Smckusic 			largv[i + 2] = argv[i];
49*5639Smckusic 		largv[argc + 2] = 0;
50*5639Smckusic 		writeobj(fd, codesiz, symtabsiz);
51*5639Smckusic 		run(PX_DEBUG, largv);
52*5639Smckusic 		/* no return */
532841Swnj 	}
54*5639Smckusic 	largv[0] = "pipe";
55*5639Smckusic 	for (i = 0; i < argc; i++)
562841Swnj 		largv[i + 1] = argv[i];
572841Swnj 	largv[argc + 1] = 0;
582841Swnj 	pipe(pv);
59*5639Smckusic 	pid = fork();
60*5639Smckusic 	if (pid != 0) {
61*5639Smckusic 		if (pv[0] != 3) {
62*5639Smckusic 			close(3);
63*5639Smckusic 			dup(pv[0]);
64*5639Smckusic 			close(pv[0]);
652841Swnj 		}
66*5639Smckusic 		close(pv[1]);
67*5639Smckusic 		run(PX_INTRP, largv);
68*5639Smckusic 		/* no return */
692841Swnj 	}
70*5639Smckusic 	writeobj(pv[1], codesiz, symtabsiz);
71*5639Smckusic 	exit(0);
72*5639Smckusic }
73*5639Smckusic 
74*5639Smckusic writeobj(fd, codesiz, symtabsiz)
75*5639Smckusic 	int fd;
76*5639Smckusic 	int codesiz, symtabsiz;
77*5639Smckusic {
78*5639Smckusic 	int i;
79*5639Smckusic 	register char *cp;
80*5639Smckusic 
81*5639Smckusic 	cp = (char *)(ADDR_LC);
82*5639Smckusic 	while (codesiz != 0) {
83*5639Smckusic 		i = (codesiz < BUFSIZ) ? codesiz : BUFSIZ;
84*5639Smckusic 		write(fd, cp, i);
85*5639Smckusic 		cp += i;
86*5639Smckusic 		codesiz -= i;
872841Swnj 	}
88*5639Smckusic 	while (symtabsiz != 0) {
89*5639Smckusic 		i = (symtabsiz < BUFSIZ) ? symtabsiz : BUFSIZ;
90*5639Smckusic 		write(fd, cp, i);
91*5639Smckusic 		cp += i;
92*5639Smckusic 		symtabsiz -= i;
93*5639Smckusic 	}
94*5639Smckusic 	close(fd);
95*5639Smckusic }
96*5639Smckusic 
97*5639Smckusic run(prog, args)
98*5639Smckusic 	char *prog;
99*5639Smckusic 	char **args;
100*5639Smckusic {
1012841Swnj 	for (;;) {
102*5639Smckusic 		execv(prog, args);
1032841Swnj 		if (errno != ETXTBSY)
1042841Swnj 			break;
1052841Swnj 		sleep(2);
1062841Swnj 	}
107*5639Smckusic 	error(0, prog);
108*5639Smckusic 	error(1, " not found.\n");
1092841Swnj }
1102841Swnj 
111*5639Smckusic error(errcode, cp)
112*5639Smckusic 	int errcode;
1132841Swnj 	register char *cp;
1142841Swnj {
1152841Swnj 	register int i;
1162841Swnj 	register char *dp;
1172841Swnj 
1182841Swnj 	dp = cp;
1192841Swnj 	i = 0;
1202841Swnj 	while (*dp++)
1212841Swnj 		i++;
1222841Swnj 	write(2, cp, i);
123*5639Smckusic 	if (errcode)
124*5639Smckusic 		exit(errcode);
1252841Swnj }
1262841Swnj 
1272841Swnj exit(i)
1282841Swnj {
1292841Swnj 	_exit(i);
1302841Swnj }
131