12841Swnj /*
2*22264Sdist  * Copyright (c) 1980 Regents of the University of California.
3*22264Sdist  * All rights reserved.  The Berkeley software License Agreement
4*22264Sdist  * specifies the terms and conditions for redistribution.
5*22264Sdist  */
6*22264Sdist 
7*22264Sdist #ifndef lint
8*22264Sdist char copyright[] =
9*22264Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\
10*22264Sdist  All rights reserved.\n";
11*22264Sdist #endif not lint
12*22264Sdist 
13*22264Sdist #ifndef lint
14*22264Sdist static char sccsid[] = "@(#)px_header.c	5.1 (Berkeley) 06/05/85";
15*22264Sdist #endif not lint
16*22264Sdist 
17*22264Sdist /*
182841Swnj  * pxheader - program to sit in front of interpreter code to make shell mods
192841Swnj  *	      unnecessary to make Pascal obj's look like real programs.
202841Swnj  *
212841Swnj  * This program lives in /usr/lib/px_header
222841Swnj  * Bill Joy UCB February 6, 1978
232841Swnj  */
242841Swnj 
25*22264Sdist static char sccsid[] = "@(#)px_header.c 5.1 06/05/85";
262841Swnj 
272948Smckusic #include <stdio.h>
282948Smckusic #include <sys/types.h>
292948Smckusic #include <a.out.h>
3010571Smckusick #include "config.h"
312948Smckusic #include "whoami.h"
322948Smckusic #include "objfmt.h"
332948Smckusic 
342841Swnj #define	ETXTBSY	26
3511879Smckusick #define	ADDR_LC \
3611879Smckusick 	(START + HEADER_BYTES - sizeof (struct exec) - sizeof (struct pxhdr))
375639Smckusic #define MAXARGS 512
382841Swnj 
392948Smckusic extern	errno;
402948Smckusic 
412841Swnj main(argc, argv)
422841Swnj 	register int argc;
432841Swnj 	register char *argv[];
442841Swnj {
455639Smckusic 	register int i;
465639Smckusic 	int codesiz, symtabsiz;
475639Smckusic 	register char *cp;
485639Smckusic 	char *largv[MAXARGS];
495639Smckusic 	int fd, pv[2], pid;
502841Swnj 
515639Smckusic 	cp = (char *)(ADDR_LC);
525639Smckusic 	codesiz = ((struct pxhdr *)(cp))->objsize + sizeof(struct pxhdr);
535639Smckusic 	symtabsiz = ((struct pxhdr *)(cp))->symtabsize;
545639Smckusic 	if (argc > MAXARGS - 3)
555639Smckusic 		error(2, "Too many arguments.\n");
565639Smckusic 	if (symtabsiz != 0) {
575639Smckusic 		largv[0] = "pxhdr";
585639Smckusic 		largv[1] = "/tmp/px00000";
595639Smckusic 		cp = &largv[1][11];
605639Smckusic 		for (i = getpid(); i > 0; i /= 10)
615639Smckusic 			*cp-- = '0' + i % 10;
625639Smckusic 		fd = creat(largv[1], 0444);
635639Smckusic 		if (fd < 0)
645639Smckusic 			error(3, "Cannot create /tmp file\n");
655639Smckusic 		for (i = 0; i < argc; i++)
665639Smckusic 			largv[i + 2] = argv[i];
675639Smckusic 		largv[argc + 2] = 0;
685639Smckusic 		writeobj(fd, codesiz, symtabsiz);
6910571Smckusick 		run(px_debug, largv);
705639Smckusic 		/* no return */
712841Swnj 	}
725639Smckusic 	largv[0] = "pipe";
735639Smckusic 	for (i = 0; i < argc; i++)
742841Swnj 		largv[i + 1] = argv[i];
752841Swnj 	largv[argc + 1] = 0;
762841Swnj 	pipe(pv);
775639Smckusic 	pid = fork();
785639Smckusic 	if (pid != 0) {
795639Smckusic 		if (pv[0] != 3) {
805639Smckusic 			close(3);
815639Smckusic 			dup(pv[0]);
825639Smckusic 			close(pv[0]);
832841Swnj 		}
845639Smckusic 		close(pv[1]);
8510571Smckusick 		run(px_intrp, largv);
865639Smckusic 		/* no return */
872841Swnj 	}
885639Smckusic 	writeobj(pv[1], codesiz, symtabsiz);
895639Smckusic 	exit(0);
905639Smckusic }
915639Smckusic 
925639Smckusic writeobj(fd, codesiz, symtabsiz)
935639Smckusic 	int fd;
945639Smckusic 	int codesiz, symtabsiz;
955639Smckusic {
965639Smckusic 	int i;
975639Smckusic 	register char *cp;
985639Smckusic 
995639Smckusic 	cp = (char *)(ADDR_LC);
1005639Smckusic 	while (codesiz != 0) {
1015639Smckusic 		i = (codesiz < BUFSIZ) ? codesiz : BUFSIZ;
1025639Smckusic 		write(fd, cp, i);
1035639Smckusic 		cp += i;
1045639Smckusic 		codesiz -= i;
1052841Swnj 	}
1065639Smckusic 	while (symtabsiz != 0) {
1075639Smckusic 		i = (symtabsiz < BUFSIZ) ? symtabsiz : BUFSIZ;
1085639Smckusic 		write(fd, cp, i);
1095639Smckusic 		cp += i;
1105639Smckusic 		symtabsiz -= i;
1115639Smckusic 	}
1125639Smckusic 	close(fd);
1135639Smckusic }
1145639Smckusic 
1155639Smckusic run(prog, args)
1165639Smckusic 	char *prog;
1175639Smckusic 	char **args;
1185639Smckusic {
1192841Swnj 	for (;;) {
1205639Smckusic 		execv(prog, args);
1212841Swnj 		if (errno != ETXTBSY)
1222841Swnj 			break;
1232841Swnj 		sleep(2);
1242841Swnj 	}
1255639Smckusic 	error(0, prog);
1265639Smckusic 	error(1, " not found.\n");
1272841Swnj }
1282841Swnj 
1295639Smckusic error(errcode, cp)
1305639Smckusic 	int errcode;
1312841Swnj 	register char *cp;
1322841Swnj {
1332841Swnj 	register int i;
1342841Swnj 	register char *dp;
1352841Swnj 
1362841Swnj 	dp = cp;
1372841Swnj 	i = 0;
1382841Swnj 	while (*dp++)
1392841Swnj 		i++;
1402841Swnj 	write(2, cp, i);
1415639Smckusic 	if (errcode)
1425639Smckusic 		exit(errcode);
1432841Swnj }
1442841Swnj 
1452841Swnj exit(i)
1462841Swnj {
1472841Swnj 	_exit(i);
1482841Swnj }
149