Skip to content
Snippets Groups Projects
Commit 3000ece5 authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

Support UTF-8 and PETSCII terminal spying

Converts UTF-8 output to CP437 equivalent (cterm doesn't yet support UTF-8).
Fixes issue #717 (more or less).

The terminal dimensions are also read from the node*/terminal.ini file, but
aren't applied to the cterm runtime (though maybe they can/should be, probably
requires a cterm re-init).
parent 6274d33b
No related branches found
No related tags found
No related merge requests found
Pipeline #5944 passed
...@@ -29,15 +29,44 @@ ...@@ -29,15 +29,44 @@
#include <genwrap.h> #include <genwrap.h>
#include <sockwrap.h> #include <sockwrap.h>
#include "ini_file.h"
#include "spyon.h" #include "spyon.h"
#include "ciolib.h" #include "ciolib.h"
#include "cterm.h" #include "cterm.h"
#include "uifc.h" #include "uifc.h"
#include "str_util.h"
struct cterminal *cterm; struct cterminal *cterm;
extern uifcapi_t uifc; /* User Interface (UIFC) Library API */ extern uifcapi_t uifc; /* User Interface (UIFC) Library API */
cterm_emulation_t cterm_emu = CTERM_EMULATION_ANSI_BBS;
char term_type[INI_MAX_VALUE_LEN] = "unknown";
int term_cols = 80;
int term_rows = 25;
bool term_utf8 = false;
int spyon(char *sockname) { time_t read_term_ini(const char* path)
{
FILE* fp = iniOpenFile(path, /* for_modify: */false);
if(fp != NULL) {
char chars[INI_MAX_VALUE_LEN];
iniReadString(fp, ROOT_SECTION, "type", /* default: */NULL, term_type);
iniReadString(fp, ROOT_SECTION, "chars", /* default: */NULL, chars);
term_cols = iniReadInteger(fp, ROOT_SECTION, "cols", term_cols);
term_rows = iniReadInteger(fp, ROOT_SECTION, "rows", term_rows);
term_utf8 = false;
if(stricmp(term_type, "PETSCII") == 0)
cterm_emu = CTERM_EMULATION_PETASCII;
else {
cterm_emu = CTERM_EMULATION_ANSI_BBS;
if(stricmp(chars, "UTF-8") == 0)
term_utf8 = true;
}
fclose(fp);
}
return fdate(path);
}
int spyon(char *sockname, int nodenum, scfg_t* cfg) {
#if defined _WIN32 #if defined _WIN32
uifc.msg("Spying not supported on Win32 yet!"); uifc.msg("Spying not supported on Win32 yet!");
return SPY_SOCKETLOST; return SPY_SOCKETLOST;
...@@ -46,12 +75,14 @@ int spyon(char *sockname) { ...@@ -46,12 +75,14 @@ int spyon(char *sockname) {
struct sockaddr_un spy_name; struct sockaddr_un spy_name;
socklen_t spy_len; socklen_t spy_len;
unsigned char key; unsigned char key;
unsigned char buf; char buf[100000];
char term_ini_fname[MAX_PATH + 1];
time_t term_ini_ftime;
int idle_count = 0;
int i; int i;
fd_set rd; fd_set rd;
bool b; bool b;
int retval=0; int retval=0;
int telnet_strip=0;
struct text_info ti; struct text_info ti;
char *scrn; char *scrn;
...@@ -63,6 +94,11 @@ int spyon(char *sockname) { ...@@ -63,6 +94,11 @@ int spyon(char *sockname) {
return(SPY_NOSOCKET); return(SPY_NOSOCKET);
} }
snprintf(term_ini_fname, sizeof term_ini_fname, "%sterminal.ini"
,cfg->node_path[nodenum - 1]);
term_ini_ftime = read_term_ini(term_ini_fname);
spy_name.sun_family=AF_UNIX; spy_name.sun_family=AF_UNIX;
SAFECOPY(spy_name.sun_path,sockname); SAFECOPY(spy_name.sun_path,sockname);
#ifdef SUN_LEN #ifdef SUN_LEN
...@@ -82,9 +118,9 @@ int spyon(char *sockname) { ...@@ -82,9 +118,9 @@ int spyon(char *sockname) {
textbackground(BLUE); textbackground(BLUE);
clrscr(); clrscr();
gotoxy(1,ti.screenheight); gotoxy(1,ti.screenheight);
cputs("Local spy mode... press CTRL-C to return to monitor"); cprintf("Spying on node %d ... press CTRL-C to return to monitor", nodenum);
clreol(); clreol();
cterm = cterm_init(ti.screenheight - 1, ti.screenwidth, 1, 1, 0, 0, NULL, CTERM_EMULATION_ANSI_BBS); cterm = cterm_init(ti.screenheight - 1, ti.screenwidth, 1, 1, 0, 0, NULL, cterm_emu);
while(spy_sock!=INVALID_SOCKET && cterm != NULL) { while(spy_sock!=INVALID_SOCKET && cterm != NULL) {
struct timeval tv; struct timeval tv;
tv.tv_sec=0; tv.tv_sec=0;
...@@ -104,21 +140,21 @@ int spyon(char *sockname) { ...@@ -104,21 +140,21 @@ int spyon(char *sockname) {
break; break;
} }
if(spy_sock != INVALID_SOCKET && FD_ISSET(spy_sock,&rd)) { if(spy_sock != INVALID_SOCKET && FD_ISSET(spy_sock,&rd)) {
if((i=read(spy_sock,&buf,1))==1) { if((i=read(spy_sock, buf, sizeof(buf) - 1)) > 0) {
if(telnet_strip) { if(idle_count >= 1000 && fdate(term_ini_fname) > term_ini_ftime) {
telnet_strip++; term_ini_ftime = read_term_ini(term_ini_fname);
if(buf==255 && telnet_strip==2) { if(cterm_emu != cterm->emulation) {
telnet_strip=0; cterm_end(cterm, 1);
cterm_write(cterm, &buf,1,NULL,0,NULL); cterm = cterm_init(ti.screenheight - 1, ti.screenwidth, 1, 1, 0, 0, NULL, cterm_emu);
} }
if(telnet_strip==3)
telnet_strip=0;
} }
else if(term_utf8) {
if(buf==255) buf[i] = '\0';
telnet_strip=1; utf8_to_cp437_inplace(buf);
else i = strlen(buf);
cterm_write(cterm, &buf,1,NULL,0,NULL); }
idle_count = 0;
cterm_write(cterm, buf, i, NULL, 0, NULL);
} }
else if(i<0) { else if(i<0) {
close(spy_sock); close(spy_sock);
...@@ -126,6 +162,8 @@ int spyon(char *sockname) { ...@@ -126,6 +162,8 @@ int spyon(char *sockname) {
retval=SPY_SOCKETLOST; retval=SPY_SOCKETLOST;
break; break;
} }
} else {
++idle_count;
} }
if(kbhit()) { if(kbhit()) {
key=getch(); key=getch();
......
/* spyon.h */
/* Synchronet for *nix node spy headers */ /* Synchronet for *nix node spy headers */
/* $Id: spyon.h,v 1.3 2018/07/24 01:12:32 rswindell Exp $ */
/**************************************************************************** /****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) * * @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
...@@ -17,24 +13,14 @@ ...@@ -17,24 +13,14 @@
* See the GNU General Public License for more details: gpl.txt or * * See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html * * http://www.fsf.org/copyleft/gpl.html *
* * * *
* Anonymous FTP access to the most recent released source is available at *
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
* *
* Anonymous CVS access to the development source and modification history *
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
* (just hit return, no password is necessary) *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
* *
* For Synchronet coding style and modification guidelines, see * * For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html * * http://www.synchro.net/source.html *
* * * *
* You are encouraged to submit any modifications (preferably in Unix diff *
* format) via e-mail to mods@synchro.net *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. * * Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/ ****************************************************************************/
#include "scfgdefs.h"
enum { enum {
SPY_NOSOCKET SPY_NOSOCKET
,SPY_NOCONNECT ,SPY_NOCONNECT
...@@ -44,4 +30,4 @@ enum { ...@@ -44,4 +30,4 @@ enum {
,SPY_CLOSED ,SPY_CLOSED
}; };
int spyon(char *sockname); int spyon(char *sockname, int nodenum, scfg_t*);
...@@ -161,7 +161,7 @@ void node_toggles(scfg_t *cfg,int nodenum) { ...@@ -161,7 +161,7 @@ void node_toggles(scfg_t *cfg,int nodenum) {
} }
} }
int dospy(int nodenum, bbs_startup_t *bbs_startup) { int dospy(scfg_t *cfg, int nodenum, bbs_startup_t *bbs_startup) {
char str[80],str2[80]; char str[80],str2[80];
int i; int i;
...@@ -169,7 +169,7 @@ int dospy(int nodenum, bbs_startup_t *bbs_startup) { ...@@ -169,7 +169,7 @@ int dospy(int nodenum, bbs_startup_t *bbs_startup) {
snprintf(str,sizeof(str),"%slocalspy%d.sock", bbs_startup->temp_dir, nodenum); snprintf(str,sizeof(str),"%slocalspy%d.sock", bbs_startup->temp_dir, nodenum);
else else
snprintf(str,sizeof(str),"%slocalspy%d.sock", bbs_startup->ctrl_dir, nodenum); snprintf(str,sizeof(str),"%slocalspy%d.sock", bbs_startup->ctrl_dir, nodenum);
i=spyon(str); i=spyon(str, nodenum, cfg);
switch(i) { switch(i) {
case SPY_NOSOCKET: case SPY_NOSOCKET:
uifc.msg("Could not create socket"); uifc.msg("Could not create socket");
...@@ -1208,7 +1208,7 @@ USAGE: ...@@ -1208,7 +1208,7 @@ USAGE:
} }
if(j==-2-CIO_KEY_F(12)) { /* Spy */ if(j==-2-CIO_KEY_F(12)) { /* Spy */
dospy(main_dflt,&bbs_startup); dospy(&cfg,main_dflt,&bbs_startup);
continue; continue;
} }
...@@ -1297,7 +1297,7 @@ USAGE: ...@@ -1297,7 +1297,7 @@ USAGE:
break; break;
case 1: /* Spy */ case 1: /* Spy */
dospy(j,&bbs_startup); dospy(&cfg,j,&bbs_startup);
break; break;
case 2: /* Send message */ case 2: /* Send message */
...@@ -1366,7 +1366,7 @@ USAGE: ...@@ -1366,7 +1366,7 @@ USAGE:
switch(uifc.list(WIN_MID|WIN_SAV|WIN_ACT,0,0,0,&i,0,"Node Options",opt)) { switch(uifc.list(WIN_MID|WIN_SAV|WIN_ACT,0,0,0,&i,0,"Node Options",opt)) {
case 0: /* Spy */ case 0: /* Spy */
dospy(j,&bbs_startup); dospy(&cfg,j,&bbs_startup);
break; break;
case 1: /* Chat with User */ case 1: /* Chat with User */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment