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