Annotation of qemu/slirp/misc.c, revision 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