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

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

unix.superglobalmegacorp.com