|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* Keyserv.c A process that translates keypresses to
|
|
Packit |
15a96c |
* ANSI or VT102 escape sequences.
|
|
Packit |
15a96c |
* Communications with this process from minicom
|
|
Packit |
15a96c |
* goes through pipes, file descriptors 3 & 4.
|
|
Packit |
15a96c |
*
|
|
Packit |
15a96c |
* This file is part of the minicom communications package,
|
|
Packit |
15a96c |
* Copyright 1991-1995 Miquel van Smoorenburg.
|
|
Packit |
15a96c |
*
|
|
Packit |
15a96c |
* This program is free software; you can redistribute it and/or
|
|
Packit |
15a96c |
* modify it under the terms of the GNU General Public License
|
|
Packit |
15a96c |
* as published by the Free Software Foundation; either version
|
|
Packit |
15a96c |
* 2 of the License, or (at your option) any later version.
|
|
Packit |
15a96c |
* You should have received a copy of the GNU General Public License along
|
|
Packit |
15a96c |
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
Packit |
15a96c |
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
#ifdef HAVE_CONFIG_H
|
|
Packit |
15a96c |
#include <config.h>
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
#include <unistd.h>
|
|
Packit |
15a96c |
#include <stdlib.h>
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
#include "port.h"
|
|
Packit |
15a96c |
#include "minicom.h"
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Emulation modes */
|
|
Packit |
15a96c |
#define EVT100 1
|
|
Packit |
15a96c |
#define EANSI 2
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Pipe file descriptors */
|
|
Packit |
15a96c |
#define from_minicom 3
|
|
Packit |
15a96c |
#define to_minicom 4
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Set modes to normal */
|
|
Packit |
15a96c |
int keypadmode = NORMAL;
|
|
Packit |
15a96c |
int cursormode = NORMAL;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
int mode = EVT100; /* Emulation mode selector */
|
|
Packit |
15a96c |
int parent; /* Process ID of minicom */
|
|
Packit |
15a96c |
jmp_buf mainloop; /* To jump to after a 'HELLO' signal */
|
|
Packit |
15a96c |
char **escseq; /* Translation table to use */
|
|
Packit |
15a96c |
static int argument; /* Argument to 'HELLO' command */
|
|
Packit |
15a96c |
static int esc_char = 1; /* Escape character (initially ^A) */
|
|
Packit |
15a96c |
static int bs_code = 8; /* Code that backspace key sends */
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
char *st_vtesc[] = {
|
|
Packit |
15a96c |
"", "\033OP", "\033OQ", "\033OR", "\033OS", "", "", "", "", "", "",
|
|
Packit |
15a96c |
"\033[H", "", "\033[A", "\033[D", "\033[C", "\033[B", "\033[K", "",
|
|
Packit |
15a96c |
"", "\177" };
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
char *app_vtesc[] = {
|
|
Packit |
15a96c |
"", "\033OP", "\033OQ", "\033OR", "\033OS", "", "", "", "", "", "",
|
|
Packit |
15a96c |
"\033[H", "", "\033OA", "\033OD", "\033OC", "\033OB", "\033[K", "",
|
|
Packit |
15a96c |
"", "\177" };
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
char *ansiesc[] = {
|
|
Packit |
15a96c |
"", "\033OP", "\033OQ", "\033OR", "\033OS", "\033OT", "\033OU", "\033OV",
|
|
Packit |
15a96c |
"\033OW", "\033OX", "\033OY", "\033[H", "\033[V", "\033[A", "\033[D",
|
|
Packit |
15a96c |
"\033[C", "\033[B", "\033[Y", "\033[U", "0", "\177" };
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* We got a signal. This means that there is some information for us.
|
|
Packit |
15a96c |
* Read it, and jump to the main loop.
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
void handler(int dummy)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
unsigned char buf[8];
|
|
Packit |
15a96c |
int n;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
(void)dummy;
|
|
Packit |
15a96c |
signal(HELLO, handler);
|
|
Packit |
15a96c |
n = read(from_minicom, buf, 8);
|
|
Packit |
15a96c |
if (n <= 0) {
|
|
Packit |
15a96c |
n = 2;
|
|
Packit |
15a96c |
buf[0] = 0;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
if (n % 2 == 1) {
|
|
Packit |
15a96c |
n++;
|
|
Packit |
15a96c |
read(from_minicom, buf + n, 1);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
argument = buf[n-1];
|
|
Packit |
15a96c |
longjmp(mainloop, (int)buf[n - 2]);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* Send a string to the modem
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
void sendstr(char *s)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
write(1, s, strlen(s));
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* Main program of keyserv.
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
int main(int argc, char **argv)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
int c;
|
|
Packit |
15a96c |
char ch;
|
|
Packit |
15a96c |
int f, fun;
|
|
Packit |
15a96c |
int stopped = 0;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
if (argc < 2 || (parent = atoi(argv[1])) == 0) {
|
|
Packit |
15a96c |
printf("Usage: %s <parent>\n", *argv);
|
|
Packit |
15a96c |
exit(1);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Initialize signal handlers */
|
|
Packit |
15a96c |
/* signal(SIGHUP, SIG_IGN); */
|
|
Packit |
15a96c |
signal(SIGQUIT, SIG_IGN);
|
|
Packit |
15a96c |
signal(SIGINT, SIG_IGN);
|
|
Packit |
15a96c |
#ifdef SIGTSTP
|
|
Packit |
15a96c |
signal(SIGTSTP, SIG_IGN);
|
|
Packit |
15a96c |
signal(SIGTTIN, SIG_IGN);
|
|
Packit |
15a96c |
signal(SIGTTOU, SIG_IGN);
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
signal(HELLO, handler);
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Set up escape sequence table */
|
|
Packit |
15a96c |
escseq = st_vtesc;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Cbreak, no echo (minicom itself sets to raw if needed) */
|
|
Packit |
15a96c |
setcbreak(1);
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
if ((fun = setjmp(mainloop)) != 0) {
|
|
Packit |
15a96c |
switch (fun) {
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* We come here after minicom has told us something */
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
case KVT100: /* VT100 keyboard */
|
|
Packit |
15a96c |
mode = EVT100;
|
|
Packit |
15a96c |
escseq = st_vtesc;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case KANSI: /* ANSI keyboard */
|
|
Packit |
15a96c |
mode = EANSI;
|
|
Packit |
15a96c |
escseq = ansiesc;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case KKPST: /* Keypad in standard mode, not used */
|
|
Packit |
15a96c |
keypadmode = NORMAL;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case KKPAPP: /* Keypad in applications mode, not used */
|
|
Packit |
15a96c |
keypadmode = APPL;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case KCURST: /* Standard cursor keys */
|
|
Packit |
15a96c |
cursormode = NORMAL;
|
|
Packit |
15a96c |
if (mode == EVT100)
|
|
Packit |
15a96c |
escseq = st_vtesc;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case KCURAPP: /* cursor keys in applications mode */
|
|
Packit |
15a96c |
cursormode = APPL;
|
|
Packit |
15a96c |
if (mode == EVT100)
|
|
Packit |
15a96c |
escseq = app_vtesc;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case KSTOP: /* Sleep until further notice */
|
|
Packit |
15a96c |
stopped = 1;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case KSIGIO: /* Wait for keypress and tell parent */
|
|
Packit |
15a96c |
kill(parent, ACK);
|
|
Packit |
15a96c |
f = read(0, &ch, 1);
|
|
Packit |
15a96c |
if (f == 1) {
|
|
Packit |
15a96c |
write(to_minicom, &ch, 1);
|
|
Packit |
15a96c |
kill(parent, HELLO);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case KSTART: /* Restart when stopped */
|
|
Packit |
15a96c |
stopped = 0;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case KSETBS: /* Set code that BS key sends */
|
|
Packit |
15a96c |
bs_code = argument;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case KSETESC: /* Set escape character */
|
|
Packit |
15a96c |
esc_char = argument;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
default:
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
if (fun != KSIGIO)
|
|
Packit |
15a96c |
kill(parent, ACK);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
/* Wait if stopped */
|
|
Packit |
15a96c |
if (stopped)
|
|
Packit |
15a96c |
pause();
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Main loop: read keyboard, send to modem */
|
|
Packit |
15a96c |
while (1) {
|
|
Packit |
15a96c |
c = wxgetch();
|
|
Packit |
15a96c |
if (c > 256 && c < 256 + NUM_KEYS) {
|
|
Packit |
15a96c |
sendstr(escseq[c - 256]);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
if (c < 256) {
|
|
Packit |
15a96c |
if (c == K_ERA)
|
|
Packit |
15a96c |
c = bs_code;
|
|
Packit |
15a96c |
ch = c;
|
|
Packit |
15a96c |
/* Test for escape characters */
|
|
Packit |
15a96c |
if (c == esc_char || (esc_char == 128 && c > 128)) {
|
|
Packit |
15a96c |
/* If we typed too fast, and the escape sequence
|
|
Packit |
15a96c |
* was not that of a function key, the next key
|
|
Packit |
15a96c |
* is already in the buffer.
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
if (c == esc_char && pendingkeys > 0) {
|
|
Packit |
15a96c |
ch = wxgetch();
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
write(to_minicom, &ch, 1);
|
|
Packit |
15a96c |
kill(parent, HELLO);
|
|
Packit |
15a96c |
} else {
|
|
Packit |
15a96c |
write(1, &ch, 1);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
return 0;
|
|
Packit |
15a96c |
}
|