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
Branches
Tags
No related merge requests found
Pipeline #5944 passed
......@@ -29,15 +29,44 @@
#include <genwrap.h>
#include <sockwrap.h>
#include "ini_file.h"
#include "spyon.h"
#include "ciolib.h"
#include "cterm.h"
#include "uifc.h"
#include "str_util.h"
struct cterminal *cterm;
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
uifc.msg("Spying not supported on Win32 yet!");
return SPY_SOCKETLOST;
......@@ -46,12 +75,14 @@ int spyon(char *sockname) {
struct sockaddr_un spy_name;
socklen_t spy_len;
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;
fd_set rd;
bool b;
int retval=0;
int telnet_strip=0;
struct text_info ti;
char *scrn;
......@@ -63,6 +94,11 @@ int spyon(char *sockname) {
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;
SAFECOPY(spy_name.sun_path,sockname);
#ifdef SUN_LEN
......@@ -82,9 +118,9 @@ int spyon(char *sockname) {
textbackground(BLUE);
clrscr();
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();
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) {
struct timeval tv;
tv.tv_sec=0;
......@@ -104,21 +140,21 @@ int spyon(char *sockname) {
break;
}
if(spy_sock != INVALID_SOCKET && FD_ISSET(spy_sock,&rd)) {
if((i=read(spy_sock,&buf,1))==1) {
if(telnet_strip) {
telnet_strip++;
if(buf==255 && telnet_strip==2) {
telnet_strip=0;
cterm_write(cterm, &buf,1,NULL,0,NULL);
if((i=read(spy_sock, buf, sizeof(buf) - 1)) > 0) {
if(idle_count >= 1000 && fdate(term_ini_fname) > term_ini_ftime) {
term_ini_ftime = read_term_ini(term_ini_fname);
if(cterm_emu != cterm->emulation) {
cterm_end(cterm, 1);
cterm = cterm_init(ti.screenheight - 1, ti.screenwidth, 1, 1, 0, 0, NULL, cterm_emu);
}
if(telnet_strip==3)
telnet_strip=0;
}
else
if(buf==255)
telnet_strip=1;
else
cterm_write(cterm, &buf,1,NULL,0,NULL);
if(term_utf8) {
buf[i] = '\0';
utf8_to_cp437_inplace(buf);
i = strlen(buf);
}
idle_count = 0;
cterm_write(cterm, buf, i, NULL, 0, NULL);
}
else if(i<0) {
close(spy_sock);
......@@ -126,6 +162,8 @@ int spyon(char *sockname) {
retval=SPY_SOCKETLOST;
break;
}
} else {
++idle_count;
}
if(kbhit()) {
key=getch();
......
/* spyon.h */
/* 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.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
......@@ -17,24 +13,14 @@
* See the GNU General Public License for more details: gpl.txt or *
* 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 *
* 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. *
****************************************************************************/
#include "scfgdefs.h"
enum {
SPY_NOSOCKET
,SPY_NOCONNECT
......@@ -44,4 +30,4 @@ enum {
,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) {
}
}
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];
int i;
......@@ -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);
else
snprintf(str,sizeof(str),"%slocalspy%d.sock", bbs_startup->ctrl_dir, nodenum);
i=spyon(str);
i=spyon(str, nodenum, cfg);
switch(i) {
case SPY_NOSOCKET:
uifc.msg("Could not create socket");
......@@ -1208,7 +1208,7 @@ USAGE:
}
if(j==-2-CIO_KEY_F(12)) { /* Spy */
dospy(main_dflt,&bbs_startup);
dospy(&cfg,main_dflt,&bbs_startup);
continue;
}
......@@ -1297,7 +1297,7 @@ USAGE:
break;
case 1: /* Spy */
dospy(j,&bbs_startup);
dospy(&cfg,j,&bbs_startup);
break;
case 2: /* Send message */
......@@ -1366,7 +1366,7 @@ USAGE:
switch(uifc.list(WIN_MID|WIN_SAV|WIN_ACT,0,0,0,&i,0,"Node Options",opt)) {
case 0: /* Spy */
dospy(j,&bbs_startup);
dospy(&cfg,j,&bbs_startup);
break;
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