Annotation of previous/src/slirp/misc.c, revision 1.1.1.3

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

unix.superglobalmegacorp.com

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