/*----------------------------------------------------------------*/ /* skeys.c Keven Miller 03/07/2012 kevenm@3kranger.com */ /* save function keys to a file; used with rkeys to restore them */ /* Unix: cc -o skeys skeys.c */ /* MPE: setvar ccopts "-Aa +e +w1" */ /* ccxllk skeys,skeys.pub */ /*----------------------------------------------------------------*/ #ifdef __mpexl #pragma list off #endif #include #include #ifdef __mpexl #pragma intrinsic FOPEN #pragma intrinsic FCONTROL #pragma intrinsic FCLOSE #pragma intrinsic FREAD #else #include #include #endif #define proc /*----------------------------------------------------------------*/ proc int skeys ( char *fname ) { int fn, len; short serr, noecho; char keys [2048], *cp; FILE *f; #ifndef __mpexl int x, cnt; struct termios tbuf, sbuf; #endif /* Enable Block Mode and Display User Keys */ printf ( "\x1B" "Z" /* Display Mode OFF */ /* "\x1B" "&s1G" Inhibit Hand Shake ON */ "\x1B" "&s1H" /* Inhibit DC2 */ "\x1B" "&k1B" /* Block Mode ON */ "\x1B" "&s1D" /* Page Mode ON */ "\x1B" "j" /* Begin User Key Definition */ "\x1B" "H" /* Home Up */ "\x1B" "d" /* Xmit screen */ ); fflush (stdout); /* Set TTY to Block Mode */ #ifdef __mpexl fn = mpe_fileno ( fileno (stdin)); FCONTROL ( fn, 13, &noecho ); /* Echo OFF */ FCONTROL ( fn, 29, &serr ); /* User Block Mode ON */ serr = 036; FCONTROL ( fn, 41, &serr ); /* Unedit mode RS */ serr = 3; FCONTROL ( fn, 4, &serr ); /* Timeout 3 secs */ printf ( "\x1B" "d" ); /* Xmit screen */ fflush (stdout); /* Read Screen */ len = FREAD ( fn, keys, -sizeof (keys) ); keys [len] = 0; /* Return TTY to Normal */ serr = 0; FCONTROL ( fn, 41, &serr ); /* Unedit Mode Normal */ FCONTROL ( fn, 28, 0 ); /* User Block Mode OFF */ if ( !noecho ) FCONTROL ( fn, 12, &serr ); /* Echo ON */ #else fn = fileno (stdin); tcgetattr ( fn, &tbuf ); sbuf = tbuf; tbuf.c_lflag &= ~(ECHO | ICANON); /* Echo OFF, raw mode */ tbuf.c_iflag &= ~(ICRNL | INLCR); /* CR = CR */ tcsetattr ( fn, TCSADRAIN, &tbuf ); printf ( "\x1B" "d" "\x11" ); /* Xmit screen, DC1 */ fflush (stdout); /* Read until RS 0x1E is received */ x = 0; for ( cnt = 0; cnt < 2; ++cnt) { len = read ( fn, &keys [x], sizeof (keys)); if ( len < 0 ) break; x += len; if ( x ) { if ( keys [x-1] == 0x1E ) break; /* Minisoft W92/Secure92 do not send RS 0x1E */ if ( keys [x-1] == '\r' ) break; } } if ( x ) keys [x-1] = 0; tcsetattr ( fn, TCSANOW, &sbuf ); #endif printf ( "\x1B" "k" /* End User Key Definition */ "\x1B" "&s0D" /* Page Mode OFF */ "\x1B" "&k0B" /* Block Mode OFF */ "\x1B" "&s0H" /* Inhibit DC2 OFF */ /* "\x1B" "&s0G" Inhibit Hand Shake OFF */ "\x1B" "&jB" /* Display User Keys */ ); fflush (stdout); /* Remove line terminators */ while (( cp = strstr ( keys, "\r\n\x1B" ))) strcpy ( cp, &cp [2] ); cp = strchr ( keys, 0 ); if ( strcmp ( &cp [-2], "\r\n" ) == 0 ) cp [-2] = 0; len = strlen (keys); /* Save keys */ f = fopen ( fname, "wb" ); if ( f ) { fwrite ( keys, 1, len, f ); fclose ( f ); } return ( f ? 1 : -1 ); } /*----------------------------------------------------------------*/ proc int main ( int ac, char *av [] ) { if ( skeys ( ac > 1 ? av [1] : "" ) < 0 ) perror ( av [1] ); } /*----------------------------------------------------------------*/