fork_exec(struct socket *so, const char *ex, int do_pty)

{

	int s;

	struct sockaddr_in addr;

	int addrlen = sizeof(addr);

	int opt;

        int master = -1;

	char *argv[256];

#if 0

	char buff[256];

#endif

	/* don't want to clobber the original */

	char *bptr;

	const char *curarg;

	int c, i, ret;



	DEBUG_CALL("fork_exec");

	DEBUG_ARG("so = %lx", (long)so);

	DEBUG_ARG("ex = %lx", (long)ex);

	DEBUG_ARG("do_pty = %lx", (long)do_pty);



	if (do_pty == 2) {

#if 0

		if (slirp_openpty(&master, &s) == -1) {

			lprint("Error: openpty failed: %s\n", strerror(errno));

			return 0;

		}

#else

                return 0;

#endif

	} else {

		addr.sin_family = AF_INET;

		addr.sin_port = 0;

		addr.sin_addr.s_addr = INADDR_ANY;



		if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0 ||

		    bind(s, (struct sockaddr *)&addr, addrlen) < 0 ||

		    listen(s, 1) < 0) {

			lprint("Error: inet socket: %s\n", strerror(errno));

			closesocket(s);



			return 0;

		}

	}



	switch(fork()) {

	 case -1:

		lprint("Error: fork failed: %s\n", strerror(errno));

		close(s);

		if (do_pty == 2)

		   close(master);

		return 0;



	 case 0:

		/* Set the DISPLAY */

		if (do_pty == 2) {

			(void) close(master);

#ifdef TIOCSCTTY /* XXXXX */

			(void) setsid();

			ioctl(s, TIOCSCTTY, (char *)NULL);

#endif

		} else {

			getsockname(s, (struct sockaddr *)&addr, &addrlen);

			close(s);

			/*

			 * Connect to the socket

			 * XXX If any of these fail, we're in trouble!

	 		 */

			s = socket(AF_INET, SOCK_STREAM, 0);

			addr.sin_addr = loopback_addr;

                        do {

                            ret = connect(s, (struct sockaddr *)&addr, addrlen);

                        } while (ret < 0 && errno == EINTR);

		}



#if 0

		if (x_port >= 0) {

#ifdef HAVE_SETENV

			sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);

			setenv("DISPLAY", buff, 1);

#else

			sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);

			putenv(buff);

#endif

		}

#endif

		dup2(s, 0);

		dup2(s, 1);

		dup2(s, 2);

		for (s = getdtablesize() - 1; s >= 3; s--)

		   close(s);



		i = 0;

		bptr = strdup(ex); /* No need to free() this */

		if (do_pty == 1) {

			/* Setup "slirp.telnetd -x" */

			argv[i++] = "slirp.telnetd";

			argv[i++] = "-x";

			argv[i++] = bptr;

		} else

		   do {

			/* Change the string into argv[] */

			curarg = bptr;

			while (*bptr != ' ' && *bptr != (char)0)

			   bptr++;

			c = *bptr;

			*bptr++ = (char)0;

			argv[i++] = strdup(curarg);

		   } while (c);



		argv[i] = 0;

		execvp(argv[0], argv);



		/* Ooops, failed, let's tell the user why */

		  {

			  char buff[256];



			  sprintf(buff, "Error: execvp of %s failed: %s\n",

				  argv[0], strerror(errno));

			  write(2, buff, strlen(buff)+1);

		  }

		close(0); close(1); close(2); /* XXX */

		exit(1);



	 default:

		if (do_pty == 2) {

			close(s);

			so->s = master;

		} else {

			/*

			 * XXX this could block us...

			 * XXX Should set a timer here, and if accept() doesn't

		 	 * return after X seconds, declare it a failure

		 	 * The only reason this will block forever is if socket()

		 	 * of connect() fail in the child process

		 	 */

                        do {

                            so->s = accept(s, (struct sockaddr *)&addr, &addrlen);

                        } while (so->s < 0 && errno == EINTR);

                        closesocket(s);

			opt = 1;

			setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int));

			opt = 1;

			setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));

		}

		fd_nonblock(so->s);



		/* Append the telnet options now */

		if (so->so_m != 0 && do_pty == 1)  {

			sbappend(so, so->so_m);

			so->so_m = 0;

		}



		return 1;

	}

}

fork_exec(struct socket *so, const char *ex, int do_pty)

