/***********************************************************************/ /* File KKEY.C - RML Kermit - Keyboard/Screen Routines Chris Kennington, RML. 6th June 1985 */ #define DEFS1 1 #define F4 0x9b #include "stdio.h" #include "ctype.h" #include "b:kext.h" /* Globals local to this file: */ static int dtr = 1; /* DTR toggle-switch */ static char *valid[] = {0, /* validity strings per mode */ /* one string for each kmode, contains all valid chars as l.c.; ESC maps to {, ? maps to DELT (\175 & \177) */ 0, /* KERMit mode */ "\177bcefhklpqrsz", /* CONN mode */ "\177abcfhklnqrt", /* SEND mode */ "\177abcfhklnqt", /* RECeive mode */ "\177abcfhklnqrt", /* CoMmaND mode */ "\177kq", /* PARaMeter mode */ "\177abcfhklnqrt", /* AUTO mode */ "\177cefhklpqrs", /* DISK mode */ 0,0}; /* end of table */ static char *texts[] = { /* help-texts or 0, one per char */ 0, "A - Abort transfer", "B - send 1-sec line-Break", "C - Clear screen", 0,"E+ E- switch Echo on/off", "F - Front panel", 0,"H - Help on ESC facility", 0,0,"K - return to Kermit command-mode", "L - Set Listing/Debugging level", 0,"N - set slow-Network option", 0, "P - set Parameters", "Q - Quit from Kermit", "R - switch to Receive mode", "S - switch to Send mode", "T - simulate Timeout (send NAK)", 0,0,0,0,0,"Z+ Z- toggle DTR on/off", 0,0,0,0,"? - print this help-text",0}; static char confm[] = {NL,"To confirm, hit CR or \"Y\". Enter new for each command."}; confirm() /* verify destructive action */ /* Prod user for "Y" as confirmation, return TRUE or FALSE */ { char c; txtout(" - Yes? "); while( (c = kbdin()) == 0 ) ; /* force next read */ c &= 0x5f; if ( (c == 'Y') || (c == CR) ) { txtout("OK "); return(TRUE); } else { outc(c); return(FALSE); } } /* end of confirm() */ keyget(ic) /* get char from keyboard */ /* Returns 1 if char, else 0; char in *ic; Handles low-level escape-sequences. */ char *ic; { char c, ch, i, *string; int *ip; if ( (ch = kbdin()) == 0 ) /* try to read */ return(0); /* no char (or null) */ /* there is a char to deal with */ *ic = ch; ch &= (char)0x7f; if ( (ch == CTLC) && (kmode != CONN) ) kermkill(0); /* kill if confirmed */ /* if not confirmed, fall through */ if (ch != ESC) return(1); /* normal return */ /* ESC (or F4) is break-in */ if ( (kmode == CONN) && (*ic == ESC) ) return(1); /* ESC in CONN */ string = valid[kmode]; /* validity string */ if (string == 0) /* F4s invalid */ return(0); Rept: txtout(eprompt); /* respond with prompt */ Ignore: while ( (ch = kbdin()) == 0) ; /* force next read */ for (i=0; (ch|(char)0x60) != (c = string[i]); ++i) { /* search string for match to char; ESC matches {, ? matches DEL */ if (c == 0) { /* end of string, invalid */ if (ch == F4) /* F4 */ goto Rept; goto End; } } /* fall through when test satisfied, i.e. matching char in string; char represents an action valid in this mode */ ch |= 0x20; /* force lower case */ switch(ch) { /* select action */ /* come out of case by break if CR/prompt wanted, by return(0) if not */ case SP: case '-': goto Ignore; case 0x23: /* CTLC - quit or abort */ kermkill(0); /* if not confirmed, fall through */ case 'a': /* abort transfer */ txtout("A ** Abort current transfer"); if (confirm() == TRUE) { printmsg("Aborting;%s%s",dots,trying); abtflag = 1; *ic = CR; /* supply phantom CR */ return(1); } break; case 'b': /* send break */ txtout("B - sending 1-sec \"break\" ... "); s4break(10); txtout("Sent"); break; case 'c': /* clear screen */ clrscrn(); break; case 'e': /* Echo switch */ txtout("E ** Echo now "); ip = &echo; goto Next; case 'f': /* Front panel */ txtout("F ** calling Front Panel - K to continue; "); fpanel(); break; case 'h': txtout("The F4 key provides a means of setting some parameters or"); txtout("\r taking actions, depending on what Kermit mode you are in."); txtout("\rInput is a single character or one followed by +, - or a digit;"); txtout("\r ? will tell you what chars are valid at any time. "); break; case 'k': /* Back to Kermit */ outc('K'); abtflag = 1; kmode = KERM; return(0); case 'l': /* list chars transferred */ txtout("L ** List/Debug now "); ip = &list; goto Next; case 'n': /* slow-network option */ txtout("N ** Slow-network option now "); ip = &netslow; goto Next; case 'p': /* set parameters */ i = kmode; kmode = PARM; setshow(); cursor(9); /* this is arbitrary */ kmode = i; break; case 'q': /* cancel program */ outc('Q'); kermkill(0); break; case 'r': /* switch to receive */ outc('R'); kmode = RECV; return(0); case 's': /* switch to send */ outc('S'); kmode = SEND; return(0); case 't': /* simulate timeout */ txtout("T ** simulate Timeout "); ++timouts; nakflag = 1; break; case 'z': /* toggle DTR */ txtout("Z - toggle DTR (enter + or -) "); ip = &dtr; goto Next; case '?': /* help */ txtout("? - Valid inputs after F4 in this mode are:-"); while ( (c = *string++) != 0 ) { outc(NL); txtout(" "); c &= 0x1f; /* range 0-31 */ txtout(texts[c]); } txtout(confm); break; default: bell(); } /* end switch */ goto End; /* end of main-line code */ Next: /* 3rd char of input, +, - or digit */ while ( (c = kbdin()) == 0 ) ; outc(c); Next2: switch (c) { case '+': case ';': ++(*ip); printf(" ON = %d ",(char)*ip); break; case '-': case '=': case '0': *ip = 0; txtout(" OFF "); break; case '1': case '2': case '3': if (ip != &parity) { c - '+'; goto Next2; } *ip = c - '0'; printf(" = %s. ", parsets[parity]); setpar(); break; case F4: goto Rept; default: bell(); txtout(" unchanged "); } /* end of switch */ if (ip == &dtr) { if (dtr == 0) comctrl &= 0x7f; /* drop DTR */ else comctrl |= 0x80; /* raise DTR */ s4set(commode,comctrl); } /* end of second-character processing */ End: outc(NL); return(0); /* no char for Kermit */ } /* end of keyget() */ keyline(str) /* get line of text from keyboard */ char *str; /* Read keyboard until a line has accumulated in str[], max length 80 char. Terminate on CR or LF, cancel (returning null string) on CTL-C, allow deletion by DELT or CTL-H, store & echo all other chars except controls after conversion to U.C. Return length of string. */ { char ptr, c; outc(DEOL); ptr = 0; while (TRUE) { while (keyget(&c) == 0) ; switch(c) { case CTLC: ptr = 0; case CR: case LF: str[ptr] = 0; txtout(". "); return(ptr); case DELT: case BKSP: if (ptr > 0) { --ptr; outc(BKSP); outc(SP); outc(BKSP); } else bell(); break; default: /* other chars */ if (c < SP) ; /* discard controls */ else if (ptr < 80) { outc(c); str[ptr++] = c; } else bell(); /* overfull */ } } /* end of while & switch */ /* we never reach here */ } /* End of keyline() */ upper(line) /* convert line to upper case */ char *line; { CHAR c; while ( (c = *line) != 0 ) { if (islower(c)) *line &= (CHAR)0x0df; ++line; } return; } /* end of upper() */ /************* END of file KERMKEY.C *****************/