# 2.11BSD#431 - /usr/src/ucb/tn3270/tn3270.c

##### Functions

    DataToNetwork     X
    DataToTerminal    X
    EmptyTerminal     X
    ExitPerror        X
    ExitString        X
    StringToTerminal  X
    TtyChars          X
    _putchar          X
    command           X
    main              X
    mode              X
    netflush          X
    outputPurge       X
    quit              X
    suspend           X
    ttyflush          X

##### Variables

    HaveInput         X

##### Macros

    BYTES_PER_LINE    X
    FD_NEXT           X
    HELPINDENT        X
    IBUFSIZ           X
    SB_ACCUM          X
    Sb_Command        X
    Sb_Option         X
    TELOPTS           X
    TS_DATA           X
    TS_DO             X
    TS_DONT           X
    TS_IAC            X
    TS_SB             X
    TS_SE             X
    TS_WILL           X
    TS_WONT           X
    min               X
    strip             X

##### struct's

    cmd               X

       1: /*
       2:  *	Copyright 1984, 1985 by the Regents of the University of
       3:  *	California and by Gregory Glenn Minshall.
       4:  *
       5:  *	Permission to use, copy, modify, and distribute these
       6:  *	programs and their documentation for any purpose and
       7:  *	without fee is hereby granted, provided that this
       8:  *	copyright and permission appear on all copies and
       9:  *	supporting documentation, the name of the Regents of
      10:  *	the University of California not be used in advertising
      11:  *	or publicity pertaining to distribution of the programs
      12:  *	without specific prior permission, and notice be given in
      13:  *	supporting documentation that copying and distribution is
      14:  *	by permission of the Regents of the University of California
      15:  *	and by Gregory Glenn Minshall.  Neither the Regents of the
      16:  *	University of California nor Gregory Glenn Minshall make
      17:  *	representations about the suitability of this software
      18:  *	for any purpose.  It is provided "as is" without
      19:  *	express or implied warranty.
      20:  */
      21:
      22:
      23: #if defined(DOSCCS) && !defined(lint)
      24: static char sccsid[] = "@(#)tn3270.c	2.8\t1/1/94";
      25: #endif
      26:
      27: /*
      28:  * User telnet program, specially modified for tn3270.
      29:  */
      30: #include <sys/types.h>
      31: #include <sys/socket.h>
      32: #include <sys/ioctl.h>
      33: #include <sys/time.h>
      34:
      35: #include <netinet/in.h>
      36: #include <arpa/inet.h>
      37:
      38: #define TELOPTS
      39: #include <arpa/telnet.h>
      40:
      41: #include <stdio.h>
      42: #include <ctype.h>
      43: #include <errno.h>
      44: #include <signal.h>
      45: #include <setjmp.h>
      46: #include <netdb.h>
      47:
      48: #define strip(x)    ((x)&0177)
      49: #define min(x,y)    ((x<y)? x:y)
      50:
      51: #ifndef pdp11
      52: #define IBUFSIZ 8*BUFSIZ
      53: static char Ibuf[IBUFSIZ], *Ifrontp = Ibuf, *Ibackp = Ibuf;
      54: #else
      55:     /* Move Ibuf onto stack to use last segment. */
      56: #define IBUFSIZ 3*BUFSIZ
      57: static char *Ibuf, *Ifrontp, *Ibackp;
      58: #endif
      59: static char ttyobuf[BUFSIZ], *tfrontp = ttyobuf, *tbackp = ttyobuf;
      60: static char netobuf[BUFSIZ], *nfrontp = netobuf, *nbackp = netobuf;
      61:
      62: static char SbBuffer[100], *pSb = SbBuffer;
      63: #define Sb_Option SbBuffer[0]
      64: #define Sb_Command SbBuffer[1]
      65:
      66:
      67: static char hisopts[256];
      68: static char myopts[256];
      69:
      70: static char doopt[] = { IAC, DO, '%', 'c', 0 };
      71: static char dont[] = { IAC, DONT, '%', 'c', 0 };
      72: static char will[] = { IAC, WILL, '%', 'c', 0 };
      73: static char wont[] = { IAC, WONT, '%', 'c', 0 };
      74: static char sb_terminal[] = { IAC, SB,
      75:             TELOPT_TTYPE, TELQUAL_IS,
      76:             'I', 'B', 'M', '-', '3', '2', '7', '7', '-', '2',
      77:             IAC, SE };
      78:
      79: /* The following is a real, live, global. */
      80:
      81: /* The point of HaveInput is to give a hint to the terminal output processor
      82:  * that some input from some source (network or terminal) has come in.
      83:  */
      84:
      85: int HaveInput = 1;  /* we have received input in the not too distant past */
      86:
      87:
      88: static int  connected;
      89: static int  SentTerminalType = 0;       /* returned sb_terminal to other? */
      90: static int  In3270 = 0;         /* we are in 3270 binary mode */
      91: static int  ISend = 0;          /* trying to send network data in */
      92: static int  ForceMode = -1;         /* for debugging */
      93: static int  net;
      94: static int  showoptions = 0;
      95: static int  debug = 0;
      96: static int  crmod = 0;
      97: static int  printnet = 0;
      98: static FILE *NetTrace;
      99: static char *prompt;
     100: static char escape = CTRL(]);
     101:
     102: static char line[200];
     103: static int  margc;
     104: static char *margv[20];
     105:
     106: static jmp_buf  toplevel;
     107: static jmp_buf  peerdied;
     108:
     109: extern  int errno;
     110:
     111: int quit(), suspend();
     112: static int  tn(), bye(), help();
     113: static int  setescape(), status(), toggle(), setoptions();
     114: static int  setcrmod(), setdebug(), SetPrintNet();
     115:
     116: #define HELPINDENT (sizeof ("connect"))
     117:
     118: struct cmd {
     119:     char    *name;      /* command name */
     120:     char    *help;      /* help string */
     121:     int (*handler)();   /* routine which executes command */
     122:     int dohelp;     /* Should we give general help information? */
     123: };
     124:
     125: static char openhelp[] =    "connect to a site";
     126: static char closehelp[] =   "close current connection";
     127: static char quithelp[] =    "exit telnet";
     128: static char zhelp[] =   "suspend telnet";
     129: static char debughelp[] =   "toggle debugging";
     130: static char escapehelp[] =  "set escape character";
     131: static char statushelp[] =  "print status information";
     132: static char helphelp[] =    "print help information";
     133: static char optionshelp[] = "toggle viewing of options processing";
     134: static char crmodhelp[] =   "toggle mapping of received carriage returns";
     135: static char printnethelp[] = "print out raw data to/from net";
     136:
     137: static struct cmd cmdtab[] = {
     138:     { "open",   openhelp,   tn, 1 },
     139:     { "close",  closehelp,  bye, 1 },
     140:     { "quit",   quithelp,   quit, 1 },
     141:     { "z",      zhelp,      suspend, 1 },
     142:     { "suspend",    zhelp,      suspend, 0 },
     143:     { "escape", escapehelp, setescape, 0 },
     144:     { "status", statushelp, status, 1 },
     145:     { "options",    optionshelp,    setoptions, 0 },
     146:     { "crmod",  crmodhelp,  setcrmod, 0 },
     147:     { "debug",  debughelp,  setdebug, 0 },
     148:     { "printnet",   printnethelp,   SetPrintNet, 0 },
     149:     { "?",      helphelp,   help, 1 },
     150:     { "help",   helphelp,   help, 0 },
     151:     0
     152: };
     153:
     154: static struct sockaddr_in sin;
     155:
     156: static int  intr(), deadpeer(), inputAvailable();
     157: static char *control();
     158: static struct   cmd *getcmd();
     159: static struct   servent *sp;
     160:
     161: static struct   tchars otc;
     162: static struct   ltchars oltc;
     163: static struct   sgttyb ottyb;
     164:
     165: main(argc, argv)
     166:     int argc;
     167:     char *argv[];
     168: {
     169: #ifdef pdp11
     170:     char    SIbuf[IBUFSIZ];
     171:
     172:     Ibuf = Ifrontp = Ibackp = SIbuf;
     173:     setbuf(stdout, NULL);
     174: #endif
     175:     ioctl(0, TIOCGETP, (char *)&ottyb);
     176:     ioctl(0, TIOCGETC, (char *)&otc);
     177:     ioctl(0, TIOCGLTC, (char *)&oltc);
     178:     sp = getservbyname("telnet", "tcp");
     179:     if (sp == 0) {
     180:         ExitString(stderr, "telnet: tcp/telnet: unknown service\n", 1);
     181:     }
     182:     NetTrace = stdout;
     183:     prompt = argv[0];
     184:     if (argc > 1 && !strcmp(argv[1], "-d")) {
     185:         debug = SO_DEBUG, argv++, argc--;
     186:     }
     187:     if (argc > 1 && !strcmp(argv[1], "-n")) {
     188:         argv++;
     189:         argc--;
     190:         if (argc > 1) {     /* get file name */
     191:         NetTrace = fopen(argv[1], "w");
     192:         argv++;
     193:         argc--;
     194:         if (NetTrace == NULL) {
     195:             NetTrace = stdout;
     196:         }
     197:         }
     198:     }
     199:     if (argc != 1) {
     200:         if (setjmp(toplevel) != 0)
     201:             Exit(0);
     202:         tn(argc, argv);
     203:     }
     204:     setjmp(toplevel);
     205:     for (;;)
     206:         command(1);
     207: }
     208:
     209: static char *hostname;
     210: static char hnamebuf[32];
     211:
     212: static
     213: tn(argc, argv)
     214:     int argc;
     215:     char *argv[];
     216: {
     217:     struct hostent *host;
     218:     char *strcpy();
     219:
     220:     if (connected) {
     221:         printf("?Already connected to %s\n", hostname);
     222:         return;
     223:     }
     224:     if (argc < 2) {
     225:         (void) strcpy(line, "Connect ");
     226:         printf("(to) ");
     227:         gets(&line[strlen(line)]);
     228:         makeargv();
     229:         argc = margc;
     230:         argv = margv;
     231:     }
     232:     if (argc > 3) {
     233:         printf("usage: %s host-name [port]\n", argv[0]);
     234:         return;
     235:     }
     236:     host = gethostbyname(argv[1]);
     237:     if (host) {
     238:         sin.sin_family = host->h_addrtype;
     239:         bcopy(host->h_addr, (caddr_t)&sin.sin_addr, host->h_length);
     240:         hostname = host->h_name;
     241:     } else {
     242:         sin.sin_family = AF_INET;
     243:         sin.sin_addr.s_addr = inet_addr(argv[1]);
     244:         if (sin.sin_addr.s_addr == -1) {
     245:             printf("%s: unknown host\n", argv[1]);
     246:             return;
     247:         }
     248:         (void) strcpy(hnamebuf, argv[1]);
     249:         hostname = hnamebuf;
     250:     }
     251:     sin.sin_port = sp->s_port;
     252:     if (argc == 3) {
     253:         sin.sin_port = atoi(argv[2]);
     254:         sin.sin_port = htons(sin.sin_port);
     255:     }
     256:     net = socket(AF_INET, SOCK_STREAM, 0);
     257:     if (net < 0) {
     258:         perror("telnet: socket");
     259:         return;
     260:     }
     261:     if (debug && setsockopt(net, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
     262:         perror("setsockopt (SO_DEBUG)");
     263:     signal(SIGINT, intr);
     264:     signal(SIGPIPE, deadpeer);
     265:     printf("Trying...\n");
     266:     if (connect(net, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
     267:         perror("telnet: connect");
     268:         signal(SIGINT, SIG_DFL);
     269:         return;
     270:     }
     271:     connected++;
     272:     call(status, "status", 0);
     273:     if (setjmp(peerdied) == 0)
     274:         telnet();
     275:     if (In3270) {
     276:         Stop3270(1);
     277:     }
     278:     ExitString(stderr, "Connection closed by foreign host.\n", 1);
     279: }
     280:
     281: /*
     282:  * Print status about the connection.
     283:  */
     284: /*VARARGS*/
     285: static
     286: status()
     287: {
     288:     if (connected)
     289:         printf("Connected to %s.\n", hostname);
     290:     else
     291:         printf("No connection.\n");
     292:     /*printf("Escape character is '%s'.\n", control(escape));*/
     293:     fflush(stdout);
     294: }
     295:
     296: static
     297: makeargv()
     298: {
     299:     register char *cp;
     300:     register char **argp = margv;
     301:
     302:     margc = 0;
     303:     for (cp = line; *cp;) {
     304:         while (isspace(*cp))
     305:             cp++;
     306:         if (*cp == '\0')
     307:             break;
     308:         *argp++ = cp;
     309:         margc += 1;
     310:         while (*cp != '\0' && !isspace(*cp))
     311:             cp++;
     312:         if (*cp == '\0')
     313:             break;
     314:         *cp++ = '\0';
     315:     }
     316:     *argp++ = 0;
     317: }
     318:
     319: /*VARARGS*/
     320: suspend()
     321: {
     322:     register int save;
     323:
     324:     save = mode(0);
     325:     kill(0, SIGTSTP);
     326:     /* reget parameters in case they were changed */
     327:     ioctl(0, TIOCGETP, (char *)&ottyb);
     328:     ioctl(0, TIOCGETC, (char *)&otc);
     329:     ioctl(0, TIOCGLTC, (char *)&oltc);
     330:     (void) mode(save);
     331: }
     332:
     333: /*VARARGS*/
     334: static
     335: bye()
     336: {
     337:     register char *op;
     338:
     339:     (void) mode(0);
     340:     if (connected) {
     341:         shutdown(net, 2);
     342:         printf("Connection closed.\n");
     343:         close(net);
     344:         connected = 0;
     345:         /* reset his options */
     346:         for (op = hisopts; op < &hisopts[256]; op++)
     347:             *op = 0;
     348:     }
     349: }
     350:
     351: /*VARARGS*/
     352: quit()
     353: {
     354:     call(bye, "bye", 0);
     355:     Exit(0);
     356: }
     357:
     358: /*
     359:  * Help command.
     360:  */
     361: static
     362: help(argc, argv)
     363:     int argc;
     364:     char *argv[];
     365: {
     366:     register struct cmd *c;
     367:
     368:     if (argc == 1) {
     369:         printf("Commands may be abbreviated.  Commands are:\n\n");
     370:         for (c = cmdtab; c->name; c++)
     371:             if (c->dohelp) {
     372:                 printf("%-*s\t%s\n", HELPINDENT, c->name, c->help);
     373:             }
     374:         return;
     375:     }
     376:     while (--argc > 0) {
     377:         register char *arg;
     378:         arg = *++argv;
     379:         c = getcmd(arg);
     380:         if (c == (struct cmd *)-1)
     381:             printf("?Ambiguous help command %s\n", arg);
     382:         else if (c == (struct cmd *)0)
     383:             printf("?Invalid help command %s\n", arg);
     384:         else
     385:             printf("%s\n", c->help);
     386:     }
     387: }
     388:
     389: /*
     390:  * Call routine with argc, argv set from args (terminated by 0).
     391:  * VARARGS2
     392:  */
     393: static
     394: call(routine, args)
     395:     int (*routine)();
     396:     int args;
     397: {
     398:     register int *argp;
     399:     register int argc;
     400:
     401:     for (argc = 0, argp = &args; *argp++ != 0; argc++)
     402:         ;
     403:     (*routine)(argc, &args);
     404: }
     405:
     406: static struct   tchars notc =   { -1, -1, -1, -1, -1, -1 };
     407: static struct   ltchars noltc = { -1, -1, -1, -1, -1, -1 };
     408:
     409: mode(f)
     410:     register int f;
     411: {
     412:     static int prevmode = 0;
     413:     struct tchars *tc, tc3;
     414:     struct ltchars *ltc;
     415:     struct sgttyb sb;
     416:     int onoff, old;
     417:
     418:     if (prevmode == f)
     419:         return (f);
     420:     old = prevmode;
     421:     prevmode = f;
     422:     sb = ottyb;
     423:     if (ForceMode != -1) {
     424:         f = ForceMode;
     425:         ForceMode = -1;
     426:     }
     427:     switch (f) {
     428:
     429:     case 0:
     430:         onoff = 0;
     431:         tc = &otc;
     432:         ltc = &oltc;
     433:         break;
     434:
     435:     case 1:     /* the rawest */
     436:     case 2:     /* allows for local echoing, newline mapping */
     437:     case 3:     /* like 1, but with XON/XOFF */
     438:
     439:         sb.sg_flags |= CBREAK;
     440:         if ((f == 1) || (f == 3)) {
     441:             sb.sg_flags &= ~(ECHO|CRMOD);
     442:         } else {
     443:             sb.sg_flags |= ECHO|CRMOD;
     444:         }
     445:         sb.sg_erase = sb.sg_kill = -1;
     446:         if (f == 3) {
     447:             tc = &tc3;
     448:             tc3 = notc;
     449:             /* get XON, XOFF characters */
     450:             tc3.t_startc = otc.t_startc;
     451:             tc3.t_stopc = otc.t_stopc;
     452:         } else {
     453:             tc = &notc;
     454:         }
     455:         ltc = &noltc;
     456:         onoff = 1;
     457:         break;
     458:
     459:     default:
     460:         return(old);
     461:     }
     462:     ioctl(fileno(stdin), TIOCSLTC, (char *)ltc);
     463:     ioctl(fileno(stdin), TIOCSETC, (char *)tc);
     464:     ioctl(fileno(stdin), TIOCSETP, (char *)&sb);
     465:     ioctl(fileno(stdin), FIONBIO, (char *)&onoff);
     466:     ioctl(fileno(stdout), FIONBIO, (char *)&onoff);
     467:     ioctl(fileno(stdin), FIOASYNC, (char *)&onoff);
     468:     return (old);
     469: }
     470:
     471: static char sibuf[BUFSIZ], *sbp;
     472: static char tibuf[BUFSIZ], *tbp;
     473: static int  scc, tcc;
     474: static int tin, tout;           /* file descriptors */
     475:
     476: /*
     477:  * Select from tty and network...
     478:  */
     479: static
     480: telnet()
     481: {
     482:     int on = 1;
     483:     int negativePid = -getpid();
     484:     int schedValue;
     485:
     486:     (void) mode(2);
     487:     ioctl(net, FIONBIO, (char *)&on);
     488:     ioctl(net, FIOASYNC, (char *)&on);  /* hear about input */
     489:     ioctl(net, SIOCSPGRP, (char *)&negativePid);    /* set my pid */
     490:     tin = fileno(stdin);
     491:     tout = fileno(stdout);
     492:
     493:     for (;;) {
     494:     while (schedValue = Scheduler(0)) {
     495:         if (schedValue == -1) {
     496:         (void) mode(0);
     497:         return;
     498:         }
     499:     }
     500:         /* If there is data waiting to go out to terminal, don't
     501: 		 * schedule any more data for the terminal.
     502: 		 */
     503:     if (tfrontp-tbackp || !In3270) {
     504:         schedValue = 1;
     505:     } else {
     506:         schedValue = DoTerminalOutput();
     507:     }
     508:     if (schedValue) {
     509:         if (Scheduler(1) == -1) {
     510:         (void) mode(0);
     511:         return;
     512:         }
     513:     }
     514:     }
     515: }
     516:
     517:
     518: /* Loop around once. */
     519:
     520: static
     521: Scheduler(block)
     522: int block;      /* should we block in the select? */
     523: {
     524:     register int c;
     525:     fd_set ibits, obits;
     526:         /* One wants to be a bit careful about setting returnValue
     527: 		 * to one, since a one implies we did some useful work,
     528: 		 * and therefore probably won't be called to block next
     529: 		 * time.
     530: 		 */
     531:     int returnValue = 0;
     532:     static struct timeval TimeValue = {0};
     533:
     534:     FD_ZERO(&ibits);
     535:     FD_ZERO(&obits);
     536:
     537:     if (!In3270) {
     538:     if (nfrontp - nbackp)
     539:         FD_SET(net, &obits);
     540:     else if (tcc == 0) {
     541:         FD_SET(tin, &ibits);
     542:     }
     543:     if (tfrontp - tbackp)
     544:         FD_SET(tout, &obits);
     545:     else if (!ISend)
     546:         FD_SET(net, &ibits);
     547:     } else {
     548:     if (nfrontp - nbackp) { /* something for network? */
     549:         FD_SET(net, &obits);    /* yes - wait for space */
     550:     }
     551:     if (tcc == 0) {     /* any pending tty input? */
     552:         FD_SET(tin, &ibits);    /* no, look for new input */
     553:     }
     554:     if (tfrontp-tbackp) {   /* any pending tty output? */
     555:         FD_SET(tout, &obits);   /* yes - wait for space */
     556:     }
     557:     if (!ISend) {       /* any pending net input? */
     558:         FD_SET(net, &ibits);    /* no, look for new input */
     559:     }
     560:     }
     561:     if (scc < 0 && tcc < 0) {
     562:         return(-1);
     563:     }
     564:     if (HaveInput) {        /* Reprime SIGIO handler if appropriate */
     565:     HaveInput = 0;
     566:     signal(SIGIO, inputAvailable);
     567:     }
     568:     select(16, &ibits, &obits, (fd_set *) 0,
     569:                 (block)? (struct timeval *)0:&TimeValue);
     570:
     571: #define FD_NEXT(p) (ffs((p)->fds_bits[0])-1)   /* Until there's a better way */
     572:
     573:     if (FD_NEXT(&ibits) < 0 && FD_NEXT(&obits) < 0 && block) {
     574:             /* I don't like this, does it ever happen? */
     575:         printf("sleep(5) from tn3270, after select\n");
     576:         sleep(5);
     577:         return(0);
     578:     }
     579:
     580:     /*
     581:      * Something to read from the network...
     582:      */
     583:     if (FD_ISSET(net, &ibits)) {
     584:         scc = read(net, sibuf, sizeof (sibuf));
     585:         if (scc < 0 && errno == EWOULDBLOCK)
     586:             scc = 0;
     587:         else {
     588:             if (scc <= 0)
     589:                 return(-1);
     590:             sbp = sibuf;
     591:             if (printnet) {
     592:                 Dump('<', sbp, scc);
     593:             }
     594:             returnValue = 1;        /* did something useful */
     595:         }
     596:     }
     597:
     598:     /*
     599:      * Something to read from the tty...
     600:      */
     601:     if (FD_ISSET(tin, &ibits)) {
     602:         tcc = read(tin, tibuf, sizeof tibuf);
     603:         if (tcc < 0 && errno == EWOULDBLOCK)
     604:             tcc = 0;
     605:         else {
     606:             if (tcc <= 0)
     607:                 return(-1);
     608:             tbp = tibuf;
     609:             returnValue = 1;        /* did something useful */
     610:         }
     611:     }
     612:
     613:     if (tcc > 0) {
     614:     if (In3270) {
     615:         c = DataFromTerminal(tbp, tcc);
     616:         if (c) {
     617:         returnValue = 1;        /* did something useful */
     618:         }
     619:         tcc -= c;
     620:         tbp += c;
     621:     } else {
     622:         returnValue = 1;        /* did something useful */
     623:         while (tcc > 0) {
     624:         if ((&netobuf[BUFSIZ] - nfrontp) < 2)
     625:             break;
     626:         c = *tbp++ & 0377, tcc--;
     627:         if (strip(c) == escape) {
     628:             command(0);
     629:             tcc = 0;
     630:             break;
     631:         }
     632:         if (c == IAC)
     633:             *nfrontp++ = c;
     634:         *nfrontp++ = c;
     635:         }
     636:     }
     637:     }
     638:     if (FD_ISSET(net, &obits) && (c = (int) (nfrontp - nbackp)) > 0) {
     639:     netflush();
     640:     if (c != (int) (nfrontp-nbackp)) {
     641:         returnValue = 1;
     642:     }
     643:     }
     644:     if (scc > 0) {
     645:     if (Ifrontp+scc >= Ibuf+IBUFSIZ) {
     646:         if (Ibackp != Ibuf) {   /* do some copying */
     647:         bcopy(Ibackp, Ibuf, Ifrontp-Ibackp);
     648:         Ifrontp -= (Ibackp-Ibuf);
     649:         Ibackp = Ibuf;
     650:         }
     651:     }
     652:     if (Ifrontp+scc < Ibuf+IBUFSIZ) {
     653:         returnValue = 1;        /* doing something useful */
     654:         telrcv();
     655:     }       /* Else - we may never recover */
     656:     }
     657:     if (FD_ISSET(tout, &obits) && (c = (int) (tfrontp - tbackp)) > 0) {
     658:     ttyflush();
     659:     if (c != (int) (tfrontp-tbackp)) {
     660:         returnValue = 1;
     661:     }
     662:     }
     663:     if (In3270 && (c = (int) (Ifrontp-Ibackp))) {
     664:         Ibackp += DataFromNetwork(Ibackp, Ifrontp-Ibackp, ISend);
     665:         if (c != (int) (Ifrontp-Ibackp)) {
     666:         returnValue = 1;
     667:         }
     668:         if (Ibackp == Ifrontp) {
     669:             Ibackp = Ifrontp = Ibuf;
     670:             ISend = 0;  /* take data from network */
     671:         }
     672:     }
     673:     return(returnValue);                /* good return */
     674: }
     675:
     676: command(top)
     677:     int top;
     678: {
     679:     register struct cmd *c;
     680:     int oldmode;
     681:
     682:     oldmode = mode(0);
     683:     if (!top)
     684:         putchar('\n');
     685:     else
     686:         signal(SIGINT, SIG_DFL);
     687:     for (;;) {
     688:         printf("%s> ", prompt);
     689:         if (gets(line) == 0) {
     690:             if (feof(stdin)) {
     691:                 clearerr(stdin);
     692:                 putchar('\n');
     693:             }
     694:             break;
     695:         }
     696:         if (line[0] == 0)
     697:             break;
     698:         makeargv();
     699:         c = getcmd(margv[0]);
     700:         if (c == (struct cmd *)-1) {
     701:             printf("?Ambiguous command\n");
     702:             continue;
     703:         }
     704:         if (c == 0) {
     705:             printf("?Invalid command\n");
     706:             continue;
     707:         }
     708:         (*c->handler)(margc, margv);
     709:         if (c->handler != help)
     710:             break;
     711:     }
     712:     if (!top) {
     713:         if (!connected)
     714:             longjmp(toplevel, 1);
     715:         (void) mode(oldmode);
     716:     }
     717: }
     718:
     719: /*
     720:  * Telnet receiver states for fsm
     721:  */
     722: #define TS_DATA     0
     723: #define TS_IAC      1
     724: #define TS_WILL     2
     725: #define TS_WONT     3
     726: #define TS_DO       4
     727: #define TS_DONT     5
     728: #define TS_SB       6   /* in sub-negotiation */
     729: #define TS_SE       7   /* coming out of sub-negotiation */
     730:
     731: #define SB_ACCUM(c) {*pSb = c;  /* accumulate character */ \
     732:             if (pSb >= SbBuffer+sizeof (SbBuffer)) { \
     733:                 /* can't accept any more */ \
     734:                 pSb = SbBuffer; \
     735:             } \
     736:             pSb++;}
     737:
     738: static
     739: telrcv()
     740: {
     741:     register int c;
     742:     register char *Sbp;
     743:     register int Scc;
     744:     static int state = TS_DATA;
     745:
     746:     while (scc > 0) {
     747:         c = *sbp++ & 0377, scc--;
     748:         switch (state) {
     749:
     750:         case TS_DATA:
     751:             if (c == IAC) {
     752:                 state = TS_IAC;
     753:                 continue;
     754:             }
     755:                 /* We optimize this loop, since it is
     756: 				 * where we spend 99% of this routine.
     757: 				 */
     758:             if (In3270) {
     759:                 *Ifrontp++ = c;
     760:                 Sbp = sbp;
     761:                 Scc = scc;
     762:                 while (Scc > 0) {
     763:                 c = *Sbp++ & 0377, Scc--;
     764:                 if (c == IAC) {
     765:                     state = TS_IAC;
     766:                     break;
     767:                 }
     768:                 *Ifrontp++ = c;
     769:                 }
     770:                 sbp = Sbp;
     771:                 scc = Scc;
     772:             } else {
     773:                 *tfrontp++ = c;
     774:                 /*
     775: 			     * This hack is needed since we can't set
     776: 			     * CRMOD on output only.  Machines like MULTICS
     777: 			     * like to send \r without \n; since we must
     778: 			     * turn off CRMOD to get proper input, the mapping
     779: 			     * is done here (sigh).
     780: 			     */
     781:                 if (c == '\r' && crmod && !In3270)
     782:                     *tfrontp++ = '\n';
     783:             }
     784:             continue;
     785:
     786:
     787:         case TS_IAC:
     788:             switch (c) {
     789:
     790:             case WILL:
     791:                 state = TS_WILL;
     792:                 continue;
     793:
     794:             case WONT:
     795:                 state = TS_WONT;
     796:                 continue;
     797:
     798:             case DO:
     799:                 state = TS_DO;
     800:                 continue;
     801:
     802:             case DONT:
     803:                 state = TS_DONT;
     804:                 continue;
     805:
     806:             case DM:
     807:                 outputPurge();
     808:                 break;
     809:
     810:             case NOP:
     811:             case GA:
     812:                 break;
     813:
     814:             case SB:
     815:                 state = TS_SB;
     816:                 pSb = SbBuffer; /* where to collect */
     817:                 continue;
     818:
     819:             case EOR:
     820:                 if (In3270) {
     821:                     Ibackp += DataFromNetwork(Ibackp,
     822:                         Ifrontp-Ibackp, 1);
     823:                     if (Ibackp == Ifrontp) {
     824:                     Ibackp = Ifrontp = Ibuf;
     825:                     ISend = 0;  /* should have been! */
     826:                     } else {
     827:                     ISend = 1;
     828:                     }
     829:                 }
     830:                 break;
     831:
     832:             case IAC:
     833:                 if (In3270) {
     834:                     *Ifrontp++ = IAC;
     835:                 } else {
     836:                     *tfrontp++ = IAC;
     837:                 }
     838:                 break;
     839:
     840:             default:
     841:                 break;
     842:             }
     843:             state = TS_DATA;
     844:             continue;
     845:
     846:         case TS_WILL:
     847:             printoption("RCVD", will, c, !hisopts[c]);
     848:             if (!hisopts[c])
     849:                 willoption(c);
     850:             state = TS_DATA;
     851:             continue;
     852:
     853:         case TS_WONT:
     854:             printoption("RCVD", wont, c, hisopts[c]);
     855:             if (hisopts[c])
     856:                 wontoption(c);
     857:             state = TS_DATA;
     858:             continue;
     859:
     860:         case TS_DO:
     861:             printoption("RCVD", doopt, c, !myopts[c]);
     862:             if (!myopts[c])
     863:                 dooption(c);
     864:             state = TS_DATA;
     865:             continue;
     866:
     867:         case TS_DONT:
     868:             printoption("RCVD", dont, c, myopts[c]);
     869:             if (myopts[c]) {
     870:                 myopts[c] = 0;
     871:                 if (c == TELOPT_BINARY) {
     872:                     SetIn3270();
     873:                 }
     874:                 sprintf(nfrontp, wont, c);
     875:                 nfrontp += sizeof (wont) - 2;
     876:                 printoption("SENT", wont, c);
     877:             }
     878:             state = TS_DATA;
     879:             continue;
     880:         case TS_SB:
     881:             if (c == IAC) {
     882:                 state = TS_SE;
     883:                 continue;
     884:             }
     885:             SB_ACCUM(c);
     886:             continue;
     887:         case TS_SE:
     888:             if (c != SE) {
     889:             if (c != IAC) {
     890:                 SB_ACCUM(IAC);
     891:             }
     892:             SB_ACCUM(c);
     893:             state = TS_SB;
     894:             } else {
     895:             /* this is the end of the sub negotiation */
     896:             /* we only allow a termtype, send, sub */
     897:             if ((Sb_Option != TELOPT_TTYPE) ||
     898:                 (Sb_Command != TELQUAL_SEND)) {
     899:                 /* what to do? XXX */
     900:             } else {
     901:                 /* send our type */
     902:                 SentTerminalType = 1;
     903:                 SetIn3270();
     904:                 bcopy(sb_terminal, nfrontp, sizeof sb_terminal);
     905:                 nfrontp += sizeof sb_terminal;
     906:                 printoption("SENT", sb_terminal,
     907:                     TELOPT_TTYPE);
     908:             }
     909:             state = TS_DATA;
     910:             }
     911:         }
     912:     }
     913: }
     914:
     915: static
     916: willoption(option)
     917:     int option;
     918: {
     919:     char *fmt;
     920:
     921:     switch (option) {
     922:
     923:     case TELOPT_ECHO:
     924:         (void) mode(1);
     925:
     926:     case TELOPT_BINARY:
     927:         hisopts[option] = 1;
     928:         SetIn3270();
     929:         fmt = doopt;
     930:         break;
     931:
     932:     case TELOPT_EOR:
     933:     case TELOPT_SGA:
     934:         hisopts[option] = 1;
     935:         fmt = doopt;
     936:         break;
     937:
     938:     case TELOPT_TM:
     939:         fmt = dont;
     940:         break;
     941:
     942:     default:
     943:         fmt = dont;
     944:         break;
     945:     }
     946:     sprintf(nfrontp, fmt, option);
     947:     nfrontp += sizeof (dont) - 2;
     948:     printoption("SENT", fmt, option);
     949: }
     950:
     951: static
     952: wontoption(option)
     953:     int option;
     954: {
     955:     char *fmt;
     956:
     957:     switch (option) {
     958:
     959:     case TELOPT_BINARY:
     960:         hisopts[option] = 0;
     961:         SetIn3270();
     962:         fmt = doopt;
     963:         break;
     964:
     965:     case TELOPT_ECHO:
     966:         (void) mode(2);
     967:
     968:     case TELOPT_SGA:
     969:         hisopts[option] = 0;
     970:         fmt = dont;
     971:         break;
     972:
     973:     default:
     974:         fmt = dont;
     975:     }
     976:     sprintf(nfrontp, fmt, option);
     977:     nfrontp += sizeof (doopt) - 2;
     978:     printoption("SENT", fmt, option);
     979: }
     980:
     981: static
     982: dooption(option)
     983:     int option;
     984: {
     985:     char *fmt;
     986:
     987:     switch (option) {
     988:
     989:     case TELOPT_TTYPE:
     990:     case TELOPT_BINARY:
     991:         myopts[option] = 1;
     992:         SetIn3270();
     993:         fmt = will;
     994:         break;
     995:
     996:     case TELOPT_TM:
     997:         fmt = wont;
     998:         break;
     999:
    1000:     case TELOPT_ECHO:
    1001:         (void) mode(2);
    1002:         fmt = will;
    1003:         hisopts[option] = 0;
    1004:         break;
    1005:
    1006:     case TELOPT_EOR:
    1007:     case TELOPT_SGA:
    1008:         fmt = will;
    1009:         break;
    1010:
    1011:     default:
    1012:         fmt = wont;
    1013:         break;
    1014:     }
    1015:     sprintf(nfrontp, fmt, option);
    1016:     nfrontp += (sizeof dont)-2;
    1017:     printoption("SENT", fmt, option);
    1018: }
    1019:
    1020: static
    1021: SetIn3270()
    1022: {
    1023:     if (SentTerminalType && myopts[TELOPT_BINARY] && hisopts[TELOPT_BINARY]) {
    1024:     if (!In3270) {
    1025:         In3270 = 1;
    1026:         OptInit();      /* initialize mappings */
    1027:         /* initialize terminal key mapping */
    1028:         (void) DataFromTerminal(ttyobuf, 0);
    1029:         (void) mode(3);
    1030:     }
    1031:     } else {
    1032:     if (In3270) {
    1033:         Stop3270(1);
    1034:         In3270 = 0;
    1035:         (void) mode(2);
    1036:     }
    1037:     }
    1038: }
    1039:
    1040: /*
    1041:  * Set the escape character.
    1042:  */
    1043: static
    1044: setescape(argc, argv)
    1045:     int argc;
    1046:     char *argv[];
    1047: {
    1048:     register char *arg;
    1049:     char buf[50];
    1050:
    1051:     if (argc > 2)
    1052:         arg = argv[1];
    1053:     else {
    1054:         printf("new escape character: ");
    1055:         gets(buf);
    1056:         arg = buf;
    1057:     }
    1058:     if (arg[0] != '\0')
    1059:         escape = arg[0];
    1060:     printf("Escape character is '%s'.\n", control(escape));
    1061:     fflush(stdout);
    1062: }
    1063:
    1064: /*VARARGS*/
    1065: static
    1066: setoptions()
    1067: {
    1068:
    1069:     showoptions = !showoptions;
    1070:     printf("%s show option processing.\n", showoptions ? "Will" : "Wont");
    1071:     fflush(stdout);
    1072: }
    1073:
    1074: /*VARARGS*/
    1075: static
    1076: setcrmod()
    1077: {
    1078:
    1079:     crmod = !crmod;
    1080:     printf("%s map carriage return on output.\n", crmod ? "Will" : "Wont");
    1081:     fflush(stdout);
    1082: }
    1083:
    1084: /*VARARGS*/
    1085: static
    1086: setdebug()
    1087: {
    1088:
    1089:     debug = !debug;
    1090:     printf("%s turn on socket level debugging.\n",
    1091:         debug ? "Will" : "Wont");
    1092:     fflush(stdout);
    1093:     if (debug && net > 0 && setsockopt(net, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
    1094:         perror("setsockopt (SO_DEBUG)");
    1095: }
    1096:
    1097: /*VARARGS*/
    1098: static
    1099: SetPrintNet()
    1100: {
    1101:
    1102:     printnet = !printnet;
    1103:     printf("%s turn on printing of raw network traffic.\n",
    1104:         printnet ? "Will" : "Wont");
    1105: }
    1106:
    1107: /*
    1108:  * Construct a control character sequence
    1109:  * for a special character.
    1110:  */
    1111: static char *
    1112: control(c)
    1113:     register int c;
    1114: {
    1115:     static char buf[3];
    1116:
    1117:     if (c == 0177)
    1118:         return ("^?");
    1119:     if (c >= 040) {
    1120:         buf[0] = c;
    1121:         buf[1] = 0;
    1122:     } else {
    1123:         buf[0] = '^';
    1124:         buf[1] = '@'+c;
    1125:         buf[2] = 0;
    1126:     }
    1127:     return (buf);
    1128: }
    1129:
    1130: static struct cmd *
    1131: getcmd(name)
    1132:     register char *name;
    1133: {
    1134:     register char *p, *q;
    1135:     register struct cmd *c, *found;
    1136:     register int nmatches, longest;
    1137:
    1138:     longest = 0;
    1139:     nmatches = 0;
    1140:     found = 0;
    1141:     for (c = cmdtab; p = c->name; c++) {
    1142:         for (q = name; *q == *p++; q++)
    1143:             if (*q == 0)        /* exact match? */
    1144:                 return (c);
    1145:         if (!*q) {          /* the name was a prefix */
    1146:             if (q - name > longest) {
    1147:                 longest = q - name;
    1148:                 nmatches = 1;
    1149:                 found = c;
    1150:             } else if (q - name == longest)
    1151:                 nmatches++;
    1152:         }
    1153:     }
    1154:     if (nmatches > 1)
    1155:         return ((struct cmd *)-1);
    1156:     return (found);
    1157: }
    1158:
    1159: static
    1160: deadpeer()
    1161: {
    1162:     (void) mode(0);
    1163:     longjmp(peerdied, -1);
    1164: }
    1165:
    1166: static
    1167: intr()
    1168: {
    1169:     (void) mode(0);
    1170:     longjmp(toplevel, -1);
    1171: }
    1172:
    1173: static
    1174: inputAvailable()
    1175: {
    1176:     HaveInput = 1;
    1177: }
    1178:
    1179: /* outputPurge() - get rid of all output destined for terminal. */
    1180: outputPurge()
    1181: {
    1182:     ioctl(fileno(stdout), TIOCFLUSH, (char *)0);
    1183:     tbackp = tfrontp = ttyobuf;
    1184: }
    1185:
    1186: ttyflush()
    1187: {
    1188:     int n;
    1189:
    1190:     if ((n = tfrontp - tbackp) > 0)
    1191:         n = write(tout, tbackp, n);
    1192:     if (n < 0)
    1193:         return;
    1194:     tbackp += n;
    1195:     if (tbackp == tfrontp)
    1196:         tbackp = tfrontp = ttyobuf;
    1197: }
    1198:
    1199: /* TtyChars() - returns the number of characters in the TTY buffer */
    1200: TtyChars()
    1201: {
    1202:     return(tfrontp-tbackp);
    1203: }
    1204:
    1205: netflush()
    1206: {
    1207:     int n;
    1208:
    1209:     if ((n = nfrontp - nbackp) > 0)
    1210:         n = write(net, nbackp, n);
    1211:     if (n < 0) {
    1212:         if (errno != ENOBUFS && errno != EWOULDBLOCK) {
    1213:             (void) mode(0);
    1214:             perror(hostname);
    1215:             close(net);
    1216:             longjmp(peerdied, -1);
    1217:             /*NOTREACHED*/
    1218:         }
    1219:         n = 0;
    1220:     }
    1221:     if (printnet) {
    1222:         Dump('>', nbackp, n);
    1223:     }
    1224:     nbackp += n;
    1225:     if (nbackp == nfrontp)
    1226:         nbackp = nfrontp = netobuf;
    1227: }
    1228:
    1229: /* DataToNetwork - queue up some data to go to network.  When last byte is
    1230:     queued, we add on an IAC EOR sequence (so, don't call us until you
    1231:     want that done...)
    1232:  */
    1233:
    1234: int
    1235: DataToNetwork(buffer, count)
    1236: register char   *buffer;        /* where the data is */
    1237: register int    count;          /* how much to send */
    1238: {
    1239:     register int c;
    1240:     int origCount;
    1241:
    1242:     origCount = count;
    1243:
    1244:     while (count) {
    1245:     if ((&netobuf[sizeof netobuf] - nfrontp) < 6) {
    1246:         netflush();
    1247:         if ((&netobuf[sizeof netobuf] - nfrontp) < 6) {
    1248:         break;
    1249:         }
    1250:     }
    1251:     c = *buffer++;
    1252:     count--;
    1253:     if (c == IAC) {
    1254:         *nfrontp++ = IAC;
    1255:         *nfrontp++ = IAC;
    1256:     } else {
    1257:         *nfrontp++ = c;
    1258:     }
    1259:     }
    1260:
    1261:     if (!count) {
    1262:     *nfrontp++ = IAC;
    1263:     *nfrontp++ = EOR;
    1264:     netflush();     /* try to move along as quickly as ... */
    1265:     }
    1266:     return(origCount - count);
    1267: }
    1268:
    1269: /* DataToTerminal - queue up some data to go to terminal. */
    1270:
    1271: int
    1272: DataToTerminal(buffer, count)
    1273: register char   *buffer;        /* where the data is */
    1274: register int    count;          /* how much to send */
    1275: {
    1276:     int origCount;
    1277:     fd_set o;
    1278:
    1279:     origCount = count;
    1280:
    1281:     while (count) {
    1282:     if (tfrontp >= &ttyobuf[sizeof ttyobuf]) {
    1283:         ttyflush();
    1284:         while (tfrontp >= &ttyobuf[sizeof ttyobuf]) {
    1285:         FD_ZERO(&o);
    1286:         FD_SET(tout, &o);
    1287:         (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
    1288:                         (struct timeval *) 0);
    1289:         ttyflush();
    1290:         }
    1291:     }
    1292:     *tfrontp++ = *buffer++;
    1293:     count--;
    1294:     }
    1295:     return(origCount - count);
    1296: }
    1297:
    1298: /* EmptyTerminal - called to make sure that the terminal buffer is empty.
    1299:  *			Note that we consider the buffer to run all the
    1300:  *			way to the kernel (thus the select).
    1301:  */
    1302:
    1303: void
    1304: EmptyTerminal()
    1305: {
    1306:     fd_set o;
    1307:
    1308:     FD_ZERO(&o);
    1309:     FD_SET(tout, &o);
    1310:
    1311:     if (tfrontp == tbackp) {
    1312:     (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
    1313:             (struct timeval *) 0);  /* wait for TTLOWAT */
    1314:     } else {
    1315:     while (tfrontp != tbackp) {
    1316:         ttyflush();
    1317:         (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
    1318:                 (struct timeval *) 0);  /* wait for TTLOWAT */
    1319:     }
    1320:     }
    1321: }
    1322:
    1323:
    1324:
    1325: /* StringToTerminal - output a null terminated string to the terminal */
    1326:
    1327: int
    1328: StringToTerminal(s)
    1329: char *s;
    1330: {
    1331:     int count;
    1332:
    1333:     count = strlen(s);
    1334:     if (count) {
    1335:     (void) DataToTerminal(s, count);    /* we know it always goes... */
    1336:     }
    1337: }
    1338:
    1339:
    1340: /* _putchar - output a single character to the terminal.  This name is so that
    1341:  *	curses(3x) can call us to send out data.
    1342:  */
    1343:
    1344: _putchar(c)
    1345: char c;
    1346: {
    1347:     if (tfrontp >= &ttyobuf[sizeof ttyobuf]) {
    1348:     (void) DataToTerminal(&c, 1);
    1349:     } else {
    1350:     *tfrontp++ = c;     /* optimize if possible. */
    1351:     }
    1352: }
    1353:
    1354: static
    1355: SetForExit()
    1356: {
    1357:     (void) mode(2);         /* switch modes to flush output */
    1358:     (void) mode(0);
    1359:     fflush(stdout);
    1360:     fflush(stderr);
    1361:     if (In3270) {
    1362:     Stop3270(0);
    1363:     }
    1364:     (void) mode(2);         /* make sure we go back to mode 0 */
    1365:     (void) mode(0);
    1366: }
    1367:
    1368: static
    1369: Exit(returnCode)
    1370: int returnCode;
    1371: {
    1372:     SetForExit();
    1373:     exit(returnCode);
    1374: }
    1375:
    1376: ExitString(file, string, returnCode)
    1377: FILE *file;
    1378: char *string;
    1379: int returnCode;
    1380: {
    1381:     SetForExit();
    1382:     fwrite(string, 1, strlen(string), file);
    1383:     exit(returnCode);
    1384: }
    1385:
    1386: ExitPerror(string, returnCode)
    1387: char *string;
    1388: int returnCode;
    1389: {
    1390:     SetForExit();
    1391:     perror(string);
    1392:     exit(returnCode);
    1393: }
    1394:
    1395:
    1396: static
    1397: Dump(direction, buffer, length)
    1398: char    direction;
    1399: char    *buffer;
    1400: int length;
    1401: {
    1402: #   define BYTES_PER_LINE   32
    1403:     char *pThis;
    1404:     int offset;
    1405:
    1406:     offset = 0;
    1407:
    1408:     while (length) {
    1409:     /* print one line */
    1410:     fprintf(NetTrace, "%c 0x%x\t", direction, offset);
    1411:     pThis = buffer;
    1412:     buffer = buffer+min(length, BYTES_PER_LINE);
    1413:     while (pThis < buffer) {
    1414:         fprintf(NetTrace, "%.2x", (*pThis)&0xff);
    1415:         pThis++;
    1416:     }
    1417:     fprintf(NetTrace, "\n");
    1418:     length -= BYTES_PER_LINE;
    1419:     offset += BYTES_PER_LINE;
    1420:     if (length < 0) {
    1421:         return;
    1422:     }
    1423:     /* find next unique line */
    1424:     }
    1425: }
    1426:
    1427:
    1428:
    1429: /*VARARGS*/
    1430: static
    1431: printoption(direction, fmt, option, what)
    1432:     char *direction, *fmt;
    1433:     int option, what;
    1434: {
    1435:     if (!showoptions)
    1436:         return;
    1437:     printf("%s ", direction);
    1438:     if (fmt == doopt)
    1439:         fmt = "do";
    1440:     else if (fmt == dont)
    1441:         fmt = "dont";
    1442:     else if (fmt == will)
    1443:         fmt = "will";
    1444:     else if (fmt == wont)
    1445:         fmt = "wont";
    1446:     else if (fmt == sb_terminal)
    1447:         fmt = "will (terminal)";
    1448:     else
    1449:         fmt = "???";
    1450:     if (option < TELOPT_SUPDUP)
    1451:         printf("%s %s", fmt, telopts[option]);
    1452:     else
    1453:         printf("%s %d", fmt, option);
    1454:     if (*direction == '<') {
    1455:         printf("\r\n");
    1456:         return;
    1457:     }
    1458:     printf(" (%s)\r\n", what ? "reply" : "don't reply");
    1459: }

#### Defined functions

DataToNetwork defined in line 1234; used 3 times

- in /usr/src/ucb/tn3270/keyboard.c line 343, 373, 393

DataToTerminal defined in line 1271; used 3 times

- in line 1335, 1348
- in /usr/src/ucb/tn3270/datastream.c line 696

Dump defined in line 1396; used 2 times

- in line 592, 1222

EmptyTerminal defined in line 1303; used 5 times

- in /usr/src/ucb/tn3270/datastream.c line 38, 136, 411, 477, 502

Exit defined in line 1368; used 2 times

- in line 201, 355

ExitPerror defined in line 1386; never used
ExitString defined in line 1376; used 3 times

- in line 180, 278
- in /usr/src/ucb/tn3270/datastream.c line 201

Scheduler defined in line 520; used 2 times

- in line 494, 509

SetForExit defined in line 1354; used 3 times

- in line 1372, 1381, 1390

SetIn3270 defined in line 1020; used 5 times

- in line 872, 903, 928, 961, 992

SetPrintNet defined in line 1098; used 2 times

- in line 114, 148

StringToTerminal defined in line 1327; used 6 times

- in /usr/src/ucb/tn3270/datastream.c line 107, 131-134(2), 150, 498, 571

TtyChars defined in line 1200; never used
_putchar defined in line 1344; never used
bye defined in line 334; used 3 times

- in line 112, 139, 354

call defined in line 393; used 2 times

- in line 272, 354

command defined in line 676; used 4 times

- in line 206, 628
- in /usr/src/ucb/tn3270/keyboard.c line 487, 734

control defined in line 1111; used 2 times

- in line 157, 1060

deadpeer defined in line 1159; used 2 times

- in line 156, 264

dooption defined in line 981; used 1 times

- in line 863

getcmd defined in line 1130; used 3 times

- in line 158, 379, 699

help defined in line 361; used 7 times

- in line 112, 120, 149-150(2), 372, 385, 709

inputAvailable defined in line 1173; used 2 times

- in line 156, 566

intr defined in line 1166; used 2 times

- in line 156, 263

main defined in line 165; never used
makeargv defined in line 296; used 2 times

- in line 228, 698

mode defined in line 409; used 24 times

- in line 324, 330, 339, 486, 496, 510, 682, 715, 924, 966, 1001, 1029, 1035, 1162, 1169, 1213, 1357-1358(2), 1364-1365(2)
- in /usr/src/ucb/tn3270/datastream.c line 97, 110, 137-139(2)

netflush defined in line 1205; used 4 times

- in line 639, 1246, 1264
- in /usr/src/ucb/tn3270/keyboard.c line 399

outputPurge defined in line 1180; used 2 times

- in line 807
- in /usr/src/ucb/tn3270/datastream.c line 182

printoption defined in line 1430; used 9 times

- in line 847, 854, 861, 868, 876, 906, 948, 978, 1017

quit defined in line 352; used 3 times

- in line 111, 140
- in /usr/src/ucb/tn3270/termin.c line 118

setcrmod defined in line 1075; used 2 times

- in line 114, 146

setdebug defined in line 1085; used 2 times

- in line 114, 147

setescape defined in line 1043; used 2 times

- in line 113, 143

setoptions defined in line 1065; used 2 times

- in line 113, 145

status defined in line 285; used 3 times

- in line 113, 144, 272

suspend defined in line 320; used 4 times

- in line 111, 141-142(2)
- in /usr/src/ucb/tn3270/keyboard.c line 740

telnet defined in line 479; used 1 times

- in line 274

telrcv defined in line 738; used 1 times

- in line 654

tn defined in line 212; used 3 times

- in line 112, 138, 202

ttyflush defined in line 1186; used 4 times

- in line 658, 1283, 1289, 1316

willoption defined in line 915; used 1 times

- in line 849

wontoption defined in line 951; used 1 times

- in line 856

#### Defined variables

ForceMode defined in line 92; used 3 times

- in line 423-425(3)

HaveInput defined in line 85; used 3 times

- in line 564-565(2), 1176

ISend defined in line 91; used 6 times

- in line 545, 557, 664, 670, 825-827(2)

Ibackp defined in line 57; used 19 times

- in line 53, 172, 646-649(5), 663-669(7), 821-824(5)

Ibuf defined in line 57; used 11 times

- in line 53(2), 172, 645-652(6), 669, 824

Ifrontp defined in line 57; used 16 times

- in line 172, 645-652(4), 663-669(5), 759, 768, 822-824(3), 834

In3270 defined in line 90; used 14 times

- in line 275, 503, 537, 614, 663, 758, 781, 820, 833, 1024-1025(2), 1032-1034(2), 1361

SbBuffer defined in line 62; used 7 times

- in line 62-64(3), 732-734(3), 816

SentTerminalType defined in line 89; used 2 times

- in line 902, 1023

closehelp defined in line 126; used 1 times

- in line 139

cmdtab defined in line 137; used 2 times

- in line 370, 1141

connected defined in line 88; used 6 times

- in line 220, 271, 288, 340-344(2), 713

crmod defined in line 96; used 4 times

- in line 781, 1079-1080(3)

crmodhelp defined in line 134; used 1 times

- in line 146

debug defined in line 95; used 6 times

- in line 185, 261, 1089-1093(4)

debughelp defined in line 129; used 1 times

- in line 147

dont defined in line 71; used 8 times

- in line 868, 939-947(3), 970-974(2), 1016, 1440

doopt defined in line 70; used 6 times

- in line 861, 929, 935, 962, 977, 1438

escape defined in line 100; used 3 times

- in line 627, 1059-1060(2)

escapehelp defined in line 130; used 1 times

- in line 143

helphelp defined in line 132; used 2 times

- in line 149-150(2)

hisopts defined in line 67; used 12 times

- in line 346(2), 847-848(2), 854-855(2), 927, 934, 960, 969, 1003, 1023

hnamebuf defined in line 210; used 2 times

- in line 248-249(2)

hostname defined in line 209; used 5 times

- in line 221, 240, 249, 289, 1214

line defined in line 102; used 6 times

- in line 225-227(3), 303, 689, 696

margc defined in line 103; used 4 times

- in line 229, 302, 309, 708

margv defined in line 104; used 4 times

- in line 230, 300, 699, 708

myopts defined in line 68; used 7 times

- in line 861-862(2), 868-870(3), 991, 1023

net defined in line 93; used 20 times

- in line 256-266(4), 341-343(2), 487-489(3), 539, 546-549(2), 558, 583-584(2), 638, 1093(2), 1210-1215(2)

netobuf defined in line 60; used 8 times

- in line 60(2), 624, 1226, 1245-1247(4)

nfrontp defined in line 60; used 27 times

- in line 538, 548, 624, 633-640(4), 874-875(2), 904-905(2), 946-947(2), 976-977(2), 1015-1016(2), 1209, 1225-1226(2), 1245-1247(2), 1254-1263(5)

noltc defined in line 407; used 1 times

- in line 455

notc defined in line 406; used 2 times

- in line 448-453(2)

oltc defined in line 162; used 3 times

- in line 177, 329, 432

openhelp defined in line 125; used 1 times

- in line 138

optionshelp defined in line 133; used 1 times

- in line 145

otc defined in line 161; used 5 times

- in line 176, 328, 431, 450-451(2)

ottyb defined in line 163; used 3 times

- in line 175, 327, 422

pSb defined in line 62; used 5 times

- in line 731-736(4), 816

peerdied defined in line 107; used 3 times

- in line 273, 1163, 1216

printnet defined in line 97; used 5 times

- in line 591, 1102-1104(3), 1221

printnethelp defined in line 135; used 1 times

- in line 148

prompt defined in line 99; used 2 times

- in line 183, 688

quithelp defined in line 127; used 1 times

- in line 140

sb_terminal defined in line 74; used 5 times

- in line 904-906(4), 1446

sbp defined in line 471; used 5 times

- in line 590-592(2), 747, 760, 770

scc defined in line 473; used 13 times

- in line 561, 584-592(5), 644-645(2), 652, 746-747(2), 761, 771

sccsid defined in line 24; never used
showoptions defined in line 94; used 4 times

- in line 1069-1070(3), 1435

sibuf defined in line 471; used 3 times

- in line 584(2), 590

sin defined in line 154; used 11 times

- in line 238-244(5), 251-254(4), 266(2)

sp defined in line 159; used 3 times

- in line 178-179(2), 251

statushelp defined in line 131; used 1 times

- in line 144

tbp defined in line 472; used 4 times

- in line 608, 615-620(2), 626

tcc defined in line 473; used 13 times

- in line 540, 551, 561, 602-606(4), 613-629(6)

tfrontp defined in line 59; used 20 times

- in line 503, 543, 554, 657-659(2), 773, 782, 836, 1183, 1190-1196(3), 1202, 1282-1284(2), 1292, 1311-1315(2), 1347-1350(2)

tibuf defined in line 472; used 3 times

- in line 602(2), 608

tin defined in line 474; used 5 times

- in line 490, 541, 552, 601-602(2)

toplevel defined in line 106; used 4 times

- in line 200-204(2), 714, 1170

tout defined in line 474; used 10 times

- in line 491, 544, 555, 657, 1191, 1286-1287(2), 1309-1317(3)

ttyobuf defined in line 59; used 11 times

- in line 59(2), 1028, 1183, 1196, 1282-1284(4), 1347(2)

will defined in line 72; used 5 times

- in line 847, 993, 1002, 1008, 1442

wont defined in line 73; used 7 times

- in line 854, 874-876(3), 997, 1012, 1444

zhelp defined in line 128; used 2 times

- in line 141-142(2)

#### Defined struct's

cmd defined in line 118; used 20 times

- in line 137(2), 158(2), 366(2), 380-382(4), 679(2), 700(2), 1130-1135(4), 1155(2)

#### Defined macros

BYTES_PER_LINE defined in line 1402; used 3 times

- in line 1412, 1418-1419(2)

FD_NEXT defined in line 571; used 2 times

- in line 573(2)

HELPINDENT defined in line 116; used 1 times

- in line 372

IBUFSIZ defined in line 56; used 4 times

- in line 53, 170, 645, 652

SB_ACCUM defined in line 731; used 3 times

- in line 885-892(3)

Sb_Command defined in line 64; used 1 times

- in line 898

Sb_Option defined in line 63; used 1 times

- in line 897

TELOPTS defined in line 38; never used
TS_DATA defined in line 722; used 7 times

- in line 744, 843, 850, 857, 864, 878, 909

TS_DO defined in line 726; used 1 times

- in line 799

TS_DONT defined in line 727; used 1 times

- in line 803

TS_IAC defined in line 723; used 2 times

- in line 752, 765

TS_SB defined in line 728; used 2 times

- in line 815, 893

TS_SE defined in line 729; used 1 times

- in line 882

TS_WILL defined in line 724; used 1 times

- in line 791

TS_WONT defined in line 725; used 1 times

- in line 795

min defined in line 49; used 1 times

- in line 1412

strip defined in line 48; used 1 times

- in line 627

Last modified: 1994-01-01 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 4931 |