{

	int s;

	struct sockaddr_in addr;

	int addrlen = sizeof(addr);

	int opt;

        int master = -1;

	char *argv[256];

#if 0

	char buff[256];

#endif

	

	char *bptr;

	const char *curarg;

	int c, i, ret;



	DEBUG_CALL("fork_exec");

	DEBUG_ARG("so = %lx", (long)so);

	DEBUG_ARG("ex = %lx", (long)ex);

	DEBUG_ARG("do_pty = %lx", (long)do_pty);



	if (do_pty == 2) {

#if 0

		if (slirp_openpty(&master, &s) == -1) {

			lprint("Error: openpty failed: %s\n", strerror(errno));

			return 0;

		}

#else

                return 0;

#endif

	} else {

		addr.sin_family = AF_INET;

		addr.sin_port = 0;

		addr.sin_addr.s_addr = INADDR_ANY;



		if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0 ||

		    bind(s, (struct sockaddr *)&addr, addrlen) < 0 ||

		    listen(s, 1) < 0) {

			lprint("Error: inet socket: %s\n", strerror(errno));

			closesocket(s);



			return 0;

		}

	}



	switch(fork()) {

	 case -1:

		lprint("Error: fork failed: %s\n", strerror(errno));

		close(s);

		if (do_pty == 2)

		   close(master);

		return 0;



	 case 0:

		

		if (do_pty == 2) {

			(void) close(master);

#ifdef TIOCSCTTY 

			(void) setsid();

			ioctl(s, TIOCSCTTY, (char *)NULL);

#endif

		} else {

			getsockname(s, (struct sockaddr *)&addr, &addrlen);

			close(s);

			







			s = socket(AF_INET, SOCK_STREAM, 0);

			addr.sin_addr = loopback_addr;

                        do {

                            ret = connect(s, (struct sockaddr *)&addr, addrlen);

                        } while (ret < 0 && errno == EINTR);

		}



#if 0

		if (x_port >= 0) {

#ifdef HAVE_SETENV

			sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);

			setenv("DISPLAY", buff, 1);

#else

			sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);

			putenv(buff);

#endif

		}

#endif

		dup2(s, 0);

		dup2(s, 1);

		dup2(s, 2);

		for (s = getdtablesize() - 1; s >= 3; s--)

		   close(s);



		i = 0;

		bptr = strdup(ex); 

		if (do_pty == 1) {

			

			argv[i++] = "slirp.telnetd";

			argv[i++] = "-x";

			argv[i++] = bptr;

		} else

		   do {

			

			curarg = bptr;

			while (*bptr != ' ' && *bptr != (char)0)

			   bptr++;

			c = *bptr;

			*bptr++ = (char)0;

			argv[i++] = strdup(curarg);

		   } while (c);



		argv[i] = 0;

		execvp(argv[0], argv);



		

		  {

			  char buff[256];



			  sprintf(buff, "Error: execvp of %s failed: %s\n",

				  argv[0], strerror(errno));

			  write(2, buff, strlen(buff)+1);

		  }

		close(0); close(1); close(2); 

		exit(1);



	 default:

		if (do_pty == 2) {

			close(s);

			so->s = master;

		} else {

			













                        do {

                            so->s = accept(s, (struct sockaddr *)&addr, &addrlen);

                        } while (so->s < 0 && errno == EINTR);

                        closesocket(s);

			opt = 1;

			setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int));

			opt = 1;

			setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));

		}

		fd_nonblock(so->s);



		

		if (so->so_m != 0 && do_pty == 1)  {

			sbappend(so, so->so_m);

			so->so_m = 0;

		}



		return 1;

	}

}

FUNC_0(struct socket *VAR_0, const char *VAR_1, int VAR_2)

