...
 
Commits (2)
  • Rob Swindell's avatar
    Use an enum for ANSI output state · f26b296b
    Rob Swindell authored
    No functional change with regard to the ANSI output state, just making the code easier to read.
    
    Removed the conversion of `[ and \xFA[ to \x1b[ in putmsg(). This unexplained output translation has been supported since at least v2.xx and I have no recollection of exactly why it was added. If I recall correctly, some BBS software at some point in time sent ANSI-encoded messages into message networks by translating the ESC (\x1b) character in the ANSI sequences to either ` or \xFA in the process. This "feature" seems like it would still work, but it's completely undocumented and I have no idea why it was added (and seriously doubt anyone relies on this behavior), so I'm removing it. If anyone misses this feature, I'll happily add it back, but I'm skeptical that'll happen.
    f26b296b
  • Rob Swindell's avatar
    Don't pass-through ANSI Device Attributes (DA) requests · 9919c23e
    Rob Swindell authored
    putmsg(), used to display messages and display/menu files, will no longer pass-through the ANSI sequence ESC[c (found in some corrupted ANSI posts to fsxNet->FSX_BOT echo) to the client terminal since this will stimulate a (unwanted) response from the client.
    
    I do wonder if the outchar_esc value check should be == here instead of >=, but I'm not familiar with the string and SOS states. I wonder if any display files sent from the BBS would ever include those sequences.
    9919c23e
......@@ -566,57 +566,46 @@ const char* sbbs_t::term_charset(long term)
/****************************************************************************/
int sbbs_t::outchar(char ch)
{
/*
* outchar_esc values:
* 0: No sequence
* 1: ESC
* 2: CSI
* 3: Final byte
* 4: APS, DCS, PM, or OSC
* 5: SOS
* 6: ESC inside of SOS
*/
if(console&CON_ECHO_OFF)
return 0;
if(ch==ESC && outchar_esc < 4)
outchar_esc=1;
else if(outchar_esc==1) {
if(ch=='[')
outchar_esc++;
else if(ch=='_' || ch=='P' || ch == '^' || ch == ']')
outchar_esc=4;
if(ch == ESC && outchar_esc < ansiState_string)
outchar_esc = ansiState_esc;
else if(outchar_esc == ansiState_esc) {
if(ch == '[')
outchar_esc = ansiState_csi;
else if(ch == '_' || ch == 'P' || ch == '^' || ch == ']')
outchar_esc = ansiState_string;
else if(ch=='X')
outchar_esc=5;
else if(ch >= 0x40 && ch <= 0x5f)
outchar_esc=3;
outchar_esc = ansiState_sos;
else if(ch >= '@' && ch <= '_')
outchar_esc = ansiState_final;
else
outchar_esc=0;
outchar_esc = ansiState_none;
}
else if(outchar_esc==2) {
if(ch>='@' && ch<='~')
outchar_esc++;
else if(outchar_esc == ansiState_csi) {
if(ch >= '@' && ch <= '~')
outchar_esc = ansiState_final;
}
else if(outchar_esc==4) { // APS, DCS, PM, or OSC
else if(outchar_esc == ansiState_string) { // APS, DCS, PM, or OSC
if (ch == ESC)
outchar_esc = 1;
if (!((ch >= 0x08 && ch <= 0x0d) || (ch >= 0x20 && ch <= 0x7e)))
outchar_esc = 0;
outchar_esc = ansiState_esc;
if (!((ch >= '\b' && ch <= '\r') || (ch >= ' ' && ch <= '~')))
outchar_esc = ansiState_none;
}
else if(outchar_esc==5) { // SOS
else if(outchar_esc == ansiState_sos) { // SOS
if (ch == ESC)
outchar_esc++;
outchar_esc = ansiState_sos_esc;
}
else if(outchar_esc==6) { // ESC inside SOS
else if(outchar_esc == ansiState_sos_esc) { // ESC inside SOS
if (ch == '\\')
outchar_esc = 1;
outchar_esc = ansiState_esc;
else if (ch == 'X')
outchar_esc = 0;
outchar_esc = ansiState_none;
else
outchar_esc = 5;
outchar_esc = ansiState_sos;
}
else
outchar_esc=0;
outchar_esc = ansiState_none;
long term = term_supports();
char utf8[UTF8_MAX_LEN + 1] = "";
if(!(term&PETSCII)) {
......@@ -642,7 +631,7 @@ int sbbs_t::outchar(char ch)
if(!(console&CON_R_ECHO))
return 0;
if((console&CON_R_ECHOX) && (uchar)ch>=' ' && !outchar_esc) {
if((console&CON_R_ECHOX) && (uchar)ch>=' ' && outchar_esc == ansiState_none) {
ch=text[YNQP][3];
if(text[YNQP][2]==0 || ch==0) ch='X';
}
......@@ -677,7 +666,7 @@ int sbbs_t::outchar(char ch)
outcom(ch);
}
}
if(!outchar_esc) {
if(outchar_esc == ansiState_none) {
/* Track cursor position locally */
switch(ch) {
case '\a': // 7
......@@ -718,8 +707,8 @@ int sbbs_t::outchar(char ch)
break;
}
}
if(outchar_esc==3)
outchar_esc=0;
if(outchar_esc == ansiState_final)
outchar_esc = ansiState_none;
if(lncntr==rows-1 && ((useron.misc&(UPAUSE^(console&CON_PAUSEOFF))) || sys_status&SS_PAUSEON)
&& !(sys_status&(SS_PAUSEOFF|SS_ABORT))) {
......
......@@ -3369,7 +3369,7 @@ sbbs_t::sbbs_t(ushort node_num, union xp_sockaddr *addr, size_t addr_len, const
pause_hotspot = NULL;
console = 0;
online = 0;
outchar_esc = 0;
outchar_esc = ansiState_none;
nodemsg_inside = 0; /* allows single nest */
hotkey_inside = 0; /* allows single nest */
event_time = 0;
......
......@@ -193,10 +193,6 @@ char sbbs_t::putmsgfrag(const char* buf, long* mode, long org_cols, JSObject* ob
l+=2;
}
}
else if((str[l]=='`' || str[l]=='') && str[l+1]=='[') {
outchar(ESC); /* Convert `[ and [ to ESC[ */
l++;
}
else if(!((*mode)&P_NOXATTRS)
&& (cfg.sys_misc&SM_PCBOARD) && str[l]=='@' && str[l+1]=='X'
&& isxdigit((unsigned char)str[l+2]) && isxdigit((unsigned char)str[l+3])) {
......@@ -348,12 +344,12 @@ char sbbs_t::putmsgfrag(const char* buf, long* mode, long org_cols, JSObject* ob
}
/* ansi escape sequence */
if(outchar_esc) {
if(outchar_esc >= ansiState_csi) {
if(str[l]=='A' || str[l]=='B' || str[l]=='H' || str[l]=='J'
|| str[l]=='f' || str[l]=='u') /* ANSI anim */
lncntr=0; /* so defeat pause */
if(str[l]=='"') {
l++; /* don't pass on keyboard reassignment */
if(str[l]=='"' || str[l]=='c') {
l++; /* don't pass on keyboard reassignment or Device Attributes (DA) requests */
continue;
}
}
......
......@@ -348,7 +348,15 @@ public:
scfg_t cfg;
int outchar_esc; // track ANSI escape seq output
enum ansiState {
ansiState_none // No sequence
,ansiState_esc // Escape
,ansiState_csi // CSI
,ansiState_final // Final byte
,ansiState_string // APS, DCS, PM, or OSC
,ansiState_sos // SOS
,ansiState_sos_esc // ESC inside SOS
} outchar_esc; // track ANSI escape seq output
int rioctl(ushort action); // remote i/o control
bool rio_abortable;
......