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