Annotation of qemu/slirp/misc.c, revision 1.1.1.4

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

unix.superglobalmegacorp.com