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