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