{

	int VAR_3;

	struct sockaddr_in VAR_4;

	int VAR_5 = sizeof(VAR_4);

	int VAR_6;

        int VAR_7 = -1;

	char *VAR_8[256];

#if 0

	char VAR_14[256];

#endif

	

	char *VAR_9;

	const char *VAR_10;

	int VAR_11, VAR_12, VAR_13;



	DEBUG_CALL("FUNC_0");

	DEBUG_ARG("VAR_0 = %lx", (long)VAR_0);

	DEBUG_ARG("VAR_1 = %lx", (long)VAR_1);

	DEBUG_ARG("VAR_2 = %lx", (long)VAR_2);



	if (VAR_2 == 2) {

#if 0

		if (slirp_openpty(&VAR_7, &VAR_3) == -1) {

			lprint("Error: openpty failed: %VAR_3\n", strerror(errno));

			return 0;

		}

#else

                return 0;

#endif

	} else {

		VAR_4.sin_family = AF_INET;

		VAR_4.sin_port = 0;

		VAR_4.sin_addr.s_addr = INADDR_ANY;



		if ((VAR_3 = socket(AF_INET, SOCK_STREAM, 0)) < 0 ||

		    bind(VAR_3, (struct sockaddr *)&VAR_4, VAR_5) < 0 ||

		    listen(VAR_3, 1) < 0) {

			lprint("Error: inet socket: %VAR_3\n", strerror(errno));

			closesocket(VAR_3);



			return 0;

		}

	}



	switch(fork()) {

	 case -1:

		lprint("Error: fork failed: %VAR_3\n", strerror(errno));

		close(VAR_3);

		if (VAR_2 == 2)

		   close(VAR_7);

		return 0;



	 case 0:

		

		if (VAR_2 == 2) {

			(void) close(VAR_7);

#ifdef TIOCSCTTY 

			(void) setsid();

			ioctl(VAR_3, TIOCSCTTY, (char *)NULL);

#endif

		} else {

			getsockname(VAR_3, (struct sockaddr *)&VAR_4, &VAR_5);

			close(VAR_3);

			







			VAR_3 = socket(AF_INET, SOCK_STREAM, 0);

			VAR_4.sin_addr = loopback_addr;

                        do {

                            VAR_13 = connect(VAR_3, (struct sockaddr *)&VAR_4, VAR_5);

                        } while (VAR_13 < 0 && errno == EINTR);

		}



#if 0

		if (x_port >= 0) {

#ifdef HAVE_SETENV

			sprintf(VAR_14, "%VAR_3:%d.%d", inet_ntoa(our_addr), x_port, x_screen);

			setenv("DISPLAY", VAR_14, 1);

#else

			sprintf(VAR_14, "DISPLAY=%VAR_3:%d.%d", inet_ntoa(our_addr), x_port, x_screen);

			putenv(VAR_14);

#endif

		}

#endif

		dup2(VAR_3, 0);

		dup2(VAR_3, 1);

		dup2(VAR_3, 2);

		for (VAR_3 = getdtablesize() - 1; VAR_3 >= 3; VAR_3--)

		   close(VAR_3);



		VAR_12 = 0;

		VAR_9 = strdup(VAR_1); 

		if (VAR_2 == 1) {

			

			VAR_8[VAR_12++] = "slirp.telnetd";

			VAR_8[VAR_12++] = "-x";

			VAR_8[VAR_12++] = VAR_9;

		} else

		   do {

			

			VAR_10 = VAR_9;

			while (*VAR_9 != ' ' && *VAR_9 != (char)0)

			   VAR_9++;

			VAR_11 = *VAR_9;

			*VAR_9++ = (char)0;

			VAR_8[VAR_12++] = strdup(VAR_10);

		   } while (VAR_11);



		VAR_8[VAR_12] = 0;

		execvp(VAR_8[0], VAR_8);



		

		  {

			  char VAR_14[256];



			  sprintf(VAR_14, "Error: execvp of %VAR_3 failed: %VAR_3\n",

				  VAR_8[0], strerror(errno));

			  write(2, VAR_14, strlen(VAR_14)+1);

		  }

		close(0); close(1); close(2); 

		exit(1);



	 default:

		if (VAR_2 == 2) {

			close(VAR_3);

			VAR_0->VAR_3 = VAR_7;

		} else {

			













                        do {

                            VAR_0->VAR_3 = accept(VAR_3, (struct sockaddr *)&VAR_4, &VAR_5);

                        } while (VAR_0->VAR_3 < 0 && errno == EINTR);

                        closesocket(VAR_3);

			VAR_6 = 1;

			setsockopt(VAR_0->VAR_3,SOL_SOCKET,SO_REUSEADDR,(char *)&VAR_6,sizeof(int));

			VAR_6 = 1;

			setsockopt(VAR_0->VAR_3,SOL_SOCKET,SO_OOBINLINE,(char *)&VAR_6,sizeof(int));

		}

		fd_nonblock(VAR_0->VAR_3);



		

		if (VAR_0->so_m != 0 && VAR_2 == 1)  {

			sbappend(VAR_0, VAR_0->so_m);

			VAR_0->so_m = 0;

		}



		return 1;

	}

}

