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

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

unix.superglobalmegacorp.com