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

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

unix.superglobalmegacorp.com