FUNC_0(struct socket *VAR_0, const char *VAR_1, int VAR_2)
{ int VAR_3; struct sockaddr_in VAR_4; int VAR_5 = sizeof(VAR_4); int VAR_6; int VAR_7 = -1; char *VAR_8[256]; #if 0
char VAR_14[256]; #endif
char *VAR_9; const char *VAR_10; int VAR_11, VAR_12, VAR_13; DEBUG_CALL("FUNC_0"); DEBUG_ARG("VAR_0 = %lx", (long)VAR_0); DEBUG_ARG("VAR_1 = %lx", (long)VAR_1); DEBUG_ARG("VAR_2 = %lx", (long)VAR_2); if (VAR_2 == 2) { #if 0
if (slirp_openpty(&VAR_7, &VAR_3) == -1) { lprint("Error: openpty failed: %VAR_3\n", strerror(errno)); return 0; } #else
return 0; #endif
} else { VAR_4.sin_family = AF_INET; VAR_4.sin_port = 0; VAR_4.sin_addr.s_addr = INADDR_ANY; if ((VAR_3 = socket(AF_INET, SOCK_STREAM, 0)) < 0 ||
bind(VAR_3, (struct sockaddr *)&VAR_4, VAR_5) < 0 ||
listen(VAR_3, 1) < 0) { lprint("Error: inet socket: %VAR_3\n", strerror(errno)); closesocket(VAR_3); return 0; } } switch(fork()) { case -1:
lprint("Error: fork failed: %VAR_3\n", strerror(errno)); close(VAR_3); if (VAR_2 == 2)
close(VAR_7); return 0; case 0:
if (VAR_2 == 2) { (void) close(VAR_7); #ifdef TIOCSCTTY
(void) setsid(); ioctl(VAR_3, TIOCSCTTY, (char *)NULL); #endif
} else { getsockname(VAR_3, (struct sockaddr *)&VAR_4, &VAR_5); close(VAR_3); VAR_3 = socket(AF_INET, SOCK_STREAM, 0); VAR_4.sin_addr = loopback_addr; do { VAR_13 = connect(VAR_3, (struct sockaddr *)&VAR_4, VAR_5); } while (VAR_13 < 0 && errno == EINTR); } #if 0
if (x_port >= 0) { #ifdef HAVE_SETENV
sprintf(VAR_14, "%VAR_3:%d.%d", inet_ntoa(our_addr), x_port, x_screen); setenv("DISPLAY", VAR_14, 1); #else
sprintf(VAR_14, "DISPLAY=%VAR_3:%d.%d", inet_ntoa(our_addr), x_port, x_screen); putenv(VAR_14); #endif
} #endif
dup2(VAR_3, 0); dup2(VAR_3, 1); dup2(VAR_3, 2); for (VAR_3 = getdtablesize() - 1; VAR_3 >= 3; VAR_3--) close(VAR_3); VAR_12 = 0; VAR_9 = strdup(VAR_1); if (VAR_2 == 1) { VAR_8[VAR_12++] = "slirp.telnetd"; VAR_8[VAR_12++] = "-x"; VAR_8[VAR_12++] = VAR_9; } else do { VAR_10 = VAR_9; while (*VAR_9 != ' ' && *VAR_9 != (char)0)
VAR_9++; VAR_11 = *VAR_9; *VAR_9++ = (char)0; VAR_8[VAR_12++] = strdup(VAR_10); } while (VAR_11); VAR_8[VAR_12] = 0; execvp(VAR_8[0], VAR_8); { char VAR_14[256]; sprintf(VAR_14, "Error: execvp of %VAR_3 failed: %VAR_3\n",
VAR_8[0], strerror(errno)); write(2, VAR_14, strlen(VAR_14)+1); } close(0); close(1); close(2); exit(1); default:
if (VAR_2 == 2) { close(VAR_3); VAR_0->VAR_3 = VAR_7; } else { do { VAR_0->VAR_3 = accept(VAR_3, (struct sockaddr *)&VAR_4, &VAR_5); } while (VAR_0->VAR_3 < 0 && errno == EINTR); closesocket(VAR_3); VAR_6 = 1; setsockopt(VAR_0->VAR_3,SOL_SOCKET,SO_REUSEADDR,(char *)&VAR_6,sizeof(int)); VAR_6 = 1; setsockopt(VAR_0->VAR_3,SOL_SOCKET,SO_OOBINLINE,(char *)&VAR_6,sizeof(int)); } fd_nonblock(VAR_0->VAR_3); if (VAR_0->so_m != 0 && VAR_2 == 1)  { sbappend(VAR_0, VAR_0->so_m); VAR_0->so_m = 0; } return 1; } }