Annotation of 43BSDReno/libexec/telnetd/utility.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1989 Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms are permitted provided
        !             6:  * that: (1) source distributions retain this entire copyright notice and
        !             7:  * comment, and (2) distributions including binaries display the following
        !             8:  * acknowledgement:  ``This product includes software developed by the
        !             9:  * University of California, Berkeley and its contributors'' in the
        !            10:  * documentation or other materials provided with the distribution and in
        !            11:  * all advertising materials mentioning features or use of this software.
        !            12:  * Neither the name of the University nor the names of its contributors may
        !            13:  * be used to endorse or promote products derived from this software without
        !            14:  * specific prior written permission.
        !            15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            16:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            17:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            18:  */
        !            19: 
        !            20: #ifndef lint
        !            21: static char sccsid[] = "@(#)utility.c  5.4 (Berkeley) 6/28/90";
        !            22: #endif /* not lint */
        !            23: 
        !            24: #define PRINTOPTIONS
        !            25: #include "telnetd.h"
        !            26: 
        !            27: /*
        !            28:  * utility functions performing io related tasks
        !            29:  */
        !            30: 
        !            31: /*
        !            32:  * ttloop
        !            33:  *
        !            34:  *     A small subroutine to flush the network output buffer, get some data
        !            35:  * from the network, and pass it through the telnet state machine.  We
        !            36:  * also flush the pty input buffer (by dropping its data) if it becomes
        !            37:  * too full.
        !            38:  */
        !            39: 
        !            40: void
        !            41: ttloop()
        !            42: {
        !            43:     void netflush();
        !            44: 
        !            45: #ifdef DIAGNOSTICS
        !            46:     if (diagnostic & TD_REPORT) {
        !            47:        sprintf(nfrontp, "td: ttloop\r\n");
        !            48:        nfrontp += strlen(nfrontp);
        !            49:     }
        !            50: #endif /* DIAGNOSTICS */
        !            51:     if (nfrontp-nbackp) {
        !            52:        netflush();
        !            53:     }
        !            54:     ncc = read(net, netibuf, sizeof netibuf);
        !            55:     if (ncc < 0) {
        !            56:        syslog(LOG_INFO, "ttloop:  read: %m\n");
        !            57:        exit(1);
        !            58:     } else if (ncc == 0) {
        !            59:        syslog(LOG_INFO, "ttloop:  peer died: %m\n");
        !            60:        exit(1);
        !            61:     }
        !            62: #ifdef DIAGNOSTICS
        !            63:     if (diagnostic & TD_REPORT) {
        !            64:        sprintf(nfrontp, "td: ttloop read %d chars\r\n", ncc);
        !            65:        nfrontp += strlen(nfrontp);
        !            66:     }
        !            67: #endif /* DIAGNOSTICS */
        !            68:     netip = netibuf;
        !            69:     telrcv();                  /* state machine */
        !            70:     if (ncc > 0) {
        !            71:        pfrontp = pbackp = ptyobuf;
        !            72:        telrcv();
        !            73:     }
        !            74: }  /* end of ttloop */
        !            75: 
        !            76: /*
        !            77:  * Check a descriptor to see if out of band data exists on it.
        !            78:  */
        !            79: stilloob(s)
        !            80: int    s;              /* socket number */
        !            81: {
        !            82:     static struct timeval timeout = { 0 };
        !            83:     fd_set     excepts;
        !            84:     int value;
        !            85: 
        !            86:     do {
        !            87:        FD_ZERO(&excepts);
        !            88:        FD_SET(s, &excepts);
        !            89:        value = select(s+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout);
        !            90:     } while ((value == -1) && (errno == EINTR));
        !            91: 
        !            92:     if (value < 0) {
        !            93:        fatalperror(pty, "select");
        !            94:     }
        !            95:     if (FD_ISSET(s, &excepts)) {
        !            96:        return 1;
        !            97:     } else {
        !            98:        return 0;
        !            99:     }
        !           100: }
        !           101: 
        !           102: ptyflush()
        !           103: {
        !           104:        int n;
        !           105: 
        !           106:        if ((n = pfrontp - pbackp) > 0) {
        !           107: #ifdef DIAGNOSTICS
        !           108:                if (diagnostic & (TD_REPORT | TD_PTYDATA)) {
        !           109:                        sprintf(nfrontp, "td: ptyflush %d chars\r\n", n);
        !           110:                        nfrontp += strlen(nfrontp);
        !           111:                }
        !           112:                if (diagnostic & TD_PTYDATA) {
        !           113:                        printdata("pd", pbackp, n);
        !           114:                }
        !           115: #endif /* DIAGNOSTICS */
        !           116:                n = write(pty, pbackp, n);
        !           117:        }
        !           118:        if (n < 0)
        !           119:                return;
        !           120:        pbackp += n;
        !           121:        if (pbackp == pfrontp)
        !           122:                pbackp = pfrontp = ptyobuf;
        !           123: }
        !           124: 
        !           125: /*
        !           126:  * nextitem()
        !           127:  *
        !           128:  *     Return the address of the next "item" in the TELNET data
        !           129:  * stream.  This will be the address of the next character if
        !           130:  * the current address is a user data character, or it will
        !           131:  * be the address of the character following the TELNET command
        !           132:  * if the current address is a TELNET IAC ("I Am a Command")
        !           133:  * character.
        !           134:  */
        !           135: char *
        !           136: nextitem(current)
        !           137: char   *current;
        !           138: {
        !           139:     if ((*current&0xff) != IAC) {
        !           140:        return current+1;
        !           141:     }
        !           142:     switch (*(current+1)&0xff) {
        !           143:     case DO:
        !           144:     case DONT:
        !           145:     case WILL:
        !           146:     case WONT:
        !           147:        return current+3;
        !           148:     case SB:           /* loop forever looking for the SE */
        !           149:        {
        !           150:            register char *look = current+2;
        !           151: 
        !           152:            for (;;) {
        !           153:                if ((*look++&0xff) == IAC) {
        !           154:                    if ((*look++&0xff) == SE) {
        !           155:                        return look;
        !           156:                    }
        !           157:                }
        !           158:            }
        !           159:        }
        !           160:     default:
        !           161:        return current+2;
        !           162:     }
        !           163: }  /* end of nextitem */
        !           164: 
        !           165: 
        !           166: /*
        !           167:  * netclear()
        !           168:  *
        !           169:  *     We are about to do a TELNET SYNCH operation.  Clear
        !           170:  * the path to the network.
        !           171:  *
        !           172:  *     Things are a bit tricky since we may have sent the first
        !           173:  * byte or so of a previous TELNET command into the network.
        !           174:  * So, we have to scan the network buffer from the beginning
        !           175:  * until we are up to where we want to be.
        !           176:  *
        !           177:  *     A side effect of what we do, just to keep things
        !           178:  * simple, is to clear the urgent data pointer.  The principal
        !           179:  * caller should be setting the urgent data pointer AFTER calling
        !           180:  * us in any case.
        !           181:  */
        !           182: netclear()
        !           183: {
        !           184:     register char *thisitem, *next;
        !           185:     char *good;
        !           186: #define        wewant(p)       ((nfrontp > p) && ((*p&0xff) == IAC) && \
        !           187:                                ((*(p+1)&0xff) != EC) && ((*(p+1)&0xff) != EL))
        !           188: 
        !           189:     thisitem = netobuf;
        !           190: 
        !           191:     while ((next = nextitem(thisitem)) <= nbackp) {
        !           192:        thisitem = next;
        !           193:     }
        !           194: 
        !           195:     /* Now, thisitem is first before/at boundary. */
        !           196: 
        !           197:     good = netobuf;    /* where the good bytes go */
        !           198: 
        !           199:     while (nfrontp > thisitem) {
        !           200:        if (wewant(thisitem)) {
        !           201:            int length;
        !           202: 
        !           203:            next = thisitem;
        !           204:            do {
        !           205:                next = nextitem(next);
        !           206:            } while (wewant(next) && (nfrontp > next));
        !           207:            length = next-thisitem;
        !           208:            bcopy(thisitem, good, length);
        !           209:            good += length;
        !           210:            thisitem = next;
        !           211:        } else {
        !           212:            thisitem = nextitem(thisitem);
        !           213:        }
        !           214:     }
        !           215: 
        !           216:     nbackp = netobuf;
        !           217:     nfrontp = good;            /* next byte to be sent */
        !           218:     neturg = 0;
        !           219: }  /* end of netclear */
        !           220: 
        !           221: /*
        !           222:  *  netflush
        !           223:  *             Send as much data as possible to the network,
        !           224:  *     handling requests for urgent data.
        !           225:  */
        !           226: void
        !           227: netflush()
        !           228: {
        !           229:     int n;
        !           230:     extern int not42;
        !           231: 
        !           232:     if ((n = nfrontp - nbackp) > 0) {
        !           233: #ifdef DIAGNOSTICS
        !           234:        if (diagnostic & TD_REPORT) {
        !           235:            sprintf(nfrontp, "td: netflush %d chars\r\n", n);
        !           236:            n += strlen(nfrontp);  /* get count first */
        !           237:            nfrontp += strlen(nfrontp);  /* then move pointer */
        !           238:        }
        !           239: #endif /* DIAGNOSTICS */
        !           240:        /*
        !           241:         * if no urgent data, or if the other side appears to be an
        !           242:         * old 4.2 client (and thus unable to survive TCP urgent data),
        !           243:         * write the entire buffer in non-OOB mode.
        !           244:         */
        !           245:        if ((neturg == 0) || (not42 == 0)) {
        !           246:            n = write(net, nbackp, n);  /* normal write */
        !           247:        } else {
        !           248:            n = neturg - nbackp;
        !           249:            /*
        !           250:             * In 4.2 (and 4.3) systems, there is some question about
        !           251:             * what byte in a sendOOB operation is the "OOB" data.
        !           252:             * To make ourselves compatible, we only send ONE byte
        !           253:             * out of band, the one WE THINK should be OOB (though
        !           254:             * we really have more the TCP philosophy of urgent data
        !           255:             * rather than the Unix philosophy of OOB data).
        !           256:             */
        !           257:            if (n > 1) {
        !           258:                n = send(net, nbackp, n-1, 0);  /* send URGENT all by itself */
        !           259:            } else {
        !           260:                n = send(net, nbackp, n, MSG_OOB);      /* URGENT data */
        !           261:            }
        !           262:        }
        !           263:     }
        !           264:     if (n < 0) {
        !           265:        if (errno == EWOULDBLOCK || errno == EINTR)
        !           266:                return;
        !           267:        cleanup();
        !           268:     }
        !           269:     nbackp += n;
        !           270:     if (nbackp >= neturg) {
        !           271:        neturg = 0;
        !           272:     }
        !           273:     if (nbackp == nfrontp) {
        !           274:        nbackp = nfrontp = netobuf;
        !           275:     }
        !           276:     return;
        !           277: }  /* end of netflush */
        !           278: 
        !           279: 
        !           280: /*
        !           281:  * writenet
        !           282:  *
        !           283:  * Just a handy little function to write a bit of raw data to the net.
        !           284:  * It will force a transmit of the buffer if necessary
        !           285:  *
        !           286:  * arguments
        !           287:  *    ptr - A pointer to a character string to write
        !           288:  *    len - How many bytes to write
        !           289:  */
        !           290: writenet(ptr, len)
        !           291: register char *ptr;
        !           292: register int len;
        !           293: {
        !           294:        /* flush buffer if no room for new data) */
        !           295:        if ((&netobuf[BUFSIZ] - nfrontp) < len) {
        !           296:                /* if this fails, don't worry, buffer is a little big */
        !           297:                netflush();
        !           298:        }
        !           299: 
        !           300:        bcopy(ptr, nfrontp, len);
        !           301:        nfrontp += len;
        !           302: 
        !           303: }  /* end of writenet */
        !           304: 
        !           305: 
        !           306: /*
        !           307:  * miscellaneous functions doing a variety of little jobs follow ...
        !           308:  */
        !           309: 
        !           310: 
        !           311: fatal(f, msg)
        !           312:        int f;
        !           313:        char *msg;
        !           314: {
        !           315:        char buf[BUFSIZ];
        !           316: 
        !           317:        (void) sprintf(buf, "telnetd: %s.\r\n", msg);
        !           318:        (void) write(f, buf, (int)strlen(buf));
        !           319:        sleep(1);       /*XXX*/
        !           320:        exit(1);
        !           321: }
        !           322: 
        !           323: fatalperror(f, msg)
        !           324:        int f;
        !           325:        char *msg;
        !           326: {
        !           327:        char buf[BUFSIZ], *strerror();
        !           328: 
        !           329:        (void) sprintf(buf, "%s: %s\r\n", msg, strerror(errno));
        !           330:        fatal(f, buf);
        !           331: }
        !           332: 
        !           333: char editedhost[32];
        !           334: 
        !           335: edithost(pat, host)
        !           336:        register char *pat;
        !           337:        register char *host;
        !           338: {
        !           339:        register char *res = editedhost;
        !           340:        char *strncpy();
        !           341: 
        !           342:        if (!pat)
        !           343:                pat = "";
        !           344:        while (*pat) {
        !           345:                switch (*pat) {
        !           346: 
        !           347:                case '#':
        !           348:                        if (*host)
        !           349:                                host++;
        !           350:                        break;
        !           351: 
        !           352:                case '@':
        !           353:                        if (*host)
        !           354:                                *res++ = *host++;
        !           355:                        break;
        !           356: 
        !           357:                default:
        !           358:                        *res++ = *pat;
        !           359:                        break;
        !           360:                }
        !           361:                if (res == &editedhost[sizeof editedhost - 1]) {
        !           362:                        *res = '\0';
        !           363:                        return;
        !           364:                }
        !           365:                pat++;
        !           366:        }
        !           367:        if (*host)
        !           368:                (void) strncpy(res, host,
        !           369:                                sizeof editedhost - (res - editedhost) -1);
        !           370:        else
        !           371:                *res = '\0';
        !           372:        editedhost[sizeof editedhost - 1] = '\0';
        !           373: }
        !           374: 
        !           375: static char *putlocation;
        !           376: 
        !           377: putstr(s)
        !           378: register char *s;
        !           379: {
        !           380: 
        !           381:        while (*s)
        !           382:                putchr(*s++);
        !           383: }
        !           384: 
        !           385: putchr(cc)
        !           386: {
        !           387:        *putlocation++ = cc;
        !           388: }
        !           389: 
        !           390: putf(cp, where)
        !           391: register char *cp;
        !           392: char *where;
        !           393: {
        !           394:        char *slash;
        !           395: #ifndef        NO_GETTYTAB
        !           396:        char datebuffer[60];
        !           397: #endif /* NO_GETTYTAB */
        !           398:        extern char *rindex();
        !           399: 
        !           400:        putlocation = where;
        !           401: 
        !           402:        while (*cp) {
        !           403:                if (*cp != '%') {
        !           404:                        putchr(*cp++);
        !           405:                        continue;
        !           406:                }
        !           407:                switch (*++cp) {
        !           408: 
        !           409:                case 't':
        !           410:                        slash = rindex(line, '/');
        !           411:                        if (slash == (char *) 0)
        !           412:                                putstr(line);
        !           413:                        else
        !           414:                                putstr(&slash[1]);
        !           415:                        break;
        !           416: 
        !           417:                case 'h':
        !           418:                        putstr(editedhost);
        !           419:                        break;
        !           420: 
        !           421: #ifndef        NO_GETTYTAB
        !           422:                case 'd':
        !           423:                        get_date(datebuffer);
        !           424:                        putstr(datebuffer);
        !           425:                        break;
        !           426: #endif /* NO_GETTYTAB */
        !           427: 
        !           428:                case '%':
        !           429:                        putchr('%');
        !           430:                        break;
        !           431:                }
        !           432:                cp++;
        !           433:        }
        !           434: }
        !           435: 
        !           436: /*ARGSUSED*/
        !           437: #ifdef NO_GETTYTAB
        !           438: getent(cp, name)
        !           439: char *cp, *name;
        !           440: {
        !           441:        return(0);
        !           442: }
        !           443: 
        !           444: /*ARGSUSED*/
        !           445: char *
        !           446: getstr(cp, cpp)
        !           447: char *cp, **cpp;
        !           448: {
        !           449:        return(0);
        !           450: }
        !           451: #endif /* NO_GETTYTAB */
        !           452: 
        !           453: #ifdef DIAGNOSTICS
        !           454: /*
        !           455:  * Print telnet options and commands in plain text, if possible.
        !           456:  */
        !           457: void
        !           458: printoption(fmt, option)
        !           459: register char *fmt;
        !           460: register int option;
        !           461: {
        !           462:        if (TELOPT_OK(option))
        !           463:                sprintf(nfrontp, "%s %s\r\n", fmt, TELOPT(option));
        !           464:        else if (TELCMD_OK(option))
        !           465:                sprintf(nfrontp, "%s %s\r\n", fmt, TELCMD(option));
        !           466:        else
        !           467:                sprintf(nfrontp, "%s %d\r\n", fmt, option);
        !           468:        nfrontp += strlen(nfrontp);
        !           469:        return;
        !           470: }
        !           471: 
        !           472: char *slcnames[] = { SLC_NAMES };
        !           473: 
        !           474: void
        !           475: printsub(dirp, pointer, length)
        !           476: char   *dirp;
        !           477: unsigned char  *pointer;       /* where suboption data sits */
        !           478: int    length;                 /* length of suboption data */
        !           479: {
        !           480:     register int i;
        !           481: 
        !           482:        if (dirp) {
        !           483:            sprintf(nfrontp, "%s suboption ", dirp);
        !           484:            nfrontp += strlen(nfrontp);
        !           485:            if (length >= 3) {
        !           486:                register int j;
        !           487: 
        !           488:                i = pointer[length-2];
        !           489:                j = pointer[length-1];
        !           490: 
        !           491:                if (i != IAC || j != SE) {
        !           492:                    sprintf(nfrontp, "(terminated by ");
        !           493:                    nfrontp += strlen(nfrontp);
        !           494:                    if (TELOPT_OK(i))
        !           495:                        sprintf(nfrontp, "%s ", TELOPT(i));
        !           496:                    else if (TELCMD_OK(i))
        !           497:                        sprintf(nfrontp, "%s ", TELCMD(i));
        !           498:                    else
        !           499:                        sprintf(nfrontp, "%d ", i);
        !           500:                    nfrontp += strlen(nfrontp);
        !           501:                    if (TELOPT_OK(j))
        !           502:                        sprintf(nfrontp, "%s", TELOPT(j));
        !           503:                    else if (TELCMD_OK(j))
        !           504:                        sprintf(nfrontp, "%s", TELCMD(j));
        !           505:                    else
        !           506:                        sprintf(nfrontp, "%d", j);
        !           507:                    nfrontp += strlen(nfrontp);
        !           508:                    sprintf(nfrontp, ", not IAC SE!) ");
        !           509:                    nfrontp += strlen(nfrontp);
        !           510:                }
        !           511:            }
        !           512:            length -= 2;
        !           513:        }
        !           514:        if (length < 1) {
        !           515:            sprintf(nfrontp, "(Empty suboption???)");
        !           516:            nfrontp += strlen(nfrontp);
        !           517:            return;
        !           518:        }
        !           519:        switch (pointer[0]) {
        !           520:        case TELOPT_TTYPE:
        !           521:            sprintf(nfrontp, "TERMINAL-TYPE ");
        !           522:            nfrontp += strlen(nfrontp);
        !           523:            switch (pointer[1]) {
        !           524:            case TELQUAL_IS:
        !           525:                sprintf(nfrontp, "IS \"%.*s\"", length-2, (char *)pointer+2);
        !           526:                break;
        !           527:            case TELQUAL_SEND:
        !           528:                sprintf(nfrontp, "SEND");
        !           529:                break;
        !           530:            default:
        !           531:                sprintf(nfrontp,
        !           532:                                "- unknown qualifier %d (0x%x).",
        !           533:                                pointer[1], pointer[1]);
        !           534:            }
        !           535:            nfrontp += strlen(nfrontp);
        !           536:            break;
        !           537:        case TELOPT_TSPEED:
        !           538:            sprintf(nfrontp, "TERMINAL-SPEED");
        !           539:            nfrontp += strlen(nfrontp);
        !           540:            if (length < 2) {
        !           541:                sprintf(nfrontp, " (empty suboption???)");
        !           542:                nfrontp += strlen(nfrontp);
        !           543:                break;
        !           544:            }
        !           545:            switch (pointer[1]) {
        !           546:            case TELQUAL_IS:
        !           547:                sprintf(nfrontp, " IS %.*s", length-2, (char *)pointer+2);
        !           548:                nfrontp += strlen(nfrontp);
        !           549:                break;
        !           550:            default:
        !           551:                if (pointer[1] == 1)
        !           552:                    sprintf(nfrontp, " SEND");
        !           553:                else
        !           554:                    sprintf(nfrontp, " %d (unknown)", pointer[1]);
        !           555:                nfrontp += strlen(nfrontp);
        !           556:                for (i = 2; i < length; i++) {
        !           557:                    sprintf(nfrontp, " ?%d?", pointer[i]);
        !           558:                    nfrontp += strlen(nfrontp);
        !           559:                }
        !           560:                break;
        !           561:            }
        !           562:            break;
        !           563: 
        !           564:        case TELOPT_LFLOW:
        !           565:            sprintf(nfrontp, "TOGGLE-FLOW-CONTROL");
        !           566:            nfrontp += strlen(nfrontp);
        !           567:            if (length < 2) {
        !           568:                sprintf(nfrontp, " (empty suboption???)");
        !           569:                nfrontp += strlen(nfrontp);
        !           570:                break;
        !           571:            }
        !           572:            switch (pointer[1]) {
        !           573:            case 0:
        !           574:                sprintf(nfrontp, " OFF"); break;
        !           575:            case 1:
        !           576:                sprintf(nfrontp, " ON"); break;
        !           577:            default:
        !           578:                sprintf(nfrontp, " %d (unknown)", pointer[1]);
        !           579:            }
        !           580:            nfrontp += strlen(nfrontp);
        !           581:            for (i = 2; i < length; i++) {
        !           582:                sprintf(nfrontp, " ?%d?", pointer[i]);
        !           583:                nfrontp += strlen(nfrontp);
        !           584:            }
        !           585:            break;
        !           586: 
        !           587:        case TELOPT_NAWS:
        !           588:            sprintf(nfrontp, "NAWS");
        !           589:            nfrontp += strlen(nfrontp);
        !           590:            if (length < 2) {
        !           591:                sprintf(nfrontp, " (empty suboption???)");
        !           592:                nfrontp += strlen(nfrontp);
        !           593:                break;
        !           594:            }
        !           595:            if (length == 2) {
        !           596:                sprintf(nfrontp, " ?%d?", pointer[1]);
        !           597:                nfrontp += strlen(nfrontp);
        !           598:                break;
        !           599:            }
        !           600:            sprintf(nfrontp, " %d %d (%d)",
        !           601:                pointer[1], pointer[2],
        !           602:                (int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2])));
        !           603:            nfrontp += strlen(nfrontp);
        !           604:            if (length == 4) {
        !           605:                sprintf(nfrontp, " ?%d?", pointer[3]);
        !           606:                nfrontp += strlen(nfrontp);
        !           607:                break;
        !           608:            }
        !           609:            sprintf(nfrontp, " %d %d (%d)",
        !           610:                pointer[3], pointer[4],
        !           611:                (int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4])));
        !           612:            nfrontp += strlen(nfrontp);
        !           613:            for (i = 5; i < length; i++) {
        !           614:                sprintf(nfrontp, " ?%d?", pointer[i]);
        !           615:                nfrontp += strlen(nfrontp);
        !           616:            }
        !           617:            break;
        !           618: 
        !           619:        case TELOPT_LINEMODE:
        !           620:            sprintf(nfrontp, "LINEMODE ");
        !           621:            nfrontp += strlen(nfrontp);
        !           622:            if (length < 2) {
        !           623:                sprintf(nfrontp, " (empty suboption???)");
        !           624:                nfrontp += strlen(nfrontp);
        !           625:                break;
        !           626:            }
        !           627:            switch (pointer[1]) {
        !           628:            case WILL:
        !           629:                sprintf(nfrontp, "WILL ");
        !           630:                goto common;
        !           631:            case WONT:
        !           632:                sprintf(nfrontp, "WONT ");
        !           633:                goto common;
        !           634:            case DO:
        !           635:                sprintf(nfrontp, "DO ");
        !           636:                goto common;
        !           637:            case DONT:
        !           638:                sprintf(nfrontp, "DONT ");
        !           639:            common:
        !           640:                nfrontp += strlen(nfrontp);
        !           641:                if (length < 3) {
        !           642:                    sprintf(nfrontp, "(no option???)");
        !           643:                    nfrontp += strlen(nfrontp);
        !           644:                    break;
        !           645:                }
        !           646:                switch (pointer[2]) {
        !           647:                case LM_FORWARDMASK:
        !           648:                    sprintf(nfrontp, "Forward Mask");
        !           649:                    nfrontp += strlen(nfrontp);
        !           650:                    for (i = 3; i < length; i++) {
        !           651:                        sprintf(nfrontp, " %x", pointer[i]);
        !           652:                        nfrontp += strlen(nfrontp);
        !           653:                    }
        !           654:                    break;
        !           655:                default:
        !           656:                    sprintf(nfrontp, "%d (unknown)", pointer[2]);
        !           657:                    nfrontp += strlen(nfrontp);
        !           658:                    for (i = 3; i < length; i++) {
        !           659:                        sprintf(nfrontp, " %d", pointer[i]);
        !           660:                        nfrontp += strlen(nfrontp);
        !           661:                    }
        !           662:                    break;
        !           663:                }
        !           664:                break;
        !           665:                
        !           666:            case LM_SLC:
        !           667:                sprintf(nfrontp, "SLC");
        !           668:                nfrontp += strlen(nfrontp);
        !           669:                for (i = 2; i < length - 2; i += 3) {
        !           670:                    if (pointer[i+SLC_FUNC] <= NSLC)
        !           671:                        sprintf(nfrontp, " %s", slcnames[pointer[i+SLC_FUNC]]);
        !           672:                    else
        !           673:                        sprintf(nfrontp, " %d", pointer[i+SLC_FUNC]);
        !           674:                    nfrontp += strlen(nfrontp);
        !           675:                    switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) {
        !           676:                    case SLC_NOSUPPORT:
        !           677:                        sprintf(nfrontp, " NOSUPPORT"); break;
        !           678:                    case SLC_CANTCHANGE:
        !           679:                        sprintf(nfrontp, " CANTCHANGE"); break;
        !           680:                    case SLC_VARIABLE:
        !           681:                        sprintf(nfrontp, " VARIABLE"); break;
        !           682:                    case SLC_DEFAULT:
        !           683:                        sprintf(nfrontp, " DEFAULT"); break;
        !           684:                    }
        !           685:                    nfrontp += strlen(nfrontp);
        !           686:                    sprintf(nfrontp, "%s%s%s",
        !           687:                        pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "",
        !           688:                        pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "",
        !           689:                        pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : "");
        !           690:                    nfrontp += strlen(nfrontp);
        !           691:                    if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN|
        !           692:                                                SLC_FLUSHOUT| SLC_LEVELBITS)) {
        !           693:                        sprintf(nfrontp, "(0x%x)", pointer[i+SLC_FLAGS]);
        !           694:                        nfrontp += strlen(nfrontp);
        !           695:                    }
        !           696:                    sprintf(nfrontp, " %d;", pointer[i+SLC_VALUE]);
        !           697:                    nfrontp += strlen(nfrontp);
        !           698:                    if ((pointer[i+SLC_VALUE] == IAC) &&
        !           699:                        (pointer[i+SLC_VALUE+1] == IAC))
        !           700:                                i++;
        !           701:                }
        !           702:                for (; i < length; i++) {
        !           703:                    sprintf(nfrontp, " ?%d?", pointer[i]);
        !           704:                    nfrontp += strlen(nfrontp);
        !           705:                }
        !           706:                break;
        !           707: 
        !           708:            case LM_MODE:
        !           709:                sprintf(nfrontp, "MODE ");
        !           710:                nfrontp += strlen(nfrontp);
        !           711:                if (length < 3) {
        !           712:                    sprintf(nfrontp, "(no mode???)");
        !           713:                    nfrontp += strlen(nfrontp);
        !           714:                    break;
        !           715:                }
        !           716:                {
        !           717:                    char tbuf[32];
        !           718:                    sprintf(tbuf, "%s%s%s%s%s",
        !           719:                        pointer[2]&MODE_EDIT ? "|EDIT" : "",
        !           720:                        pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "",
        !           721:                        pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "",
        !           722:                        pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "",
        !           723:                        pointer[2]&MODE_ACK ? "|ACK" : "");
        !           724:                    sprintf(nfrontp, "%s", tbuf[1] ? &tbuf[1] : "0");
        !           725:                    nfrontp += strlen(nfrontp);
        !           726:                }
        !           727:                if (pointer[2]&~(MODE_EDIT|MODE_TRAPSIG|MODE_ACK)) {
        !           728:                    sprintf(nfrontp, " (0x%x)", pointer[2]);
        !           729:                    nfrontp += strlen(nfrontp);
        !           730:                }
        !           731:                for (i = 3; i < length; i++) {
        !           732:                    sprintf(nfrontp, " ?0x%x?", pointer[i]);
        !           733:                    nfrontp += strlen(nfrontp);
        !           734:                }
        !           735:                break;
        !           736:            default:
        !           737:                sprintf(nfrontp, "%d (unknown)", pointer[1]);
        !           738:                nfrontp += strlen(nfrontp);
        !           739:                for (i = 2; i < length; i++) {
        !           740:                    sprintf(nfrontp, " %d", pointer[i]);
        !           741:                    nfrontp += strlen(nfrontp);
        !           742:                }
        !           743:            }
        !           744:            break;
        !           745: 
        !           746:        case TELOPT_STATUS: {
        !           747:            register char *cp;
        !           748:            register int j, k;
        !           749: 
        !           750:            sprintf(nfrontp, "STATUS");
        !           751:            nfrontp += strlen(nfrontp);
        !           752: 
        !           753:            switch (pointer[1]) {
        !           754:            default:
        !           755:                if (pointer[1] == TELQUAL_SEND)
        !           756:                    sprintf(nfrontp, " SEND");
        !           757:                else
        !           758:                    sprintf(nfrontp, " %d (unknown)", pointer[1]);
        !           759:                nfrontp += strlen(nfrontp);
        !           760:                for (i = 2; i < length; i++) {
        !           761:                    sprintf(nfrontp, " ?%d?", pointer[i]);
        !           762:                    nfrontp += strlen(nfrontp);
        !           763:                }
        !           764:                break;
        !           765:            case TELQUAL_IS:
        !           766:                sprintf(nfrontp, " IS\r\n");
        !           767:                nfrontp += strlen(nfrontp);
        !           768: 
        !           769:                for (i = 2; i < length; i++) {
        !           770:                    switch(pointer[i]) {
        !           771:                    case DO:    cp = "DO"; goto common2;
        !           772:                    case DONT:  cp = "DONT"; goto common2;
        !           773:                    case WILL:  cp = "WILL"; goto common2;
        !           774:                    case WONT:  cp = "WONT"; goto common2;
        !           775:                    common2:
        !           776:                        i++;
        !           777:                        if (TELOPT_OK((int)pointer[i]))
        !           778:                            sprintf(nfrontp, " %s %s", cp, TELOPT(pointer[i]));
        !           779:                        else
        !           780:                            sprintf(nfrontp, " %s %d", cp, pointer[i]);
        !           781:                        nfrontp += strlen(nfrontp);
        !           782: 
        !           783:                        sprintf(nfrontp, "\r\n");
        !           784:                        nfrontp += strlen(nfrontp);
        !           785:                        break;
        !           786: 
        !           787:                    case SB:
        !           788:                        sprintf(nfrontp, " SB ");
        !           789:                        nfrontp += strlen(nfrontp);
        !           790:                        i++;
        !           791:                        j = k = i;
        !           792:                        while (j < length) {
        !           793:                            if (pointer[j] == SE) {
        !           794:                                if (j+1 == length)
        !           795:                                    break;
        !           796:                                if (pointer[j+1] == SE)
        !           797:                                    j++;
        !           798:                                else
        !           799:                                    break;
        !           800:                            }
        !           801:                            pointer[k++] = pointer[j++];
        !           802:                        }
        !           803:                        printsub(0, &pointer[i], k - i);
        !           804:                        if (i < length) {
        !           805:                            sprintf(nfrontp, " SE");
        !           806:                            nfrontp += strlen(nfrontp);
        !           807:                            i = j;
        !           808:                        } else
        !           809:                            i = j - 1;
        !           810: 
        !           811:                        sprintf(nfrontp, "\r\n");
        !           812:                        nfrontp += strlen(nfrontp);
        !           813: 
        !           814:                        break;
        !           815:                                
        !           816:                    default:
        !           817:                        sprintf(nfrontp, " %d", pointer[i]);
        !           818:                        nfrontp += strlen(nfrontp);
        !           819:                        break;
        !           820:                    }
        !           821:                }
        !           822:                break;
        !           823:            }
        !           824:            break;
        !           825:          }
        !           826: 
        !           827:        case TELOPT_XDISPLOC:
        !           828:            sprintf(nfrontp, "X-DISPLAY-LOCATION ");
        !           829:            nfrontp += strlen(nfrontp);
        !           830:            switch (pointer[1]) {
        !           831:            case TELQUAL_IS:
        !           832:                sprintf(nfrontp, "IS \"%.*s\"", length-2, (char *)pointer+2);
        !           833:                break;
        !           834:            case TELQUAL_SEND:
        !           835:                sprintf(nfrontp, "SEND");
        !           836:                break;
        !           837:            default:
        !           838:                sprintf(nfrontp, "- unknown qualifier %d (0x%x).",
        !           839:                                pointer[1], pointer[1]);
        !           840:            }
        !           841:            nfrontp += strlen(nfrontp);
        !           842:            break;
        !           843: 
        !           844:        case TELOPT_ENVIRON:
        !           845:            sprintf(nfrontp, "ENVIRON ");
        !           846:            nfrontp += strlen(nfrontp);
        !           847:            switch (pointer[1]) {
        !           848:            case TELQUAL_IS:
        !           849:                sprintf(nfrontp, "IS ");
        !           850:                goto env_common;
        !           851:            case TELQUAL_SEND:
        !           852:                sprintf(nfrontp, "SEND ");
        !           853:                goto env_common;
        !           854:            case TELQUAL_INFO:
        !           855:                sprintf(nfrontp, "INFO ");
        !           856:            env_common:
        !           857:            nfrontp += strlen(nfrontp);
        !           858:                {
        !           859:                    register int noquote = 2;
        !           860:                    for (i = 2; i < length; i++ ) {
        !           861:                        switch (pointer[i]) {
        !           862:                        case ENV_VAR:
        !           863:                            if (pointer[1] == TELQUAL_SEND)
        !           864:                                goto def_case;
        !           865:                            sprintf(nfrontp, "\" VAR " + noquote);
        !           866:                            nfrontp += strlen(nfrontp);
        !           867:                            noquote = 2;
        !           868:                            break;
        !           869: 
        !           870:                        case ENV_VALUE:
        !           871:                            sprintf(nfrontp, "\" VALUE " + noquote);
        !           872:                            nfrontp += strlen(nfrontp);
        !           873:                            noquote = 2;
        !           874:                            break;
        !           875: 
        !           876:                        case ENV_ESC:
        !           877:                            sprintf(nfrontp, "\" ESC " + noquote);
        !           878:                            nfrontp += strlen(nfrontp);
        !           879:                            noquote = 2;
        !           880:                            break;
        !           881: 
        !           882:                        default:
        !           883:                        def_case:
        !           884:                            if (isprint(pointer[i]) && pointer[i] != '"') {
        !           885:                                if (noquote) {
        !           886:                                    *nfrontp++ = '"';
        !           887:                                    noquote = 0;
        !           888:                                }
        !           889:                                *nfrontp++ = pointer[i];
        !           890:                            } else {
        !           891:                                sprintf(nfrontp, "\" %03o " + noquote,
        !           892:                                                        pointer[i]);
        !           893:                                nfrontp += strlen(nfrontp);
        !           894:                                noquote = 2;
        !           895:                            }
        !           896:                            break;
        !           897:                        }
        !           898:                    }
        !           899:                    if (!noquote)
        !           900:                        *nfrontp++ = '"';
        !           901:                    break;
        !           902:                }
        !           903:            }
        !           904:            break;
        !           905: 
        !           906:        default:
        !           907:            sprintf(nfrontp, "Unknown option ");
        !           908:            nfrontp += strlen(nfrontp);
        !           909:            for (i = 0; i < length; i++) {
        !           910:                sprintf(nfrontp, " %d", pointer[i]);
        !           911:                nfrontp += strlen(nfrontp);
        !           912:            }
        !           913:            break;
        !           914:        }
        !           915:        sprintf(nfrontp, "\r\n");
        !           916:        nfrontp += strlen(nfrontp);
        !           917: }
        !           918: 
        !           919: /*
        !           920:  * Dump a data buffer in hex and ascii to the output data stream.
        !           921:  */
        !           922: void
        !           923: printdata(tag, ptr, cnt)
        !           924: register char *tag;
        !           925: register char *ptr;
        !           926: register int cnt;
        !           927: {
        !           928: register int i;
        !           929: char xbuf[30];
        !           930: 
        !           931:        while (cnt) {
        !           932:                /* flush net output buffer if no room for new data) */
        !           933:                if ((&netobuf[BUFSIZ] - nfrontp) < 80) {
        !           934:                        netflush();
        !           935:                }
        !           936: 
        !           937:                /* add a line of output */
        !           938:                sprintf(nfrontp, "%s: ", tag);
        !           939:                nfrontp += strlen(nfrontp);
        !           940:                for (i = 0; i < 20 && cnt; i++) {
        !           941:                        sprintf(nfrontp, "%02x", *ptr);
        !           942:                        nfrontp += strlen(nfrontp); 
        !           943:                        if (isprint(*ptr)) {
        !           944:                                xbuf[i] = *ptr;
        !           945:                        } else {
        !           946:                                xbuf[i] = '.';
        !           947:                        }
        !           948:                        if (i % 2) { 
        !           949:                                *nfrontp = ' ';
        !           950:                                nfrontp++;
        !           951:                        }
        !           952:                        cnt--;
        !           953:                        ptr++;
        !           954:                }
        !           955:                xbuf[i] = '\0';
        !           956:                sprintf(nfrontp, " %s\r\n", xbuf );
        !           957:                nfrontp += strlen(nfrontp);
        !           958:        } 
        !           959: }
        !           960: 
        !           961: #endif /* DIAGNOSTICS */
        !           962: 
        !           963: #ifdef NO_STRERROR
        !           964: char *
        !           965: strerror(errno)
        !           966: {
        !           967:        extern char *sys_errlist[];
        !           968: 
        !           969:        return(sys_errlist[errno]);
        !           970: }
        !           971: #endif

unix.superglobalmegacorp.com

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