1*30330Sminshall /* 2*30330Sminshall * Copyright (c) 1984, 1985, 1986 by the Regents of the 3*30330Sminshall * University of California and by Gregory Glenn Minshall. 4*30330Sminshall * 5*30330Sminshall * Permission to use, copy, modify, and distribute these 6*30330Sminshall * programs and their documentation for any purpose and 7*30330Sminshall * without fee is hereby granted, provided that this 8*30330Sminshall * copyright and permission appear on all copies and 9*30330Sminshall * supporting documentation, the name of the Regents of 10*30330Sminshall * the University of California not be used in advertising 11*30330Sminshall * or publicity pertaining to distribution of the programs 12*30330Sminshall * without specific prior permission, and notice be given in 13*30330Sminshall * supporting documentation that copying and distribution is 14*30330Sminshall * by permission of the Regents of the University of California 15*30330Sminshall * and by Gregory Glenn Minshall. Neither the Regents of the 16*30330Sminshall * University of California nor Gregory Glenn Minshall make 17*30330Sminshall * representations about the suitability of this software 18*30330Sminshall * for any purpose. It is provided "as is" without 19*30330Sminshall * express or implied warranty. 20*30330Sminshall */ 21*30330Sminshall 22*30330Sminshall #ifndef lint 23*30330Sminshall static char sccsid[] = "@(#)termin.c 3.1 10/29/86"; 24*30330Sminshall #endif /* ndef lint */ 25*30330Sminshall 26*30330Sminshall /* this takes characters from the keyboard, and produces 3270 keystroke 27*30330Sminshall codes 28*30330Sminshall */ 29*30330Sminshall 30*30330Sminshall #include <ctype.h> 31*30330Sminshall 32*30330Sminshall #include "m4.out" /* output of termcodes.m4 */ 33*30330Sminshall #include "state.h" 34*30330Sminshall 35*30330Sminshall #include "globals.h" 36*30330Sminshall #include "inbound.ext" 37*30330Sminshall #include "outbound.ext" 38*30330Sminshall #include "telnet.ext" 39*30330Sminshall #include "termin.ext" 40*30330Sminshall 41*30330Sminshall #define IsControl(c) (!isprint(c) || (isspace(c) && ((c) != ' '))) 42*30330Sminshall 43*30330Sminshall #define NextState(x) (x->next) 44*30330Sminshall 45*30330Sminshall /* XXX temporary - hard code in the state table */ 46*30330Sminshall 47*30330Sminshall #define MATCH_ANY 0xff /* actually, match any character */ 48*30330Sminshall 49*30330Sminshall 50*30330Sminshall static char 51*30330Sminshall ourBuffer[100], /* where we store stuff */ 52*30330Sminshall *ourPHead = ourBuffer, /* first character in buffer */ 53*30330Sminshall *ourPTail = ourBuffer; /* where next character goes */ 54*30330Sminshall 55*30330Sminshall static state 56*30330Sminshall *headOfControl = 0; /* where we enter code state table */ 57*30330Sminshall 58*30330Sminshall #define FullChar (ourPTail == ourBuffer+sizeof ourBuffer) 59*30330Sminshall #define EmptyChar (ourPTail == ourPHead) 60*30330Sminshall 61*30330Sminshall 62*30330Sminshall /* AddChar - put a character in our buffer */ 63*30330Sminshall 64*30330Sminshall static void 65*30330Sminshall AddChar(c) 66*30330Sminshall int c; 67*30330Sminshall { 68*30330Sminshall if (!FullChar) { 69*30330Sminshall *ourPTail++ = (char) c; 70*30330Sminshall } else { 71*30330Sminshall RingBell(); 72*30330Sminshall } 73*30330Sminshall } 74*30330Sminshall 75*30330Sminshall /* FlushChar - put everything where it belongs */ 76*30330Sminshall 77*30330Sminshall static void 78*30330Sminshall FlushChar() 79*30330Sminshall { 80*30330Sminshall ourPTail = ourBuffer; 81*30330Sminshall ourPHead = ourBuffer; 82*30330Sminshall } 83*30330Sminshall 84*30330Sminshall 85*30330Sminshall int 86*30330Sminshall TerminalIn() 87*30330Sminshall { 88*30330Sminshall /* send data from us to next link in stream */ 89*30330Sminshall int count; 90*30330Sminshall 91*30330Sminshall count = 0; 92*30330Sminshall 93*30330Sminshall if (!EmptyChar) { /* send up the link */ 94*30330Sminshall count += DataFrom3270(ourPHead, ourPTail-ourPHead); 95*30330Sminshall ourPHead += count; 96*30330Sminshall if (EmptyChar) { 97*30330Sminshall FlushChar(); 98*30330Sminshall } 99*30330Sminshall } 100*30330Sminshall /* return value answers question: "did we do anything useful?" */ 101*30330Sminshall return(count? 1:0); 102*30330Sminshall } 103*30330Sminshall 104*30330Sminshall int 105*30330Sminshall DataFromTerminal(buffer, count) 106*30330Sminshall register char *buffer; /* the data read in */ 107*30330Sminshall register int count; /* how many bytes in this buffer */ 108*30330Sminshall { 109*30330Sminshall register state *regControlPointer; 110*30330Sminshall register char c; 111*30330Sminshall register int result; 112*30330Sminshall int origCount; 113*30330Sminshall 114*30330Sminshall static int InControl = 0; 115*30330Sminshall static int WaitingForSynch = 0; 116*30330Sminshall static state *controlPointer; 117*30330Sminshall extern state *InitControl(); 118*30330Sminshall 119*30330Sminshall if (!headOfControl) { 120*30330Sminshall /* need to initialize */ 121*30330Sminshall headOfControl = InitControl((char *)0, 0); 122*30330Sminshall if (!headOfControl) { /* should not occur */ 123*30330Sminshall quit(); 124*30330Sminshall } 125*30330Sminshall } 126*30330Sminshall 127*30330Sminshall 128*30330Sminshall origCount = count; 129*30330Sminshall 130*30330Sminshall while (count) { 131*30330Sminshall c = *buffer++&0x7f; 132*30330Sminshall count--; 133*30330Sminshall 134*30330Sminshall if (!InControl && !IsControl(c)) { 135*30330Sminshall AddChar(c); /* add ascii character */ 136*30330Sminshall } else { 137*30330Sminshall if (!InControl) { /* first character of sequence */ 138*30330Sminshall InControl = 1; 139*30330Sminshall controlPointer = headOfControl; 140*30330Sminshall } 141*30330Sminshall /* control pointer points to current position in state table */ 142*30330Sminshall for (regControlPointer = controlPointer; ; 143*30330Sminshall regControlPointer = NextState(regControlPointer)) { 144*30330Sminshall if (!regControlPointer) { /* ran off end */ 145*30330Sminshall RingBell(); 146*30330Sminshall regControlPointer = headOfControl; 147*30330Sminshall InControl = 0; 148*30330Sminshall break; 149*30330Sminshall } 150*30330Sminshall if ((regControlPointer->match == c) /* hit this character */ 151*30330Sminshall || (regControlPointer->match == MATCH_ANY)) { 152*30330Sminshall result = regControlPointer->result; 153*30330Sminshall if (result == TC_GOTO) { 154*30330Sminshall regControlPointer = regControlPointer->address; 155*30330Sminshall break; /* go to next character */ 156*30330Sminshall } 157*30330Sminshall if (WaitingForSynch) { 158*30330Sminshall if (result == TC_SYNCH) { 159*30330Sminshall WaitingForSynch = 0; 160*30330Sminshall } else { 161*30330Sminshall RingBell(); 162*30330Sminshall } 163*30330Sminshall } 164*30330Sminshall else if (result == TC_FLINP) { 165*30330Sminshall FlushChar(); /* Don't add FLINP */ 166*30330Sminshall } else { 167*30330Sminshall if (result == TC_MASTER_RESET) { 168*30330Sminshall FlushChar(); 169*30330Sminshall } 170*30330Sminshall AddChar(result); /* add this code */ 171*30330Sminshall } 172*30330Sminshall InControl = 0; /* out of control now */ 173*30330Sminshall break; 174*30330Sminshall } 175*30330Sminshall } 176*30330Sminshall controlPointer = regControlPointer; /* save state */ 177*30330Sminshall } 178*30330Sminshall } 179*30330Sminshall (void) TerminalIn(); /* try to send data */ 180*30330Sminshall return(origCount-count); 181*30330Sminshall } 182