diff --git a/src/sbbs3/sbbsdefs.h b/src/sbbs3/sbbsdefs.h index 42a7968d70cdda843c471ba8c05fb37815736929..4e1902cf596c7e40585dd97c11a284834f3ece73 100644 --- a/src/sbbs3/sbbsdefs.h +++ b/src/sbbs3/sbbsdefs.h @@ -399,6 +399,7 @@ typedef enum { /* Values for xtrn_t.event */ #define XTRN_TEMP_DIR (1<<24) /* Place drop files in temp dir */ #define XTRN_UART (1<<25) /* Enable the virtual UART driver */ #define XTRN_FOSSIL (1<<26) /* Enable the int14h/FOSSIL driver */ +#define XTRN_NODISPLAY (1<<27) /* Disable local screen/display */ #define XTRN_CONIO (1<<31) /* Intercept Windows Console I/O (Drwy) */ /* Bits in user.qwk */ @@ -815,6 +816,7 @@ enum { /* readmail and delmailidx which types */ #define EX_STDIO (EX_STDIN|EX_STDOUT) #define EX_UART XTRN_UART #define EX_FOSSIL XTRN_FOSSIL +#define EX_NODISPLAY XTRN_NODISPLAY #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 diff --git a/src/sbbs3/scfg/scfgxtrn.c b/src/sbbs3/scfg/scfgxtrn.c index adece05dcf10828ffb85fff6097d744931178455..f2e58a987573d5f61e67202def6ead5df00a708c 100644 --- a/src/sbbs3/scfg/scfgxtrn.c +++ b/src/sbbs3/scfg/scfgxtrn.c @@ -1220,6 +1220,8 @@ void xtrn_cfg(uint section) sprintf(opt[k++],"%-27.27s%s","Execute on Event",str); sprintf(opt[k++],"%-27.27s%s","Pause After Execution" ,cfg.xtrn[i]->misc&XTRN_PAUSE ? "Yes" : "No"); + sprintf(opt[k++],"%-27.27s%s","Disable Local Display" + ,cfg.xtrn[i]->misc&XTRN_NODISPLAY ? "Yes" : "No"); sprintf(opt[k++],"%-23.23s%-4s%s","BBS Drop File Type" ,cfg.xtrn[i]->misc&REALNAME ? "(R)":nulstr ,dropfile(cfg.xtrn[i]->type,cfg.xtrn[i]->misc)); @@ -1255,7 +1257,7 @@ void xtrn_cfg(uint section) case -CIO_KEY_RIGHT-2: i = next; break; - case 0: + case __COUNTER__: uifc.helpbuf= "`Online Program Name:`\n" "\n" @@ -1266,7 +1268,7 @@ void xtrn_cfg(uint section) ,cfg.xtrn[i]->name,sizeof(cfg.xtrn[i]->name)-1,K_EDIT)) SAFECOPY(cfg.xtrn[i]->name,str); break; - case 1: + case __COUNTER__: uifc.helpbuf= "`Online Program Internal Code:`\n" "\n" @@ -1285,7 +1287,7 @@ void xtrn_cfg(uint section) uifc.helpbuf=0; } break; - case 2: + case __COUNTER__: uifc.helpbuf= "`Online Program Start-up Directory:`\n" "\n" @@ -1298,7 +1300,7 @@ void xtrn_cfg(uint section) uifc.input(WIN_MID|WIN_SAV,0,10,"" ,cfg.xtrn[i]->path,sizeof(cfg.xtrn[i]->path)-1,K_EDIT); break; - case 3: + case __COUNTER__: uifc.helpbuf= "`Online Program Command Line:`\n" "\n" @@ -1309,7 +1311,7 @@ void xtrn_cfg(uint section) uifc.input(WIN_MID|WIN_SAV,0,10,"Command" ,cfg.xtrn[i]->cmd,sizeof(cfg.xtrn[i]->cmd)-1,K_EDIT); break; - case 4: + case __COUNTER__: uifc.helpbuf= "`Online Program Clean-up Command:`\n" "\n" @@ -1321,7 +1323,7 @@ void xtrn_cfg(uint section) uifc.input(WIN_MID|WIN_SAV,0,10,"Clean-up" ,cfg.xtrn[i]->clean,sizeof(cfg.xtrn[i]->clean)-1,K_EDIT); break; - case 5: + case __COUNTER__: ultoa(cfg.xtrn[i]->cost,str,10); uifc.helpbuf= "`Online Program Cost to Run:`\n" @@ -1334,15 +1336,15 @@ void xtrn_cfg(uint section) ,str,10,K_EDIT|K_NUMBER); cfg.xtrn[i]->cost=atol(str); break; - case 6: + case __COUNTER__: sprintf(str,"%s Access",cfg.xtrn[i]->name); getar(str,cfg.xtrn[i]->arstr); break; - case 7: + case __COUNTER__: sprintf(str,"%s Execution",cfg.xtrn[i]->name); getar(str,cfg.xtrn[i]->run_arstr); break; - case 8: + case __COUNTER__: k=(cfg.xtrn[i]->misc&MULTIUSER) ? 0:1; uifc.helpbuf= "`Supports Multiple Users:`\n" @@ -1361,10 +1363,10 @@ void xtrn_cfg(uint section) uifc.changes=TRUE; } break; - case 9: + case __COUNTER__: choose_io_method(&cfg.xtrn[i]->misc); break; - case 10: + case __COUNTER__: k=(cfg.xtrn[i]->misc&XTRN_NATIVE) ? 0:1; uifc.helpbuf=native_help; k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 @@ -1378,7 +1380,7 @@ void xtrn_cfg(uint section) uifc.changes=TRUE; } break; - case 11: + case __COUNTER__: k=(cfg.xtrn[i]->misc&XTRN_SH) ? 0:1; uifc.helpbuf = use_shell_help; k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 @@ -1392,7 +1394,7 @@ void xtrn_cfg(uint section) uifc.changes=TRUE; } break; - case 12: + case __COUNTER__: k=(cfg.xtrn[i]->misc&MODUSERDAT) ? 0:1; uifc.helpbuf= "`Program Can Modify User Data:`\n" @@ -1412,7 +1414,7 @@ void xtrn_cfg(uint section) uifc.changes=TRUE; } break; - case 13: + case __COUNTER__: k=0; strcpy(opt[k++],"No"); strcpy(opt[k++],"Logon"); @@ -1466,7 +1468,7 @@ void xtrn_cfg(uint section) uifc.changes=TRUE; } break; - case 14: + case __COUNTER__: k=(cfg.xtrn[i]->misc&XTRN_PAUSE) ? 0:1; uifc.helpbuf= "`Pause Screen After Execution:`\n" @@ -1486,7 +1488,27 @@ void xtrn_cfg(uint section) uifc.changes=TRUE; } break; - case 15: + case __COUNTER__: + k=(cfg.xtrn[i]->misc&XTRN_NODISPLAY) ? 0:1; + uifc.helpbuf= + "`Disable Local Screen Display:`\n" + "\n" + "Set this option to `Yes` if you wish to prevent this program from\n" + "displaying on the local screen.\n" + "\n" + "This will disable 'Screen' output in the `DOOR.SYS` and `PCBOARD.SYS` drop\n" + "files and on Windows, stop the creation a new console window when\n" + "executing this program." + ; + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 + ,"Disable Local Screen Display", uifcYesNoOpts); + if((!k && !(cfg.xtrn[i]->misc & XTRN_NODISPLAY)) + || (k && (cfg.xtrn[i]->misc & XTRN_NODISPLAY))) { + cfg.xtrn[i]->misc ^= XTRN_NODISPLAY; + uifc.changes=TRUE; + } + break; + case __COUNTER__: k=0; strcpy(opt[k++],"None"); sprintf(opt[k++],"%-15s %s","Synchronet","XTRN.DAT"); @@ -1561,7 +1583,7 @@ void xtrn_cfg(uint section) } } break; - case 16: + case __COUNTER__: k = (cfg.xtrn[i]->misc & STARTUPDIR) ? 1 : (cfg.xtrn[i]->misc & XTRN_TEMP_DIR) ? 2 : 0; strcpy(opt[0],"Node Directory"); strcpy(opt[1],"Start-up Directory"); @@ -1600,7 +1622,7 @@ void xtrn_cfg(uint section) uifc.changes=TRUE; } break; - case 17: + case __COUNTER__: while(1) { k=0; if(cfg.xtrn[i]->textra) diff --git a/src/sbbs3/xtrn.cpp b/src/sbbs3/xtrn.cpp index 28e7482e8ca9782229333ff7ccd9f743629ef4d5..daca8ae017dc5c50463ea51d33994a0e4d45a68c 100644 --- a/src/sbbs3/xtrn.cpp +++ b/src/sbbs3/xtrn.cpp @@ -448,6 +448,8 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir) SAFEPRINTF(path,"%sDOSXTRN.RET", cfg.node_dir); (void)remove(path); + SAFEPRINTF(path,"%sDOSXTRN.ERR", cfg.node_dir); + (void)remove(path); // Create temporary environment file SAFEPRINTF(path,"%sDOSXTRN.ENV", node_dir); @@ -595,13 +597,14 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir) pthread_mutex_lock(&input_thread_mutex); } + DWORD creation_flags = (mode & EX_NODISPLAY) ? CREATE_NO_WINDOW : CREATE_NEW_CONSOLE; success=CreateProcess( NULL, // pointer to name of executable module fullcmdline, // pointer to command line string NULL, // process security attributes NULL, // thread security attributes native && !(mode&EX_OFFLINE), // handle inheritance flag - CREATE_NEW_CONSOLE/*|CREATE_SEPARATE_WOW_VDM*/, // creation flags + creation_flags, // creation flags env_block, // pointer to new environment block p_startup_dir, // pointer to current directory name &startup_info, // pointer to STARTUPINFO @@ -791,8 +794,7 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir) if(online && hangup_event!=NULL && WaitForSingleObject(hangup_event,0)==WAIT_OBJECT_0) { - lprintf(LOG_NOTICE,"Node %d External program requested hangup (dropped DTR)" - ,cfg.node_num); + lputs(LOG_NOTICE, "External program requested hangup (dropped DTR)"); hangup(); } @@ -831,21 +833,40 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir) errormsg(WHERE, ERR_CHK, "ExitCodeProcess",(DWORD)process_info.hProcess); if(retval==STILL_ACTIVE) { - lprintf(LOG_INFO,"Node %d Terminating process from line %d",cfg.node_num,__LINE__); + lprintf(LOG_INFO,"Terminating process from line %d", __LINE__); TerminateProcess(process_info.hProcess, GetLastError()); } // Get return value if(!native) { - sprintf(str,"%sDOSXTRN.RET", cfg.node_dir); - FILE* fp=fopen(str,"r"); - if(fp!=NULL) { + SAFEPRINTF(path, "%sDOSXTRN.RET", cfg.node_dir); + FILE* fp=fopen(path,"r"); + if(fp == NULL) { + lprintf(LOG_ERR, "Error %d opening %s", errno, path); + } else { if(fscanf(fp,"%d",&retval) != 1) { - lprintf(LOG_ERR, "Node %d Error reading return value from %s", cfg.node_num, str); - retval = -1; + lprintf(LOG_ERR, "Error reading return value from %s", path); + retval = -2; } fclose(fp); } + if(retval == -1) { + SAFEPRINTF(path, "%sDOSXTRN.ERR", cfg.node_dir); + fp = fopen(path, "r"); + if(fp == NULL) { + lprintf(LOG_ERR, "Error %d opening %s after DOSXTRN.RET contained -1", errno, path); + } else { + char errstr[256] = ""; + int errval = 0; + if(fscanf(fp, "%d\n", &errval) == 1) { + fgets(errstr, sizeof(errstr), fp); + truncsp(errstr); + lprintf(LOG_ERR, "DOSXTRN Error %d (%s) executing: %s", errval, errstr, cmdline); + } else + lprintf(LOG_ERR, "DOSXTRN.RET contained -1 and we failed to parse: %s", path); + fclose(fp); + } + } } } diff --git a/src/sbbs3/xtrn_sec.cpp b/src/sbbs3/xtrn_sec.cpp index 26972cb304304f6f0633318cbb3b6b23fb6dbf5a..02c6e90eb526dd677075ec3514f3f4a67d989841 100644 --- a/src/sbbs3/xtrn_sec.cpp +++ b/src/sbbs3/xtrn_sec.cpp @@ -381,7 +381,7 @@ void sbbs_t::xtrndat(const char *name, const char *dropdir, uchar type, ulong tl ,8 /* 03: Data bits */ ,cfg.node_num /* 04: Node number */ ,dte_rate /* 05: DTE rate */ - ,'Y' /* 06: Screen display */ + ,(misc & XTRN_NODISPLAY) ? 'N': 'Y' /* 06: Screen display */ ,'Y' /* 07: Printer toggle */ ,'Y' /* 08: Page bell */ ,'Y'); /* 09: Caller alarm */ @@ -712,7 +712,7 @@ void sbbs_t::xtrndat(const char *name, const char *dropdir, uchar type, ulong tl return; } PCBoard::sys sys{}; - sys.Screen = true; + sys.Screen = !(misc & XTRN_NODISPLAY); sys.PageBell = sys_status & SS_SYSPAGE; sys.Alarm = startup->sound.answer[0] && !sound_muted(&cfg); sys.ErrorCorrected = true; @@ -1393,7 +1393,7 @@ bool sbbs_t::exec_xtrn(uint xtrnnum) mode|=EX_UART; else if(cfg.xtrn[xtrnnum]->misc&XTRN_FOSSIL) mode|=EX_FOSSIL; - mode|=(cfg.xtrn[xtrnnum]->misc&(XTRN_CHKTIME|XTRN_NATIVE|XTRN_NOECHO|WWIVCOLOR)); + mode|=(cfg.xtrn[xtrnnum]->misc&(XTRN_CHKTIME|XTRN_NATIVE|XTRN_NOECHO|XTRN_NODISPLAY|WWIVCOLOR)); if(cfg.xtrn[xtrnnum]->misc&MODUSERDAT) { /* Delete MODUSER.DAT */ SAFEPRINTF(str,"%sMODUSER.DAT",dropdir); /* if for some weird */ (void)removecase(str); /* reason it's there */