Annotation of previous_trunk/src/slirp/misc.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1995 Danny Gasparovski.
        !             3:  * 
        !             4:  * Please read the file COPYRIGHT for the
        !             5:  * terms and conditions of the copyright.
        !             6:  */
        !             7: 
        !             8: #define WANT_SYS_IOCTL_H
        !             9: #include <stdlib.h>
        !            10: #include <slirp.h>
        !            11: 
        !            12: u_int curtime, time_fasttimo, last_slowtimo, detach_time;
        !            13: u_int detach_wait = 600000;    /* 10 minutes */
        !            14: 
        !            15: #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: 
        !           102:     l = snprintf( tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3] );
        !           103:        if (l <= 0 || (socklen_t) l >= size) {
        !           104:                return (NULL);
        !           105:        }
        !           106:        strlcpy(dst, tmp, size);
        !           107:        return (dst);
        !           108: }
        !           109: 
        !           110: const char * inet_ntop(int af, const void *src, char *dst, socklen_t size)
        !           111: {
        !           112:        switch (af) {
        !           113:        case AF_INET:
        !           114:                return (inet_ntop4( (const unsigned char*)src, (char*)dst, size));
        !           115:        default:
        !           116:         return 0 ;
        !           117:        }
        !           118: }
        !           119: #endif
        !           120: 
        !           121: #if 0
        !           122: int x_port = -1;
        !           123: int x_display = 0;
        !           124: int x_screen = 0;
        !           125: 
        !           126: int show_x(char *buff, struct socket *inso)
        !           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:  */
        !           146: void redir_x(u_int32_t inaddr, int start_port, int display, int screen)
        !           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
        !           170: int inet_aton(const char *cp, struct in_addr *ia)
        !           171: {
        !           172:        return inet_pton(AF_INET, cp, (char*)&ia->s_addr);
        !           173: }
        !           174: #endif
        !           175: 
        !           176: /*
        !           177:  * Get our IP address and put it in our_addr
        !           178:  */
        !           179: void getouraddr()
        !           180: {
        !           181:        char buff[256];
        !           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;
        !           197: }
        !           198: 
        !           199: struct quehead {
        !           200:        struct quehead *qh_link;
        !           201:        struct quehead *qh_rlink;
        !           202: };
        !           203: 
        !           204: void insque(void *a, void *b)
        !           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: 
        !           215: void remque(void *a)
        !           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: 
        !           227: int add_exec(struct ex_list **ex_ptr, int do_pty, const char *exec, int addr, int port)
        !           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: 
        !           256: char *strerror(int error)
        !           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: 
        !           269: int fork_exec(struct socket *so, char *ex, int do_pty)
        !           270: {
        !           271:     /* not implemented */
        !           272:     return 0;
        !           273: }
        !           274: 
        !           275: #else
        !           276: 
        !           277: int slirp_openpty(int *amaster, int *aslave)
        !           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:  */
        !           351: int fork_exec(struct socket *so, char *ex, int do_pty)
        !           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: 
        !           506: #ifndef HAVE_STRDUP
        !           507: char *strdup(const char *str)
        !           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
        !           519: void snooze_hup(int num)
        !           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:        
        !           559: void snooze()
        !           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: 
        !           583: void relay(int s)
        !           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: 
        !           643: int (*lprint_print)(void *, const char *, va_list);
        !           644: char *lprint_ptr, *lprint_ptr2, **lprint_arg;
        !           645: 
        !           646: void lprint(const char *format, ...)
        !           647: {
        !           648:        va_list args;
        !           649:         
        !           650:     va_start(args, format);
        !           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: 
        !           699: void add_emu(char *buff)
        !           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: 
        !           791: int vsprintf_len(char *string, const char *format, va_list args)
        !           792: {
        !           793:        vsprintf(string, format, args);
        !           794:        return strlen(string);
        !           795: }
        !           796: 
        !           797: int sprintf_len(char *string, const char *format, ...)
        !           798: {
        !           799:        va_list args;
        !           800:        va_start(args, format);
        !           801:        vsprintf(string, format, args);
        !           802:        va_end(args);
        !           803:        return strlen(string);
        !           804: }
        !           805: 
        !           806: #endif
        !           807: 
        !           808: void u_sleep(int usec)
        !           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: 
        !           825: void fd_nonblock(int fd)
        !           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: 
        !           840: void fd_block(int fd)
        !           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:  */
        !           860: int rsh_exec(struct socket *so, struct socket *ns,
        !           861:        char *user, char *host, char *args)
        !           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.