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