diff --git a/ctrl/sbbs.ini b/ctrl/sbbs.ini index df19c8ae081249c6874e9fcbb35d2aecbb782619..c47ddf1caa6523704bc736eff165a2f961706e60 100644 --- a/ctrl/sbbs.ini +++ b/ctrl/sbbs.ini @@ -77,7 +77,9 @@ Pet40Port = 64 ; TCP port for 80-column PETSCII connections (any terminal protocol): Pet80Port = 128 - ; Note on PETSCII support: you must add the same port(s) to one of your + ; TCP port for 40-column MODE7 connections (any termnial protocol): + Mode7Port = 5050 + ; Note on PETSCII and MODE7 support: you must add the same port(s) to one of your ; *Interface= values above to open/listen/accept connections on that port. ; Example: ; TelnetInterface = 71.95.196.34,71.95.196.34:64,71.95.196.34:128 diff --git a/ctrl/text.dat b/ctrl/text.dat index 7a9f5d4c73b35d2529a82efc64c917d060f24775..424225c7e11980a201e1cd4209991dd20db21cb0 100644 --- a/ctrl/text.dat +++ b/ctrl/text.dat @@ -1124,3 +1124,5 @@ " %c \1g%.10s\1n %c %.127s%c" 935 QWKTagLineFmt "\1n\r\n\1b\1hQWK Control [\1c%s\1b]: \1g%s\r\n" 936 QWKControlCommand "Unrecognized Control Command!\1n\r\n" 937 QWKBadControlCommand +"Mode 7 terminal detected" 938 Mode7TerminalDetected +"Are you using a Mode 7 terminal" 939 Mode7TerminalQ diff --git a/exec/bullseye.js b/exec/bullseye.js index a5f3e65dd74bf4ec6c025f2eda2117deba139906..c3de0da67eeb91520b85e19e45f2922fad9241f1 100644 --- a/exec/bullseye.js +++ b/exec/bullseye.js @@ -7,6 +7,7 @@ // @format.tab-size 4, @format.use-tabs true require("sbbsdefs.js", "P_NOERROR"); +require("gettext.js", 'gettext'); "use strict"; @@ -48,7 +49,7 @@ if(bull.length < 1) { while(bbs.online && !js.terminated) { if(bbs.menu("../bullseye", P_NOERROR)) { - console.mnemonics("\r\nEnter number of bulletin or [~Quit]: "); + console.mnemonics(gettext("\r\nEnter number of bulletin or [~Quit]: ")); b = console.getnum(bull.length); } else { for(i = 0; i < bull.length; ++i) diff --git a/exec/load/termdesc.js b/exec/load/termdesc.js index c514c06524dd40f5a614c49078be3d9ab611f667..ed0135707a4d2ef495b4badd356b324a15e40be8 100644 --- a/exec/load/termdesc.js +++ b/exec/load/termdesc.js @@ -22,6 +22,8 @@ function charset(term) term = console.term_supports(); if(term & USER_PETSCII) return "CBM-ASCII"; + if(term & USER_MODE7) + return "MODE7"; if(term & USER_UTF8) return "UTF-8"; if(term & USER_NO_EXASCII) @@ -62,6 +64,8 @@ function type(verbose, usr) var type = "DUMB"; if(term & USER_PETSCII) type = "PETSCII"; + if(term & USER_MODE7) + type = "MODE7"; if(term & USER_RIP) type = "RIP"; if(term & USER_ANSI) @@ -72,6 +76,8 @@ function type(verbose, usr) // Verbose if(term & USER_PETSCII) return ((usr.settings & USER_AUTOTERM) ? bbs.text(TerminalAutoDetect) : "") + "CBM/PETSCII"; + if(term & USER_MODE7) + return ((usr.settings & USER_AUTOTERM) ? bbs.text(TerminalAutoDetect) : "") + "MODE7"; return format("%s%s / %s %s%s%s" ,(usr.settings & USER_AUTOTERM) ? bbs.text(TerminalAutoDetect) : "" ,this.charset(term) diff --git a/exec/load/text.js b/exec/load/text.js index ab3fc80346f3939ade57bb921114da7eff2a9421..a780a764743648cb90270f73f57acb9b1ad72077 100644 --- a/exec/load/text.js +++ b/exec/load/text.js @@ -944,7 +944,9 @@ var QWKEndOfMessage=934; var QWKTagLineFmt=935; var QWKControlCommand=936; var QWKBadControlCommand=937; +var Mode7TerminalDetected=938; +var Mode7TerminalQ=939; -var TOTAL_TEXT=938; +var TOTAL_TEXT=940; this; diff --git a/exec/load/userdefs.js b/exec/load/userdefs.js index 4f7aad07d75c64bf831dfcd7b6691c72bc4f01f7..d09319efa7b237339e0817f43e1ac8c03bacd2a5 100644 --- a/exec/load/userdefs.js +++ b/exec/load/userdefs.js @@ -24,7 +24,7 @@ const USER_AUTOTERM = (1<<17); // Autodetect terminal type const USER_COLDKEYS = (1<<18); // No hot-keys const USER_EXTDESC = (1<<19); // Extended file descriptions const USER_AUTOHANG = (1<<20); // Auto-hang-up after transfer -const USER_WIP = (1<<21); // Supports WIP terminal emulation +const USER_MODE7 = (1<<21); // BBC Micro Mode 7 terminal support const USER_AUTOLOGON = (1<<22); // AutoLogon via IP const USER_HTML = (1<<23); // Using Deuce's HTML terminal (*cough*) const USER_NOPAUSESPIN = (1<<24); // No spinning cursor at pause prompt diff --git a/exec/login.js b/exec/login.js index a4c7324916f33d8a8406800245ba54a03fdcb7c5..e97e2ce6ea01ba976b6f2af868cf34b4b024fbb9 100644 --- a/exec/login.js +++ b/exec/login.js @@ -27,7 +27,7 @@ if(!bbs.online) exit(); var inactive_hangup = parseInt(options.inactive_hangup, 10); if(inactive_hangup && inactive_hangup < console.max_socket_inactivity - && !(console.autoterm&(USER_ANSI | USER_PETSCII | USER_UTF8))) { + && !(console.autoterm&(USER_ANSI | USER_PETSCII | USER_UTF8 | USER_MODE7))) { console.max_socket_inactivity = inactive_hangup; log(LOG_NOTICE, "terminal not detected, reducing inactivity hang-up timeout to " + console.max_socket_inactivity + " seconds"); } @@ -67,11 +67,12 @@ for(var c=0; c < options.login_prompts; c++) { if(!str.length) // blank continue; + // New user application? if(str.toUpperCase()=="NEW") { if(bbs.newuser()) { - bbs.logon(); - exit(); + bbs.logon(); + exit(); } continue; } diff --git a/exec/logon.js b/exec/logon.js index 6094ea5ddaf410e9e5c0f022d14356a3c2b3581f..0b7feadc3813859d23a4e7b48a72bd27d23ded5b 100644 --- a/exec/logon.js +++ b/exec/logon.js @@ -11,6 +11,8 @@ require("sbbsdefs.js", 'SS_RLOGIN'); require("nodedefs.js", 'NODE_QUIET'); + + if(!bbs.mods.avatar_lib) bbs.mods.avatar_lib = load({}, 'avatar_lib.js'); if(!bbs.mods.logonlist_lib) diff --git a/exec/mode7.js b/exec/mode7.js new file mode 100644 index 0000000000000000000000000000000000000000..d930a277c2da2b89bd79c6702498a4d78d0300f7 --- /dev/null +++ b/exec/mode7.js @@ -0,0 +1,124 @@ +// Default/Classic Synchronet Command Shell +// replaces default.src/bin + +// @format.tab-size 4 + +"use strict"; + +require("sbbsdefs.js", "K_UPPER"); +require("userdefs.js", "UFLAG_T"); +require("nodedefs.js", "NODE_MAIN"); +require("key_defs.js", "KEY_UP"); +require("gettext.js", "gettext"); +load("termsetup.js"); +var shell = load({}, "shell_lib.js"); + +system.settings &= ~SYS_RA_EMU; // Use (R)e-read and (A)uto-reply keys + +const help_key = '?'; +// If user has unlimited time, display time-used rather than time-remaining +const time_code = user.security.exemptions & UFLAG_T ? "\x86Time Used: @TUSED@" : "\x86Time Left: @TLEFT@"; + +const main_menu = { + file: "mode7/mode7_main", + eval: 'bbs.main_cmds++', + node_action: NODE_MAIN, + prompt: time_code + + gettext("\x87->\x83Main\x87-> "), + command: { + 'C': { exec: 'mode7/mode7_chat.js' }, + 'D': { exec: 'eotl_xtrn.js' }, + 'E': { exec: 'mode7/mode7_email.js' }, + 'F': { exec: 'eotl_xfer.js' }, + 'G': { eval: 'shell.logoff(/* fast: */false)' }, + 'N': { exec: 'mode7/mode7_forums.js' }, + '/G': { eval: 'shell.logoff(/* fast: */true)' }, + '/O': { eval: 'shell.logoff(/* fast: */true)' }, + 'S': { exec: 'eotl_settings.js' }, + 'T': { exec: '../xtrn/ansiview/ansiview.js' }, + 'X': { exec: 'eotl_sysop.js' + ,ars: 'SYSOP' }, + '!': { eval: 'bbs.menu("sysmain")' + ,ars: 'SYSOP' }, + }, + nav: { + '\r': { }, + }, +}; + +var menu = main_menu; +var last_str_cmd = ""; + +// The menu-display/command-prompt loop +while(bbs.online && !js.terminated) { + if(!(user.settings & USER_EXPERT)) { + console.clear(); + bbs.menu(menu.file); + } + bbs.node_action = menu.node_action; + bbs.nodesync(); + eval(menu.eval); + console.newline(); + console.aborted = false; + console.putmsg(menu.prompt, P_SAVEATR); + var cmd = console.getkey(K_UPPER); + if(cmd > ' ') + console.print(cmd); + if(cmd == ';') { + cmd = console.getstr(); + if(cmd == '!') + cmd = last_str_cmd; +// var script = system.mods_dir + "str_cmds.js"; +// if(!file_exists(script)) +// script = system.exec_dir + "str_cmds.js"; +// js.exec(script, {}, cmd); + load({}, "str_cmds.js", cmd); + last_str_cmd = cmd; + continue; + } + if(cmd == '/') { + cmd = console.getkey(K_UPPER); + console.print(cmd); + cmd = '/' + cmd; + } + if(cmd > ' ') { + bbs.log_key(cmd, /* comma: */true); + } + console.newline(); + console.line_counter = 0; + if(cmd == help_key) { + if(user.settings & USER_EXPERT) + bbs.menu(menu.file); + continue; + } + var menu_cmd = menu.command[cmd]; + if(!menu_cmd) { + console.print("\r\n\x81" + gettext("Unrecognized command.")); + if(user.settings & USER_EXPERT) + console.print(" " + gettext("Hit") + "¬É'" + help_key + "'¬Ü" + gettext("for a menu.")); + console.newline(); + continue; + } + if(!bbs.compare_ars(menu_cmd.ars)) + console.print(menu_cmd.err); + else { + if(menu_cmd.msg) + console.print(menu_cmd.msg); + if(menu_cmd.eval) + eval(menu_cmd.eval); + if(menu_cmd.exec) { + var script = system.mods_dir + menu_cmd.exec; + if(!file_exists(script)) + script = system.exec_dir + menu_cmd.exec; + if(menu_cmd.args) + js.exec.apply(null, [script, {}].concat(menu_cmd.args)); + else + js.exec(script, {}); + } + } +} +// Can't do these statically through initialization: +main_menu.nav[KEY_UP] = { eval: 'shell.sub_up()' }; +main_menu.nav[KEY_DOWN] = { eval: 'shell.sub_down()' }; +main_menu.nav[KEY_RIGHT] = { eval: 'shell.grp_up()' }; +main_menu.nav[KEY_LEFT] = { eval: 'shell.grp_down()' }; diff --git a/exec/mode7/mode7_chat.js b/exec/mode7/mode7_chat.js new file mode 100644 index 0000000000000000000000000000000000000000..5be62f3afda9ec10facc7c085641ed632f138df7 --- /dev/null +++ b/exec/mode7/mode7_chat.js @@ -0,0 +1,142 @@ +// $Id: chat_sec.js,v 1.15 2020/01/05 23:50:35 rswindell Exp $ + +// Chat Section for any/all Synchronet command shells + +"use strict"; + +require("sbbsdefs.js", 'USER_EXPERT'); +require("nodedefs.js", 'NODE_CHAT'); +require("text.js", 'R_Chat'); + +// Over-ride these default values by creating/modifying the [chat] section in your ctrl/modopts.ini file +var options = load("modopts.js", "chat"); +if (!options) + options = load("modopts.js", "chat_sec"); +if (!options) + options = {}; +if (options.irc === undefined) + options.irc = true; +if (options.irc_server === undefined) + options.irc_server = "irc.synchro.net 6667"; +if (options.irc_channel === undefined) + options.irc_channel = "#Synchronet"; +if (options.irc_seclevel === undefined) + options.irc_seclevel = 90; +if (options.finger === undefined) + options.finger = true; +if (options.imsg === undefined) + options.imsg = true; + +if(user.security.restrictions & UFLAG_C) { + write(bbs.text(R_Chat)); + exit(0); +} + +// Set continue point for main menu commands +menu: +while(1) { + var str=""; + // Display TEXT\MENU\CHAT.* if not in expert mode + bbs.nodesync(); + if(!(user.settings & USER_EXPERT)) { + bbs.menu("mode7/mode7_chat"); + } + + // Update node status + bbs.node_action = NODE_CHAT; + bbs.nodesync(); + if(user.compare_ars("exempt T")) + console.putmsg ("\x86Time Used: @TUSED@"); + else + console.putmsg ("\x86Time Left: @TLEFT@"); + + // Display main Prompt + console.putmsg ("\x87->\x83Chat Menu\x87-> "); + + var keys = "ACEMNPQSTYWX?$%"; + if(options.imsg) + keys += "I"; + if(options.irc) + keys += "R"; + if(options.finger) + keys += "F"; + switch(console.getkeys(keys, K_UPPER)) { + case "S": + var val = user.chat_settings ^= CHAT_SPLITP; + writeln(""); + break; + case "A": + var val = user.chat_settings ^= CHAT_NOACT; + writeln(""); + system.node_list[bbs.node_num-1].misc ^= NODE_AOFF; + break; + case 'P': + var val = user.chat_settings ^= CHAT_NOPAGE; + writeln(""); + system.node_list[bbs.node_num-1].misc ^= NODE_POFF; + break; + case 'E': + if(user.compare_ars("SYSOP")) { + writeln(""); + system.operator_available = !system.operator_available; + } + break; + case 'F': + writeln(""); + load("finger.js"); + break; + case 'I': + writeln(""); + load({}, "sbbsimsg.js"); + break; + case 'R': + { + var server=options.irc_server; + if(user.security.level >= options.irc_seclevel || user.security.exemptions&UFLAG_C) { + write("\r\n\x01n\x01y\x01hIRC Server: "); + server=console.getstr(options.irc_server, 40, K_EDIT|K_LINE|K_AUTODEL); + if(console.aborted || server.length < 4) + break; + } + if(server.indexOf(' ') < 0) + server += " 6667"; + write("\r\n\x01n\x01y\x01hIRC Channel: "); + var channel=console.getstr(options.irc_channel, 40, K_EDIT|K_LINE|K_AUTODEL); + if(!console.aborted && channel.length) { + log("IRC to " + server + " " + channel); + bbs.replace_text(NodeActionCustom,"in Internet Relay Chat via " + client.protocol); + bbs.node_action = NODE_CUSTOM; + bbs.nodesync(); + bbs.exec("?irc -a " + server + " " + channel); // can't be load()ed because it calls exit() + bbs.revert_text(NodeActionCustom); + } + break; + } + case 'C': + bbs.multinode_chat(); + break; + case 'N': + bbs.private_chat(); + break; + case 'Y': + if(!bbs.page_sysop()) + bbs.page_guru(); + break; + case 'T': + bbs.page_guru(); + break; + case 'M': + bbs.exec_xtrn("MULTIRELAYCHAT"); + break; + case '?': + if(user.settings & USER_EXPERT) + bbs.menu("mode7/mode7_chat"); + break; + case 'Q': + break menu; + + default: + console.clear(); + break; + } +} diff --git a/exec/mode7/mode7_email.js b/exec/mode7/mode7_email.js new file mode 100644 index 0000000000000000000000000000000000000000..653d248173c25003954bf426ecb0f5c473a938b3 --- /dev/null +++ b/exec/mode7/mode7_email.js @@ -0,0 +1,88 @@ +// E-mail Section + +// $Id: email_sec.js,v 1.10 2020/04/24 08:05:39 rswindell Exp $ + +// Note: this module replaces the old ### E-mail section ### Baja code in exec/*.src +// replace "call E-mail" with "exec_bin email_sec" + +require("sbbsdefs.js", "WM_NONE"); +require("userdefs.js", "USER_EXPERT"); +var text = bbs.mods.text; +if(!text) + text = load(bbs.mods.text = {}, "text.js"); +var userprops = bbs.mods.userprops; +if(!userprops) + userprops = load(bbs.mods.userprops = {}, "userprops.js"); +const ini_section = "netmail sent"; + +const NetmailAddressHistoryLength = 10; + +while(bbs.online) { + if(!(user.settings & USER_EXPERT)) + bbs.menu("mode7/mode7_email"); + + bbs.replace_text(720,'at email menu'); + bbs.node_action = NODE_CUSTOM; + bbs.nodesync(); + bbs.revert_text(720); + + writeln(); + if(user.compare_ars("exempt T")) + console.putmsg ("\x86Time Used: @TUSED@"); + else + console.putmsg ("\x86Time Left: @TLEFT@"); + + // Display main Prompt + console.putmsg ("\x87->\x83Email Menu\x87-> "); + + var wm_mode = WM_NONE; + var cmdkeys = "EFKNRSUQ?\r"; + switch(console.getkeys(cmdkeys,K_UPPER)) { + case 'R': // Read your mail + if(user.compare_ars("GUEST")) { + console.putmsg("Guests are not permitted to read emails\r\n"); + break; + } + bbs.read_mail(MAIL_YOUR, user.number); + break; + case 'U': // Read your un-read mail + if(user.compare_ars("GUEST")) { + console.putmsg("Guests are not permitted to read emails\r\n"); + break; + } + bbs.read_mail(MAIL_YOUR, user.number, LM_UNREAD|LM_REVERSE); + break; + case 'K': // Read/Kill sent mail + if(user.compare_ars("GUEST")) { + console.putmsg("Guests are not permitted to read emails\r\n"); + break; + } + bbs.read_mail(MAIL_SENT, user.number, LM_REVERSE); + break; + case 'E': // Send Feedback + bbs.email(/* user # */1, bbs.text(text.ReFeedback)); + break; + case 'F': + if(user.compare_ars("GUEST")) { + console.putmsg("Guests are not permitted to search emails\r\n"); + break; + } + bbs.exec("?../xtrn/DDMsgReader/DDMsgReader.js -search=keyword_search -subBoard=mail -startMode=list"); + break; + case 'S': // Send Mail + case 'N': // Send Mail + if(user.compare_ars("GUEST")) { + console.putmsg("You are not permitted to send mail as a guest\r\n"); + break; + } + bbs.exec("?/sbbs/xtrn/addressbook/addressbook.js",null,"/sbbs/xtrn/addressbook/"); + break; + case 'Q': // Quit + case '\r': + exit(0); + case '?': // Display menu + if(user.settings & USER_EXPERT) + bbs.menu("mode7/mode7_email.js"); + break; + } +} diff --git a/exec/mode7/mode7_forums.js b/exec/mode7/mode7_forums.js new file mode 100755 index 0000000000000000000000000000000000000000..1739b279a7b41b63d105cbec25b1b210c4b54555 --- /dev/null +++ b/exec/mode7/mode7_forums.js @@ -0,0 +1,167 @@ +// Forums Section + +'use strict'; +require("sbbsdefs.js", "K_UPPER"); +require("userdefs.js", "USER_EXPERT"); +require("nodedefs.js", "NODE_MAIN"); +require("gettext.js", "gettext"); + +var shell = load({}, "shell_lib.js"); +var text = bbs.mods.text; +var last_str_cmd = ""; +if(!text) + text = load(bbs.mods.text = {}, "text.js"); + +main: +while(bbs.online && !console.aborted) { + console.aborted = false; + if(!(user.settings & USER_EXPERT)) { + console.home(); + bbs.menu("mode7/mode7_forums"); + } + + bbs.replace_text(720,'at forums menu via ' + client.protocol.toLowerCase()); + bbs.node_action = NODE_CUSTOM; + bbs.nodesync(); + bbs.revert_text(720); + + console.crlf(); + console.putmsg ("\x83@GRP@\x86<@GN@>\x83@SUB@\x86<@SN@>"); + console.crlf(); + console.crlf(); + if(user.compare_ars("exempt T")) + console.putmsg ("\x86Time Used: @TUSED@"); + else + console.putmsg ("\x86Time Left: @TLEFT@"); + + // Display main Prompt + console.putmsg ("\x87->\x83Forums\x87-> "); + + var cmd = console.getkey(K_UPPER); + console.print(cmd); + switch(cmd) { + case 'N': writeln('\r\n\x86' + gettext("New Message Scan")); + bbs.scan_subs(SCAN_NEW); + break; + case 'R': bbs.scan_msgs(); + break; + case 'L': bbs.list_msgs() + break; + case 'P': bbs.post_msg(); + break; + case 'C': writeln('\r\n\x86' + gettext("Continuous New Message Scan") + '\r\n'); + bbs.scan_subs(SCAN_CONT); + break; + case 'C': bbs.exec("?filescancfg.js"); + break; + case 'M': console.newline(); + var res = bbs.exec("?postpoll.js"); + if(console.aborted) { + console.aborted = false; + } + if(res > 1) + console.pause(); + break; + case 'V': bbs.exec("?scanpolls.js"); + break; + case 'T': console.home(); + bbs.qwk_sec() + break; + case 'J': shell.select_msg_area() + break; + case 'F': writeln('\r\n\x86' + gettext("Find Text in Messages") + '\r\n'); + bbs.scan_subs(SCAN_FIND); + break; + case 'S': writeln('\r\n\x86' + gettext("Scan for Messages Posted to You") + '\r\n'); + bbs.scan_subs(SCAN_TOYOU) + break; + case '&': console.home() + bbs.exec("?eotl_msgscanconf.js"); + break; + case '!': if (user.compare_ars("SYSOP")) + bbs.menu("sysmain"); + break; + case '*': shell.show_subs(bbs.curgrp) + break; + case '#': writeln('\r\n\x86' + gettext("Type the actual number, not the symbol.")); + console.pause(); + break; + case KEY_RIGHT: + case '>': + case '}': + case ')': + case '+': + shell.sub_up(); + break; + case KEY_LEFT: + case '<': + case '{': + case '(': + case '-': shell.sub_down(); + break; + case KEY_UP: + case ']': shell.grp_up(); + break; + case KEY_DOWN: + case '[': shell.grp_down(); + break; + case '?': // Display menu + if(user.settings & USER_EXPERT) + bbs.menu("mode7/mode7_forums"); + break; + case 'Q': exit(); + break; + } + if(cmd >= '1' && cmd <= '9') { + shell.get_sub_num(cmd); + continue; + } + if(cmd == ';' && user.compare_ars("SYSOP")) { + cmd = console.getstr(); + if(cmd == '!') + cmd = last_str_cmd; + var script = system.mods_dir + "str_cmds.js"; + if(!file_exists(script)) + script = system.exec_dir + "str_cmds.js"; + js.exec(script, {}, cmd); + last_str_cmd = cmd; + continue; + } + + if(cmd == '/') { + cmd = console.getkey(K_UPPER); + console.print(cmd); + switch(cmd) { + case 'D': if (user.compare_ars("REST NOT D")) { + writeln('\r\n\x86' + gettext("Download File(s) from User(s)")); + shell.download_user_files(); + } + continue main; + case 'F': writeln('\r\n\x86' + gettext("Find Text in Messages")); + bbs.scan_subs(SCAN_FIND); + continue main; + case 'N': bbs.scan_subs(SCAN_NEW, /* all */true); + continue main; + case 'U': writeln('\r\n\x86' + gettext("Upload File to User")); + shell.upload_user_file(); + continue main; + case 'O': shell.logoff(/* fast: */true); + continue main; + case 'S': bbs.scan_subs(SCAN_TOYOU, /* all */true) + continue main; + case '*': shell.show_grps(); + continue main; + case '#': writeln('\r\n\x86' + gettext("Type the actual number, not the symbol.")); + console.pause(); + continue main; + } + + if(cmd >= '1' && cmd <= '9') { + shell.get_grp_num(cmd); + continue; + } + + } + console.home(); + console.aborted = false; +} diff --git a/exec/noyesbar.js b/exec/noyesbar.js index 7855eb7c434bf192d5e875d07560f56265849948..bd97f405396617adf238f1144ef82484e0c4f83d 100644 --- a/exec/noyesbar.js +++ b/exec/noyesbar.js @@ -8,6 +8,10 @@ const yes_key = yes_str[0]; const no_str = bbs.text(bbs.text.No); const no_key = no_str[0]; +var options = load("modopts.js", "noyesbar"); +if(!options) + options = {}; + while(console.question.substring(0, 2) == "\r\n") { console.crlf(); console.question = console.question.substring(2); @@ -18,18 +22,21 @@ if(console.question.substring(0, 2) == "\x01\?") { console.question = console.question.substring(2); } -console.putmsg("\x01n\x01b\x01h[\x01c@CHECKMARK@\x01b] \x01y@QUESTION->@? @CLEAR_HOT@", P_NOABORT); +console.putmsg(options.noyes_question || "\x01n\x01b\x01h[\x01c@CHECKMARK@\x01b] \x01y@QUESTION->@? @CLEAR_HOT@", P_NOABORT); var affirm = false; while(bbs.online && !js.terminated) { var str; if(affirm) - str = format("\x01n\x01b\x01h \x01~%s \x014\x01w\x01e[\x01~%s]", no_str, yes_str); + str = format(options.highlight_yes_fmt || "\x01n\x01b\x01h \x01~%s \x014\x01w\x01e[\x01~%s]", no_str, yes_str); else - str = format("\x01h\x014\x01w\x01e[\x01~%s]\x01n\x01b\x01h \x01~%s ", no_str, yes_str); + str = format(options.highlight_no_fmt || "\x01h\x014\x01w\x01e[\x01~%s]\x01n\x01b\x01h \x01~%s ", no_str, yes_str); console.print(str); var key = console.getkey(0).toUpperCase(); console.backspace(console.strlen(str)); - console.print("\x01n\x01h\x01>"); + if(console.term_supports(USER_MODE7)) + console.print(" "); + else + console.print("\x01n\x01h\x01>"); if(console.aborted) break; if(key == '\r') diff --git a/exec/yesnobar.js b/exec/yesnobar.js index 6b64c4a4ec27358821639318a3b1e7b120374260..1b7f454cedc61cb1291fbeb9f4d8d3392d4dee2b 100644 --- a/exec/yesnobar.js +++ b/exec/yesnobar.js @@ -1,5 +1,4 @@ // JS version of yesnobar.src - require("sbbsdefs.js", "P_NOABORT"); "use strict"; @@ -9,6 +8,10 @@ const yes_key = yes_str[0]; const no_str = bbs.text(bbs.text.No); const no_key = no_str[0]; +var options = load("modopts.js", "yesnobar"); +if(!options) + options = {}; + while(console.question.substring(0, 2) == "\r\n") { console.crlf(); console.question = console.question.substring(2); @@ -19,18 +22,22 @@ if(console.question.substring(0, 2) == "\x01\?") { console.question = console.question.substring(2); } -console.putmsg("\x01n\x01b\x01h[\x01c@CHECKMARK@\x01b] \x01y@QUESTION->@? @CLEAR_HOT@", P_NOABORT); +console.putmsg(options.yesno_question || "\x01n\x01b\x01h[\x01c@CHECKMARK@\x01b] \x01y@QUESTION->@? @CLEAR_HOT@", P_NOABORT); var affirm = true; while(bbs.online && !js.terminated) { var str; if(affirm) - str = format("\x01h\x014\x01w\x01e[\x01~%s]\x01n\x01b\x01h \x01~%s ", yes_str, no_str); + str = format(options.highlight_yes_fmt || "\x01n\x01b\x01h \x01~%s \x014\x01w\x01e[\x01~%s]", no_str, yes_str); else - str = format("\x01n\x01b\x01h \x01~%s \x014\x01w\x01e[\x01~%s]", yes_str, no_str); + str = format(options.highlight_no_fmt || "\x01h\x014\x01w\x01e[\x01~%s]\x01n\x01b\x01h \x01~%s ", no_str, yes_str); console.print(str); var key = console.getkey(0).toUpperCase(); console.backspace(console.strlen(str)); - console.print("\x01n\x01h\x01>"); + if(console.term_supports(USER_MODE7)) + console.print(" "); + else + console.print("\x01n\x01h\x01>"); + if(console.aborted) break; if(key == '\r') diff --git a/src/sbbs3/answer.cpp b/src/sbbs3/answer.cpp index 2c0e2921b3ffc0d37c23498349bd229259306fea..62a45ca9c90d96e09a96b6f98c98f7154eb8c2a1 100644 --- a/src/sbbs3/answer.cpp +++ b/src/sbbs3/answer.cpp @@ -553,6 +553,9 @@ bool sbbs_t::answer() SAFECOPY(terminal, "PETSCII"); outchar(FF); center(str); + } else if (autoterm & MODE7) { + SAFECOPY(terminal, "MODE7"); + center(str); } else { /* ANSI+ terminal detection */ putcom( "\r\n" /* locate cursor at column 1 */ "\x1b[s" /* save cursor position (necessary for HyperTerm auto-ANSI) */ diff --git a/src/sbbs3/ars.c b/src/sbbs3/ars.c index 9f1a995d163580a4b065c21997986bc4e3685beb..2719f0a12b8bc78eaeb92c51c0a093f6a65abfca 100644 --- a/src/sbbs3/ars.c +++ b/src/sbbs3/ars.c @@ -337,6 +337,10 @@ uchar* arstr(ushort* count, const char* str, scfg_t* cfg, uchar* ar_buf) artype = AR_PETSCII; i += 6; } + else if (!strnicmp(str + i, "MODE7", 5)) { + artype = AR_MODE7; + i += 4; + } else if (!strnicmp(str + i, "ASCII", 5)) { artype = AR_ASCII; i += 4; diff --git a/src/sbbs3/ars_defs.h b/src/sbbs3/ars_defs.h index 9d4c003bd56fc9f698e2c0afb553465cc2dbf7ee..fa5de5060506dd44ac5a15925e94555ad985a0bd 100644 --- a/src/sbbs3/ars_defs.h +++ b/src/sbbs3/ars_defs.h @@ -116,6 +116,7 @@ enum { /* Access requirement binaries */ , AR_UTF8 , AR_CP437 , AR_USERNAME + , AR_MODE7 }; enum ar_type { @@ -148,6 +149,7 @@ static inline enum ar_type ar_type(int artype) case AR_GUEST: case AR_QNODE: case AR_QUIET: + case AR_MODE7: return AR_BOOL; case AR_SUBCODE: case AR_DIRCODE: diff --git a/src/sbbs3/chk_ar.cpp b/src/sbbs3/chk_ar.cpp index 731c0796b78d46537d57d721a3d894fb33bf63a1..ca0e4e71895de359263d736c0002b78bc3704bb9 100644 --- a/src/sbbs3/chk_ar.cpp +++ b/src/sbbs3/chk_ar.cpp @@ -128,6 +128,20 @@ bool sbbs_t::ar_exp(const uchar **ptrptr, user_t* user, client_t* client) noaccess_val = PETSCII; } break; + case AR_MODE7: + { + int val = term_supports(); + val &= CHARSET_FLAGS; + if (val != CHARSET_MODE7) + result = _not; + else + result = !_not; + if (!result) { + noaccess_str = text[NoAccessTerminal]; + noaccess_val = MODE7; + } + } + break; case AR_ASCII: if ((term_supports() & CHARSET_FLAGS) != CHARSET_ASCII) result = _not; diff --git a/src/sbbs3/con_out.cpp b/src/sbbs3/con_out.cpp index eda850dfd58735ff572b3578b1b69face90ef4a9..c1b99074afa16b95ce9e8db05e7630ac5d085049 100644 --- a/src/sbbs3/con_out.cpp +++ b/src/sbbs3/con_out.cpp @@ -245,6 +245,11 @@ unsigned char cp437_to_petscii(unsigned char ch) return ch; } +unsigned char cp437_to_mode7(unsigned char ch) +{ + return ch; +} + /* Perform PETSCII conversion to ANSI-BBS/CP437 */ int sbbs_t::petscii_to_ansibbs(unsigned char ch) { @@ -539,6 +544,9 @@ char* sbbs_t::term_type(user_t* user, int term, char* str, size_t size) if (term & PETSCII) safe_snprintf(str, size, "%sCBM/PETSCII" , (user->misc & AUTOTERM) ? text[TerminalAutoDetect] : nulstr); + else if (term & MODE7) + safe_snprintf(str, size, "%s/MODE7" + , (user->misc & AUTOTERM) ? text[TerminalAutoDetect] : nulstr); else safe_snprintf(str, size, "%s%s / %s %s%s%s" , (user->misc & AUTOTERM) ? text[TerminalAutoDetect] : nulstr @@ -560,6 +568,8 @@ const char* sbbs_t::term_type(int term) term = term_supports(); if (term & PETSCII) return "PETSCII"; + if (term & MODE7) + return "MODE7"; if (term & RIP) return "RIP"; if (term & ANSI) @@ -576,6 +586,8 @@ const char* sbbs_t::term_charset(int term) term = term_supports(); if (term & PETSCII) return "CBM-ASCII"; + if (term & MODE7) + return "MODE7"; if (term & UTF8) return "UTF-8"; if (term & NO_EXASCII) diff --git a/src/sbbs3/logon.cpp b/src/sbbs3/logon.cpp index 5c3022c0ca380c9de4a733f1f2ae481bbe579d4c..f9231b09299086e9e9d69e2b3b2eee91f41235c0 100644 --- a/src/sbbs3/logon.cpp +++ b/src/sbbs3/logon.cpp @@ -182,8 +182,8 @@ bool sbbs_t::logon() } if ((useron.misc & AUTOTERM) - // User manually-enabled PETSCII, but they're logging in with an ANSI (auto-detected) terminal - || ((useron.misc & PETSCII) && (autoterm & ANSI))) { + // User manually-enabled PETSCII or MODE7, but they're logging in with an ANSI (auto-detected) terminal + || (((useron.misc & PETSCII) || (useron.misc & MODE7)) && (autoterm & ANSI))) { useron.misc &= ~(ANSI | RIP | CHARSET_FLAGS); useron.misc |= (AUTOTERM | autoterm); } diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp index 20bea4fad629d17e756a4f979553c6aba448d9f9..2b6feda0e5e27b13f3de3010491ec3b867a7e1c2 100644 --- a/src/sbbs3/main.cpp +++ b/src/sbbs3/main.cpp @@ -24,6 +24,7 @@ #include "telnet.h" #include "netwrap.h" #include "petdefs.h" +#include "mode7defs.h" #include "filedat.h" #include "js_rtpool.h" #include "js_request.h" @@ -5663,6 +5664,12 @@ NO_SSH: sbbs->outcom(PETSCII_UPPERLOWER); } + if (inet_addrport(&local_addr) == startup->mode7_port) { + sbbs->autoterm = MODE7; + sbbs->cols = 40; + sbbs->rows = 25; + } + sbbs->bprintf("\r\n%s\r\n", VERSION_NOTICE); sbbs->bprintf("%s connection from: %s\r\n", client.protocol, host_ip); diff --git a/src/sbbs3/newuser.cpp b/src/sbbs3/newuser.cpp index 7775414cbce12091cdd0ec6a671a3907227456c2..e46c3b31bbecabdca9381bb9e8e0b4f0ea6b93c5 100644 --- a/src/sbbs3/newuser.cpp +++ b/src/sbbs3/newuser.cpp @@ -153,6 +153,9 @@ bool sbbs_t::newuser() autoterm |= PETSCII; outcom(PETSCII_UPPERLOWER); bputs(text[PetTerminalDetected]); + } else if (useron.misc & MODE7) { + autoterm |= MODE7; + bputs(text[Mode7TerminalDetected]); } else { if (!yesno(text[ExAsciiTerminalQ])) useron.misc |= NO_EXASCII; diff --git a/src/sbbs3/prntfile.cpp b/src/sbbs3/prntfile.cpp index caf470b4d592e6bde3d03d8168c089600c02f968..71fc770859255035c1cb83f0a0cd25b5783c3e02 100644 --- a/src/sbbs3/prntfile.cpp +++ b/src/sbbs3/prntfile.cpp @@ -22,6 +22,7 @@ #include "sbbs.h" #include "utf8.h" #include "petdefs.h" +#include "mode7defs.h" #ifndef PRINTFILE_MAX_LINE_LEN #define PRINTFILE_MAX_LINE_LEN (8 * 1024) @@ -54,6 +55,8 @@ bool sbbs_t::printfile(const char* fname, int mode, int org_cols, JSObject* obj) mode |= P_NOPAUSE; } else if (stricmp(p, ".seq") == 0) { mode |= P_PETSCII; + } else if (stricmp(p, ".m7") == 0) { + mode |= P_MODE7; } else if (stricmp(p, ".utf8") == 0) { mode |= P_UTF8; } @@ -283,6 +286,8 @@ bool sbbs_t::menu(const char *code, int mode, JSObject* obj) break; if ((term & PETSCII) && menu_exists(code, "seq", path)) break; + if ((term & MODE7) && menu_exists(code, "m7", path)) + break; if (term & NO_EXASCII) { next = "asc"; last = "msg"; diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h index 5723daed8b26cf8d187b611ab81eb8725a6efe72..411a1cfe29b9a60b323e2d88d2bdf32fa42247a5 100644 --- a/src/sbbs3/sbbs.h +++ b/src/sbbs3/sbbs.h @@ -981,6 +981,7 @@ public: bool saveline(void); bool restoreline(void); int petscii_to_ansibbs(unsigned char); + int mode7_to_ansibbs(unsigned char); size_t print_utf8_as_cp437(const char*, size_t); int attr(int); /* Change text color/attributes */ void ctrl_a(char); /* Performs Ctrl-Ax attribute changes */ @@ -1431,6 +1432,7 @@ extern "C" { /* con_out.cpp */ unsigned char cp437_to_petscii(unsigned char); + unsigned char cp437_to_mode7(unsigned char); /* xtrn.cpp */ bool native_executable(scfg_t*, const char* cmdline, int mode); diff --git a/src/sbbs3/sbbs_ini.c b/src/sbbs3/sbbs_ini.c index 6ba8123a248e3d6ef0b829f1123d27e8b64ef41e..a550ea306b5dae49a82d0b94f75f0c4d67beb2a9 100644 --- a/src/sbbs3/sbbs_ini.c +++ b/src/sbbs3/sbbs_ini.c @@ -448,6 +448,9 @@ void sbbs_read_ini( bbs->pet80_port = iniGetShortInt(list, section, "Pet80Port", 128); + bbs->mode7_port + = iniGetShortInt(list, section, "Mode7Port", 5050); + bbs->ssh_port = iniGetShortInt(list, section, "SSHPort", 22); bbs->ssh_connect_timeout @@ -936,6 +939,9 @@ bool sbbs_write_ini( if (!iniSetUInt16(lp, section, "Pet80Port", bbs->pet80_port, &style)) break; + if (!iniSetUInt16(lp, section, "Mode7Port", bbs->mode7_port, &style)) + break; + if (strListCmp(bbs->ssh_interfaces, global->interfaces) == 0) iniRemoveValue(lp, section, "SSHInterface"); else if (!iniSetStringList(lp, section, "SSHInterface", ",", bbs->ssh_interfaces, &style)) diff --git a/src/sbbs3/sbbsdefs.h b/src/sbbs3/sbbsdefs.h index b4c285ca30ff6749abdf4cfbb99d3d040cae085a..d1ac52f537dd1b404a64e25024b74b548ffe64a1 100644 --- a/src/sbbs3/sbbsdefs.h +++ b/src/sbbs3/sbbsdefs.h @@ -568,7 +568,7 @@ typedef enum { /* Values for xtrn_t.event */ #define COLDKEYS (1 << 18) /* No hot-keys */ #define EXTDESC (1 << 19) /* Extended file descriptions */ #define AUTOHANG (1 << 20) /* Auto-hang-up after transfer */ -#define WIP_UNUSED (1 << 21) /* Supports WIP terminal emulation */ +#define MODE7 (1 << 21) /* BBC Micro Mode 7 terminal support */ #define AUTOLOGON (1 << 22) /* AutoLogon via IP */ #define HTML_UNUSED (1 << 23) /* Using Zuul/HTML terminal */ #define NOPAUSESPIN (1 << 24) /* No spinning cursor at pause prompt */ @@ -579,9 +579,10 @@ typedef enum { /* Values for xtrn_t.event */ #define MOUSE (1U << 31) /* Mouse supported terminal */ #define TERM_FLAGS (ANSI | COLOR | RIP | SWAP_DELETE | ICE_COLOR | MOUSE | CHARSET_FLAGS) -#define CHARSET_FLAGS (NO_EXASCII | PETSCII | UTF8) +#define CHARSET_FLAGS (NO_EXASCII | PETSCII | UTF8 | MODE7) #define CHARSET_ASCII NO_EXASCII // US-ASCII #define CHARSET_PETSCII PETSCII // CBM-ASCII +#define CHARSET_MODE7 MODE7 // MODE 7 #define CHARSET_UTF8 UTF8 #define CHARSET_CP437 0 @@ -694,6 +695,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_MODE7 (1 << 21) /* Message is native Mode 7 */ /* Bits in 'mode' for listfiles */ #define FL_ULTIME (1 << 0) /* List files by upload time */ diff --git a/src/sbbs3/scfg/scfgsrvr.c b/src/sbbs3/scfg/scfgsrvr.c index 4e870ce2c329fc8f21cea5a16772890ab52b3cd1..b52ce44848a1a2d0c40a7a0798025b57f6ed6be4 100644 --- a/src/sbbs3/scfg/scfgsrvr.c +++ b/src/sbbs3/scfg/scfgsrvr.c @@ -557,6 +557,8 @@ static void termsrvr_cfg(void) snprintf(opt[i++], MAX_OPLN, "%-30s%s", "40 Column PETSCII Support", startup.pet40_port ? str : strDisabled ); snprintf(str, sizeof str, "Port %u", startup.pet80_port); snprintf(opt[i++], MAX_OPLN, "%-30s%s", "80 Column PETSCII Support", startup.pet80_port ? str : strDisabled); + snprintf(str, sizeof str, "Port %u", startup.mode7_port); + snprintf(opt[i++], MAX_OPLN, "%-30s%s", "BBC Mode 7 Support", startup.mode7_port ? str : strDisabled); snprintf(opt[i++], MAX_OPLN, "%-30s%s", "DOS Program Support", startup.options & BBS_OPT_NO_DOS ? "No" : "Yes"); snprintf(opt[i++], MAX_OPLN, "%-30s%s", "Max Concurrent Connections", maximum(startup.max_concurrent_connections)); snprintf(opt[i++], MAX_OPLN, "%-30s%s", "Max Login Inactivity", vduration(startup.max_login_inactivity)); @@ -621,9 +623,14 @@ static void termsrvr_cfg(void) startup.pet80_port = atoi(str); break; case 8: - startup.options ^= BBS_OPT_NO_DOS; + SAFEPRINTF(str, "%u", startup.mode7_port); + if (uifc.input(WIN_MID | WIN_SAV, 0, 0, "BBC Mode 7 Port", str, 5, K_NUMBER | K_EDIT) > 0) + startup.mode7_port = atoi(str); break; case 9: + startup.options ^= BBS_OPT_NO_DOS; + break; + case 10: SAFECOPY(str, maximum(startup.max_concurrent_connections)); if (uifc.input(WIN_MID | WIN_SAV, 0, 0, "Maximum Concurrent (Unauthenticated) Connections", str, 10, K_EDIT) > 0) startup.max_concurrent_connections = atoi(str); @@ -637,7 +644,7 @@ static void termsrvr_cfg(void) "`Maximum User Inactivity` setting in `System->Advanced Options`.\n" \ "Normally, if enabled, this socket inactivity duration should be `longer`\n" \ "than the `Maximum User Inactivity` setting in `System->Advanced Options`.\n" - case 10: + case 11: uifc.helpbuf = "`Maximum Socket Inactivity at Login:`\n" "\n" @@ -651,7 +658,7 @@ static void termsrvr_cfg(void) if (uifc.input(WIN_MID | WIN_SAV, 0, 0, "Maximum Socket Inactivity at Login", str, 10, K_EDIT) > 0) startup.max_login_inactivity = (uint16_t)parse_duration(str); break; - case 11: + case 12: uifc.helpbuf = "`Maximum Socket Inactivity at New User Registration:`\n" "\n" @@ -665,7 +672,7 @@ static void termsrvr_cfg(void) if (uifc.input(WIN_MID | WIN_SAV, 0, 0, "Maximum Socket Inactivity at New User Registration", str, 10, K_EDIT) > 0) startup.max_newuser_inactivity = (uint16_t)parse_duration(str); break; - case 12: + case 13: uifc.helpbuf = "`Maximum Socket Inactivity during User Session:`\n" "\n" @@ -681,34 +688,34 @@ static void termsrvr_cfg(void) if (uifc.input(WIN_MID | WIN_SAV, 0, 0, "Maximum Socket Inactivity during User Session", str, 10, K_EDIT) > 0) startup.max_session_inactivity = (uint16_t)parse_duration(str); break; - case 13: + case 14: SAFEPRINTF(str, "%u", startup.outbuf_drain_timeout); if (uifc.input(WIN_MID | WIN_SAV, 0, 0, "Output Buffer Drain Timeout (milliseconds)", str, 5, K_NUMBER | K_EDIT) > 0) startup.outbuf_drain_timeout = atoi(str); break; - case 14: + case 15: startup.options ^= BBS_OPT_NO_EVENTS; break; - case 15: + case 16: if (startup.options & BBS_OPT_NO_EVENTS) break; startup.options ^= BBS_OPT_NO_QWK_EVENTS; break; - case 16: + case 17: if (startup.options & BBS_OPT_NO_EVENTS) break; uifc.list(WIN_MID | WIN_SAV, 0, 0, 0, &startup.event_log_level, 0, "Event Log Level", iniLogLevelStringList()); break; - case 17: + case 18: startup.options ^= BBS_OPT_NO_HOST_LOOKUP; break; - case 18: + case 19: getar("Terminal Server Login", startup.login_ars); break; - case 19: + case 20: js_startup_cfg(&startup.js); break; - case 20: + case 21: login_attempt_cfg(&startup.login_attempt); break; default: diff --git a/src/sbbs3/startup.h b/src/sbbs3/startup.h index bdefe555fa193011286cd3cfa2cb413fa11f5562..58d70b865b0b061d800183465725120bec13e4d7 100644 --- a/src/sbbs3/startup.h +++ b/src/sbbs3/startup.h @@ -129,6 +129,7 @@ typedef struct { uint16_t rlogin_port; uint16_t pet40_port; // 40-column PETSCII terminal server uint16_t pet80_port; // 80-column PETSCII terminal server + uint16_t mode7_port; // 40-column MODE7 terminal server uint16_t ssh_port; uint16_t ssh_connect_timeout; int ssh_error_level; diff --git a/src/sbbs3/text.h b/src/sbbs3/text.h index b7097f503eed638ef00d6fed431f9992b659714b..548c2785b4a2b4657e58cdec9e733bd89e6bcfbc 100644 --- a/src/sbbs3/text.h +++ b/src/sbbs3/text.h @@ -954,6 +954,8 @@ enum text { ,QWKTagLineFmt ,QWKControlCommand ,QWKBadControlCommand + ,Mode7TerminalDetected + ,Mode7TerminalQ ,TOTAL_TEXT }; diff --git a/src/sbbs3/text_defaults.c b/src/sbbs3/text_defaults.c index 6c568a1ec92a09c016bd58b7e79df623d1717d92..4929b181ae183e41338039a77992e5f9c61b8308 100644 --- a/src/sbbs3/text_defaults.c +++ b/src/sbbs3/text_defaults.c @@ -1507,4 +1507,6 @@ const char * const text_defaults[TOTAL_TEXT]={ "\x25\x73\x0d\x0a" // 936 QWKControlCommand ,"\x55\x6e\x72\x65\x63\x6f\x67\x6e\x69\x7a\x65\x64\x20\x43\x6f\x6e\x74\x72\x6f\x6c\x20\x43\x6f\x6d\x6d\x61\x6e\x64\x21\x01\x6e\x0d" "\x0a" // 937 QWKBadControlCommand + ,"\x4d\x6f\x64\x65\x20\x37\x20\x74\x65\x72\x6d\x69\x6e\x61\x6c\x20\x64\x65\x74\x65\x63\x74\x65\x64" // 938 Mode7TerminalDetected + ,"\x41\x72\x65\x20\x79\x6f\x75\x20\x75\x73\x69\x6e\x67\x20\x61\x20\x4d\x6f\x64\x65\x20\x37\x20\x74\x65\x72\x6d\x69\x6e\x61\x6c" // 939 Mode7TerminalQ }; diff --git a/src/sbbs3/text_id.c b/src/sbbs3/text_id.c index abf977c9445570075c159292bff0b606057a8b66..213aaf14910484fdbf7ab7e5dedf661c15e9e61b 100644 --- a/src/sbbs3/text_id.c +++ b/src/sbbs3/text_id.c @@ -938,4 +938,6 @@ const char* const text_id[]={ ,"QWKTagLineFmt" ,"QWKControlCommand" ,"QWKBadControlCommand" + ,"Mode7TerminalDetected" + ,"Mode7TerminalQ" }; diff --git a/src/sbbs3/userdat.c b/src/sbbs3/userdat.c index 5d28ebe2d623d03a4696546f1268e02b7851b8a2..9049296eb10243cf73eeef145363c52200663bd3 100644 --- a/src/sbbs3/userdat.c +++ b/src/sbbs3/userdat.c @@ -2177,6 +2177,12 @@ static bool ar_exp(scfg_t* cfg, uchar **ptrptr, user_t* user, client_t* client) else result = !not; break; + case AR_MODE7: + if (user == NULL || (user->misc & CHARSET_FLAGS) != CHARSET_MODE7) + result = not; + else + result = !not; + break; case AR_ASCII: if (user == NULL || (user->misc & CHARSET_FLAGS) != CHARSET_ASCII) result = not; diff --git a/src/sbbs3/useredit.cpp b/src/sbbs3/useredit.cpp index eddc505f0c8ae7079745aea518b8998185ddcecb..77d9366f6c0fff9fb48cb4c007421ccb2b1db702 100644 --- a/src/sbbs3/useredit.cpp +++ b/src/sbbs3/useredit.cpp @@ -880,7 +880,7 @@ void sbbs_t::user_config(user_t* user) case 'T': if (yesno(text[AutoTerminalQ])) { user->misc |= AUTOTERM; - user->misc &= ~(ANSI | RIP | PETSCII | UTF8); + user->misc &= ~(ANSI | RIP | PETSCII | UTF8 | MODE7); if (user == &useron) user->misc |= autoterm; } diff --git a/src/sbbs3/xtrn.cpp b/src/sbbs3/xtrn.cpp index 69b8ef8cd43ae9b28d5c2094b0288c463cf02255..152d43e00fc9d1f54dc7d70556f135ab33cc3dd1 100644 --- a/src/sbbs3/xtrn.cpp +++ b/src/sbbs3/xtrn.cpp @@ -214,6 +214,13 @@ static void petscii_convert(BYTE* buf, uint len) } } +static void mode7_convert(BYTE* buf, uint len) +{ + for (uint i = 0; i < len; i++) { + buf[i] = cp437_to_mode7(buf[i]); + } +} + static BYTE* cp437_to_utf8(BYTE* input, size_t& len, BYTE* outbuf, size_t maxlen) { size_t outlen = 0; @@ -1961,6 +1968,8 @@ int sbbs_t::external(const char* cmdline, int mode, const char* startup_dir) } if (term_supports(PETSCII)) petscii_convert(bp, output_len); + else if (term_supports(MODE7)) + mode7_convert(bp, output_len); else if (term_supports(UTF8)) bp = cp437_to_utf8(bp, output_len, utf8_buf, sizeof utf8_buf); } diff --git a/src/xpdev/mode7defs.h b/src/xpdev/mode7defs.h new file mode 100644 index 0000000000000000000000000000000000000000..4dd59ca0b342eba35cc46599db3e2e81d79abef8 --- /dev/null +++ b/src/xpdev/mode7defs.h @@ -0,0 +1,72 @@ +/* Commodore/PET definitions */ + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * See the GNU Lesser General Public License for more details: lgpl.txt or * + * http://www.fsf.org/copyleft/lesser.html * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ +#ifndef _MODE7DFS_H_ +#define _MODE7DEFS_H_ + +enum mode7_char { + /* Colors */ + MODE7_ALPHA_RED = 129, + MODE7_ALPHA_GREEN = 130, + MODE7_ALPHA_YELLOW = 131, + MODE7_ALPHA_BLUE = 132, + MODE7_ALPHA_MAGENTA = 133, + MODE7_ALPHA_CYAN = 134, + MODE7_ALPHA_WHITE = 135, + MODE7_FLASH = 136, + MODE7_STEADY = 137, + MODE7_NORMAL_HEIGHT = 140, + MODE7_DOUBLE_HEIGHT = 141, + MODE7_GRAPHIC_RED = 145, + MODE7_GRAPHIC_GREEN = 146, + MODE7_GRAPHIC_YELLOW = 147, + MODE7_GRAPHIC_BLUE = 148, + MODE7_GRAPHIC_MAGENTA = 149, + MODE7_GRAPHIC_CYAN = 150, + MODE7_GRAPHIC_WHITE = 151, + MODE7_CONCEAL = 152, + MODE7_CONTIGUOUS_GFX = 153, + MODE7_SEPARATED_GFX = 154, + MODE7_BLACK_BG = 156, + MODE7_NEW_BG = 157, + MODE7_HOLD_GFX = 158, + MODE7_RELEASE_GFX = 159, + + /* Cursor movement */ + MODE7_LEFT = 8, + MODE7_RIGHT = 9, + MODE7_DOWN = 10, + MODE7_UP = 11, + MODE7_HOME = 30, + MODE7_CLEAR = 12, + /* Symbols (which don't align with ASCII) */ + MODE7_BRITPOUND = 96, + MODE7_QUARTER = 123, + MODE7_HALF = 92, + MODE7_THREE_QUARTER = 125, + MODE7_DIVIDE = 126 + /* Replacement chars (missing ASCII chars) */ +// PETSCII_BACKSLASH = '/', // the 109 graphics char is an 'M' in shifted/text mode :-( +// PETSCII_BACKTICK = 0xAD, // a graphics char actually +// PETSCII_TILDE = 0xA8, // a graphics char actually +// PETSCII_UNDERSCORE = 0xA4, // a graphics char actually +}; + +#endif /* Don't add anything after this line */ diff --git a/text/answer.m7 b/text/answer.m7 new file mode 100644 index 0000000000000000000000000000000000000000..e491c9f7c4a808c5507a03d5f0f1e516c8468aa9 --- /dev/null +++ b/text/answer.m7 @@ -0,0 +1,15 @@ +Åù ó|,$|h4xl0|,h<th<|_<th<(|$ Åùó s{5s{5ˇj5ˇpj7}juˇj5ˇjw ˇ ë///////,,.,,.,-.,,-.,-,,-.,-,/,//////// +CLIENT +ÜCONN: @CONN@ +ÜADDR: @HOST@ +ÜIP : @IP@ +SERVER +ÜNAME:É@BBS@ +ÜADDR: @HOSTNAME@ +ÜNODE: @NODE@ (of @TNODE@) +ÜTIME: @DATETIME@ @TIMEZONE@ +ÜADMN: @SYSOP@ + +ÖIf you are a new user to the system, +ÖtypeÜ"New"Önow. Otherwise enter your +Öusername or number now. diff --git a/text/bullseye.m7 b/text/bullseye.m7 new file mode 100755 index 0000000000000000000000000000000000000000..343c8a2e314495e2f76360f0609d4c4b7b2148e2 --- /dev/null +++ b/text/bullseye.m7 @@ -0,0 +1,6 @@ +@CLS@Åùó|l4|h4| | |$l<h4x|0|,ÉLast updated: úÅùóˇ{4oz%ˇ0ˇ0ˇ1j5j5ˇj5sˇÉFeb 5 2025 úë//,,.-,/,.,.,.-.-.,-.,,/////////////// ì7````````````````````````````````````k ì5ÑùÉ1 - Statistics for úìj ì5ÑùÉ@BBS-L........................@úìj +ì5 j +ì5ÑùÉ2 - New user instructions úìj ì5 j ì5ÑùÉ3 - About Synchronet úìj ì5 j ì5 j ì5 j ì5 j ì5 j ì`````````````````````````````````````` + +@EOF@ +https://zxnet.co.uk/teletext/editor/#0:QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECACdL_NjT5oafEHxB8SbHmhp4-MPiwHMw8-iDrwyYemXI6QHAJ0v_9tN_pL_Yf2H9jqa6mv_U15_wcbLiQNUDJgyaoECBAcIr16xYuWrF6xcsXLFy1ctXLFq5YsXr169evXr169evXr16BAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQICbdGjRo0aNGjRo0aNGjRo0aNGjRo0aNGjRo0aNGjRo0aPWgJtQh0GxQLUFPph6aefTTj5oM2_kgQIECBAgQIECBAgOE9SAm1CHQcCFCprZi5cuXLly5cuXLly5cuXLly5cuXLoCA4T1ICbVAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECDUgJtQh0GyQLUE7L3QdeeXkg07ufTl1x9NO_dzQIECBAgOE9SAm1QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAg1ICbUIdBs0C1BBxb-vRBT87sejlv3ZeiBAgQIECBAgQIDhPUgJtUCBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQINSAm1QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAg1ICbVAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECDUgJtUCBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQINSAm1QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAg1ICaNGjRo0aNGjRo0aNGjRo0aNGjRo0aNGjRo0aNGjRo0aNGgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECA:PS=0:RE=0:zx=Jm00 diff --git a/text/menu/mode7/mode7_chat.m7 b/text/menu/mode7/mode7_chat.m7 new file mode 100755 index 0000000000000000000000000000000000000000..ac048cba1e8a2e540ba2a3a21cefee0368ce2eda --- /dev/null +++ b/text/menu/mode7/mode7_chat.m7 @@ -0,0 +1,4 @@ +@CLS@Åùó|,h4h4xl0l< ÉPlease use chat úÅùóˇpj7k5ˇk5j5 Éresponsibly. úë//,,-.-.,-.-.///////////////////////// ÉùÑ(C)hat multinode úÉùÑ(N)ode to Node Chat úÉùÑ(Y)ell for the Sysop úÉùÑ(T)alk with the AI Guru úÉùÑ(F)inger Remote Query úÉùÑ(R)elay Chat (IRC) úÉùÑ(I)nter BBS Instant Messaging úÉùÑ(M)ulti Relay Chat úÉùÑ úÑù úÑùÉ(A)ctivity Alerts : @ALERTS|L3@ úÑùÉ(P)aging Allowed : @PAGER|L3@ úÑùÉ(S)plit Screen Chat : @SPLITP|L3@ ú@SHOW:!SYSOP@ÑùÜThe Sysop is: @SYSAVAIL|L18@ ú@SHOW@@SHOW:SYSOP@ÑùÉ(E)nable Paging : @SYSAVAILYN|L3@ úÑù ú@SHOW@Åùá (Q)uit to main menu ú + +@EOF@ +https://zxnet.co.uk/teletext/editor/#0:QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECACdL_FmhpoaeNjDY8QIEAOhsy4eeVB155UGPRh6IECBAgQHAJ0v_4am-tr_1tdTVAgQA-WXnw37uenFs8rkCBAgQIECBAcIr16xYtXLVyxauWrl69evXr169evXr169evXr169evXr16BAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIAZ0IohqdGHog29dnTTu35MqBAgQIECBAgQIECBAgQIECBAcBnQiicp35MqDpvQTt-TKgh6MPRAgQIECBAgQIECBAgQIEBwGdCKLKnLs2IM2_kg6aMqCn557-CBAgQIECBAgQIECBAgQHAZ0IoqKcOzWg76emhB00ZUEGSgj9eXVAgQIECBAgQIECBAcBnQiiMp07s-XkgpZdu_plQUeuXl5QIECBAgQIECBAgQIEBwGdCKKSnLsw-UEPRh6IFEmlDUoECBAgQIECBAgQIECBAgQHAZ0Iokqd3TLyQQoVNBJ3c-mHd0QTcvPnhz6d2dAgQIECBAcBnQiiap67OmlBSy7MPlBD0YeiBAgQIECBAgQIECBAgQIEBwGdCIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQHAh0GogqcfTT209PKCDsy8unNAgQOkECDMi0qlP5MZwECBAcCHQaigpw59O7Ogg7Nm_vlyIECBA6QQKEGPFpfJjOAgQIEBwIdBqKanhs09EFPHyy5dyCHow9EDpBAp0JkmpQ-TGcBAgQHAh0NApyJ9dAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAcBnQiBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIEBwYgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIBiBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECA:PS=0:RE=0:zx=XN00 diff --git a/text/menu/mode7/mode7_email.m7 b/text/menu/mode7/mode7_email.m7 new file mode 100755 index 0000000000000000000000000000000000000000..2b94aef1be9f781584ea318279404052c623a444 --- /dev/null +++ b/text/menu/mode7/mode7_email.m7 @@ -0,0 +1,4 @@ +@CLS@Åùó|,_<<t_<th4| ÉSending of spam is úÅùóˇsj55ˇj7ˇj5ˇp Éstrictly prohibited. úë//,,-..,-.,-.,,/////////////////////// î7````````````````````````````````````k î5 ìppppppîj î5 ì54<4 jîj î5 ì55`5wjîj î5 ì-,,,,.îj î5 j î5É(S) Send Local, QWK, or Email îj î5É(R) Read email sent to you îj î5É(U) Read your unread messages îj î5É(E) Email the Sysop îj î5É(F) Find text in emails îj î5É(K) Kill/Read sent mail îj î5 j î5 É (Q)uit to main menu îj î5 j î`````````````````````````````````````` + +@EOF@ +https://zxnet.co.uk/teletext/editor/`0:QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECACdL_FmB486YHnTQ0-IEAOnl3ZNO7Og35kHPhh2oNPNAgQHAJ0v_56mrX_qb_9TX_wQA-fTlpx9NnlBw5b9GnFp6Zci5AcIr16xYtXLli1csWrlixevXr169evXr169evXr169evXr16BAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQICjdGjRo0aNGjRo0aNGjRo0aNGjRo0aNGjRo0aNGjRo0aPWgKNUCBAgQIECBAgQIECBAgQIECBAgQIECBAgJ8OHDhw4FNSAo1QIECBAgQIECBAgQIECBAgQIECBAgQIECAm1aPGiDUU1ICjVAgQIECBAgQIECBAgQIECBAgQIECBAgQICbVqja99RTUgKNUCBAgQIECBAgQIECBAgQIECBAgQIECBAgJrVixYsXFNSAo1QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAg1ICjUGopqUFPLuyIJm_Hh2LEFGvLWIN_JBF24dOxAgQIEBTUgKNQaikpQUsuHIgy7cOnYg55d3RB03oPO_qgQIECBAgQFNSAo1BqKqlBSy4ciDzv68kHXdyy4ciDbl588OfLzQIECBAU1ICjUGoiqUEXbh07EHTRlQU_PPfwQIECBAgQIECBAgQIEBTUgKNQaiMpQRtO7Ig6ZfHRBp3IMu3Dp2c0CBAgQIECBAgQFNSAo1BqJalBL07Ni-llw5EHPLu6INuHTsQIECBAgQIECBAU1ICjVAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECDUgKNUANAgQIECBAooqeunog6b0G3Dp3INuXd1QIECBAgQFNSAo1QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAg1ICiNGjRo0aNGjRo0aNGjRo0aNGjRo0aNGjRo0aNGjRo0aNGgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECA:PS=0:RE=0:zx=EA00 diff --git a/text/menu/mode7/mode7_forums.m7 b/text/menu/mode7/mode7_forums.m7 new file mode 100755 index 0000000000000000000000000000000000000000..76f89fa46782cecfe1b7af472802cd7fdcdca934 --- /dev/null +++ b/text/menu/mode7/mode7_forums.m7 @@ -0,0 +1,20 @@ +Åùó|,h<|h<th4|_<<th<$ÉPlease use +Åùóˇ`juˇj7}*u?j55ˇb{5Éresponsibly. +ë//,/-,,-.,/,.-..,-,.///////////////////ÉùÑ(N)ew Message Scan +ÉùÑ(R)ead Messages +ÉùÑ(L)ist Messages +ÉùÑ(P)ost New Message +ÉùÑ(C)ontinuous New Scan +ÉùÑ(M)ake a Poll +ÉùÑ(V)iew/Vote in Poll +ÉùÑ(T)ransfer QWK Packet +Åùá(F)ind Text in Messages +Åùá(S)can For Messages to You +ÑùÉ(J)ump to New Area +ÑùÉ< > _ Select Subboard +ÑùÉ[ ] /_ Select Group +ÑùÉ(&) Message scan config + +ÑùÉ(Q)uit to Main Menu +@EOF@ +https://zxnet.co.uk/teletext/editor/#0:QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECACdL_Fmh580POmhp8wPHnTQ8SA6GzLh55UHXnlQIECBAgQIAJ0v_R6uv_U3-qur_U1a_8XtqD5ZefDfu56cWzyuQIECBAgIr16xetWLFq5YvWLlq5csWrFy9evXr169evXr169evXr168GdCKJynL3QTcvPnhz5UFPHh3IECBAgQIECBAgQIECBAgQIAZ0IopKcuHIgm5efPDny80CBAgQIECBAgQIECBAgQIECBAgBnQiiYp08-iCbl588OfLzQIECBAgQIECBAgQIECBAgQIECAGdCKKCnfz6IJ2Xugm5efPDnyoECBAgQIECBAgQIECBAgQIAZ0Iohqd-7pp3dd_XmgnZe6Cnjw7kCBAgQIECBAgQIECBAgBnQiiapw68qDCgob9mxAgQIECBAgQIECBAgQIECBAgQIECAGdCKKynTl7r62_plQadyChv2bECBAgQIECBAgQIECBAgQIAZ0IoqKeWHdzzZeSCjXloKGHHry9ECBAgQIECBAgQIECBAgAnQ6iMp07siCpl8dEGncgm5efPDny80CBAgQIECBAgQIECACdDqKanHh3II2_kgm5efPDny80HTegs7-qBAgQIECBAgQIAh0GolKeu3gg6b0E7L3QQeWXCgQIECBAgQIECBAgQIECBAgCHQbxA-QX0CCnl2ZcfRBT64sW_DyyIECBAgQIECBAgQIECAIdB20F1AvvoKeXZlx9EEflv68ECBAgQIECBAgQIECBAgQIAh0GoTKUE3Lz54c-VBzx4dyDHv3ZtOdAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECAodBqKKnrp6IOm9BNw6dyCbl3dUCBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECA:PS=0:RE=0:zx=TD00 diff --git a/text/menu/mode7/mode7_main.m7 b/text/menu/mode7/mode7_main.m7 new file mode 100755 index 0000000000000000000000000000000000000000..7936030474bbf781f58a11c14dede9799c190944 --- /dev/null +++ b/text/menu/mode7/mode7_main.m7 @@ -0,0 +1,23 @@ +Åùó|,$|h4xl0|,h4h4|,th<|_<th<(|$á +Åùós{5s{5ˇj5ˇpj7k5ˇ`}juˇj5ˇjw ˇá +ë//,,.,,.,-.,,-.-.,/,-,,-.,-,/,/////////ÉùÑ@DATETIMEZONE|C40@ +Ñùá(N)etworked Forums î ú5 +Ñù î ú5 +Ñùá(E)mail and Netmail î ú5 +Ñù î ú5 +Ñùá(F)ile Transfers î ú5 +Ñù î ú5 +Ñùá(C)hat and InterBBS Comms î ú5 +Ñù î ú5 +Ñùá(D)oors and External Programsî ú5 +Ñù î ú5 +Ñùá(S)ettings î ú5 +Ñù î ú5 +Ñùá(G)oodbye - Logoff î ú5 +î ppppppppppppppppppppppppppppppppp5 +ÅùÉCTRL-CáAbort Text Display +ÅùÉCTRL-PáSend Private Messages +ÅùÉCTRL-UáDisplay Who's Online +@EOF@ + +https://zxnet.co.uk/teletext/editor/#0:QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECACdL_FiT5oaeNjD4s0NNDT4s6aHnzA86aHij4kQIECBAgQIAJ0vz9teftr_1Nf_DU31tf6P7q6_9TX_q7oP6BAgQIECBAgIr16xYuWLFyxauWLFq5auWL1i1YsWrli1YvWL169evXr169AgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIAh0OonKcvTvv5a8uRBG38uu3mgQIECBAgQIECAogONUCBAgCHUCBAgQIECBAgQIECBAgQIECBAgQIECBAgQICiA41QIECAIdDqIqnbh07EGHdkQTsvTbh07ECBAgQIECBAgKIDjVAgQIAh1AgQIECBAgQIECBAgQIECBAgQIECBAgQIECAogONUCBAgCHQ6iMp07MqCpyw7uebLy5oECBAgQIECBAgQICiA41QIECAIdQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgKIDjVAgQIAh0OohqdGHogw7siCTu6ZeUKFTQQ9-3bzQIECAogONUCBAgCHUCBAgQIECBAgQIECBAgQIECBAgQIECBAgQICiA41QIECAIdDqIinfv5c0GHdkQRfHTLy3YdiChy35-WHbzKIDjVAgQIAh1AgQIECBAgQIECBAgQIECBAgQIECBAgQIECAogONUCBAgCHQ6impy9Omndn5oECBAgQIECBAgQIECBAgQICiA41QIECAIdQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgKIDjVAgQIAh0Oojqd-_Ji85UC1BM359-bMgQIECBAgQIECAogONUCBAgKIOHDhw4cOHDhw4cOHDhw4cOHDhw4cOHDhw4cOHDg1QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIAJ0HDqUpi2GHg4t_LogqZfHRBE08-GzD5QIECBAgQIECBAgAnQcOpSmLaAenl3ZEFDlp7YemVBNy8-eHPl5oECBAgQIECACdBw6lKYtqh4mnnw2YfKCvo3p-aCfu2ad2VAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECA:PS=0:RE=0:zx=BU00 diff --git a/text/menu/msghdr.m7 b/text/menu/msghdr.m7 new file mode 100644 index 0000000000000000000000000000000000000000..8155870f616cd966804ac6bfdb281571289a88e7 --- /dev/null +++ b/text/menu/msghdr.m7 @@ -0,0 +1,6 @@ +ÑùÜSubj:á@MSG_SUBJECT-L................@ +ÑùÜAttr:á@MSG_ATTR-L...................@ +ÑùÜTo :á@MSG_TO-L.....................@ +ÑùÜFrom:á@MSG_FROM-L...................@ +ÑùÜDate:á@MSG_DATE-L..........@@MSG_TIMEZONE-L8@ + diff --git a/text/system.m7 b/text/system.m7 new file mode 100644 index 0000000000000000000000000000000000000000..4cb8c6f521f3372327e13c2a0cc0c2c534c48f10 --- /dev/null +++ b/text/system.m7 @@ -0,0 +1,16 @@ +@CLS@¬Ç@BBS@¬álocated in¬Ç@LOCATION@¬á +with your sysop,¬Ç@SYSOP@¬áhere to serve you. + +¬Ç@HOSTNAME@¬áis running¬Ç@OS_VER@¬á +and has been online continuously for¬Ç@UPTIME@¬áhours. + +¬ÇSystem Totals: + +Users: ¬Ö@TUSER|L.......@¬átoday:¬Ö@STATS.NUSERS@ +Logons: ¬Ö@STATS.LOGONS|L@¬átoday:¬Ö@STATS.LTODAY@ +Timeused: ¬Ö@STATS.TIMEON|L@¬átoday:¬Ö@STATS.TTODAY@ +Messages: ¬Ö@TMSG|L........@¬átoday:¬Ö@STATS.PTODAY@ +E-mail: ¬Ö@MAILW:0|L.....@¬átoday:¬Ö@STATS.ETODAY@ +Feedback: ¬Ö@MAILW:1|L.....@¬átoday:¬Ö@STATS.FTODAY@ +Files: ¬Ö@TFILE|L.......@¬átoday:¬Ö@STATS.ULS@ + Downloaded today: ¬Ö@STATS.DLS@ (@STATS.DLB@ bytes)