From 4f66de65615cdd47b860b4e2606bac5efa3f261d Mon Sep 17 00:00:00 2001 From: "Rob Swindell (on Windows 11)" <rob@synchro.net> Date: Mon, 7 Apr 2025 20:45:02 -0700 Subject: [PATCH] Modified text and menu files can now be placed in mods/text/* (e.g. mods/text/menu/main.msg), but only when the mods dir is configured in SCFG->System->Advanced Options (by default, this set to ../mods/). While menu-related functions will always check/read the file from the mods/text dir (if exists), printfile() function requires the new P_MODS flag to be specified to check/read the file from the mods/text directory. This resolves feature request/issue #879 --- src/sbbs3/atcodes.cpp | 4 ++-- src/sbbs3/main.cpp | 4 ++-- src/sbbs3/prntfile.cpp | 33 +++++++++++++++++++++++++++++++-- src/sbbs3/putmsg.cpp | 2 +- src/sbbs3/sbbsdefs.h | 1 + src/sbbs3/str.cpp | 6 ++++++ 6 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/sbbs3/atcodes.cpp b/src/sbbs3/atcodes.cpp index b155a5faef..7a8f296731 100644 --- a/src/sbbs3/atcodes.cpp +++ b/src/sbbs3/atcodes.cpp @@ -1610,12 +1610,12 @@ const char* sbbs_t::atcode(const char* sp, char* str, size_t maxlen, int* pmode, } if (!strncmp(sp, "TYPE:", 5)) { - printfile(cmdstr(sp + 5, nulstr, nulstr, str), 0); + printfile(cmdstr(sp + 5, nulstr, nulstr, str), P_MODS); return nulstr; } if (!strncmp(sp, "INCLUDE:", 8)) { - printfile(cmdstr(sp + 8, nulstr, nulstr, str), P_NOCRLF | P_SAVEATR); + printfile(cmdstr(sp + 8, nulstr, nulstr, str), P_NOCRLF | P_SAVEATR | P_MODS); return nulstr; } diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp index 6eede662b1..259c458594 100644 --- a/src/sbbs3/main.cpp +++ b/src/sbbs3/main.cpp @@ -5770,7 +5770,7 @@ NO_SSH: lprintf(LOG_WARNING, "%04d %s [%s] !No nodes available for login.", client_socket, client.protocol, host_ip); SAFEPRINTF(str, "%snonodes.txt", scfg.text_dir); if (fexist(str)) - sbbs->printfile(str, P_NOABORT); + sbbs->printfile(str, P_NOABORT | P_MODS); else { sbbs->cp437_out("\r\nSorry, all terminal nodes are in use or otherwise unavailable.\r\n"); sbbs->cp437_out("Please try again later.\r\n"); @@ -5846,7 +5846,7 @@ NO_SSH: , client_socket, client.protocol, new_node->cfg.node_num); SAFEPRINTF(str, "%snonodes.txt", scfg.text_dir); if (fexist(str)) - sbbs->printfile(str, P_NOABORT); + sbbs->printfile(str, P_NOABORT | P_MODS); else sbbs->cp437_out("\r\nSorry, initialization failed. Try again later.\r\n"); sbbs->flush_output(3000); diff --git a/src/sbbs3/prntfile.cpp b/src/sbbs3/prntfile.cpp index 10073394b5..31485a3242 100644 --- a/src/sbbs3/prntfile.cpp +++ b/src/sbbs3/prntfile.cpp @@ -35,7 +35,7 @@ /* for pauses, aborts and ANSI. 'str' is the path of the file to print */ /* Called from functions menu and text_sec */ /****************************************************************************/ -bool sbbs_t::printfile(const char* fname, int mode, int org_cols, JSObject* obj) +bool sbbs_t::printfile(const char* inpath, int mode, int org_cols, JSObject* obj) { char* buf; char fpath[MAX_PATH + 1]; @@ -45,7 +45,16 @@ bool sbbs_t::printfile(const char* fname, int mode, int org_cols, JSObject* obj) int l, length, savcon = console; FILE *stream; - SAFECOPY(fpath, fname); + if (FULLPATH(fpath, inpath, sizeof fpath) == NULL) + SAFECOPY(fpath, inpath); + if ((mode & P_MODS) && cfg.mods_dir[0] != '\0') { + if (strncmp(fpath, cfg.text_dir, strlen(cfg.text_dir)) == 0) { + char modpath[MAX_PATH + 1]; + snprintf(modpath, sizeof modpath, "%stext/%s", cfg.mods_dir, fpath + strlen(cfg.text_dir)); + if(fexistcase(modpath)) + SAFECOPY(fpath, modpath); + } + } (void)fexistcase(fpath); p = getfext(fpath); if (p != NULL) { @@ -308,6 +317,10 @@ bool sbbs_t::menu(const char *code, int mode, JSObject* obj) return printfile(path, mode, /* org_cols: */ 0, obj); } +//**************************************************************************** +// Check (return true) if a menu file exists with specified type/extension +// 'path' buffer must be at least (MAX_PATH + 1) bytes in size +//**************************************************************************** bool sbbs_t::menu_exists(const char *code, const char* ext, char* path) { char pathbuf[MAX_PATH + 1]; @@ -337,6 +350,16 @@ bool sbbs_t::menu_exists(const char *code, const char* ext, char* path) SAFEPRINTF3(prefix, "%smenu/%s%s", cfg.text_dir, subdir, code); FULLPATH(path, prefix, MAX_PATH); SAFECOPY(prefix, path); + if (cfg.mods_dir[0] != '\0') { + char modprefix[MAX_PATH + 1]; + char modpath[MAX_PATH + 1]; + snprintf(modprefix, sizeof modprefix, "%stext/menu/%s%s", cfg.mods_dir, subdir, code); + snprintf(modpath, sizeof modpath, "%s.%s", modprefix, ext); + if (fexist(modpath)) { + FULLPATH(path, modprefix, MAX_PATH); + SAFECOPY(prefix, path); + } + } } // Display specified EXACT width file safe_snprintf(path, MAX_PATH, "%s.%ucol.%s", prefix, term->cols, ext); @@ -379,6 +402,12 @@ bool sbbs_t::random_menu(const char *name, int mode, JSObject* obj) str_list_t names = NULL; SAFEPRINTF2(path, "%smenu/%s", cfg.text_dir, name); + if (cfg.mods_dir[0] != '\0') { + char modpath[MAX_PATH + 1]; + SAFEPRINTF2(modpath, "%stext/menu/%s", cfg.mods_dir, name); + if (fexist(modpath)) + SAFECOPY(path, modpath); + } if (glob(path, GLOB_NOESCAPE | GLOB_MARK, NULL, &g) != 0) { return false; } diff --git a/src/sbbs3/putmsg.cpp b/src/sbbs3/putmsg.cpp index 05003f0883..756219f47a 100644 --- a/src/sbbs3/putmsg.cpp +++ b/src/sbbs3/putmsg.cpp @@ -212,7 +212,7 @@ char sbbs_t::putmsgfrag(const char* buf, int& mode, unsigned org_cols, JSObject* tmp2[i] = 0; sys_status |= SS_NEST_PF; /* keep it only one message deep! */ SAFEPRINTF2(path, "%s%s", cfg.text_dir, tmp2); - printfile(path, 0); + printfile(path, P_MODS); sys_status &= ~SS_NEST_PF; } } diff --git a/src/sbbs3/sbbsdefs.h b/src/sbbs3/sbbsdefs.h index 593387d156..ac6f272d7f 100644 --- a/src/sbbs3/sbbsdefs.h +++ b/src/sbbs3/sbbsdefs.h @@ -699,6 +699,7 @@ typedef enum { // Values for xtrn_t.event #define P_REMOTE (1 << 18) // Only print when online == ON_REMOTE #define P_INDENT (1 << 19) // Indent lines to current cursor column #define P_ATCODES (1 << 20) // Trusted @-codes in formatted string +#define P_MODS (1 << 21) // Display from mods/text dir, if file is there #define P_XATTR_SHIFT 20 #define P_WILDCAT (SM_WILDCAT << P_XATTR_SHIFT) diff --git a/src/sbbs3/str.cpp b/src/sbbs3/str.cpp index b5bd65dc35..a77ac323f1 100644 --- a/src/sbbs3/str.cpp +++ b/src/sbbs3/str.cpp @@ -990,6 +990,12 @@ bool sbbs_t::trashcan(const char *insearchof, const char *name, struct trash* tr result = ::trashcan2(&cfg, insearchof, NULL, name, trash); if (result) { snprintf(str, sizeof str, "%sbad%s.msg", cfg.text_dir, name); + if (cfg.mods_dir[0] != '\0') { + char modpath[MAX_PATH + 1]; + snprintf(modpath, sizeof modpath, "%stext/bad%s.msg", cfg.mods_dir, name); + if (fexistcase(modpath)) + SAFECOPY(str, modpath); + } if (fexistcase(str)) { printfile(str, 0); flush_output(500); // give time for tx buffer to clear before disconnect -- GitLab