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