[BACK]Return to utilities.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / telnet

Annotation of src/usr.bin/telnet/utilities.c, Revision 1.4

1.4     ! jason       1: /*     $OpenBSD: utilities.c,v 1.3 1996/12/12 11:24:08 robin Exp $     */
1.2       niklas      2: /*     $NetBSD: utilities.c,v 1.5 1996/02/28 21:04:21 thorpej Exp $    */
                      3:
1.1       deraadt     4: /*
                      5:  * Copyright (c) 1988, 1993
                      6:  *     The Regents of the University of California.  All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *     This product includes software developed by the University of
                     19:  *     California, Berkeley and its contributors.
                     20:  * 4. Neither the name of the University nor the names of its contributors
                     21:  *    may be used to endorse or promote products derived from this software
                     22:  *    without specific prior written permission.
                     23:  *
                     24:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     25:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     26:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     27:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     28:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     29:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     30:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     31:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     32:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     33:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     34:  * SUCH DAMAGE.
                     35:  */
                     36:
                     37: #ifndef lint
1.2       niklas     38: #if 0
                     39: static char sccsid[] = "@(#)utilities.c        8.3 (Berkeley) 5/30/95";
                     40: static char rcsid[] = "$NetBSD: utilities.c,v 1.5 1996/02/28 21:04:21 thorpej Exp $";
                     41: #else
1.4     ! jason      42: static char rcsid[] = "$OpenBSD: utilities.c,v 1.3 1996/12/12 11:24:08 robin Exp $";
1.2       niklas     43: #endif
1.1       deraadt    44: #endif /* not lint */
                     45:
                     46: #define        TELOPTS
                     47: #define        TELCMDS
                     48: #define        SLC_NAMES
                     49: #include <arpa/telnet.h>
                     50: #include <sys/types.h>
                     51: #include <sys/time.h>
1.3       robin      52: #include <sys/socket.h>
                     53: #include <unistd.h>
