|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.