15d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*
25d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Copyright (c) 1995 Danny Gasparovski.
35d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
45d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Please read the file COPYRIGHT for the
55d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * terms and conditions of the copyright.
65d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
75d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
85d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <slirp.h>
95d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneru_int curtime, time_fasttimo, last_slowtimo;
115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint x_port = -1;
145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint x_display = 0;
155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint x_screen = 0;
165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint
185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnershow_x(buff, inso)
195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	char *buff;
205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	struct socket *inso;
215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (x_port < 0) {
235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		lprint("X Redir: X not being redirected.\r\n");
245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else {
255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		lprint("X Redir: In sh/bash/zsh/etc. type: DISPLAY=%s:%d.%d; export DISPLAY\r\n",
265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		      inet_ntoa(our_addr), x_port, x_screen);
275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		lprint("X Redir: In csh/tcsh/etc. type:    setenv DISPLAY %s:%d.%d\r\n",
285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		      inet_ntoa(our_addr), x_port, x_screen);
295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (x_display)
305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		   lprint("X Redir: Redirecting to display %d\r\n", x_display);
315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	return CFG_OK;
345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*
385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * XXX Allow more than one X redirection?
395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid
415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerredir_x(inaddr, start_port, display, screen)
425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	u_int32_t inaddr;
435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	int start_port;
445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	int display;
455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	int screen;
465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	int i;
485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (x_port >= 0) {
505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		lprint("X Redir: X already being redirected.\r\n");
515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		show_x(0, 0);
525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else {
535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		for (i = 6001 + (start_port-1); i <= 6100; i++) {
545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			if (solisten(htons(i), inaddr, htons(6000 + display), 0)) {
555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner				/* Success */
565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner				x_port = i - 6000;
575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner				x_display = display;
585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner				x_screen = screen;
595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner				show_x(0, 0);
605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner				return;
615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			}
625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		lprint("X Redir: Error: Couldn't redirect a port for X. Weird.\r\n");
645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*
695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Get our IP address and put it in our_addr
705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid
725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnergetouraddr(void)
735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	char buff[256];
755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	struct hostent *he = NULL;
765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (gethostname(buff,256) == 0)
785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            he = gethostbyname(buff);
795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (he)
805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            our_addr = *(struct in_addr *)he->h_addr;
815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (our_addr.s_addr == 0)
825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            our_addr.s_addr = loopback_addr.s_addr;
835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct quehead {
865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	struct quehead *qh_link;
875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	struct quehead *qh_rlink;
885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerinline void
915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerinsque(void *a, void *b)
925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	register struct quehead *element = (struct quehead *) a;
945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	register struct quehead *head = (struct quehead *) b;
955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	element->qh_link = head->qh_link;
965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	head->qh_link = (struct quehead *)element;
975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	element->qh_rlink = (struct quehead *)head;
985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	((struct quehead *)(element->qh_link))->qh_rlink
995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	= (struct quehead *)element;
1005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerinline void
1035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerremque(void *a)
1045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  register struct quehead *element = (struct quehead *) a;
1065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  ((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink;
1075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  ((struct quehead *)(element->qh_rlink))->qh_link = element->qh_link;
1085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  element->qh_rlink = NULL;
1095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  /*  element->qh_link = NULL;  TCP FIN1 crashes if you do this.  Why ? */
1105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* #endif */
1135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint
1165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneradd_exec(struct ex_list **ex_ptr, int do_pty, char *exec, int addr, int port)
1175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	struct ex_list *tmp_ptr;
1195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	/* First, check if the port is "bound" */
1215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	for (tmp_ptr = *ex_ptr; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) {
1225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (port == tmp_ptr->ex_fport && addr == tmp_ptr->ex_addr)
1235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		   return -1;
1245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
1255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	tmp_ptr = *ex_ptr;
1275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	*ex_ptr = (struct ex_list *)malloc(sizeof(struct ex_list));
1285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	(*ex_ptr)->ex_fport = port;
1295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	(*ex_ptr)->ex_addr = addr;
1305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	(*ex_ptr)->ex_pty = do_pty;
1315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	(*ex_ptr)->ex_exec = (do_pty == 3) ? exec : strdup(exec);
1325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	(*ex_ptr)->ex_next = tmp_ptr;
1335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	return 0;
1345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef HAVE_STRERROR
1375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*
1395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * For systems with no strerror
1405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
1415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerextern int sys_nerr;
1435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerextern char *sys_errlist[];
1445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerchar *
1465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstrerror(error)
1475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	int error;
1485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (error < sys_nerr)
1505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	   return sys_errlist[error];
1515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	else
1525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	   return "Unknown error.";
1535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32
1595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint
1615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerfork_exec(struct socket *so, const char *ex, int do_pty)
1625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* not implemented */
1645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
1655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
1685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef CONFIG_QEMU
1705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint
1715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerslirp_openpty(amaster, aslave)
1725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     int *amaster, *aslave;
1735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	register int master, slave;
1755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef HAVE_GRANTPT
1775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	char *ptr;
1785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if ((master = open("/dev/ptmx", O_RDWR)) < 0 ||
1805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    grantpt(master) < 0 ||
1815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    unlockpt(master) < 0 ||
1825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    (ptr = ptsname(master)) == NULL)  {
1835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		close(master);
1845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		return -1;
1855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
1865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if ((slave = open(ptr, O_RDWR)) < 0 ||
1885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    ioctl(slave, I_PUSH, "ptem") < 0 ||
1895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    ioctl(slave, I_PUSH, "ldterm") < 0 ||
1905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    ioctl(slave, I_PUSH, "ttcompat") < 0) {
1915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		close(master);
1925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		close(slave);
1935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		return -1;
1945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
1955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	*amaster = master;
1975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	*aslave = slave;
1985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	return 0;
1995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
2015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	static char line[] = "/dev/ptyXX";
2035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	register const char *cp1, *cp2;
2045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	for (cp1 = "pqrsPQRS"; *cp1; cp1++) {
2065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		line[8] = *cp1;
2075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		for (cp2 = "0123456789abcdefghijklmnopqrstuv"; *cp2; cp2++) {
2085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			line[9] = *cp2;
2095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			if ((master = open(line, O_RDWR, 0)) == -1) {
2105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner				if (errno == ENOENT)
2115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner				   return (-1);    /* out of ptys */
2125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			} else {
2135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner				line[5] = 't';
2145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner				/* These will fail */
2155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner				(void) chown(line, getuid(), 0);
2165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner				(void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP);
2175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef HAVE_REVOKE
2185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner				(void) revoke(line);
2195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner				if ((slave = open(line, O_RDWR, 0)) != -1) {
2215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner					*amaster = master;
2225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner					*aslave = slave;
2235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner					return 0;
2245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner				}
2255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner				(void) close(master);
2265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner				line[5] = 'p';
2275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			}
2285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
2295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
2305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	errno = ENOENT; /* out of ptys */
2315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	return (-1);
2325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
2345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*
2375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * XXX This is ugly
2385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * We create and bind a socket, then fork off to another
2395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * process, which connects to this socket, after which we
2405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * exec the wanted program.  If something (strange) happens,
2415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * the accept() call could block us forever.
2425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
2435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * do_pty = 0   Fork/exec inetd style
2445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * do_pty = 1   Fork/exec using slirp.telnetd
2455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * do_ptr = 2   Fork/exec using pty
2465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
2475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint
2485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerfork_exec(struct socket *so, const char *ex, int do_pty)
2495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
2505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	int s;
2515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	struct sockaddr_in addr;
2525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	socklen_t addrlen = sizeof(addr);
2535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	int opt;
2545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int master = -1;
2555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	const char *argv[256];
2565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
2575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	char buff[256];
2585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	/* don't want to clobber the original */
2605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	char *bptr;
2615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	const char *curarg;
2625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	int c, i, ret;
2635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	DEBUG_CALL("fork_exec");
2655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	DEBUG_ARG("so = %lx", (long)so);
2665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	DEBUG_ARG("ex = %lx", (long)ex);
2675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	DEBUG_ARG("do_pty = %lx", (long)do_pty);
2685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (do_pty == 2) {
2705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
2715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (slirp_openpty(&master, &s) == -1) {
2725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			lprint("Error: openpty failed: %s\n", strerror(errno));
2735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			return 0;
2745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
2755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
2765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                return 0;
2775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else {
2795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		addr.sin_family = AF_INET;
2805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		addr.sin_port = 0;
2815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		addr.sin_addr.s_addr = INADDR_ANY;
2825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0 ||
2845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		    bind(s, (struct sockaddr *)&addr, addrlen) < 0 ||
2855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		    listen(s, 1) < 0) {
2865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			lprint("Error: inet socket: %s\n", strerror(errno));
2875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			closesocket(s);
2885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			return 0;
2905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
2915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
2925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	switch(fork()) {
2945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	 case -1:
2955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		lprint("Error: fork failed: %s\n", strerror(errno));
2965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		close(s);
2975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (do_pty == 2)
2985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		   close(master);
2995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		return 0;
3005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	 case 0:
3025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		/* Set the DISPLAY */
3035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (do_pty == 2) {
3045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			(void) close(master);
3055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TIOCSCTTY /* XXXXX */
3065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			(void) setsid();
3075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			ioctl(s, TIOCSCTTY, (char *)NULL);
3085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
3095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		} else {
3105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			getsockname(s, (struct sockaddr *)&addr, &addrlen);
3115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			close(s);
3125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			/*
3135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			 * Connect to the socket
3145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			 * XXX If any of these fail, we're in trouble!
3155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	 		 */
3165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			s = socket(AF_INET, SOCK_STREAM, 0);
3175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			addr.sin_addr = loopback_addr;
3185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        do {
3195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            ret = connect(s, (struct sockaddr *)&addr, addrlen);
3205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        } while (ret < 0 && errno == EINTR);
3215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
3225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
3245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (x_port >= 0) {
3255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef HAVE_SETENV
3265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
3275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			setenv("DISPLAY", buff, 1);
3285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
3295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
3305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			putenv(buff);
3315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
3325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
3335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
3345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		dup2(s, 0);
3355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		dup2(s, 1);
3365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		dup2(s, 2);
3375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		for (s = getdtablesize() - 1; s >= 3; s--)
3385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		   close(s);
3395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		i = 0;
3415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		bptr = strdup(ex); /* No need to free() this */
3425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (do_pty == 1) {
3435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			/* Setup "slirp.telnetd -x" */
3445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			argv[i++] = "slirp.telnetd";
3455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			argv[i++] = "-x";
3465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			argv[i++] = bptr;
3475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		} else
3485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		   do {
3495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			/* Change the string into argv[] */
3505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			curarg = bptr;
3515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			while (*bptr != ' ' && *bptr != (char)0)
3525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			   bptr++;
3535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			c = *bptr;
3545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			*bptr++ = (char)0;
3555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			argv[i++] = strdup(curarg);
3565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		   } while (c);
3575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                argv[i] = NULL;
3595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		execvp(argv[0], (char **)argv);
3605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		/* Ooops, failed, let's tell the user why */
3625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		  {
3635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			  char buff[256];
3645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			  snprintf(buff, sizeof(buff),
3665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                   "Error: execvp of %s failed: %s\n",
3675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                   argv[0], strerror(errno));
3685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			  write(2, buff, strlen(buff)+1);
3695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		  }
3705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		close(0); close(1); close(2); /* XXX */
3715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		exit(1);
3725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	 default:
3745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (do_pty == 2) {
3755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			close(s);
3765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			so->s = master;
3775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		} else {
3785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			/*
3795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			 * XXX this could block us...
3805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			 * XXX Should set a timer here, and if accept() doesn't
3815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		 	 * return after X seconds, declare it a failure
3825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		 	 * The only reason this will block forever is if socket()
3835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		 	 * of connect() fail in the child process
3845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		 	 */
3855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        do {
3865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            so->s = accept(s, (struct sockaddr *)&addr, &addrlen);
3875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        } while (so->s < 0 && errno == EINTR);
3885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        closesocket(s);
3895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			opt = 1;
3905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int));
3915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			opt = 1;
3925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
3935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
3945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		fd_nonblock(so->s);
3955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		/* Append the telnet options now */
3975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (so->so_m != NULL && do_pty == 1)  {
3985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			sbappend(so, so->so_m);
3995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        so->so_m = NULL;
4005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
4015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		return 1;
4035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
4045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
4065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef HAVE_STRDUP
4085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerchar *
4095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstrdup(str)
4105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	const char *str;
4115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	char *bptr;
4135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	bptr = (char *)malloc(strlen(str)+1);
4155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	strcpy(bptr, str);
4165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	return bptr;
4185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
4205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
4225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid
4235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnersnooze_hup(num)
4245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	int num;
4255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	int s, ret;
4275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef NO_UNIX_SOCKETS
4285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	struct sockaddr_un sock_un;
4295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
4305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	struct sockaddr_in sock_in;
4315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	char buff[256];
4325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	ret = -1;
4345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (slirp_socket_passwd) {
4355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		s = socket(AF_INET, SOCK_STREAM, 0);
4365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (s < 0)
4375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		   slirp_exit(1);
4385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		sock_in.sin_family = AF_INET;
4395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		sock_in.sin_addr.s_addr = slirp_socket_addr;
4405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		sock_in.sin_port = htons(slirp_socket_port);
4415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (connect(s, (struct sockaddr *)&sock_in, sizeof(sock_in)) != 0)
4425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		   slirp_exit(1); /* just exit...*/
4435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		sprintf(buff, "kill %s:%d", slirp_socket_passwd, slirp_socket_unit);
4445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		write(s, buff, strlen(buff)+1);
4455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
4465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef NO_UNIX_SOCKETS
4475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	  else {
4485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		s = socket(AF_UNIX, SOCK_STREAM, 0);
4495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (s < 0)
4505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		   slirp_exit(1);
4515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		sock_un.sun_family = AF_UNIX;
4525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		strcpy(sock_un.sun_path, socket_path);
4535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (connect(s, (struct sockaddr *)&sock_un,
4545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			      sizeof(sock_un.sun_family) + sizeof(sock_un.sun_path)) != 0)
4555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		   slirp_exit(1);
4565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		sprintf(buff, "kill none:%d", slirp_socket_unit);
4575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		write(s, buff, strlen(buff)+1);
4585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
4595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
4605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	slirp_exit(0);
4615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid
4655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnersnooze()
4665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	sigset_t s;
4685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	int i;
4695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	/* Don't need our data anymore */
4715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	/* XXX This makes SunOS barf */
4725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*	brk(0); */
4735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	/* Close all fd's */
4755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	for (i = 255; i >= 0; i--)
4765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	   close(i);
4775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	signal(SIGQUIT, slirp_exit);
4795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	signal(SIGHUP, snooze_hup);
4805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	sigemptyset(&s);
4815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	/* Wait for any signal */
4835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	sigsuspend(&s);
4845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	/* Just in case ... */
4865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	exit(255);
4875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid
4905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerrelay(s)
4915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	int s;
4925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	char buf[8192];
4945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	int n;
4955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	fd_set readfds;
4965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	struct ttys *ttyp;
4975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	/* Don't need our data anymore */
4995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	/* XXX This makes SunOS barf */
5005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*	brk(0); */
5015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	signal(SIGQUIT, slirp_exit);
5035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	signal(SIGHUP, slirp_exit);
5045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        signal(SIGINT, slirp_exit);
5055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	signal(SIGTERM, slirp_exit);
5065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	/* Fudge to get term_raw and term_restore to work */
5085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (NULL == (ttyp = tty_attach (0, slirp_tty))) {
5095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         lprint ("Error: tty_attach failed in misc.c:relay()\r\n");
5105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         slirp_exit (1);
5115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
5125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	ttyp->fd = 0;
5135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	ttyp->flags |= TTY_CTTY;
5145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	term_raw(ttyp);
5155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	while (1) {
5175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		FD_ZERO(&readfds);
5185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		FD_SET(0, &readfds);
5205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		FD_SET(s, &readfds);
5215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		n = select(s+1, &readfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0);
5235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (n <= 0)
5255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		   slirp_exit(0);
5265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (FD_ISSET(0, &readfds)) {
5285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			n = read(0, buf, 8192);
5295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			if (n <= 0)
5305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			   slirp_exit(0);
5315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			n = writen(s, buf, n);
5325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			if (n <= 0)
5335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			   slirp_exit(0);
5345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
5355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (FD_ISSET(s, &readfds)) {
5375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			n = read(s, buf, 8192);
5385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			if (n <= 0)
5395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			   slirp_exit(0);
5405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			n = writen(0, buf, n);
5415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			if (n <= 0)
5425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			   slirp_exit(0);
5435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
5445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
5455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	/* Just in case.... */
5475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	exit(1);
5485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
5505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_QEMU
5525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "monitor.h"
5535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid lprint(const char *format, ...)
5555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    va_list args;
5575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    va_start(args, format);
5595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    monitor_vprintf(cur_mon, format, args);
5605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    va_end(args);
5615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
5635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint (*lprint_print) _P((void *, const char *, va_list));
5645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerchar *lprint_ptr, *lprint_ptr2, **lprint_arg;
5655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid
5675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef __STDC__
5685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerlprint(const char *format, ...)
5695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
5705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerlprint(va_alist) va_dcl
5715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
5725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	va_list args;
5745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef __STDC__
5765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        va_start(args, format);
5775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
5785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        char *format;
5795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        va_start(args);
5805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        format = va_arg(args, char *);
5815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
5825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
5835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	/* If we're printing to an sbuf, make sure there's enough room */
5845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	/* XXX +100? */
5855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (lprint_sb) {
5865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if ((lprint_ptr - lprint_sb->sb_wptr) >=
5875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		    (lprint_sb->sb_datalen - (strlen(format) + 100))) {
5885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			int deltaw = lprint_sb->sb_wptr - lprint_sb->sb_data;
5895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			int deltar = lprint_sb->sb_rptr - lprint_sb->sb_data;
5905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			int deltap = lprint_ptr -         lprint_sb->sb_data;
5915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			lprint_sb->sb_data = (char *)realloc(lprint_sb->sb_data,
5935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner							     lprint_sb->sb_datalen + TCP_SNDSPACE);
5945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			/* Adjust all values */
5965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			lprint_sb->sb_wptr = lprint_sb->sb_data + deltaw;
5975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			lprint_sb->sb_rptr = lprint_sb->sb_data + deltar;
5985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			lprint_ptr =         lprint_sb->sb_data + deltap;
5995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			lprint_sb->sb_datalen += TCP_SNDSPACE;
6015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
6025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
6035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
6045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (lprint_print)
6055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	   lprint_ptr += (*lprint_print)(*lprint_arg, format, args);
6065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	/* Check if they want output to be logged to file as well */
6085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (lfd) {
6095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		/*
6105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		 * Remove \r's
6115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		 * otherwise you'll get ^M all over the file
6125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		 */
6135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		int len = strlen(format);
6145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		char *bptr1, *bptr2;
6155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		bptr1 = bptr2 = strdup(format);
6175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		while (len--) {
6195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			if (*bptr1 == '\r')
6205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			   memcpy(bptr1, bptr1+1, len+1);
6215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			else
6225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			   bptr1++;
6235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
6245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		vfprintf(lfd, bptr2, args);
6255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		free(bptr2);
6265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
6275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	va_end(args);
6285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
6295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid
6315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneradd_emu(buff)
6325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	char *buff;
6335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
6345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	u_int lport, fport;
6355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	u_int8_t tos = 0, emu = 0;
6365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	char buff1[256], buff2[256], buff4[128];
6375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	char *buff3 = buff4;
6385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	struct emu_t *emup;
6395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	struct socket *so;
6405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (sscanf(buff, "%256s %256s", buff2, buff1) != 2) {
6425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		lprint("Error: Bad arguments\r\n");
6435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		return;
6445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
6455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (sscanf(buff1, "%d:%d", &lport, &fport) != 2) {
6475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		lport = 0;
6485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (sscanf(buff1, "%d", &fport) != 1) {
6495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			lprint("Error: Bad first argument\r\n");
6505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			return;
6515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
6525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
6535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (sscanf(buff2, "%128[^:]:%128s", buff1, buff3) != 2) {
6555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		buff3 = 0;
6565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (sscanf(buff2, "%256s", buff1) != 1) {
6575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			lprint("Error: Bad second argument\r\n");
6585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			return;
6595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
6605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
6615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (buff3) {
6635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (strcmp(buff3, "lowdelay") == 0)
6645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		   tos = IPTOS_LOWDELAY;
6655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		else if (strcmp(buff3, "throughput") == 0)
6665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		   tos = IPTOS_THROUGHPUT;
6675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		else {
6685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			lprint("Error: Expecting \"lowdelay\"/\"throughput\"\r\n");
6695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			return;
6705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
6715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
6725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (strcmp(buff1, "ftp") == 0)
6745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	   emu = EMU_FTP;
6755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	else if (strcmp(buff1, "irc") == 0)
6765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	   emu = EMU_IRC;
6775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	else if (strcmp(buff1, "none") == 0)
6785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	   emu = EMU_NONE; /* ie: no emulation */
6795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	else {
6805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		lprint("Error: Unknown service\r\n");
6815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		return;
6825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
6835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	/* First, check that it isn't already emulated */
6855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	for (emup = tcpemu; emup; emup = emup->next) {
6865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (emup->lport == lport && emup->fport == fport) {
6875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			lprint("Error: port already emulated\r\n");
6885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			return;
6895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
6905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
6915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	/* link it */
6935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	emup = (struct emu_t *)malloc(sizeof (struct emu_t));
6945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	emup->lport = (u_int16_t)lport;
6955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	emup->fport = (u_int16_t)fport;
6965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	emup->tos = tos;
6975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	emup->emu = emu;
6985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	emup->next = tcpemu;
6995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	tcpemu = emup;
7005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	/* And finally, mark all current sessions, if any, as being emulated */
7025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	for (so = tcb.so_next; so != &tcb; so = so->so_next) {
7035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if ((lport && lport == ntohs(so->so_lport)) ||
7045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		    (fport && fport == ntohs(so->so_fport))) {
7055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			if (emu)
7065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			   so->so_emu = emu;
7075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			if (tos)
7085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			   so->so_iptos = tos;
7095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
7105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
7115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	lprint("Adding emulation for %s to port %d/%d\r\n", buff1, emup->lport, emup->fport);
7135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
7145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
7155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef BAD_SPRINTF
7175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef vsprintf
7195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef sprintf
7205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*
7225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Some BSD-derived systems have a sprintf which returns char *
7235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
7245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint
7265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervsprintf_len(string, format, args)
7275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	char *string;
7285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	const char *format;
7295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	va_list args;
7305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	vsprintf(string, format, args);
7325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	return strlen(string);
7335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
7345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint
7365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef __STDC__
7375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnersprintf_len(char *string, const char *format, ...)
7385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
7395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnersprintf_len(va_alist) va_dcl
7405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
7415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	va_list args;
7435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef __STDC__
7445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	va_start(args, format);
7455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
7465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	char *string;
7475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	char *format;
7485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	va_start(args);
7495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	string = va_arg(args, char *);
7505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	format = va_arg(args, char *);
7515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
7525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	vsprintf(string, format, args);
7535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	return strlen(string);
7545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
7555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
7575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid
7595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneru_sleep(int usec)
7605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	struct timeval t;
7625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	fd_set fdset;
7635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	FD_ZERO(&fdset);
7655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	t.tv_sec = 0;
7675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	t.tv_usec = usec * 1000;
7685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	select(0, &fdset, &fdset, &fdset, &t);
7705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
7715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*
7735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Set fd blocking and non-blocking
7745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
7755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid
7775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerfd_nonblock(int fd)
7785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef FIONBIO
7805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32
7815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        unsigned long opt = 1;
7825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
7835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int opt = 1;
7845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
7855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	ioctlsocket(fd, FIONBIO, &opt);
7875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
7885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	int opt;
7895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	opt = fcntl(fd, F_GETFL, 0);
7915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	opt |= O_NONBLOCK;
7925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	fcntl(fd, F_SETFL, opt);
7935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
7945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
7955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid
7975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerfd_block(int fd)
7985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef FIONBIO
8005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32
8015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        unsigned long opt = 0;
8025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
8035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	int opt = 0;
8045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
8055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	ioctlsocket(fd, FIONBIO, &opt);
8075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
8085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	int opt;
8095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	opt = fcntl(fd, F_GETFL, 0);
8115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	opt &= ~O_NONBLOCK;
8125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	fcntl(fd, F_SETFL, opt);
8135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
8145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
8155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
8185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*
8195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * invoke RSH
8205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
8215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint
8225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerrsh_exec(so,ns, user, host, args)
8235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	struct socket *so;
8245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	struct socket *ns;
8255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	char *user;
8265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	char *host;
8275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	char *args;
8285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
8295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	int fd[2];
8305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	int fd0[2];
8315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	int s;
8325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	char buff[256];
8335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	DEBUG_CALL("rsh_exec");
8355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	DEBUG_ARG("so = %lx", (long)so);
8365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (pipe(fd)<0) {
8385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner          lprint("Error: pipe failed: %s\n", strerror(errno));
8395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner          return 0;
8405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
8415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* #ifdef HAVE_SOCKETPAIR */
8425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 1
8435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (socketpair(PF_UNIX,SOCK_STREAM,0, fd0) == -1) {
8445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner          close(fd[0]);
8455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner          close(fd[1]);
8465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner          lprint("Error: openpty failed: %s\n", strerror(errno));
8475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner          return 0;
8485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
8495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
8505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (slirp_openpty(&fd0[0], &fd0[1]) == -1) {
8515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner          close(fd[0]);
8525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner          close(fd[1]);
8535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner          lprint("Error: openpty failed: %s\n", strerror(errno));
8545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner          return 0;
8555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
8565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
8575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	switch(fork()) {
8595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	 case -1:
8605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           lprint("Error: fork failed: %s\n", strerror(errno));
8615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           close(fd[0]);
8625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           close(fd[1]);
8635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           close(fd0[0]);
8645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           close(fd0[1]);
8655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           return 0;
8665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	 case 0:
8685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           close(fd[0]);
8695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           close(fd0[0]);
8705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		/* Set the DISPLAY */
8725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           if (x_port >= 0) {
8735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef HAVE_SETENV
8745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner             sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
8755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner             setenv("DISPLAY", buff, 1);
8765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
8775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner             sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
8785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner             putenv(buff);
8795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
8805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           }
8815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           dup2(fd0[1], 0);
8835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           dup2(fd0[1], 1);
8845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           dup2(fd[1], 2);
8855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           for (s = 3; s <= 255; s++)
8865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner             close(s);
8875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           execlp("rsh","rsh","-l", user, host, args, NULL);
8895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           /* Ooops, failed, let's tell the user why */
8915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           sprintf(buff, "Error: execlp of %s failed: %s\n",
8935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                   "rsh", strerror(errno));
8945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           write(2, buff, strlen(buff)+1);
8955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           close(0); close(1); close(2); /* XXX */
8965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           exit(1);
8975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default:
8995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner          close(fd[1]);
9005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner          close(fd0[1]);
9015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner          ns->s=fd[0];
9025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner          so->s=fd0[0];
9035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner          return 1;
9055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
9065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
9075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
908