1 /*
2  * pxheader - program to sit in front of interpreter code to make shell mods
3  *	      unnecessary to make Pascal obj's look like real programs.
4  *
5  * This program lives in /usr/lib/px_header
6  * Bill Joy UCB February 6, 1978
7  */
8 
9 static char sccsid[] = "@(#)px_header.c 1.3 02/01/82";
10 
11 #include <stdio.h>
12 #include <sys/types.h>
13 #include <a.out.h>
14 #include "whoami.h"
15 #include "objfmt.h"
16 
17 #define	ETXTBSY	26
18 #define	ADDR_LC	HEADER_BYTES - sizeof (struct exec) - sizeof (struct pxhdr)
19 #define MAXARGS 512
20 
21 extern	errno;
22 
23 main(argc, argv)
24 	register int argc;
25 	register char *argv[];
26 {
27 	register int i;
28 	int codesiz, symtabsiz;
29 	register char *cp;
30 	char *largv[MAXARGS];
31 	int fd, pv[2], pid;
32 
33 	cp = (char *)(ADDR_LC);
34 	codesiz = ((struct pxhdr *)(cp))->objsize + sizeof(struct pxhdr);
35 	symtabsiz = ((struct pxhdr *)(cp))->symtabsize;
36 	if (argc > MAXARGS - 3)
37 		error(2, "Too many arguments.\n");
38 	if (symtabsiz != 0) {
39 		largv[0] = "pxhdr";
40 		largv[1] = "/tmp/px00000";
41 		cp = &largv[1][11];
42 		for (i = getpid(); i > 0; i /= 10)
43 			*cp-- = '0' + i % 10;
44 		fd = creat(largv[1], 0444);
45 		if (fd < 0)
46 			error(3, "Cannot create /tmp file\n");
47 		for (i = 0; i < argc; i++)
48 			largv[i + 2] = argv[i];
49 		largv[argc + 2] = 0;
50 		writeobj(fd, codesiz, symtabsiz);
51 		run(PX_DEBUG, largv);
52 		/* no return */
53 	}
54 	largv[0] = "pipe";
55 	for (i = 0; i < argc; i++)
56 		largv[i + 1] = argv[i];
57 	largv[argc + 1] = 0;
58 	pipe(pv);
59 	pid = fork();
60 	if (pid != 0) {
61 		if (pv[0] != 3) {
62 			close(3);
63 			dup(pv[0]);
64 			close(pv[0]);
65 		}
66 		close(pv[1]);
67 		run(PX_INTRP, largv);
68 		/* no return */
69 	}
70 	writeobj(pv[1], codesiz, symtabsiz);
71 	exit(0);
72 }
73 
74 writeobj(fd, codesiz, symtabsiz)
75 	int fd;
76 	int codesiz, symtabsiz;
77 {
78 	int i;
79 	register char *cp;
80 
81 	cp = (char *)(ADDR_LC);
82 	while (codesiz != 0) {
83 		i = (codesiz < BUFSIZ) ? codesiz : BUFSIZ;
84 		write(fd, cp, i);
85 		cp += i;
86 		codesiz -= i;
87 	}
88 	while (symtabsiz != 0) {
89 		i = (symtabsiz < BUFSIZ) ? symtabsiz : BUFSIZ;
90 		write(fd, cp, i);
91 		cp += i;
92 		symtabsiz -= i;
93 	}
94 	close(fd);
95 }
96 
97 run(prog, args)
98 	char *prog;
99 	char **args;
100 {
101 	for (;;) {
102 		execv(prog, args);
103 		if (errno != ETXTBSY)
104 			break;
105 		sleep(2);
106 	}
107 	error(0, prog);
108 	error(1, " not found.\n");
109 }
110 
111 error(errcode, cp)
112 	int errcode;
113 	register char *cp;
114 {
115 	register int i;
116 	register char *dp;
117 
118 	dp = cp;
119 	i = 0;
120 	while (*dp++)
121 		i++;
122 	write(2, cp, i);
123 	if (errcode)
124 		exit(errcode);
125 }
126 
127 exit(i)
128 {
129 	_exit(i);
130 }
131