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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.