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