1 /* *********************************************************** 2 * * 3 * Copyright, (C) Honeywell Bull Inc., 1987 * 4 * * 5 * Copyright, (C) Honeywell Information Systems Inc., 1986 * 6 * * 7 *********************************************************** */ 8 9 /* HISTORY COMMENTS: 10 1) change(86-06-23,Lee), approve(87-07-13,MCR7580), audit(87-07-13,Leskiw), 11 install(87-08-07,MR12.1-1072): 12 Created. 13 2) change(86-07-25,Lee), approve(87-07-13,MCR7580), audit(87-07-13,Leskiw), 14 install(87-08-07,MR12.1-1072): 15 Modifed command line args, saves to script file 16 3) change(86-08-24,Lee), approve(87-07-13,MCR7580), audit(87-07-13,Leskiw), 17 install(87-08-07,MR12.1-1072): 18 Added menus 19 4) change(86-09-07,Lee), approve(87-07-13,MCR7580), audit(87-07-13,Leskiw), 20 install(87-08-07,MR12.1-1072): 21 Added tab handling, local editing 22 5) change(86-09-11,Lee), approve(87-07-13,MCR7580), audit(87-07-13,Leskiw), 23 install(87-08-07,MR12.1-1072): 24 DOS commands, query status 25 6) change(86-09-26,Lee), approve(87-07-13,MCR7580), audit(87-07-13,Leskiw), 26 install(87-08-07,MR12.1-1072): 27 Split emulator into two versions, a debugging 28 and a non-debugging version; change the define EM_DEBUG in emulator.h 29 to 0 for non-debugging version, change to 1 for debugging version 30 END HISTORY COMMENTS */ 31 32 /* : PROCEDURE FUNCTION (emulator) 33 34 Allows a user to interact through MOWSE foreground and background channels 35 through a simple terminal interface. This terminal emulator treats foreground 36 data as would a normal emulator. However, to distinguish background data from 37 foreground data, all background data is preceeded by a carat (^). Thus any 38 background data going onto the screen will be preceeded by a carat. Similarly, 39 if keyboard input is preceed by a carat, then it will be sent to the background 40 channel. No priority will be given to either channel, information that is 41 displayed first will be displayed. If there are several background queries, 42 then background data from the keyboard will go to each background query in 43 sequence. 44 45 Unless otherwise specified, all function keys may be invoked in either 46 packet or non-packet mode (i.e. after or before attaching to MOWSE). 47 48 F1 - debugging mode only; 49 Suspend processing of terminal data; when this key is pressed 50 while foreground or background data is being received and displayed, 51 the emulator will sit in a tight loop, resulting in temporary 52 stoppage in the handling of terminal data. Hitting any other key 53 will resume processing. 54 55 F2 - Debugging mode only. Toggle display mode; there are 3 modes: 56 Printable ASCII only - only printable ascii characters except 57 for the linefeed, carriage return and tab characters will 58 be discarded. 59 Non-printable octal - any non-printable ascii character except 60 for linefeed, carriage return and tab characters will be 61 displayed as a 3 digit octal value preceeded by a backslash. 62 Any backslash character as terminal data will appear as 63 a double backslash. 64 Any character - displays all characters with character image in the 65 character set of the machine 66 67 F3 - debugging mode only. Help menu. 68 Summary of what function keys do, how to handle background data 69 70 F4 - debugging mode only. Toggle local editting flag; 71 the flag is only used when in packet-mode. 72 When local editting is enabled, pressing ESC or @ will kill and erase 73 the current line of input; pressing BACKSPACE or # will erase the 74 previous character and the \ key will serve to escape the @, #, ESC 75 and \ keys. With local editting disabled, key values are entered 76 as straight data. 77 78 F5 - Toggle between foreground terminal data only or any foreground data; 79 debugging mode only; 80 By default, foreground terminal data only is enabled. 81 82 F6 - debugging mode, CTRL-]R - non-debugging mode; 83 Show query status; when background queries are received by the 84 emulator, they are displayed immediately but the senders' capability 85 are saved in a queue until the user responds to these queries 86 (by preceeding the input with the ^ character). Thus, any data 87 entered as a response to background queries will be sent to 88 the earliest background query in the queue. Once, a background 89 message has been responded to, the capability is removed from the 90 queue. The F6 key will display the system id and the major 91 capability of the sender of all unanswered background queries. 92 93 F7 - debugging mode only; 94 Set tab size; used to change or examine the tab size. This tab 95 value determines both the amount of padding to use for displaying 96 and for the tab key (i.e. it is used in both packet and non-packet 97 mode). 98 99 F8 - debugging mode, CTRL-]C - non-debugging mode; 100 Execute DOS command; pass a command to the command interpreter on 101 the PC and resume normal terminal emulation upon completion. 102 Note that the F1 key will not work since the command interpreter 103 has control; however, ^S and ^Q will serve to suspend and resume 104 while control is not passed back to the emulator. 105 106 F9 - debugging mode; CTRL-]B - non-debugging mode; 107 Send foreground break; a foreground break is sent through the 108 foreground channel. This works only when MOWSE is attached on 109 the other side. 110 111 F10 - debugging mode; CTRL-]Q - non-debugging mode; 112 Exit the terminal emulator. 113 114 CTRL-]R - non-debugging mode only 115 Send a query reply 116 117 CTRL-]0 - non-debugging mode only 118 Send a null over the foreground channel 119 120 CTRL-]CTRL-] - non-debugging mode only 121 Send a CTRL-] over the foreground channel 122 123 Local editing is always on for non-debugging version; the # functions 124 the same as backspace and the @ functions the same as the ESC key 125 which wipes out the line. These may be escaped by the \ key. 126 127 */ 128 129 #include <ws.h> 130 #include <ws_dcls.h> 131 #include <wsmincap.h> 132 #include <keydefs.h> 133 #include <emulator.h> 134 135 #if EM_DEBUG /* Do NOT compile if !EM_DEBUG */ 136 137 char NULLBYTE; 138 char *print_mode_type[] = { /* Message strings */ 139 "PRINTABLE ASCII ONLY", 140 "OCTAL NON-PRINTABLE ASCII", 141 "ANY ASCII" 142 }; 143 144 char *on_off_status[] = { /* Status message strings */ 145 "OFF", 146 "ON" 147 }; 148 149 struct get_struc gettdatas; 150 char buff[KB_BUFFERSIZE]; 151 char kb_stack[KB_STACKSIZE]; 152 int bg_sender_buff[BG_SENDBUFF_SIZE]; 153 int bg_sender_in = 0; 154 int bg_sender_out = 0; 155 extern int packetize_flag; 156 int em_print_mode; 157 int em_tab_size; 158 int local_edit; 159 int fg_data_only; 160 161 em() 162 { 163 164 /* MISC */ 165 int str_len; 166 int i; 167 int sender_major; 168 int message_type; 169 int bg_query_flag; 170 int j; 171 int err_code; 172 int option; 173 int do_te_loop = TRUE; 174 int delay_i; 175 int ch; 176 int sys; 177 int major; 178 179 /* INITIALIZATION */ 180 str_len = 0; 181 bg_query_flag = 0; 182 183 /* : set default modes */ 184 185 local_edit = TRUE; 186 em_print_mode = ANY_CHAR; 187 fg_data_only = TRUE; 188 em_tab_size = KB_TABSIZE; 189 190 /* : initialize the structure for getting terminal data */ 191 192 gettdatas.local_buffer_pointer = &buff[0]; 193 gettdatas.local_buffer_size = sizeof(buff); 194 195 /* : print out terminal emulator banner and instructions */ 196 197 printf("===== MOWSE Terminal Emulator\n"); 198 printf("===== Hit F3 to display emulator functions.\n"); 199 200 /* : While (not asked to quit by user) */ 201 202 while (do_te_loop) { 203 204 /* : - check terminal buffer for data character from the remote machine 205 and display it if it exists */ 206 207 str_len = gettdata(&gettdatas); 208 if (gettdatas.minor_capability == FG_TERMINAL_DATA || !fg_data_only) 209 em_print_buff(buff,str_len); 210 211 /* : - loop for a while here to allow clock interrupt time to happen */ 212 213 for (delay_i = 0; delay_i < DELAY_INTERVAL; delay_i++); 214 215 /* : - check for background messages 216 - if there is background data then */ 217 218 while (gettdatas.background_pending_flag > 0) { 219 err_code = getbgmes(buff, &message_type, &sender_major); 220 221 /* : -- display the data preceeded by a carat (^) */ 222 223 if (message_type == WSINFO || message_type == WSQUERY) { 224 c_unpack(&sys, &major, sender_major); 225 printf("^[%2d:%2d]%s\n",sys,major,buff); 226 } 227 228 /* : -- if it was a query message, save sender's major in the FIFO 229 --- check for queue overflow */ 230 231 if (message_type == WSQUERY) { 232 if (bg_sender_out == ((bg_sender_in+1) % BG_SENDBUFF_SIZE)) 233 printf ("$$ query buffer overflow $$\n"); 234 else { 235 bg_sender_buff[bg_sender_in] = sender_major; 236 bg_sender_in = (bg_sender_in + 1) % BG_SENDBUFF_SIZE; 237 } 238 } 239 240 /* : -- decrement count of background messages left */ 241 242 gettdatas.background_pending_flag--; 243 } 244 245 246 /* : - check for input from the user 247 - if in packet-mode */ 248 249 if (packetize_flag) { 250 251 /* : -- check for a line of input from user */ 252 253 str_len = db_get_kb_line(buff, kb_stack, &option); 254 if (str_len > 0) { 255 256 /* : --- if input is not preceeded by ^, destined for foreground */ 257 258 if (buff[0] != '^') 259 puttdata(FG_TERMINAL_DATA,buff,str_len); 260 261 /* : --- if user wants to send input with ^ as the first character over 262 foreground, he enters ^^ and the first one is stripped, rest is 263 sent to foreground */ 264 265 else if (str_len > 1 && buff[0] == '^' && buff[1] == '^') 266 puttdata(FG_TERMINAL_DATA,buff+1,str_len-1); 267 268 /* : --- data is destined for background, get the sender major off stack and 269 send back the response */ 270 271 else if (bg_sender_in != bg_sender_out) { 272 buff[str_len] = '\0'; 273 sendqrep (buff+1,bg_sender_buff[bg_sender_out]); 274 c_unpack(&sys,&major,bg_sender_buff[bg_sender_out]); 275 printf ("$$ Reply sent to [%d:%d]\n", sys, major); 276 bg_sender_out = (bg_sender_out + 1) % BG_SENDBUFF_SIZE; 277 } 278 else 279 printf ("$$ No queries pending $$\n"); 280 } 281 282 /* : -- check if special function key was pressed */ 283 284 else if (option >= 0) 285 db_process_options(option,&do_te_loop); 286 } 287 288 /* : -- else in non-packet mode 289 --- check if a key was pressed 290 ---- check and handle any special function key 291 ---- otherwise send character over foreground channel */ 292 293 else { 294 if (get_kb_key(&ch)) { 295 if (ch > 255) 296 db_process_options(ch,&do_te_loop); 297 else 298 puttdata(FG_TERMINAL_DATA,&ch,1); 299 } 300 } 301 } 302 303 /* : print message to indicate exit from terminal emulator */ 304 305 printf("\n==== MOWSE Terminal Emulator returning to DOS ====\n"); 306 } 307 308 #else 309 em () 310 {} 311 #endif 312 ^Z