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