Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, libarchive.org for more info) to build successfully.

Commits (1)
  • Rob Swindell's avatar
    Allow FOSSIL mode of the Win32 virtual UART/FOSSIL driver to be disabled · 5b36ab9a
    Rob Swindell authored
    When configuring an external program, a Win32 sysop can now choose to *only* enable the virtual UART (and not the FOSSIL driver) feature of the Synchronet virtual UART/FOSSIL driver (dosxtrn.exe/sbbsexec.dll). Some programs (e.g. TradeWars 2) will always use the FOSSIL driver if one is detected and in order to force the use of COM/UART driver for I/O (if that is desired), then one must disable the FOSSIL driver. It's a rare use case, but I can see the potential need.
    
    Renamed the "Intercept I/O" option in SCFG to "I/O Method" and make it clear that "Socket" (for native programs) and "FOSSIL or UART" (for 16-bit DOS programs) is the default method (what was previously identified as "No" I/O Interception).
    
    If a sysop want to disable the virtual UART support (on Win32, e.g. so *only* FOSSIL is available to one or all DOS programs), they do that via their sbbsexec.ini file.
    5b36ab9a
......@@ -47,6 +47,7 @@
#define SBBSEXEC_MODE_FOSSIL (0)
#define SBBSEXEC_MODE_DOS_IN (1<<0)
#define SBBSEXEC_MODE_DOS_OUT (1<<1)
#define SBBSEXEC_MODE_UART (1<<2)
enum {
SBBSEXEC_ERROR_INUSE=1
......
......@@ -395,6 +395,7 @@ typedef enum { /* Values for xtrn_t.event */
#define SAVECOLUMNS (1<<22) /* Save/share current terminal width */
#define XTRN_UTF8 (1<<23) /* External program supports UTF-8 */
#define XTRN_TEMP_DIR (1<<24) /* Place drop files in temp dir */
#define XTRN_UART (1<<25) /* Disable the int14h/FOSSIL driver */
#define XTRN_CONIO (1<<31) /* Intercept Windows Console I/O (Drwy) */
/* Bits in cfg.xtrn_misc */
......@@ -810,6 +811,7 @@ enum { /* readmail and delmailidx which types */
#define EX_CHKTIME XTRN_CHKTIME /* Check time left */
#define EX_NOECHO XTRN_NOECHO /* Don't echo stdin to stdout */
#define EX_STDIO (EX_STDIN|EX_STDOUT)
#define EX_UART XTRN_UART
#define EX_NOLOG (1<<30) /* Don't log intercepted stdio */
#define EX_CONIO (1<<31) /* Intercept Windows console I/O (doorway) */
#define EX_UNSPECIFIED -1
......
......@@ -153,6 +153,8 @@ void sort_subs(int grpnum);
void sort_dirs(int libnum);
unsigned subs_in_group(unsigned grpnum);
char random_code_char(void);
const char* io_method(uint32_t mode);
void choose_io_method(uint32_t* misc);
BOOL load_main_cfg(scfg_t*, char*, size_t);
BOOL load_node_cfg(scfg_t*, char*, size_t);
BOOL load_msgs_cfg(scfg_t*, char*, size_t);
......
......@@ -114,9 +114,7 @@ void page_cfg()
k=0;
sprintf(opt[k++],"%-27.27s%s","Command Line",cfg.page[i]->cmd);
sprintf(opt[k++],"%-27.27s%s","Access Requirements",cfg.page[i]->arstr);
sprintf(opt[k++],"%-27.27s%s","Intercept I/O"
,(cfg.page[i]->misc&XTRN_STDIO) ? "Standard"
:cfg.page[i]->misc&XTRN_CONIO ? "Console":"No");
sprintf(opt[k++],"%-27.27s%s","I/O Method", io_method(cfg.page[i]->misc));
sprintf(opt[k++],"%-27.27s%s","Native Executable"
,cfg.page[i]->misc&XTRN_NATIVE ? "Yes" : "No");
sprintf(opt[k++],"%-27.27s%s","Use Shell to Execute"
......@@ -144,49 +142,7 @@ void page_cfg()
getar(str,cfg.page[i]->arstr);
break;
case 2:
switch(cfg.page[i]->misc&(XTRN_STDIO|XTRN_CONIO)) {
case XTRN_STDIO:
k=0;
break;
case XTRN_CONIO:
k=1;
break;
default:
k=2;
}
strcpy(opt[0],"Standard");
strcpy(opt[1],"Console");
strcpy(opt[2],"No");
opt[3][0]=0;
uifc.helpbuf=
"`Intercept I/O:`\n"
"\n"
"If you wish the screen output and keyboard input to be intercepted\n"
"when running this chat pager, set this option to either `Standard` or ~Console~.\n"
;
switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Intercept I/O"
,opt)) {
case 0:
if((cfg.page[i]->misc&(XTRN_STDIO|XTRN_CONIO)) != XTRN_STDIO) {
cfg.page[i]->misc|=XTRN_STDIO;
cfg.page[i]->misc&=~XTRN_CONIO;
uifc.changes=1;
}
break;
case 1:
if((cfg.page[i]->misc&(XTRN_STDIO|XTRN_CONIO)) != XTRN_CONIO) {
cfg.page[i]->misc|=XTRN_CONIO;
cfg.page[i]->misc&=~XTRN_STDIO;
uifc.changes=1;
}
break;
case 2:
if((cfg.page[i]->misc&(XTRN_STDIO|XTRN_CONIO)) != 0) {
cfg.page[i]->misc&=~(XTRN_STDIO|XTRN_CONIO);
uifc.changes=1;
}
break;
}
choose_io_method(&cfg.page[i]->misc);
break;
case 3:
k=(cfg.page[i]->misc&XTRN_NATIVE) ? 0:1;
......
......@@ -875,6 +875,145 @@ void tevents_cfg()
}
}
const char* io_method(uint32_t mode)
{
static char str[128];
sprintf(str,"%s%s%s"
,mode & XTRN_UART ? "UART"
: (mode & XTRN_STDIO ? "Standard"
: mode & XTRN_CONIO ? "Console": (mode & XTRN_NATIVE ? "Socket" : "FOSSIL or UART"))
,(mode & (XTRN_STDIO|WWIVCOLOR)) == (XTRN_STDIO|WWIVCOLOR) ? ", WWIV Color" : ""
,(mode & (XTRN_STDIO|XTRN_NOECHO)) == (XTRN_STDIO|XTRN_NOECHO) ? ", No Echo" : "");
return str;
}
void choose_io_method(uint32_t* misc)
{
int k;
switch((*misc) & (XTRN_STDIO|XTRN_UART)) {
case XTRN_STDIO:
k=0;
break;
case XTRN_UART:
k=2;
break;
default:
k=1;
break;
}
strcpy(opt[0], "Standard");
if((*misc) & XTRN_NATIVE) {
uifc.helpbuf=
"`I/O Method:`\n"
"\n"
"Select the type of input and output to/from this program that you would\n"
"like to have intercepted and directed to the remote user's terminal.\n"
"\n"
"`Standard`\n"
" So-called 'Standard I/O' of console mode (typically UNIX) programs.\n"
"\n"
"`Socket`\n"
" Stream (TCP) socket interface to a native (e.g. Win32 or *nix)\n"
" program. The socket descriptor/handle (number) is passed to the\n"
" program either via drop file (e.g. DOOR32.SYS) or command-line\n"
" option.\n"
"\n"
"~ Note ~\n"
" This setting is not applied when invoking Baja or JavaScript modules.\n"
;
strcpy(opt[1], "Socket");
opt[2][0] = '\0';
} else {
uifc.helpbuf=
"`I/O Method:`\n"
"\n"
"Select the type of input and output to/from this program that you would\n"
"like to have intercepted and directed to the remote user's terminal.\n"
"\n"
"`Standard`\n"
" So-called 'Standard I/O' of console mode (typically UNIX) programs.\n"
" Int29h is intercepted for output and int16h for keyboard input.\n"
" Will not intercept direct screen writes or PC-BIOS int10h calls.\n"
"\n"
"`FOSSIL`\n"
" Int14h (PC-BIOS) serial communication interface to 16-bit\n"
" MS-DOS programs. Most traditional BBS door games will support FOSSIL.\n"
" The port number (contained in the DX register of int14h calls) is\n"
" ignored by the Synchronet FOSSIL driver.\n"
"\n"
"`UART`\n"
" Communication port I/O of 16-bit MS-DOS programs via emulation of an\n"
" NS8250 Universal Asynchronous Receiver/Transmitter (UART), by\n"
" default as an IBM-PC `COM1` port (I/O port 3F8h, IRQ 4).\n"
"\n"
"~ Note ~\n"
" This setting is not applied when invoking Baja or JavaScript modules.\n"
;
strcpy(opt[1], "FOSSIL or UART");
strcpy(opt[2], "UART");
opt[3][0] = '\0';
}
switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"I/O Method"
,opt)) {
case 0: /* Standard I/O */
if(((*misc) & (XTRN_STDIO|XTRN_UART)) != XTRN_STDIO) {
(*misc) |=XTRN_STDIO;
(*misc) &=~XTRN_UART;
uifc.changes = TRUE;
}
k=((*misc) & WWIVCOLOR) ? 0:1;
uifc.helpbuf=
"`Program Uses WWIV Color Codes:`\n"
"\n"
"If this program was written for use exclusively under ~WWIV~ BBS\n"
"software, set this option to ~Yes~.\n"
;
k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
,"Program Uses WWIV Color Codes"
,uifcYesNoOpts);
if(!k && !((*misc) & WWIVCOLOR)) {
(*misc) |= WWIVCOLOR;
uifc.changes=TRUE;
}
else if(k==1 && ((*misc)&WWIVCOLOR)) {
(*misc) &= ~WWIVCOLOR;
uifc.changes=TRUE;
}
k=((*misc) & XTRN_NOECHO) ? 1:0;
uifc.helpbuf=
"`Echo Input:`\n"
"\n"
"If you want the BBS to copy (\"echo\") all keyboard input to the screen\n"
"output, set this option to ~Yes~ (for native Win32 programs only).\n"
;
k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
,"Echo Keyboard Input"
,uifcYesNoOpts);
if(!k && ((*misc) & XTRN_NOECHO)) {
(*misc) &=~XTRN_NOECHO;
uifc.changes=TRUE;
} else if(k==1 && !((*misc) & XTRN_NOECHO)) {
(*misc) |= XTRN_NOECHO;
uifc.changes=TRUE;
}
break;
case 1: /* FOSSIL or Socket */
if(((*misc) & (XTRN_STDIO|XTRN_UART)) != 0) {
(*misc) &= ~(XTRN_UART|XTRN_STDIO|WWIVCOLOR|XTRN_NOECHO);
uifc.changes=TRUE;
}
break;
case 2: /* UART */
if(((*misc) & (XTRN_STDIO|XTRN_UART)) != XTRN_UART) {
(*misc) |= XTRN_UART;
(*misc) &= ~(XTRN_STDIO|WWIVCOLOR|XTRN_NOECHO);
uifc.changes=TRUE;
}
break;
}
}
void xtrn_cfg(uint section)
{
......@@ -997,13 +1136,7 @@ void xtrn_cfg(uint section)
,cfg.xtrn[i]->run_arstr);
sprintf(opt[k++],"%-27.27s%s","Multiple Concurrent Users"
,cfg.xtrn[i]->misc&MULTIUSER ? "Yes" : "No");
sprintf(opt[k++],"%-27.27s%s%s%s","Intercept I/O"
,cfg.xtrn[i]->misc&XTRN_STDIO ? "Standard"
: cfg.xtrn[i]->misc&XTRN_CONIO ? "Console":"No"
,(cfg.xtrn[i]->misc&(XTRN_STDIO|WWIVCOLOR))
==(XTRN_STDIO|WWIVCOLOR) ? ", WWIV Color" : nulstr
,(cfg.xtrn[i]->misc&(XTRN_STDIO|XTRN_NOECHO))
==(XTRN_STDIO|XTRN_NOECHO) ? ", No Echo" : nulstr);
sprintf(opt[k++],"%-27.27s%s","I/O Method", io_method(cfg.xtrn[i]->misc));
sprintf(opt[k++],"%-27.27s%s","Native Executable/Script"
,cfg.xtrn[i]->misc&XTRN_NATIVE ? "Yes" : "No");
sprintf(opt[k++],"%-27.27s%s",use_shell_opt
......@@ -1171,84 +1304,7 @@ void xtrn_cfg(uint section)
}
break;
case 9:
switch(cfg.xtrn[i]->misc&(XTRN_STDIO|XTRN_CONIO)) {
case XTRN_STDIO:
k=0;
break;
case XTRN_CONIO:
k=1;
break;
default:
k=2;
}
strcpy(opt[0],"Standard");
strcpy(opt[1],"Console");
strcpy(opt[2],"No");
opt[3][0]=0;
uifc.helpbuf=
"`Intercept I/O:`\n"
"\n"
"If this online program uses a FOSSIL driver or SOCKET communications,\n"
"set this option to `No`.\n"
;
switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Intercept I/O"
,opt)) {
case 0: /* Standard I/O */
if((cfg.xtrn[i]->misc&(XTRN_STDIO|XTRN_CONIO)) != XTRN_STDIO) {
cfg.xtrn[i]->misc|=XTRN_STDIO;
cfg.xtrn[i]->misc&=~XTRN_CONIO;
uifc.changes=1;
}
k=(cfg.xtrn[i]->misc&WWIVCOLOR) ? 0:1;
uifc.helpbuf=
"`Program Uses WWIV Color Codes:`\n"
"\n"
"If this program was written for use exclusively under ~WWIV~ BBS\n"
"software, set this option to ~Yes~.\n"
;
k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
,"Program Uses WWIV Color Codes"
,uifcYesNoOpts);
if(!k && !(cfg.xtrn[i]->misc&WWIVCOLOR)) {
cfg.xtrn[i]->misc|=WWIVCOLOR;
uifc.changes=TRUE;
}
else if(k==1 && (cfg.xtrn[i]->misc&WWIVCOLOR)) {
cfg.xtrn[i]->misc&=~WWIVCOLOR;
uifc.changes=TRUE;
}
k=(cfg.xtrn[i]->misc&XTRN_NOECHO) ? 1:0;
uifc.helpbuf=
"`Echo Input:`\n"
"\n"
"If you want the BBS to copy (\"echo\") all keyboard input to the screen\n"
"output, set this option to ~Yes~ (for native Win32 programs only).\n"
;
k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
,"Echo Keyboard Input"
,uifcYesNoOpts);
if(!k && (cfg.xtrn[i]->misc&XTRN_NOECHO)) {
cfg.xtrn[i]->misc&=~XTRN_NOECHO;
uifc.changes=TRUE;
} else if(k==1 && !(cfg.xtrn[i]->misc&XTRN_NOECHO)) {
cfg.xtrn[i]->misc|=XTRN_NOECHO;
uifc.changes=TRUE;
}
break;
case 1: /* Console I/O */
if((cfg.xtrn[i]->misc&(XTRN_STDIO|XTRN_CONIO)) != XTRN_CONIO) {
cfg.xtrn[i]->misc|=XTRN_CONIO;
cfg.xtrn[i]->misc&=~(XTRN_STDIO|WWIVCOLOR|XTRN_NOECHO);
uifc.changes=TRUE;
}
break;
case 2: /* No */
if((cfg.xtrn[i]->misc&(XTRN_STDIO|XTRN_CONIO)) != 0) {
cfg.xtrn[i]->misc&=~(XTRN_CONIO|XTRN_STDIO|WWIVCOLOR|XTRN_NOECHO);
uifc.changes=TRUE;
}
break;
}
choose_io_method(&cfg.xtrn[i]->misc);
break;
case 10:
k=(cfg.xtrn[i]->misc&XTRN_NATIVE) ? 0:1;
......@@ -1673,11 +1729,7 @@ void xedit_cfg()
sprintf(opt[k++],"%-32.32s%s","Internal Code",cfg.xedit[i]->code);
sprintf(opt[k++],"%-32.32s%s","Command Line",cfg.xedit[i]->rcmd);
sprintf(opt[k++],"%-32.32s%s","Access Requirements",cfg.xedit[i]->arstr);
sprintf(opt[k++],"%-32.32s%s%s","Intercept I/O"
,cfg.xedit[i]->misc&XTRN_STDIO ? "Standard"
:cfg.xedit[i]->misc&XTRN_CONIO ? "Console":"No"
,(cfg.xedit[i]->misc&(XTRN_STDIO|WWIVCOLOR))
==(XTRN_STDIO|WWIVCOLOR) ? ", WWIV Color" : nulstr);
sprintf(opt[k++],"%-32.32s%s","I/O Method", io_method(cfg.xedit[i]->misc));
sprintf(opt[k++],"%-32.32s%s","Native Executable/Script"
,cfg.xedit[i]->misc&XTRN_NATIVE ? "Yes" : "No");
sprintf(opt[k++],"%-32.32s%s",use_shell_opt
......@@ -1788,66 +1840,7 @@ void xedit_cfg()
getar(str,cfg.xedit[i]->arstr);
break;
case 4:
switch(cfg.xedit[i]->misc&(XTRN_STDIO|XTRN_CONIO)) {
case XTRN_STDIO:
k=0;
break;
case XTRN_CONIO:
k=1;
break;
default:
k=2;
break;
}
strcpy(opt[0],"Standard");
strcpy(opt[1],"Console");
strcpy(opt[2],"No");
opt[3][0]=0;
uifc.helpbuf=
"`Intercept I/O:`\n"
"\n"
"If this program uses FOSSIL, Socket, or UART communications,\n"
"set this option to `No`.\n"
;
switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Intercept I/O" ,opt)) {
case 0: /* Standard */
if((cfg.xedit[i]->misc&(XTRN_STDIO|XTRN_CONIO)) != XTRN_STDIO) {
cfg.xedit[i]->misc|=XTRN_STDIO;
cfg.xedit[i]->misc&=~XTRN_CONIO;
uifc.changes=TRUE;
}
k=(cfg.xedit[i]->misc&WWIVCOLOR) ? 0:1;
uifc.helpbuf=
".Editor Uses WWIV Color Codes:.\n"
"\n"
"If this editor was written for use exclusively under WWIV, set this\n"
"option to .Yes..\n"
;
k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
,"Editor Uses WWIV Color Codes",uifcYesNoOpts);
if(!k && !(cfg.xedit[i]->misc&WWIVCOLOR)) {
cfg.xedit[i]->misc|=WWIVCOLOR;
uifc.changes=TRUE;
}
else if(k==1 && (cfg.xedit[i]->misc&WWIVCOLOR)) {
cfg.xedit[i]->misc&=~WWIVCOLOR;
uifc.changes=TRUE;
}
break;
case 1: /* Console */
if((cfg.xedit[i]->misc&(XTRN_STDIO|XTRN_CONIO)) != XTRN_CONIO) {
cfg.xedit[i]->misc|=XTRN_CONIO;
cfg.xedit[i]->misc&=~(XTRN_STDIO|WWIVCOLOR);
uifc.changes=TRUE;
}
break;
case 2: /* No */
if((cfg.xedit[i]->misc&(XTRN_STDIO|XTRN_CONIO)) != 0) {
cfg.xedit[i]->misc&=~(XTRN_CONIO|XTRN_STDIO|WWIVCOLOR);
uifc.changes=TRUE;
}
break;
}
choose_io_method(&cfg.xedit[i]->misc);
break;
case 5:
k=(cfg.xedit[i]->misc&XTRN_NATIVE) ? 0:1;
......
......@@ -478,11 +478,15 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir)
SAFEPRINTF2(fullcmdline, "%sDOSXTRN.EXE %s", cfg.exec_dir, path);
if(!(mode&EX_OFFLINE)) {
i=SBBSEXEC_MODE_FOSSIL;
if(mode&EX_STDIN)
i|=SBBSEXEC_MODE_DOS_IN;
if(mode&EX_STDOUT)
i|=SBBSEXEC_MODE_DOS_OUT;
if(mode & EX_UART)
i=SBBSEXEC_MODE_UART;
else {
i=SBBSEXEC_MODE_FOSSIL;
if(mode&EX_STDIN)
i|=SBBSEXEC_MODE_DOS_IN;
if(mode&EX_STDOUT)
i|=SBBSEXEC_MODE_DOS_OUT;
}
sprintf(str," NT %u %u"
,cfg.node_num,i);
strcat(fullcmdline,str);
......