From c5ea3bce61a7a53f980e4fab2508c9c23c0b5e3e Mon Sep 17 00:00:00 2001 From: Michiel Broek Date: Fri, 5 Nov 2004 15:16:48 +0000 Subject: [PATCH] Improved capture of remote terminal special keys --- mbsebbs/door.c | 6 +++++ mbsebbs/input.c | 58 +++++++++++++++++++++++++++++++++++----------- mbsebbs/mbsebbs.c | 21 +---------------- mbsebbs/openport.c | 26 ++++++++++----------- 4 files changed, 65 insertions(+), 46 deletions(-) diff --git a/mbsebbs/door.c b/mbsebbs/door.c index 09ec98fb..84fbda9a 100644 --- a/mbsebbs/door.c +++ b/mbsebbs/door.c @@ -304,6 +304,12 @@ void ExtDoor(char *Program, int NoDoorsys, int Y2Kdoorsys, int Comport, int NoSu else rc = execute_str((char *)"/bin/sh", (char *)"-c", Program, NULL, NULL, NULL); + /* + * First set cookedport again, this will load our original saved + * termios values. This way it doesn't matter what the door might + * have done with the original termios. + */ + cookedport(); rawport(); Altime(0); diff --git a/mbsebbs/input.c b/mbsebbs/input.c index fa41450e..a893b24e 100644 --- a/mbsebbs/input.c +++ b/mbsebbs/input.c @@ -77,16 +77,21 @@ int Escapechar(unsigned char *ch) * Escape character, if nothing follows within * 50 mSec, the user really pressed . */ - if ((rc = Waitchar(ch, 5)) == TIMEOUT) + if ((rc = Waitchar(ch, 5)) == TIMEOUT) { + Syslog('t', "Escapechar() real escape"); return rc; + } if (*ch == '[') { /* * Start of CSI sequence. If nothing follows, * return immediatly. */ - if ((rc = Waitchar(ch, 5)) == TIMEOUT) + Syslog('t', "Escapechar() CSI intro"); + if ((rc = Waitchar(ch, 5)) == TIMEOUT) { + Syslog('t', "Escapechar() nothing follows"); return rc; + } /* * Test for the most important keys. Note @@ -94,29 +99,56 @@ int Escapechar(unsigned char *ch) * guaranteed to work with PC-clients. */ c = *ch; + Syslog('t', "Escapechar() CSI input %d", c); if (c == 'A') c = KEY_UP; - if (c == 'B') + else if (c == 'B') c = KEY_DOWN; - if (c == 'C') + else if (c == 'C') c = KEY_RIGHT; - if (c == 'D') + else if (c == 'D') c = KEY_LEFT; - if ((c == '1') || (c == 'H') || (c == 0)) + else if ((c == 'H') || (c == 0)) c = KEY_HOME; - if ((c == '4') || (c == 'K') || (c == 101) || (c == 144)) + else if ((c == '4') || (c == 'K') || (c == 'F') || (c == 101) || (c == 144)) c = KEY_END; - if (c == '2') + else if ((c == '2') || (c == 'L')) { + Waitchar(ch, 5); /* Eat following ~ char */ c = KEY_INS; - if (c == '3') + } else if (c == '3') { + Waitchar(ch, 5); /* Eat following ~ char */ c = KEY_DEL; - if (c == '5') + } else if ((c == '5') || (c == 'I')) { + Waitchar(ch, 5); /* Eat following ~ char */ c = KEY_PGUP; - if (c == '6') + } else if ((c == '6') || (c == 'G')) { + Waitchar(ch, 5); /* Eat following ~ char */ c = KEY_PGDN; + } else if (c == '1') { + Syslog('t', "Possible function key"); + if ((rc = Waitchar(ch, 5)) == TIMEOUT) { + c = KEY_HOME; + } else { + c = *ch; + Syslog('t', "next %d %c", c, c); + Waitchar(ch, 5); /* Eat following ~ char */ + switch (c) { + case '1' : c = KEY_F1; break; + case '2' : c = KEY_F2; break; + case '3' : c = KEY_F3; break; + case '4' : c = KEY_F4; break; + case '5' : c = KEY_F5; break; + case '7' : c = KEY_F6; break; + case '8' : c = KEY_F7; break; + case '9' : c = KEY_F8; break; + } + } + } + Syslog('t', "Escapechar() will return %d", c); memcpy(ch, &c, sizeof(unsigned char)); return rc; } + Syslog('t', "Escapechar() not a CSI sequence"); return -1; } @@ -152,10 +184,10 @@ unsigned char Readkey(void) if ((rc == 1) && (ch == KEY_ESCAPE)) { rc = Escapechar(&ch); if (rc == 1) { - Syslog('t', "Readkey() returns %d", ch); + Syslog('t', "Readkey() escaped returns %d", ch); return ch; } else { - Syslog('t', "Readkey() returns %d", KEY_ESCAPE); + Syslog('t', "Readkey() escaped returns %d (real escape)", KEY_ESCAPE); return KEY_ESCAPE; } } diff --git a/mbsebbs/mbsebbs.c b/mbsebbs/mbsebbs.c index fee102a5..c7aa144d 100644 --- a/mbsebbs/mbsebbs.c +++ b/mbsebbs/mbsebbs.c @@ -82,7 +82,7 @@ int main(int argc, char **argv) * Set the users device to writable by other bbs users, so they * can send one-line messages */ - chmod(tty, 00666); +// chmod(tty, 00666); /* * Get MBSE_ROOT Path and load Config into Memory @@ -146,25 +146,6 @@ int main(int argc, char **argv) sprintf(pTTY, "%s", tty); } - /* - * Now that we have all terminal information, we close the tty and - * reopen the default tty so that doors will work. - */ -// cookedport(); -// close(0); -// close(1); -// if ((i = open("/dev/tty", O_RDWR|O_NONBLOCK)) < 0) { -// perror("open 0"); -// exit(MBERR_TTYIO_ERROR); -// } -// Syslog('t', "new fd %d", i); -// if ((i = open("/dev/tty", O_RDWR|O_NONBLOCK)) < 0) { -// perror("open 1"); -// exit(MBERR_TTYIO_ERROR); -// } -// Syslog('t', "new fd %d", i); -// rawport(); - umask(007); /* diff --git a/mbsebbs/openport.c b/mbsebbs/openport.c index 4a8a9f7a..86932052 100644 --- a/mbsebbs/openport.c +++ b/mbsebbs/openport.c @@ -33,10 +33,10 @@ #include "openport.h" -int hanged_up = 0; - -static struct termios savetios; -static struct termios tios; +int hanged_up = 0; +static int termios_saved = FALSE; /* Is termios saved */ +static struct termios savetios; /* Saved termios */ +static struct termios tios; @@ -50,7 +50,7 @@ void hangup(void) speed_t ispeed, ospeed; int rc; - Syslog('t', "Setting port local"); + Syslog('t', "hangup()"); if (isatty(0)) { if ((rc = tcgetattr(0,&Tios))) { @@ -94,18 +94,13 @@ int rawport(void) Syslog('t', "rawport()"); tty_status = 0; - Syslog('t', "ttyname 0 %s", ttyname(0)); - Syslog('t', "ttyname 1 %s", ttyname(1)); - Syslog('t', "fd = %d", fileno(stdin)); - Syslog('t', "fd = %d", fileno(stdout)); - Syslog('t', "fd = %d", fileno(stderr)); - if (isatty(0)) { if ((rc = tcgetattr(0,&savetios))) { WriteError("$tcgetattr(0,save) return %d",rc); return rc; } + termios_saved = TRUE; tios = savetios; tios.c_iflag &= ~(INLCR | ICRNL | ISTRIP | IXON ); /* IUCLC removed for FreeBSD */ /* @@ -118,7 +113,6 @@ int rawport(void) if ((rc = tcsetattr(0,TCSADRAIN,&tios))) WriteError("$tcsetattr(0,TCSADRAIN,raw) return %d",rc); - } else { Syslog('t', "not at a tty"); } @@ -132,9 +126,15 @@ int cookedport(void) int rc = 0; Syslog('t', "cookedport()"); + + if (termios_saved == FALSE) { + WriteError("Can't restore termios before it was saved"); + return -1; + } + if (isatty(0)) { if ((rc = tcsetattr(0,TCSAFLUSH,&savetios))) - Syslog('t', "$tcsetattr(0,TCSAFLUSH,save) return %d", rc); + WriteError("$tcsetattr(0,TCSAFLUSH,save) return %d", rc); } return rc;