1.1       deraadt    54: #include <ctype.h>
                     55:
                     56: #include "general.h"
                     57:
                     58: #include "fdset.h"
                     59:
                     60: #include "ring.h"
                     61:
                     62: #include "defines.h"
                     63:
                     64: #include "externs.h"
                     65:
                     66: FILE   *NetTrace = 0;          /* Not in bss, since needs to stay */
                     67: int    prettydump;
                     68:
                     69: /*
                     70:  * upcase()
                     71:  *
                     72:  *     Upcase (in place) the argument.
                     73:  */
                     74:
                     75:     void
                     76: upcase(argument)
                     77:     register char *argument;
                     78: {
                     79:     register int c;
                     80:
                     81:     while ((c = *argument) != 0) {
                     82:        if (islower(c)) {
                     83:            *argument = toupper(c);
                     84:        }
                     85:        argument++;
                     86:     }
                     87: }
                     88:
                     89: /*
                     90:  * SetSockOpt()
                     91:  *
                     92:  * Compensate for differences in 4.2 and 4.3 systems.
                     93:  */
                     94:
                     95:     int
                     96: SetSockOpt(fd, level, option, yesno)
                     97:     int fd, level, option, yesno;
                     98: {
                     99: #ifndef        NOT43
                    100:     return setsockopt(fd, level, option,
                    101:                                (char *)&yesno, sizeof yesno);
                    102: #else  /* NOT43 */
                    103:     if (yesno == 0) {          /* Can't do that in 4.2! */
                    104:        fprintf(stderr, "Error: attempt to turn off an option 0x%x.\n",
                    105:                                option);
                    106:        return -1;
                    107:     }
                    108:     return setsockopt(fd, level, option, 0, 0);
                    109: #endif /* NOT43 */
                    110: }
                    111: 
                    112: /*
                    113:  * The following are routines used to print out debugging information.
                    114:  */
                    115:
                    116: unsigned char NetTraceFile[256] = "(standard output)";
                    117:
                    118:     void
                    119: SetNetTrace(file)
                    120:     register char *file;
                    121: {
                    122:     if (NetTrace && NetTrace != stdout)
                    123:        fclose(NetTrace);
                    124:     if (file  && (strcmp(file, "-") != 0)) {
                    125:        NetTrace = fopen(file, "w");
                    126:        if (NetTrace) {
                    127:            strcpy((char *)NetTraceFile, file);
                    128:            return;
                    129:        }
                    130:        fprintf(stderr, "Cannot open %s.\n", file);
                    131:     }
                    132:     NetTrace = stdout;
                    133:     strcpy((char *)NetTraceFile, "(standard output)");
                    134: }
                    135:
                    136:     void
                    137: Dump(direction, buffer, length)
                    138:     char direction;
                    139:     unsigned char *buffer;
                    140:     int length;
                    141: {
                    142: #   define BYTES_PER_LINE      32
                    143: #   define min(x,y)    ((x<y)? x:y)
                    144:     unsigned char *pThis;
                    145:     int offset;
                    146:
                    147:     offset = 0;
                    148:
                    149:     while (length) {
                    150:        /* print one line */
                    151:        fprintf(NetTrace, "%c 0x%x\t", direction, offset);
                    152:        pThis = buffer;
                    153:        if (prettydump) {
                    154:            buffer = buffer + min(length, BYTES_PER_LINE/2);
                    155:            while (pThis < buffer) {
                    156:                fprintf(NetTrace, "%c%.2x",
                    157:                    (((*pThis)&0xff) == 0xff) ? '*' : ' ',
                    158:                    (*pThis)&0xff);
                    159:                pThis++;
                    160:            }
                    161:            length -= BYTES_PER_LINE/2;
                    162:            offset += BYTES_PER_LINE/2;
                    163:        } else {
                    164:            buffer = buffer + min(length, BYTES_PER_LINE);
                    165:            while (pThis < buffer) {
                    166:                fprintf(NetTrace, "%.2x", (*pThis)&0xff);
                    167:                pThis++;
                    168:            }
                    169:            length -= BYTES_PER_LINE;
                    170:            offset += BYTES_PER_LINE;
                    171:        }
                    172:        if (NetTrace == stdout) {
                    173:            fprintf(NetTrace, "\r\n");
                    174:        } else {
                    175:            fprintf(NetTrace, "\n");
                    176:        }
                    177:        if (length < 0) {
                    178:            fflush(NetTrace);
                    179:            return;
                    180:        }
                    181:        /* find next unique line */
                    182:     }
                    183:     fflush(NetTrace);
                    184: }
                    185:
                    186:
                    187:        void
                    188: printoption(direction, cmd, option)
                    189:        char *direction;
                    190:        int cmd, option;
                    191: {
                    192:        if (!showoptions)
                    193:                return;
                    194:        if (cmd == IAC) {
                    195:                if (TELCMD_OK(option))
                    196:                    fprintf(NetTrace, "%s IAC %s", direction, TELCMD(option));
                    197:                else
                    198:                    fprintf(NetTrace, "%s IAC %d", direction, option);
                    199:        } else {
                    200:                register char *fmt;
                    201:                fmt = (cmd == WILL) ? "WILL" : (cmd == WONT) ? "WONT" :
                    202:                        (cmd == DO) ? "DO" : (cmd == DONT) ? "DONT" : 0;
                    203:                if (fmt) {
                    204:                    fprintf(NetTrace, "%s %s ", direction, fmt);
                    205:                    if (TELOPT_OK(option))
                    206:                        fprintf(NetTrace, "%s", TELOPT(option));
                    207:                    else if (option == TELOPT_EXOPL)
                    208:                        fprintf(NetTrace, "EXOPL");
                    209:                    else
                    210:                        fprintf(NetTrace, "%d", option);
                    211:                } else
                    212:                    fprintf(NetTrace, "%s %d %d", direction, cmd, option);
                    213:        }
                    214:        if (NetTrace == stdout) {
                    215:            fprintf(NetTrace, "\r\n");
                    216:            fflush(NetTrace);
                    217:        } else {
                    218:            fprintf(NetTrace, "\n");
                    219:        }
                    220:        return;
                    221: }
                    222:
                    223:     void
                    224: optionstatus()
                    225: {
                    226:     register int i;
                    227:     extern char will_wont_resp[], do_dont_resp[];
                    228:
                    229:     for (i = 0; i < 256; i++) {
                    230:        if (do_dont_resp[i]) {
                    231:            if (TELOPT_OK(i))
                    232:                printf("resp DO_DONT %s: %d\n", TELOPT(i), do_dont_resp[i]);
                    233:            else if (TELCMD_OK(i))
                    234:                printf("resp DO_DONT %s: %d\n", TELCMD(i), do_dont_resp[i]);
                    235:            else
                    236:                printf("resp DO_DONT %d: %d\n", i,
                    237:                                do_dont_resp[i]);
                    238:            if (my_want_state_is_do(i)) {
                    239:                if (TELOPT_OK(i))
                    240:                    printf("want DO   %s\n", TELOPT(i));
                    241:                else if (TELCMD_OK(i))
                    242:                    printf("want DO   %s\n", TELCMD(i));
                    243:                else
                    244:                    printf("want DO   %d\n", i);
                    245:            } else {
                    246:                if (TELOPT_OK(i))
                    247:                    printf("want DONT %s\n", TELOPT(i));
                    248:                else if (TELCMD_OK(i))
                    249:                    printf("want DONT %s\n", TELCMD(i));
                    250:                else
                    251:                    printf("want DONT %d\n", i);
                    252:            }
                    253:        } else {
                    254:            if (my_state_is_do(i)) {
                    255:                if (TELOPT_OK(i))
                    256:                    printf("     DO   %s\n", TELOPT(i));
                    257:                else if (TELCMD_OK(i))
                    258:                    printf("     DO   %s\n", TELCMD(i));
                    259:                else
                    260:                    printf("     DO   %d\n", i);
                    261:            }
                    262:        }
                    263:        if (will_wont_resp[i]) {
                    264:            if (TELOPT_OK(i))
                    265:                printf("resp WILL_WONT %s: %d\n", TELOPT(i), will_wont_resp[i]);
                    266:            else if (TELCMD_OK(i))
                    267:                printf("resp WILL_WONT %s: %d\n", TELCMD(i), will_wont_resp[i]);
                    268:            else
                    269:                printf("resp WILL_WONT %d: %d\n",
                    270:                                i, will_wont_resp[i]);
                    271:            if (my_want_state_is_will(i)) {
                    272:                if (TELOPT_OK(i))
                    273:                    printf("want WILL %s\n", TELOPT(i));
                    274:                else if (TELCMD_OK(i))
                    275:                    printf("want WILL %s\n", TELCMD(i));
                    276:                else
                    277:                    printf("want WILL %d\n", i);
                    278:            } else {
                    279:                if (TELOPT_OK(i))
                    280:                    printf("want WONT %s\n", TELOPT(i));
                    281:                else if (TELCMD_OK(i))
                    282:                    printf("want WONT %s\n", TELCMD(i));
                    283:                else
                    284:                    printf("want WONT %d\n", i);
                    285:            }
                    286:        } else {
                    287:            if (my_state_is_will(i)) {
                    288:                if (TELOPT_OK(i))
                    289:                    printf("     WILL %s\n", TELOPT(i));
                    290:                else if (TELCMD_OK(i))
                    291:                    printf("     WILL %s\n", TELCMD(i));
                    292:                else
                    293:                    printf("     WILL %d\n", i);
                    294:            }
                    295:        }
                    296:     }
                    297:
                    298: }
                    299:
                    300:     void
                    301: printsub(direction, pointer, length)
                    302:     char direction;    /* '<' or '>' */
                    303:     unsigned char *pointer;    /* where suboption data sits */
                    304:     int                  length;       /* length of suboption data */
                    305: {
                    306:     register int i;
1.4     ! jason     307:     char buf[512];
1.1       deraadt   308:     extern int want_status_response;
                    309:
                    310:     if (showoptions || direction == 0 ||
                    311:        (want_status_response && (pointer[0] == TELOPT_STATUS))) {
                    312:        if (direction) {
                    313:            fprintf(NetTrace, "%s IAC SB ",
                    314:                                (direction == '<')? "RCVD":"SENT");
                    315:            if (length >= 3) {
                    316:                register int j;
                    317:
                    318:                i = pointer[length-2];
                    319:                j = pointer[length-1];
                    320:
                    321:                if (i != IAC || j != SE) {
                    322:                    fprintf(NetTrace, "(terminated by ");
                    323:                    if (TELOPT_OK(i))
                    324:                        fprintf(NetTrace, "%s ", TELOPT(i));
                    325:                    else if (TELCMD_OK(i))
                    326:                        fprintf(NetTrace, "%s ", TELCMD(i));
                    327:                    else
                    328:                        fprintf(NetTrace, "%d ", i);
                    329:                    if (TELOPT_OK(j))
                    330:                        fprintf(NetTrace, "%s", TELOPT(j));
                    331:                    else if (TELCMD_OK(j))
                    332:                        fprintf(NetTrace, "%s", TELCMD(j));
                    333:                    else
                    334:                        fprintf(NetTrace, "%d", j);
                    335:                    fprintf(NetTrace, ", not IAC SE!) ");
                    336:                }
                    337:            }
                    338:            length -= 2;
                    339:        }
                    340:        if (length < 1) {
                    341:            fprintf(NetTrace, "(Empty suboption??\?)");
                    342:            if (NetTrace == stdout)
                    343:                fflush(NetTrace);
                    344:            return;
                    345:        }
                    346:        switch (pointer[0]) {
                    347:        case TELOPT_TTYPE:
                    348:            fprintf(NetTrace, "TERMINAL-TYPE ");
                    349:            switch (pointer[1]) {
                    350:            case TELQUAL_IS:
                    351:                fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2);
                    352:                break;
                    353:            case TELQUAL_SEND:
                    354:                fprintf(NetTrace, "SEND");
                    355:                break;
                    356:            default:
                    357:                fprintf(NetTrace,
                    358:                                "- unknown qualifier %d (0x%x).",
                    359:                                pointer[1], pointer[1]);
                    360:            }
                    361:            break;
                    362:        case TELOPT_TSPEED:
                    363:            fprintf(NetTrace, "TERMINAL-SPEED");
                    364:            if (length < 2) {
                    365:                fprintf(NetTrace, " (empty suboption??\?)");
                    366:                break;
                    367:            }
                    368:            switch (pointer[1]) {
                    369:            case TELQUAL_IS:
                    370:                fprintf(NetTrace, " IS ");
                    371:                fprintf(NetTrace, "%.*s", length-2, (char *)pointer+2);
                    372:                break;
                    373:            default:
                    374:                if (pointer[1] == 1)
                    375:                    fprintf(NetTrace, " SEND");
                    376:                else
                    377:                    fprintf(NetTrace, " %d (unknown)", pointer[1]);
                    378:                for (i = 2; i < length; i++)
                    379:                    fprintf(NetTrace, " ?%d?", pointer[i]);
                    380:                break;
                    381:            }
                    382:            break;
                    383:
                    384:        case TELOPT_LFLOW:
                    385:            fprintf(NetTrace, "TOGGLE-FLOW-CONTROL");
                    386:            if (length < 2) {
                    387:                fprintf(NetTrace, " (empty suboption??\?)");
                    388:                break;
                    389:            }
                    390:            switch (pointer[1]) {
                    391:            case LFLOW_OFF:
                    392:                fprintf(NetTrace, " OFF"); break;
                    393:            case LFLOW_ON:
                    394:                fprintf(NetTrace, " ON"); break;
                    395:            case LFLOW_RESTART_ANY:
                    396:                fprintf(NetTrace, " RESTART-ANY"); break;
                    397:            case LFLOW_RESTART_XON:
                    398:                fprintf(NetTrace, " RESTART-XON"); break;
                    399:            default:
                    400:                fprintf(NetTrace, " %d (unknown)", pointer[1]);
                    401:            }
                    402:            for (i = 2; i < length; i++)
                    403:                fprintf(NetTrace, " ?%d?", pointer[i]);
                    404:            break;
                    405:
                    406:        case TELOPT_NAWS:
                    407:            fprintf(NetTrace, "NAWS");
                    408:            if (length < 2) {
                    409:                fprintf(NetTrace, " (empty suboption??\?)");
                    410:                break;
                    411:            }
                    412:            if (length == 2) {
                    413:                fprintf(NetTrace, " ?%d?", pointer[1]);
                    414:                break;
                    415:            }
                    416:            fprintf(NetTrace, " %d %d (%d)",
                    417:                pointer[1], pointer[2],
                    418:                (int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2])));
                    419:            if (length == 4) {
                    420:                fprintf(NetTrace, " ?%d?", pointer[3]);
                    421:                break;
                    422:            }
                    423:            fprintf(NetTrace, " %d %d (%d)",
                    424:                pointer[3], pointer[4],
                    425:                (int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4])));
                    426:            for (i = 5; i < length; i++)
                    427:                fprintf(NetTrace, " ?%d?", pointer[i]);
                    428:            break;
                    429:
                    430: #if    defined(AUTHENTICATION)
                    431:        case TELOPT_AUTHENTICATION:
                    432:            fprintf(NetTrace, "AUTHENTICATION");
                    433:            if (length < 2) {
                    434:                fprintf(NetTrace, " (empty suboption??\?)");
                    435:                break;
                    436:            }
                    437:            switch (pointer[1]) {
                    438:            case TELQUAL_REPLY:
                    439:            case TELQUAL_IS:
                    440:                fprintf(NetTrace, " %s ", (pointer[1] == TELQUAL_IS) ?
                    441:                                                        "IS" : "REPLY");
                    442:                if (AUTHTYPE_NAME_OK(pointer[2]))
                    443:                    fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[2]));
                    444:                else
                    445:                    fprintf(NetTrace, "%d ", pointer[2]);
                    446:                if (length < 3) {
                    447:                    fprintf(NetTrace, "(partial suboption??\?)");
                    448:                    break;
                    449:                }
                    450:                fprintf(NetTrace, "%s|%s",
                    451:                        ((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ?
                    452:                        "CLIENT" : "SERVER",
                    453:                        ((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ?
                    454:                        "MUTUAL" : "ONE-WAY");
                    455:
                    456:                auth_printsub(&pointer[1], length - 1, buf, sizeof(buf));
                    457:                fprintf(NetTrace, "%s", buf);
                    458:                break;
                    459:
                    460:            case TELQUAL_SEND:
                    461:                i = 2;
                    462:                fprintf(NetTrace, " SEND ");
                    463:                while (i < length) {
                    464:                    if (AUTHTYPE_NAME_OK(pointer[i]))
                    465:                        fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[i]));
                    466:                    else
                    467:                        fprintf(NetTrace, "%d ", pointer[i]);
                    468:                    if (++i >= length) {
                    469:                        fprintf(NetTrace, "(partial suboption??\?)");
                    470:                        break;
                    471:                    }
                    472:                    fprintf(NetTrace, "%s|%s ",
                    473:                        ((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ?
                    474:                                                        "CLIENT" : "SERVER",
                    475:                        ((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ?
                    476:                                                        "MUTUAL" : "ONE-WAY");
                    477:                    ++i;
                    478:                }
                    479:                break;
                    480:
                    481:            case TELQUAL_NAME:
                    482:                i = 2;
                    483:                fprintf(NetTrace, " NAME \"");
                    484:                while (i < length)
                    485:                    putc(pointer[i++], NetTrace);
                    486:                putc('"', NetTrace);
                    487:                break;
                    488:
                    489:            default:
                    490:                    for (i = 2; i < length; i++)
                    491:                        fprintf(NetTrace, " ?%d?", pointer[i]);
                    492:                    break;
                    493:            }
                    494:            break;
                    495: #endif
                    496:
                    497:
                    498:        case TELOPT_LINEMODE:
                    499:            fprintf(NetTrace, "LINEMODE ");
                    500:            if (length < 2) {
                    501:                fprintf(NetTrace, " (empty suboption??\?)");
                    502:                break;
                    503:            }
                    504:            switch (pointer[1]) {
                    505:            case WILL:
                    506:                fprintf(NetTrace, "WILL ");
                    507:                goto common;
                    508:            case WONT:
                    509:                fprintf(NetTrace, "WONT ");
                    510:                goto common;
                    511:            case DO:
                    512:                fprintf(NetTrace, "DO ");
                    513:                goto common;
                    514:            case DONT:
                    515:                fprintf(NetTrace, "DONT ");
                    516:            common:
                    517:                if (length < 3) {
                    518:                    fprintf(NetTrace, "(no option??\?)");
                    519:                    break;
                    520:                }
                    521:                switch (pointer[2]) {
                    522:                case LM_FORWARDMASK:
                    523:                    fprintf(NetTrace, "Forward Mask");
                    524:                    for (i = 3; i < length; i++)
                    525:                        fprintf(NetTrace, " %x", pointer[i]);
                    526:                    break;
                    527:                default:
                    528:                    fprintf(NetTrace, "%d (unknown)", pointer[2]);
                    529:                    for (i = 3; i < length; i++)
                    530:                        fprintf(NetTrace, " %d", pointer[i]);
                    531:                    break;
                    532:                }
                    533:                break;
1.2       niklas    534:
1.1       deraadt   535:            case LM_SLC:
                    536:                fprintf(NetTrace, "SLC");
                    537:                for (i = 2; i < length - 2; i += 3) {
                    538:                    if (SLC_NAME_OK(pointer[i+SLC_FUNC]))
                    539:                        fprintf(NetTrace, " %s", SLC_NAME(pointer[i+SLC_FUNC]));
                    540:                    else
                    541:                        fprintf(NetTrace, " %d", pointer[i+SLC_FUNC]);
                    542:                    switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) {
                    543:                    case SLC_NOSUPPORT:
                    544:                        fprintf(NetTrace, " NOSUPPORT"); break;
                    545:                    case SLC_CANTCHANGE:
                    546:                        fprintf(NetTrace, " CANTCHANGE"); break;
                    547:                    case SLC_VARIABLE:
                    548:                        fprintf(NetTrace, " VARIABLE"); break;
                    549:                    case SLC_DEFAULT:
                    550:                        fprintf(NetTrace, " DEFAULT"); break;
                    551:                    }
                    552:                    fprintf(NetTrace, "%s%s%s",
                    553:                        pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "",
                    554:                        pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "",
                    555:                        pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : "");
                    556:                    if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN|
                    557:                                                SLC_FLUSHOUT| SLC_LEVELBITS))
                    558:                        fprintf(NetTrace, "(0x%x)", pointer[i+SLC_FLAGS]);
                    559:                    fprintf(NetTrace, " %d;", pointer[i+SLC_VALUE]);
                    560:                    if ((pointer[i+SLC_VALUE] == IAC) &&
                    561:                        (pointer[i+SLC_VALUE+1] == IAC))
                    562:                                i++;
                    563:                }
                    564:                for (; i < length; i++)
                    565:                    fprintf(NetTrace, " ?%d?", pointer[i]);
                    566:                break;
                    567:
                    568:            case LM_MODE:
                    569:                fprintf(NetTrace, "MODE ");
                    570:                if (length < 3) {
                    571:                    fprintf(NetTrace, "(no mode??\?)");
                    572:                    break;
                    573:                }
                    574:                {
                    575:                    char tbuf[64];
                    576:                    sprintf(tbuf, "%s%s%s%s%s",
                    577:                        pointer[2]&MODE_EDIT ? "|EDIT" : "",
                    578:                        pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "",
                    579:                        pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "",
                    580:                        pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "",
                    581:                        pointer[2]&MODE_ACK ? "|ACK" : "");
                    582:                    fprintf(NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0");
                    583:                }
                    584:                if (pointer[2]&~(MODE_MASK))
                    585:                    fprintf(NetTrace, " (0x%x)", pointer[2]);
                    586:                for (i = 3; i < length; i++)
                    587:                    fprintf(NetTrace, " ?0x%x?", pointer[i]);
                    588:                break;
                    589:            default:
                    590:                fprintf(NetTrace, "%d (unknown)", pointer[1]);
                    591:                for (i = 2; i < length; i++)
                    592:                    fprintf(NetTrace, " %d", pointer[i]);
                    593:            }
                    594:            break;
                    595:
                    596:        case TELOPT_STATUS: {
                    597:            register char *cp;
                    598:            register int j, k;
                    599:
                    600:            fprintf(NetTrace, "STATUS");
                    601:
                    602:            switch (pointer[1]) {
                    603:            default:
                    604:                if (pointer[1] == TELQUAL_SEND)
                    605:                    fprintf(NetTrace, " SEND");
                    606:                else
                    607:                    fprintf(NetTrace, " %d (unknown)", pointer[1]);
                    608:                for (i = 2; i < length; i++)
                    609:                    fprintf(NetTrace, " ?%d?", pointer[i]);
                    610:                break;
                    611:            case TELQUAL_IS:
                    612:                if (--want_status_response < 0)
                    613:                    want_status_response = 0;
                    614:                if (NetTrace == stdout)
                    615:                    fprintf(NetTrace, " IS\r\n");
                    616:                else
                    617:                    fprintf(NetTrace, " IS\n");
                    618:
                    619:                for (i = 2; i < length; i++) {
                    620:                    switch(pointer[i]) {
                    621:                    case DO:    cp = "DO"; goto common2;
                    622:                    case DONT:  cp = "DONT"; goto common2;
                    623:                    case WILL:  cp = "WILL"; goto common2;
                    624:                    case WONT:  cp = "WONT"; goto common2;
                    625:                    common2:
                    626:                        i++;
                    627:                        if (TELOPT_OK((int)pointer[i]))
                    628:                            fprintf(NetTrace, " %s %s", cp, TELOPT(pointer[i]));
                    629:                        else
                    630:                            fprintf(NetTrace, " %s %d", cp, pointer[i]);
                    631:
                    632:                        if (NetTrace == stdout)
                    633:                            fprintf(NetTrace, "\r\n");
                    634:                        else
                    635:                            fprintf(NetTrace, "\n");
                    636:                        break;
                    637:
                    638:                    case SB:
                    639:                        fprintf(NetTrace, " SB ");
                    640:                        i++;
                    641:                        j = k = i;
                    642:                        while (j < length) {
                    643:                            if (pointer[j] == SE) {
                    644:                                if (j+1 == length)
                    645:                                    break;
                    646:                                if (pointer[j+1] == SE)
                    647:                                    j++;
                    648:                                else
                    649:                                    break;
                    650:                            }
                    651:                            pointer[k++] = pointer[j++];
                    652:                        }
                    653:                        printsub(0, &pointer[i], k - i);
                    654:                        if (i < length) {
                    655:                            fprintf(NetTrace, " SE");
                    656:                            i = j;
                    657:                        } else
                    658:                            i = j - 1;
                    659:
                    660:                        if (NetTrace == stdout)
                    661:                            fprintf(NetTrace, "\r\n");
                    662:                        else
                    663:                            fprintf(NetTrace, "\n");
                    664:
                    665:                        break;
1.2       niklas    666:
1.1       deraadt   667:                    default:
                    668:                        fprintf(NetTrace, " %d", pointer[i]);
                    669:                        break;
                    670:                    }
                    671:                }
                    672:                break;
                    673:            }
                    674:            break;
                    675:          }
                    676:
                    677:        case TELOPT_XDISPLOC:
                    678:            fprintf(NetTrace, "X-DISPLAY-LOCATION ");
                    679:            switch (pointer[1]) {
                    680:            case TELQUAL_IS:
                    681:                fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2);
                    682:                break;
                    683:            case TELQUAL_SEND:
                    684:                fprintf(NetTrace, "SEND");
                    685:                break;
                    686:            default:
                    687:                fprintf(NetTrace, "- unknown qualifier %d (0x%x).",
                    688:                                pointer[1], pointer[1]);
                    689:            }
                    690:            break;
                    691:
                    692:        case TELOPT_NEW_ENVIRON:
                    693:            fprintf(NetTrace, "NEW-ENVIRON ");
                    694: #ifdef OLD_ENVIRON
                    695:            goto env_common1;
                    696:        case TELOPT_OLD_ENVIRON:
                    697:            fprintf(NetTrace, "OLD-ENVIRON");
                    698:        env_common1:
                    699: #endif
                    700:            switch (pointer[1]) {
                    701:            case TELQUAL_IS:
                    702:                fprintf(NetTrace, "IS ");
                    703:                goto env_common;
                    704:            case TELQUAL_SEND:
                    705:                fprintf(NetTrace, "SEND ");
                    706:                goto env_common;
                    707:            case TELQUAL_INFO:
                    708:                fprintf(NetTrace, "INFO ");
                    709:            env_common:
                    710:                {
                    711:                    register int noquote = 2;
                    712: #if defined(ENV_HACK) && defined(OLD_ENVIRON)
                    713:                    extern int old_env_var, old_env_value;
                    714: #endif
                    715:                    for (i = 2; i < length; i++ ) {
                    716:                        switch (pointer[i]) {
                    717:                        case NEW_ENV_VALUE:
                    718: #ifdef OLD_ENVIRON
                    719:                     /* case NEW_ENV_OVAR: */
                    720:                            if (pointer[0] == TELOPT_OLD_ENVIRON) {
                    721: # ifdef        ENV_HACK
                    722:                                if (old_env_var == OLD_ENV_VALUE)
                    723:                                    fprintf(NetTrace, "\" (VALUE) " + noquote);
                    724:                                else
                    725: # endif
                    726:                                    fprintf(NetTrace, "\" VAR " + noquote);
                    727:                            } else
                    728: #endif /* OLD_ENVIRON */
                    729:                                fprintf(NetTrace, "\" VALUE " + noquote);
                    730:                            noquote = 2;
                    731:                            break;
                    732:
                    733:                        case NEW_ENV_VAR:
                    734: #ifdef OLD_ENVIRON
                    735:                     /* case OLD_ENV_VALUE: */
                    736:                            if (pointer[0] == TELOPT_OLD_ENVIRON) {
                    737: # ifdef        ENV_HACK
                    738:                                if (old_env_value == OLD_ENV_VAR)
                    739:                                    fprintf(NetTrace, "\" (VAR) " + noquote);
                    740:                                else
                    741: # endif
                    742:                                    fprintf(NetTrace, "\" VALUE " + noquote);
                    743:                            } else
                    744: #endif /* OLD_ENVIRON */
                    745:                                fprintf(NetTrace, "\" VAR " + noquote);
                    746:                            noquote = 2;
                    747:                            break;
                    748:
                    749:                        case ENV_ESC:
                    750:                            fprintf(NetTrace, "\" ESC " + noquote);
                    751:                            noquote = 2;
                    752:                            break;
                    753:
                    754:                        case ENV_USERVAR:
                    755:                            fprintf(NetTrace, "\" USERVAR " + noquote);
                    756:                            noquote = 2;
                    757:                            break;
                    758:
                    759:                        default:
                    760:                            if (isprint(pointer[i]) && pointer[i] != '"') {
                    761:                                if (noquote) {
                    762:                                    putc('"', NetTrace);
                    763:                                    noquote = 0;
                    764:                                }
                    765:                                putc(pointer[i], NetTrace);
                    766:                            } else {
                    767:                                fprintf(NetTrace, "\" %03o " + noquote,
                    768:                                                        pointer[i]);
                    769:                                noquote = 2;
                    770:                            }
                    771:                            break;
                    772:                        }
                    773:                    }
                    774:                    if (!noquote)
                    775:                        putc('"', NetTrace);
                    776:                    break;
                    777:                }
                    778:            }
                    779:            break;
                    780:
                    781:        default:
                    782:            if (TELOPT_OK(pointer[0]))
                    783:                fprintf(NetTrace, "%s (unknown)", TELOPT(pointer[0]));
                    784:            else
                    785:                fprintf(NetTrace, "%d (unknown)", pointer[0]);
                    786:            for (i = 1; i < length; i++)
                    787:                fprintf(NetTrace, " %d", pointer[i]);
                    788:            break;
                    789:        }
                    790:        if (direction) {
                    791:            if (NetTrace == stdout)
                    792:                fprintf(NetTrace, "\r\n");
                    793:            else
                    794:                fprintf(NetTrace, "\n");
                    795:        }
                    796:        if (NetTrace == stdout)
                    797:            fflush(NetTrace);
                    798:     }
                    799: }
                    800:
                    801: /* EmptyTerminal - called to make sure that the terminal buffer is empty.
                    802:  *                     Note that we consider the buffer to run all the
                    803:  *                     way to the kernel (thus the select).
                    804:  */
                    805:
                    806:     void
                    807: EmptyTerminal()
                    808: {
                    809: #if    defined(unix)
                    810:     fd_set     o;
                    811:
                    812:     FD_ZERO(&o);
                    813: #endif /* defined(unix) */
                    814:
                    815:     if (TTYBYTES() == 0) {
                    816: #if    defined(unix)
                    817:        FD_SET(tout, &o);
                    818:        (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
                    819:                        (struct timeval *) 0);  /* wait for TTLOWAT */
                    820: #endif /* defined(unix) */
                    821:     } else {
                    822:        while (TTYBYTES()) {
                    823:            (void) ttyflush(0);
                    824: #if    defined(unix)
                    825:            FD_SET(tout, &o);
                    826:            (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
                    827:                                (struct timeval *) 0);  /* wait for TTLOWAT */
                    828: #endif /* defined(unix) */
                    829:        }
                    830:     }
                    831: }
                    832:
                    833:     void
                    834: SetForExit()
                    835: {
                    836:     setconnmode(0);
                    837: #if    defined(TN3270)
                    838:     if (In3270) {
                    839:        Finish3270();
                    840:     }
                    841: #else  /* defined(TN3270) */
                    842:     do {
                    843:        (void)telrcv();                 /* Process any incoming data */
                    844:        EmptyTerminal();
                    845:     } while (ring_full_count(&netiring));      /* While there is any */
                    846: #endif /* defined(TN3270) */
                    847:     setcommandmode();
                    848:     fflush(stdout);
                    849:     fflush(stderr);
                    850: #if    defined(TN3270)
                    851:     if (In3270) {
                    852:        StopScreen(1);
                    853:     }
                    854: #endif /* defined(TN3270) */
                    855:     setconnmode(0);
                    856:     EmptyTerminal();                   /* Flush the path to the tty */
                    857:     setcommandmode();
                    858: }
                    859:
                    860:     void
                    861: Exit(returnCode)
                    862:     int returnCode;
                    863: {
                    864:     SetForExit();
                    865:     exit(returnCode);
                    866: }
                    867:
                    868:     void
                    869: ExitString(string, returnCode)
                    870:     char *string;
                    871:     int returnCode;
                    872: {
                    873:     SetForExit();
                    874:     fwrite(string, 1, strlen(string), stderr);
                    875:     exit(returnCode);
                    876: }