1 /* *********************************************************** 2 * * 3 * Copyright, (C) Honeywell Bull Inc., 1988 * 4 * * 5 * Copyright, (C) Honeywell Information Systems Inc., 1987 * 6 * * 7 *********************************************************** */ 8 9 10 /* HISTORY COMMENTS: 11 1) change(87-03-08,Wallman), approve(87-03-08,MCR7586), 12 audit(87-07-16,Flegel), install(87-08-07,MR12.1-1072): 13 First release. 14 2) change(88-02-24,Lee), approve(88-05-16,MCR7897), audit(88-09-19,Flegel), 15 install(88-10-12,MR12.2-1160): 16 Removed debugging code and unused variables, formatting. 17 3) change(88-04-11,Lee), approve(88-05-16,MCR7897), audit(88-09-19,Flegel), 18 install(88-10-12,MR12.2-1160): 19 Added calls to handled BREAK key; mapped DEL key to ASCII DEL, 20 mapped ^@ (or ^2) to ASCII NUL. 21 4) change(88-04-26,Lee), approve(88-05-16,MCR7897), audit(88-09-19,Flegel), 22 install(88-10-12,MR12.2-1160): 23 Created routine check_wst_status() to update the status when 24 WSTERM changes its mode (glass tty, sync or async). 25 5) change(88-04-27,Lee), approve(88-05-16,MCR7897), audit(88-09-19,Flegel), 26 install(88-10-12,MR12.2-1160): 27 Added calls to scroll_1_to_24() to prevent the status line from 28 being overwritten when using FANSI-CONSOLE. 29 6) change(88-05-12,Lee), approve(88-05-16,MCR7897), audit(88-09-19,Flegel), 30 install(88-10-12,MR12.2-1160): 31 Added command line handling for /B option. 32 7) change(88-05-31,Lee), approve(88-05-16,MCR7897), audit(88-09-19,Flegel), 33 install(88-10-12,MR12.2-1160): 34 Added command line handling for /A, /P; support for file and 35 printer auditing. 36 8) change(88-07-20,Lee), approve(88-05-16,MCR7897), audit(88-09-19,Flegel), 37 install(88-10-12,MR12.2-1160): 38 Default after atm changed edit mode. 39 9) change(88-07-25,Lee), approve(88-05-16,MCR7897), audit(88-09-19,Flegel), 40 install(88-10-12,MR12.2-1160): 41 Documentation additions only. Added header comments to all routines. 42 10) change(88-08-09,Lee), approve(88-05-16,MCR7897), audit(88-09-19,Flegel), 43 install(88-10-12,MR12.2-1160): 44 Fix references to include files; "wstdefs.h" was split into 45 "wstdefs.h" and "wsttype.h" to avoid declaration clash; also, 46 various constants defined to descriptive names. 47 11) change(88-08-30,Lee), approve(88-09-12,MCR7986), audit(88-09-19,Flegel), 48 install(88-10-12,MR12.2-1160): 49 Removed non-edit async mode and references to non-edit async mode 50 line editing routines. 51 12) change(89-02-22,Lee), approve(89-01-02,MCR8043), audit(89-03-14,Flegel), 52 install(89-04-24,MR12.3-1033): 53 Separated input and output parameters to int86() to avoid confusion 54 when parameters are used; enabled kb.echo flag when mowse is not active 55 and in edit-mode. 56 END HISTORY COMMENTS */ 57 58 /* WSTERM -- WorkStation TERminal Manager for Multics MOWSE */ 59 60 61 #include <stdio.h> 62 #include <dos.h> 63 #include <ws.h> 64 #include <ws_error.h> 65 #include <wsmincap.h> 66 #include <cat.h> 67 #include "wstdefs.h" 68 #include "wstglob.h" 69 70 /****************************************************************************/ 71 72 /* Program entrypoint */ 73 74 /*^L 75 ********************************************************************** 76 77 Routine: MAIN 78 79 Function: 80 This is the command module for WSTERM. It analyzes command line 81 arguments, setting appropriate flags and initializes the execution 82 environment. It then enters a listener loops that continually 83 checks and handles foreground messages, background messages, and 84 keyboard input. It stays in the listener loop until the user enters 85 a local escape sequence that signals that the program should 86 terminate. While inside the listener loop, various modes and 87 facilities may be called. 88 89 Parameters: 90 (input) argc - indicates the number of command line 91 arguments; standard argc argument passed to 92 main() 93 (input) argv - pointer to the character pointer array 94 containing the actual command line 95 arguments; standard argv argument passed to 96 main() 97 98 Returns: NONE 99 100 **********************************************************************/ 101 102 main (argc,argv) 103 int argc; 104 char *argv[]; 105 { 106 /* handle command line arguments */ 107 if (parse_args(argc,argv) < 0) 108 exit(0); 109 110 /* if /B option specified to send break to host */ 111 if (break_sends_to_host) 112 set_break(); /* set up our ^BREAK handler */ 113 else 114 enable_ctl_c_check(); /* turn ^C/BREAK checking ON */ 115 116 /* initialize screen structures for screen swapping */ 117 wst_init_modes(); 118 119 init_kb_screen(SCREEN_LINES,SCREEN_COLS); 120 init_line(&edlin); 121 122 /* initialize wsterm structures and variables */ 123 if (wstinit () < 0) { 124 /* MOWSE not invoked error, clean up and exit */ 125 126 /* restore scrolling region to full screen */ 127 reset_scroll(); 128 129 if (break_sends_to_host) 130 reset_break(); /* restore original ^BREAK handler */ 131 else 132 restore_ctl_c_check(); /* restore original ^C/BREAK checking */ 133 exit(0); 134 } 135 136 137 /* initialize wsterm's line mode flag to update on next check */ 138 wst_status = WST_UNKNOWN_MODE; 139 140 /* Listener loop -- control stays in this loop until the user 141 enters ALT-Q to quit the invocation. */ 142 143 while (local_action != QUIT) { 144 145 /* check WSTERM's status and update status line if necessary */ 146 check_wst_status(); 147 148 local_action = NUL; /* Erase possible leftovers */ 149 150 /* If there is no pending foreground message, see if 151 one is waiting in MOWSE */ 152 153 if (fg_msg_len == 0) { 154 fg_msg_len = gettdata (&tdata_arg); 155 156 /* If MOWSE doesnt have a message either, check MOWSE's status */ 157 if (fg_msg_len == 0) 158 check_MOWSE_status (); 159 } 160 161 /* Is there a foreground message? */ 162 if (fg_msg_len > 0) { 163 164 /* If FB_BREAK has been sent and this is the return FG_BREAK */ 165 if (break_sent && tdata_arg.minor_capability == FG_BREAK) { 166 167 break_sent = OFF; 168 fg_msg_len = 0; /* Discard the FG_BREAK message */ 169 170 if (read_active) { /* Terminate any active read */ 171 term_read = ON; 172 send_msg (nul_str, 0); 173 } 174 } 175 else if (~sync) /* An async message */ 176 async_msg (~FORCE); 177 else 178 sync_msg (); /* A sync message */ 179 } 180 181 /* If mowse is active ... */ 182 if (mowse_active) { 183 184 /* Is there a background message that hasn't been 185 shown in line 25? */ 186 187 if (tdata_arg.background_pending_flag && ~bk_msg_showing) 188 show_bkmsg (); 189 190 /* If we're in sync mode with characters in the 191 keyboard buffer and there is an active read command, 192 check for echo delay timer runout */ 193 194 if (sync && read_active) { 195 if (kb.cndx > 0 && check_echo_delay ()) { 196 if ((kb.echo && kb.cndx > kb.endx) || 197 ~kb.echo) 198 extract_msg (~NO_BLOCK, 199 TRO, ~kb.echo, ~HIDE); 200 } 201 } 202 } 203 204 /* Anything from the keyboard? */ 205 206 if (!wst_edit_mode || sync) { 207 if (read_keyboard (~BLOCK)) 208 process_kbrd_char (~HIDE); 209 } 210 else 211 process_edit_line(&edlin); 212 } /* End of listener loop */ 213 214 /* Bid adieu to MOWSE and return to DOS */ 215 216 destinst (&wst_mcb); 217 218 /* restore scrolling region to full screen */ 219 reset_scroll(); 220 221 /* move cursor to bottom of screen and display a new line */ 222 /* so that the DOS prompt will appear at the bottom of the screen */ 223 leave_screen(); 224 225 set_printer_timeout(wst_prt_timeout); 226 227 /* if /B specified to send break to host */ 228 if (break_sends_to_host) 229 reset_break(); /* restore original ^BREAK handler */ 230 231 else 232 restore_ctl_c_check(); /* restore original ^C/BREAK checking */ 233 234 if (wst_f_audit) 235 end_file_audit(); 236 237 if (wst_p_audit) 238 end_printer_audit(); 239 240 exit (); 241 242 } /* End of main */ 243 244 245 /**** LOCAL FUNCTIONS *********************************************************/ 246 247 248 /*^L 249 ********************************************************************** 250 251 Routine: CHECK_ECHO_DELAY 252 253 Function: 254 This function checks for echo delay timer runout. The echo 255 delay timer (currently set at 1 second) controls the echoing of 256 typeahead so that the user doesn't get too far ahead of the screen 257 display. 258 259 Parameters: NONE 260 261 Returns: ON if timer runout occurred 262 OFF is no timer runout occurred 263 264 **********************************************************************/ 265 266 check_echo_delay () 267 { 268 int newtime; /* Current clock */ 269 union regs_struct regs, outregs; 270 271 /* Record current DOS system time in 'newtime' */ 272 273 regs.hreg.ah = SYSTEM_TIME; 274 intdos (®s, &outregs); 275 newtime = regs.hreg.dh & LO_BYTE_MASK; /* Use only seconds value */ 276 277 if (oldtime == -1) /* Also set oldtime for first call */ 278 oldtime = newtime; 279 if (newtime < oldtime) /* Adjust for clock rollover */ 280 oldtime -= 60; 281 282 /* Check for timer runout */ 283 284 if (newtime - oldtime >= echo_delay) { 285 286 oldtime = newtime; /* Timer runout - record newtime */ 287 return (ON); /* Return true */ 288 } 289 290 else 291 return (OFF); /* No timer runout - return false */ 292 } /* End of check_echo_delay */ 293 294 295 296 /*^L 297 ********************************************************************** 298 299 Routine: CHECK_MOWSE_STATUS 300 301 Function: 302 This routine checks MOWSE's status flag with WSTERM's static 303 switch to determine if there has been a change in MOWSE's status 304 (either attached or detached). If MOWSE's status has changed to 305 attached, a WSTERM capability is created; if MOWSE's status has 306 changed to detached, the WSTERM capability is destroyed; otherwise 307 there is no change in status and nothing happens. 308 309 Parameters: NONE 310 311 Returns: NONE 312 313 **********************************************************************/ 314 315 check_MOWSE_status () 316 { 317 318 /* If WSTERM's static switch says MOWSE is active but Multics MOWSE is 319 detached, free WSTERM's MCB and set various static switches */ 320 321 if (mowse_active && tdata_arg.minor_capability == DETACHED) { 322 323 destinst(&wst_mcb); 324 325 mowse_active = OFF; 326 327 /* in glass tty mode, use edit mode only if the default */ 328 /* for glass tty mode is edit mode */ 329 wst_edit_mode = glass_edit_mode; 330 331 /* RL: phx21233 - always echo in edit mode when MOWSE is not */ 332 /* attached since no mowse_io_ to control printer on/off */ 333 if (wst_edit_mode) 334 kb.echo = ON; 335 336 /* RL: phx21233 - OFF in non-edit mode to prevent double echoing */ 337 else 338 kb.echo = OFF; 339 340 /* Send any typeahead */ 341 342 if (kb.cndx > 0) { 343 344 puttdata (FG_TERMINAL_DATA, kb.klin, strlen (kb.klin)); 345 346 kb.cndx = 0; /* Wipe keyboard buffer */ 347 kb.endx = 0; 348 kb.klin [0] = NUL; 349 350 ds.ccol = 0; /* Wipe keyboard display */ 351 ds.lct = 0; 352 ds.lndx = 0; 353 ds.dlin [0] = NUL; 354 ds.pstrl = 0; 355 ds.pstr [0] = NUL; 356 screen.EOP_ct = 0; 357 ds.splct [0] = NUL; 358 } 359 } 360 361 /* If WSTERM's static switch says MOWSE is not active but 362 Multics MOWSE is attached, tell MOWSE to put WSTERM into 363 the CAT and set static switches */ 364 365 else if (~mowse_active && tdata_arg.minor_capability == ATTACHED) { 366 367 cretinst ("WSTERM", /* capability name */ 368 NULL, /* NULL entry function */ 369 0, /* zero inbuff length */ 370 0, /* zero outbuff length */ 371 NULL, /* NULL data ptr */ 372 &wst_mcb); /* MCB ptr */ 373 374 mowse_active = ON; 375 kb.echo = ON; 376 377 /* mowse now active, determine mode for editing; */ 378 /* use edit mode only if default for async is edit mode */ 379 wst_edit_mode = TRUE; 380 crecho = OFF; 381 lfecho = OFF; 382 383 } 384 } /* End of check_MOWSE_status */ 385 386 387 388 /*^L 389 ********************************************************************** 390 391 Routine: CHECK_WST_STATUS 392 393 Function: 394 This routine checks WSTERM's MOWSE status flag against the 395 global flag 'wst_status' (which indicates the status that is 396 displayed on the status line). If a change is detected, the 397 wst_status flag is updated and the new status is displayed in the 398 status line. 399 400 Parameters: NONE 401 402 Returns: NONE 403 404 **********************************************************************/ 405 406 check_wst_status() 407 { 408 int status; 409 410 status = WST_UNKNOWN_MODE; 411 412 /* determine the current mode */ 413 if (~mowse_active) status = WST_GLASS_TTY_MODE; 414 else if (sync) status = WST_SYNC_MODE; 415 else status = WST_ASYNC_MODE; 416 417 /* if status is the same since last checked, do nothing */ 418 if (wst_status == status) return; 419 420 /* update the status flag for the next check */ 421 wst_status = status; 422 423 /* update the new status on the status line */ 424 update_status(); 425 } 426 427 428 429 /*^L 430 ********************************************************************** 431 432 Routine: PARSE_ARGS 433 434 Function: 435 This routine parses WSTERM's command line arguments, setting 436 appropriate flags and variables if the command line arguments are 437 recognized. Default values are assigned to flags and variables not 438 affected by the command line arguments. The following table 439 indicates the flag/variables affected by their corresponding 440 control argument specifier: 441 442 global flag default value control argument new value 443 ----------- ------------- ---------------- --------- 444 break_sent_to_host OFF /B ON 445 audit_file_name "wsterm.log" /A <user file name> 446 wst_printer_card 0 /P 0-2 447 448 Parameters: 449 (input) argc - the argc value passed to main() 450 (input) argv - the argv value passed to main 451 452 Returns: -1 if a parsing error occurred 453 0 if no error occurred 454 455 Note 1 - If a parsing error is encountered, an error message is 456 displayed by this module. 457 **********************************************************************/ 458 459 parse_args(argc,argv) 460 int argc; 461 char *argv[]; 462 { 463 int i; 464 char tmp[133]; /* trash variable for trapping invalid input */ 465 466 /* initialize with default values */ 467 break_sends_to_host = OFF; 468 audit_file_name = DEFAULT_AUDIT_FILE; 469 wst_printer_card = DEFAULT_PRINTER_CARD; 470 471 /* loop through each argument from left to right on command line */ 472 for (i = 1; i < argc; i++) { 473 474 /* check for /B */ 475 if (!strcmp(argv[i],"/B") || !strcmp(argv[i],"/b")) 476 break_sends_to_host = ON; 477 478 /* check for /A */ 479 else if (!strcmp(argv[i],"/A") || !strcmp(argv[i],"/a")) { 480 481 i++; 482 if (argc <= i || argv[i][0] == '/') { 483 printf("Missing audit file name specifier for /A argument\n"); 484 return(-1); 485 } 486 audit_file_name = argv[i]; 487 488 } 489 490 /* check for /P */ 491 else if (!strcmp(argv[i],"/P") || !strcmp(argv[i],"/p")) { 492 493 i++; 494 if (argc <= i || argv[i][0] == '/') { 495 printf("Missing printer card number (0-2) for /P argument\n"); 496 return(-1); 497 } 498 if (sscanf(argv[i],"%d%s",&wst_printer_card,tmp) != 1 || 499 wst_printer_card < MIN_PRINTER_CARD_VAL || 500 wst_printer_card > MAX_PRINTER_CARD_VAL) { 501 printf("Invalid printer card value; must be 0, 1 or 2.\n"); 502 wst_printer_card = DEFAULT_PRINTER_CARD; 503 return(-1); 504 } 505 } 506 507 /* not a recognized command line argument */ 508 else { 509 printf("Invalid WSTERM argument: %s\n", argv[i]); 510 return(-1); 511 } 512 } 513 return(0); 514 } 515 516 517 518 /*^L 519 ********************************************************************** 520 521 Routine: LEAVE_SCREEN 522 523 Function: 524 This routine is called before exiting WSTERM to leave most of 525 WSTERM's screen on the display upon exiting. This is done by 526 scrolling the screen up one line and positioning the cursor at the 527 bottom left hand corner of the screen. 528 529 Parameters: NONE 530 531 Returns: NONE 532 533 **********************************************************************/ 534 535 leave_screen() 536 { 537 union REGS reg, outreg; 538 539 /* scroll screen up a line */ 540 reg.h.ah = VIDEO_SCROLL_UP_FUNC; 541 reg.h.al = DEFAULT_LINES_TO_SCROLL; 542 reg.h.ch = CURSOR_HOME_ROW; 543 reg.h.cl = CURSOR_HOME_COL; 544 reg.h.dh = SCREEN_LINES; 545 reg.h.dl = SCREEN_COLS-1; 546 reg.h.bh = wst_fg_screen.attr; 547 int86(BIOS_VIDEO,®,&outreg); 548 549 /* move cursor to bottom line of screen, column 0 */ 550 cursor_move(SCREEN_LINES,0); 551 } 552 553 554 /* End of WSTERM */