File:  [Qemu by Fabrice Bellard] / qemu / slirp / misc.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 16:54:45 2018 UTC (3 years, 2 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu0105, qemu0104, qemu0103, qemu0102, qemu0101, qemu0100, HEAD
qemu 0.10.0

    1: /*
    2:  * Copyright (c) 1995 Danny Gasparovski.
    3:  *
    4:  * Please read the file COPYRIGHT for the
    5:  * terms and conditions of the copyright.
    6:  */
    7: 
    8: #define WANT_SYS_IOCTL_H
    9: #include <slirp.h>
   10: 
   11: u_int curtime, time_fasttimo, last_slowtimo;
   12: 
   13: #if 0
   14: int x_port = -1;
   15: int x_display = 0;
   16: int x_screen = 0;
   17: 
   18: int
   19: show_x(buff, inso)
   20: 	char *buff;
   21: 	struct socket *inso;
   22: {
   23: 	if (x_port < 0) {
   24: 		lprint("X Redir: X not being redirected.\r\n");
   25: 	} else {
   26: 		lprint("X Redir: In sh/bash/zsh/etc. type: DISPLAY=%s:%d.%d; export DISPLAY\r\n",
   27: 		      inet_ntoa(our_addr), x_port, x_screen);
   28: 		lprint("X Redir: In csh/tcsh/etc. type:    setenv DISPLAY %s:%d.%d\r\n",
   29: 		      inet_ntoa(our_addr), x_port, x_screen);
   30: 		if (x_display)
   31: 		   lprint("X Redir: Redirecting to display %d\r\n", x_display);
   32: 	}
   33: 
   34: 	return CFG_OK;
   35: }
   36: 
   37: 
   38: /*
   39:  * XXX Allow more than one X redirection?
   40:  */
   41: void
   42: redir_x(inaddr, start_port, display, screen)
   43: 	u_int32_t inaddr;
   44: 	int start_port;
   45: 	int display;
   46: 	int screen;
   47: {
   48: 	int i;
   49: 
   50: 	if (x_port >= 0) {
   51: 		lprint("X Redir: X already being redirected.\r\n");
   52: 		show_x(0, 0);
   53: 	} else {
   54: 		for (i = 6001 + (start_port-1); i <= 6100; i++) {
   55: 			if (solisten(htons(i), inaddr, htons(6000 + display), 0)) {
   56: 				/* Success */
   57: 				x_port = i - 6000;
   58: 				x_display = display;
   59: 				x_screen = screen;
   60: 				show_x(0, 0);
   61: 				return;
   62: 			}
   63: 		}
   64: 		lprint("X Redir: Error: Couldn't redirect a port for X. Weird.\r\n");
   65: 	}
   66: }
   67: #endif
   68: 
   69: /*
   70:  * Get our IP address and put it in our_addr
   71:  */
   72: void
   73: getouraddr()
   74: {
   75: 	char buff[256];
   76: 	struct hostent *he = NULL;
   77: 
   78: 	if (gethostname(buff,256) == 0)
   79:             he = gethostbyname(buff);
   80:         if (he)
   81:             our_addr = *(struct in_addr *)he->h_addr;
   82:         if (our_addr.s_addr == 0)
   83:             our_addr.s_addr = loopback_addr.s_addr;
   84: }
   85: 
   86: struct quehead {
   87: 	struct quehead *qh_link;
   88: 	struct quehead *qh_rlink;
   89: };
   90: 
   91: inline void
   92: insque(a, b)
   93: 	void *a, *b;
   94: {
   95: 	register struct quehead *element = (struct quehead *) a;
   96: 	register struct quehead *head = (struct quehead *) b;
   97: 	element->qh_link = head->qh_link;
   98: 	head->qh_link = (struct quehead *)element;
   99: 	element->qh_rlink = (struct quehead *)head;
  100: 	((struct quehead *)(element->qh_link))->qh_rlink
  101: 	= (struct quehead *)element;
  102: }
  103: 
  104: inline void
  105: remque(a)
  106:      void *a;
  107: {
  108:   register struct quehead *element = (struct quehead *) a;
  109:   ((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink;
  110:   ((struct quehead *)(element->qh_rlink))->qh_link = element->qh_link;
  111:   element->qh_rlink = NULL;
  112:   /*  element->qh_link = NULL;  TCP FIN1 crashes if you do this.  Why ? */
  113: }
  114: 
  115: /* #endif */
  116: 
  117: 
  118: int
  119: add_exec(ex_ptr, do_pty, exec, addr, port)
  120: 	struct ex_list **ex_ptr;
  121: 	int do_pty;
  122: 	char *exec;
  123: 	int addr;
  124: 	int port;
  125: {
  126: 	struct ex_list *tmp_ptr;
  127: 
  128: 	/* First, check if the port is "bound" */
  129: 	for (tmp_ptr = *ex_ptr; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) {
  130: 		if (port == tmp_ptr->ex_fport && addr == tmp_ptr->ex_addr)
  131: 		   return -1;
  132: 	}
  133: 
  134: 	tmp_ptr = *ex_ptr;
  135: 	*ex_ptr = (struct ex_list *)malloc(sizeof(struct ex_list));
  136: 	(*ex_ptr)->ex_fport = port;
  137: 	(*ex_ptr)->ex_addr = addr;
  138: 	(*ex_ptr)->ex_pty = do_pty;
  139: 	(*ex_ptr)->ex_exec = (do_pty == 3) ? exec : strdup(exec);
  140: 	(*ex_ptr)->ex_next = tmp_ptr;
  141: 	return 0;
  142: }
  143: 
  144: #ifndef HAVE_STRERROR
  145: 
  146: /*
  147:  * For systems with no strerror
  148:  */
  149: 
  150: extern int sys_nerr;
  151: extern char *sys_errlist[];
  152: 
  153: char *
  154: strerror(error)
  155: 	int error;
  156: {
  157: 	if (error < sys_nerr)
  158: 	   return sys_errlist[error];
  159: 	else
  160: 	   return "Unknown error.";
  161: }
  162: 
  163: #endif
  164: 
  165: 
  166: #ifdef _WIN32
  167: 
  168: int
  169: fork_exec(struct socket *so, const char *ex, int do_pty)
  170: {
  171:     /* not implemented */
  172:     return 0;
  173: }
  174: 
  175: #else
  176: 
  177: #ifndef CONFIG_QEMU
  178: int
  179: slirp_openpty(amaster, aslave)
  180:      int *amaster, *aslave;
  181: {
  182: 	register int master, slave;
  183: 
  184: #ifdef HAVE_GRANTPT
  185: 	char *ptr;
  186: 
  187: 	if ((master = open("/dev/ptmx", O_RDWR)) < 0 ||
  188: 	    grantpt(master) < 0 ||
  189: 	    unlockpt(master) < 0 ||
  190: 	    (ptr = ptsname(master)) == NULL)  {
  191: 		close(master);
  192: 		return -1;
  193: 	}
  194: 
  195: 	if ((slave = open(ptr, O_RDWR)) < 0 ||
  196: 	    ioctl(slave, I_PUSH, "ptem") < 0 ||
  197: 	    ioctl(slave, I_PUSH, "ldterm") < 0 ||
  198: 	    ioctl(slave, I_PUSH, "ttcompat") < 0) {
  199: 		close(master);
  200: 		close(slave);
  201: 		return -1;
  202: 	}
  203: 
  204: 	*amaster = master;
  205: 	*aslave = slave;
  206: 	return 0;
  207: 
  208: #else
  209: 
  210: 	static char line[] = "/dev/ptyXX";
  211: 	register const char *cp1, *cp2;
  212: 
  213: 	for (cp1 = "pqrsPQRS"; *cp1; cp1++) {
  214: 		line[8] = *cp1;
  215: 		for (cp2 = "0123456789abcdefghijklmnopqrstuv"; *cp2; cp2++) {
  216: 			line[9] = *cp2;
  217: 			if ((master = open(line, O_RDWR, 0)) == -1) {
  218: 				if (errno == ENOENT)
  219: 				   return (-1);    /* out of ptys */
  220: 			} else {
  221: 				line[5] = 't';
  222: 				/* These will fail */
  223: 				(void) chown(line, getuid(), 0);
  224: 				(void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP);
  225: #ifdef HAVE_REVOKE
  226: 				(void) revoke(line);
  227: #endif
  228: 				if ((slave = open(line, O_RDWR, 0)) != -1) {
  229: 					*amaster = master;
  230: 					*aslave = slave;
  231: 					return 0;
  232: 				}
  233: 				(void) close(master);
  234: 				line[5] = 'p';
  235: 			}
  236: 		}
  237: 	}
  238: 	errno = ENOENT; /* out of ptys */
  239: 	return (-1);
  240: #endif
  241: }
  242: #endif
  243: 
  244: /*
  245:  * XXX This is ugly
  246:  * We create and bind a socket, then fork off to another
  247:  * process, which connects to this socket, after which we
  248:  * exec the wanted program.  If something (strange) happens,
  249:  * the accept() call could block us forever.
  250:  *
  251:  * do_pty = 0   Fork/exec inetd style
  252:  * do_pty = 1   Fork/exec using slirp.telnetd
  253:  * do_ptr = 2   Fork/exec using pty
  254:  */
  255: int
  256: fork_exec(struct socket *so, const char *ex, int do_pty)
  257: {
  258: 	int s;
  259: 	struct sockaddr_in addr;
  260: 	socklen_t addrlen = sizeof(addr);
  261: 	int opt;
  262:         int master = -1;
  263: 	const char *argv[256];
  264: #if 0
  265: 	char buff[256];
  266: #endif
  267: 	/* don't want to clobber the original */
  268: 	char *bptr;
  269: 	const char *curarg;
  270: 	int c, i, ret;
  271: 
  272: 	DEBUG_CALL("fork_exec");
  273: 	DEBUG_ARG("so = %lx", (long)so);
  274: 	DEBUG_ARG("ex = %lx", (long)ex);
  275: 	DEBUG_ARG("do_pty = %lx", (long)do_pty);
  276: 
  277: 	if (do_pty == 2) {
  278: #if 0
  279: 		if (slirp_openpty(&master, &s) == -1) {
  280: 			lprint("Error: openpty failed: %s\n", strerror(errno));
  281: 			return 0;
  282: 		}
  283: #else
  284:                 return 0;
  285: #endif
  286: 	} else {
  287: 		addr.sin_family = AF_INET;
  288: 		addr.sin_port = 0;
  289: 		addr.sin_addr.s_addr = INADDR_ANY;
  290: 
  291: 		if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0 ||
  292: 		    bind(s, (struct sockaddr *)&addr, addrlen) < 0 ||
  293: 		    listen(s, 1) < 0) {
  294: 			lprint("Error: inet socket: %s\n", strerror(errno));
  295: 			closesocket(s);
  296: 
  297: 			return 0;
  298: 		}
  299: 	}
  300: 
  301: 	switch(fork()) {
  302: 	 case -1:
  303: 		lprint("Error: fork failed: %s\n", strerror(errno));
  304: 		close(s);
  305: 		if (do_pty == 2)
  306: 		   close(master);
  307: 		return 0;
  308: 
  309: 	 case 0:
  310: 		/* Set the DISPLAY */
  311: 		if (do_pty == 2) {
  312: 			(void) close(master);
  313: #ifdef TIOCSCTTY /* XXXXX */
  314: 			(void) setsid();
  315: 			ioctl(s, TIOCSCTTY, (char *)NULL);
  316: #endif
  317: 		} else {
  318: 			getsockname(s, (struct sockaddr *)&addr, &addrlen);
  319: 			close(s);
  320: 			/*
  321: 			 * Connect to the socket
  322: 			 * XXX If any of these fail, we're in trouble!
  323: 	 		 */
  324: 			s = socket(AF_INET, SOCK_STREAM, 0);
  325: 			addr.sin_addr = loopback_addr;
  326:                         do {
  327:                             ret = connect(s, (struct sockaddr *)&addr, addrlen);
  328:                         } while (ret < 0 && errno == EINTR);
  329: 		}
  330: 
  331: #if 0
  332: 		if (x_port >= 0) {
  333: #ifdef HAVE_SETENV
  334: 			sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
  335: 			setenv("DISPLAY", buff, 1);
  336: #else
  337: 			sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
  338: 			putenv(buff);
  339: #endif
  340: 		}
  341: #endif
  342: 		dup2(s, 0);
  343: 		dup2(s, 1);
  344: 		dup2(s, 2);
  345: 		for (s = getdtablesize() - 1; s >= 3; s--)
  346: 		   close(s);
  347: 
  348: 		i = 0;
  349: 		bptr = strdup(ex); /* No need to free() this */
  350: 		if (do_pty == 1) {
  351: 			/* Setup "slirp.telnetd -x" */
  352: 			argv[i++] = "slirp.telnetd";
  353: 			argv[i++] = "-x";
  354: 			argv[i++] = bptr;
  355: 		} else
  356: 		   do {
  357: 			/* Change the string into argv[] */
  358: 			curarg = bptr;
  359: 			while (*bptr != ' ' && *bptr != (char)0)
  360: 			   bptr++;
  361: 			c = *bptr;
  362: 			*bptr++ = (char)0;
  363: 			argv[i++] = strdup(curarg);
  364: 		   } while (c);
  365: 
  366: 		argv[i] = 0;
  367: 		execvp(argv[0], (char **)argv);
  368: 
  369: 		/* Ooops, failed, let's tell the user why */
  370: 		  {
  371: 			  char buff[256];
  372: 
  373: 			  snprintf(buff, sizeof(buff),
  374:                                    "Error: execvp of %s failed: %s\n",
  375:                                    argv[0], strerror(errno));
  376: 			  write(2, buff, strlen(buff)+1);
  377: 		  }
  378: 		close(0); close(1); close(2); /* XXX */
  379: 		exit(1);
  380: 
  381: 	 default:
  382: 		if (do_pty == 2) {
  383: 			close(s);
  384: 			so->s = master;
  385: 		} else {
  386: 			/*
  387: 			 * XXX this could block us...
  388: 			 * XXX Should set a timer here, and if accept() doesn't
  389: 		 	 * return after X seconds, declare it a failure
  390: 		 	 * The only reason this will block forever is if socket()
  391: 		 	 * of connect() fail in the child process
  392: 		 	 */
  393:                         do {
  394:                             so->s = accept(s, (struct sockaddr *)&addr, &addrlen);
  395:                         } while (so->s < 0 && errno == EINTR);
  396:                         closesocket(s);
  397: 			opt = 1;
  398: 			setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int));
  399: 			opt = 1;
  400: 			setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
  401: 		}
  402: 		fd_nonblock(so->s);
  403: 
  404: 		/* Append the telnet options now */
  405: 		if (so->so_m != 0 && do_pty == 1)  {
  406: 			sbappend(so, so->so_m);
  407: 			so->so_m = 0;
  408: 		}
  409: 
  410: 		return 1;
  411: 	}
  412: }
  413: #endif
  414: 
  415: #ifndef HAVE_STRDUP
  416: char *
  417: strdup(str)
  418: 	const char *str;
  419: {
  420: 	char *bptr;
  421: 
  422: 	bptr = (char *)malloc(strlen(str)+1);
  423: 	strcpy(bptr, str);
  424: 
  425: 	return bptr;
  426: }
  427: #endif
  428: 
  429: #if 0
  430: void
  431: snooze_hup(num)
  432: 	int num;
  433: {
  434: 	int s, ret;
  435: #ifndef NO_UNIX_SOCKETS
  436: 	struct sockaddr_un sock_un;
  437: #endif
  438: 	struct sockaddr_in sock_in;
  439: 	char buff[256];
  440: 
  441: 	ret = -1;
  442: 	if (slirp_socket_passwd) {
  443: 		s = socket(AF_INET, SOCK_STREAM, 0);
  444: 		if (s < 0)
  445: 		   slirp_exit(1);
  446: 		sock_in.sin_family = AF_INET;
  447: 		sock_in.sin_addr.s_addr = slirp_socket_addr;
  448: 		sock_in.sin_port = htons(slirp_socket_port);
  449: 		if (connect(s, (struct sockaddr *)&sock_in, sizeof(sock_in)) != 0)
  450: 		   slirp_exit(1); /* just exit...*/
  451: 		sprintf(buff, "kill %s:%d", slirp_socket_passwd, slirp_socket_unit);
  452: 		write(s, buff, strlen(buff)+1);
  453: 	}
  454: #ifndef NO_UNIX_SOCKETS
  455: 	  else {
  456: 		s = socket(AF_UNIX, SOCK_STREAM, 0);
  457: 		if (s < 0)
  458: 		   slirp_exit(1);
  459: 		sock_un.sun_family = AF_UNIX;
  460: 		strcpy(sock_un.sun_path, socket_path);
  461: 		if (connect(s, (struct sockaddr *)&sock_un,
  462: 			      sizeof(sock_un.sun_family) + sizeof(sock_un.sun_path)) != 0)
  463: 		   slirp_exit(1);
  464: 		sprintf(buff, "kill none:%d", slirp_socket_unit);
  465: 		write(s, buff, strlen(buff)+1);
  466: 	}
  467: #endif
  468: 	slirp_exit(0);
  469: }
  470: 
  471: 
  472: void
  473: snooze()
  474: {
  475: 	sigset_t s;
  476: 	int i;
  477: 
  478: 	/* Don't need our data anymore */
  479: 	/* XXX This makes SunOS barf */
  480: /*	brk(0); */
  481: 
  482: 	/* Close all fd's */
  483: 	for (i = 255; i >= 0; i--)
  484: 	   close(i);
  485: 
  486: 	signal(SIGQUIT, slirp_exit);
  487: 	signal(SIGHUP, snooze_hup);
  488: 	sigemptyset(&s);
  489: 
  490: 	/* Wait for any signal */
  491: 	sigsuspend(&s);
  492: 
  493: 	/* Just in case ... */
  494: 	exit(255);
  495: }
  496: 
  497: void
  498: relay(s)
  499: 	int s;
  500: {
  501: 	char buf[8192];
  502: 	int n;
  503: 	fd_set readfds;
  504: 	struct ttys *ttyp;
  505: 
  506: 	/* Don't need our data anymore */
  507: 	/* XXX This makes SunOS barf */
  508: /*	brk(0); */
  509: 
  510: 	signal(SIGQUIT, slirp_exit);
  511: 	signal(SIGHUP, slirp_exit);
  512:         signal(SIGINT, slirp_exit);
  513: 	signal(SIGTERM, slirp_exit);
  514: 
  515: 	/* Fudge to get term_raw and term_restore to work */
  516: 	if (NULL == (ttyp = tty_attach (0, slirp_tty))) {
  517:          lprint ("Error: tty_attach failed in misc.c:relay()\r\n");
  518:          slirp_exit (1);
  519:     }
  520: 	ttyp->fd = 0;
  521: 	ttyp->flags |= TTY_CTTY;
  522: 	term_raw(ttyp);
  523: 
  524: 	while (1) {
  525: 		FD_ZERO(&readfds);
  526: 
  527: 		FD_SET(0, &readfds);
  528: 		FD_SET(s, &readfds);
  529: 
  530: 		n = select(s+1, &readfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0);
  531: 
  532: 		if (n <= 0)
  533: 		   slirp_exit(0);
  534: 
  535: 		if (FD_ISSET(0, &readfds)) {
  536: 			n = read(0, buf, 8192);
  537: 			if (n <= 0)
  538: 			   slirp_exit(0);
  539: 			n = writen(s, buf, n);
  540: 			if (n <= 0)
  541: 			   slirp_exit(0);
  542: 		}
  543: 
  544: 		if (FD_ISSET(s, &readfds)) {
  545: 			n = read(s, buf, 8192);
  546: 			if (n <= 0)
  547: 			   slirp_exit(0);
  548: 			n = writen(0, buf, n);
  549: 			if (n <= 0)
  550: 			   slirp_exit(0);
  551: 		}
  552: 	}
  553: 
  554: 	/* Just in case.... */
  555: 	exit(1);
  556: }
  557: #endif
  558: 
  559: #ifdef CONFIG_QEMU
  560: extern void term_vprintf(const char *fmt, va_list ap);
  561: 
  562: void lprint(const char *format, ...)
  563: {
  564:     va_list args;
  565: 
  566:     va_start(args, format);
  567:     term_vprintf(format, args);
  568:     va_end(args);
  569: }
  570: #else
  571: int (*lprint_print) _P((void *, const char *, va_list));
  572: char *lprint_ptr, *lprint_ptr2, **lprint_arg;
  573: 
  574: void
  575: #ifdef __STDC__
  576: lprint(const char *format, ...)
  577: #else
  578: lprint(va_alist) va_dcl
  579: #endif
  580: {
  581: 	va_list args;
  582: 
  583: #ifdef __STDC__
  584:         va_start(args, format);
  585: #else
  586:         char *format;
  587:         va_start(args);
  588:         format = va_arg(args, char *);
  589: #endif
  590: #if 0
  591: 	/* If we're printing to an sbuf, make sure there's enough room */
  592: 	/* XXX +100? */
  593: 	if (lprint_sb) {
  594: 		if ((lprint_ptr - lprint_sb->sb_wptr) >=
  595: 		    (lprint_sb->sb_datalen - (strlen(format) + 100))) {
  596: 			int deltaw = lprint_sb->sb_wptr - lprint_sb->sb_data;
  597: 			int deltar = lprint_sb->sb_rptr - lprint_sb->sb_data;
  598: 			int deltap = lprint_ptr -         lprint_sb->sb_data;
  599: 
  600: 			lprint_sb->sb_data = (char *)realloc(lprint_sb->sb_data,
  601: 							     lprint_sb->sb_datalen + TCP_SNDSPACE);
  602: 
  603: 			/* Adjust all values */
  604: 			lprint_sb->sb_wptr = lprint_sb->sb_data + deltaw;
  605: 			lprint_sb->sb_rptr = lprint_sb->sb_data + deltar;
  606: 			lprint_ptr =         lprint_sb->sb_data + deltap;
  607: 
  608: 			lprint_sb->sb_datalen += TCP_SNDSPACE;
  609: 		}
  610: 	}
  611: #endif
  612: 	if (lprint_print)
  613: 	   lprint_ptr += (*lprint_print)(*lprint_arg, format, args);
  614: 
  615: 	/* Check if they want output to be logged to file as well */
  616: 	if (lfd) {
  617: 		/*
  618: 		 * Remove \r's
  619: 		 * otherwise you'll get ^M all over the file
  620: 		 */
  621: 		int len = strlen(format);
  622: 		char *bptr1, *bptr2;
  623: 
  624: 		bptr1 = bptr2 = strdup(format);
  625: 
  626: 		while (len--) {
  627: 			if (*bptr1 == '\r')
  628: 			   memcpy(bptr1, bptr1+1, len+1);
  629: 			else
  630: 			   bptr1++;
  631: 		}
  632: 		vfprintf(lfd, bptr2, args);
  633: 		free(bptr2);
  634: 	}
  635: 	va_end(args);
  636: }
  637: 
  638: void
  639: add_emu(buff)
  640: 	char *buff;
  641: {
  642: 	u_int lport, fport;
  643: 	u_int8_t tos = 0, emu = 0;
  644: 	char buff1[256], buff2[256], buff4[128];
  645: 	char *buff3 = buff4;
  646: 	struct emu_t *emup;
  647: 	struct socket *so;
  648: 
  649: 	if (sscanf(buff, "%256s %256s", buff2, buff1) != 2) {
  650: 		lprint("Error: Bad arguments\r\n");
  651: 		return;
  652: 	}
  653: 
  654: 	if (sscanf(buff1, "%d:%d", &lport, &fport) != 2) {
  655: 		lport = 0;
  656: 		if (sscanf(buff1, "%d", &fport) != 1) {
  657: 			lprint("Error: Bad first argument\r\n");
  658: 			return;
  659: 		}
  660: 	}
  661: 
  662: 	if (sscanf(buff2, "%128[^:]:%128s", buff1, buff3) != 2) {
  663: 		buff3 = 0;
  664: 		if (sscanf(buff2, "%256s", buff1) != 1) {
  665: 			lprint("Error: Bad second argument\r\n");
  666: 			return;
  667: 		}
  668: 	}
  669: 
  670: 	if (buff3) {
  671: 		if (strcmp(buff3, "lowdelay") == 0)
  672: 		   tos = IPTOS_LOWDELAY;
  673: 		else if (strcmp(buff3, "throughput") == 0)
  674: 		   tos = IPTOS_THROUGHPUT;
  675: 		else {
  676: 			lprint("Error: Expecting \"lowdelay\"/\"throughput\"\r\n");
  677: 			return;
  678: 		}
  679: 	}
  680: 
  681: 	if (strcmp(buff1, "ftp") == 0)
  682: 	   emu = EMU_FTP;
  683: 	else if (strcmp(buff1, "irc") == 0)
  684: 	   emu = EMU_IRC;
  685: 	else if (strcmp(buff1, "none") == 0)
  686: 	   emu = EMU_NONE; /* ie: no emulation */
  687: 	else {
  688: 		lprint("Error: Unknown service\r\n");
  689: 		return;
  690: 	}
  691: 
  692: 	/* First, check that it isn't already emulated */
  693: 	for (emup = tcpemu; emup; emup = emup->next) {
  694: 		if (emup->lport == lport && emup->fport == fport) {
  695: 			lprint("Error: port already emulated\r\n");
  696: 			return;
  697: 		}
  698: 	}
  699: 
  700: 	/* link it */
  701: 	emup = (struct emu_t *)malloc(sizeof (struct emu_t));
  702: 	emup->lport = (u_int16_t)lport;
  703: 	emup->fport = (u_int16_t)fport;
  704: 	emup->tos = tos;
  705: 	emup->emu = emu;
  706: 	emup->next = tcpemu;
  707: 	tcpemu = emup;
  708: 
  709: 	/* And finally, mark all current sessions, if any, as being emulated */
  710: 	for (so = tcb.so_next; so != &tcb; so = so->so_next) {
  711: 		if ((lport && lport == ntohs(so->so_lport)) ||
  712: 		    (fport && fport == ntohs(so->so_fport))) {
  713: 			if (emu)
  714: 			   so->so_emu = emu;
  715: 			if (tos)
  716: 			   so->so_iptos = tos;
  717: 		}
  718: 	}
  719: 
  720: 	lprint("Adding emulation for %s to port %d/%d\r\n", buff1, emup->lport, emup->fport);
  721: }
  722: #endif
  723: 
  724: #ifdef BAD_SPRINTF
  725: 
  726: #undef vsprintf
  727: #undef sprintf
  728: 
  729: /*
  730:  * Some BSD-derived systems have a sprintf which returns char *
  731:  */
  732: 
  733: int
  734: vsprintf_len(string, format, args)
  735: 	char *string;
  736: 	const char *format;
  737: 	va_list args;
  738: {
  739: 	vsprintf(string, format, args);
  740: 	return strlen(string);
  741: }
  742: 
  743: int
  744: #ifdef __STDC__
  745: sprintf_len(char *string, const char *format, ...)
  746: #else
  747: sprintf_len(va_alist) va_dcl
  748: #endif
  749: {
  750: 	va_list args;
  751: #ifdef __STDC__
  752: 	va_start(args, format);
  753: #else
  754: 	char *string;
  755: 	char *format;
  756: 	va_start(args);
  757: 	string = va_arg(args, char *);
  758: 	format = va_arg(args, char *);
  759: #endif
  760: 	vsprintf(string, format, args);
  761: 	return strlen(string);
  762: }
  763: 
  764: #endif
  765: 
  766: void
  767: u_sleep(usec)
  768: 	int usec;
  769: {
  770: 	struct timeval t;
  771: 	fd_set fdset;
  772: 
  773: 	FD_ZERO(&fdset);
  774: 
  775: 	t.tv_sec = 0;
  776: 	t.tv_usec = usec * 1000;
  777: 
  778: 	select(0, &fdset, &fdset, &fdset, &t);
  779: }
  780: 
  781: /*
  782:  * Set fd blocking and non-blocking
  783:  */
  784: 
  785: void
  786: fd_nonblock(fd)
  787: 	int fd;
  788: {
  789: #ifdef FIONBIO
  790: 	int opt = 1;
  791: 
  792: 	ioctlsocket(fd, FIONBIO, &opt);
  793: #else
  794: 	int opt;
  795: 
  796: 	opt = fcntl(fd, F_GETFL, 0);
  797: 	opt |= O_NONBLOCK;
  798: 	fcntl(fd, F_SETFL, opt);
  799: #endif
  800: }
  801: 
  802: void
  803: fd_block(fd)
  804: 	int fd;
  805: {
  806: #ifdef FIONBIO
  807: 	int opt = 0;
  808: 
  809: 	ioctlsocket(fd, FIONBIO, &opt);
  810: #else
  811: 	int opt;
  812: 
  813: 	opt = fcntl(fd, F_GETFL, 0);
  814: 	opt &= ~O_NONBLOCK;
  815: 	fcntl(fd, F_SETFL, opt);
  816: #endif
  817: }
  818: 
  819: 
  820: #if 0
  821: /*
  822:  * invoke RSH
  823:  */
  824: int
  825: rsh_exec(so,ns, user, host, args)
  826: 	struct socket *so;
  827: 	struct socket *ns;
  828: 	char *user;
  829: 	char *host;
  830: 	char *args;
  831: {
  832: 	int fd[2];
  833: 	int fd0[2];
  834: 	int s;
  835: 	char buff[256];
  836: 
  837: 	DEBUG_CALL("rsh_exec");
  838: 	DEBUG_ARG("so = %lx", (long)so);
  839: 
  840: 	if (pipe(fd)<0) {
  841:           lprint("Error: pipe failed: %s\n", strerror(errno));
  842:           return 0;
  843: 	}
  844: /* #ifdef HAVE_SOCKETPAIR */
  845: #if 1
  846:         if (socketpair(PF_UNIX,SOCK_STREAM,0, fd0) == -1) {
  847:           close(fd[0]);
  848:           close(fd[1]);
  849:           lprint("Error: openpty failed: %s\n", strerror(errno));
  850:           return 0;
  851:         }
  852: #else
  853:         if (slirp_openpty(&fd0[0], &fd0[1]) == -1) {
  854:           close(fd[0]);
  855:           close(fd[1]);
  856:           lprint("Error: openpty failed: %s\n", strerror(errno));
  857:           return 0;
  858:         }
  859: #endif
  860: 
  861: 	switch(fork()) {
  862: 	 case -1:
  863:            lprint("Error: fork failed: %s\n", strerror(errno));
  864:            close(fd[0]);
  865:            close(fd[1]);
  866:            close(fd0[0]);
  867:            close(fd0[1]);
  868:            return 0;
  869: 
  870: 	 case 0:
  871:            close(fd[0]);
  872:            close(fd0[0]);
  873: 
  874: 		/* Set the DISPLAY */
  875:            if (x_port >= 0) {
  876: #ifdef HAVE_SETENV
  877:              sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
  878:              setenv("DISPLAY", buff, 1);
  879: #else
  880:              sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
  881:              putenv(buff);
  882: #endif
  883:            }
  884: 
  885:            dup2(fd0[1], 0);
  886:            dup2(fd0[1], 1);
  887:            dup2(fd[1], 2);
  888:            for (s = 3; s <= 255; s++)
  889:              close(s);
  890: 
  891:            execlp("rsh","rsh","-l", user, host, args, NULL);
  892: 
  893:            /* Ooops, failed, let's tell the user why */
  894: 
  895:            sprintf(buff, "Error: execlp of %s failed: %s\n",
  896:                    "rsh", strerror(errno));
  897:            write(2, buff, strlen(buff)+1);
  898:            close(0); close(1); close(2); /* XXX */
  899:            exit(1);
  900: 
  901:         default:
  902:           close(fd[1]);
  903:           close(fd0[1]);
  904:           ns->s=fd[0];
  905:           so->s=fd0[0];
  906: 
  907:           return 1;
  908: 	}
  909: }
  910: #endif

unix.superglobalmegacorp.com