Enigma 1/2 - A killer BBS System developed by Bryan Ashby that is one of the most customizable BBS products out there today for modern OSes. Think back to days of BBS systems running in pure BASIC language that you could tweak, develop from, remove or move sections of, or just completely outright morph to your own creation, and you’ll understand the interest in Enigma 1/2.
The BBS runs off core files developed in JSON and allows SYSOPs that may not be too privy on how to work with that type of code to do customization by a simplified form, HJSON. For the record, I am one of those type of SYSOPs. I’ve worked with structured language frequently, but for whatever reason, my aging mind has not grasped JSON in it’s totality.
One of the things I really wanted to see was a SYSOP monitoring and maintenance area within the BBS instead of relying on any engine work at the command prompt of the OS. Bryan contributed in large form with the recent addition of “Waiting For Caller” front end; showing the sysop BBS activity occurring at any moment. NICE. But that still leaves SYSOP Maintenance functions to be had, and for me where I operate in the cloud, that’s requires logging into my remote system, getting to the right directory, and executing the various commands. I’d rather be BBS’ing!
Many of the maintenance functions needed to keep the BBS going uses a module called “OPUTIL.JS”, run from the command prompt of the OS the system is installed on. Of course, there are other commands associated with system maintenance that are not part of Enigma build that are also frequently utilized.
Op Util format
Some examples of commands are (shown in Linux form):
- ./oputil.js user nuke pw IL0veEnigma (changes password)
- ./oputil.js fb scan ansiart (scans filebase area for storage tag area ansiart)
- tar -czvf westwood_backup.tar.gz /home/nuke/enigma-bbs (backs up my BBS)
- poll_bink.sh (forces a message transaction between BBS and FTN)
- sudo apt install && sudo apt update (linux update refreshment)
So if you’re familiar with LINUX or Windows command prompt use, there is a solution available to make a Front End within the BBS for the SYSOP to run these frequent tasks. All you need is to make a shell (SH) script, or for Windows, a batch (BAT) file.
Enigma offers an awesome little module called Abracadabra, and this is one of the tools available to drive executable system files from within the BBS, and manages the input/output for the user at the screen. Using this with linux or windows scripting solves the dilemma of trying to make a JSON creation of your own (though this is still encouraged to learn)!
One of my key mantras I always tell my subordinates in my line of work: keep it simple stupid. The more complex something gets, the harder it is to manage and easier to break. So let’s keep it simple, shall we?
-
Step 1) Define commands you want to use and create a menu for it - here’s a snapshot of mine and I call it SYSOPMENU.ANS
-
Step 2) Add a command call to your sysop menu to your menu.hjson area
{ value: { command: "/SYSOPMENU" } action: [ { // SYSOP Privileged Area acs: GM[sysops] action: @menu:sysopMainMenu } ]
-
Step 3) Develop your shell scripts to support the commands you’ve identified in your menu. For this example, we will develop resetting a user’s password. This script is for LINUX:
-
Repeat step 3 for all your other commands. ALTERNATIVE: You can execute all your commands within one script and pass an argument to it to definte what the sysop action is, then perhaps use a CASE statement to work the execution flow based on the parameter. Guided by my mantra, I made single scripts for each command, and I will probably revisit that later myself as a clean-up improvement for my system.
-
Step 4) build the menu-driven command functionality in your menu.hjson to execute the command (script) calls via the abracadabra module. Below is my code in totality for all the SYSOP functions. Literally a cut and paste, of each command segment, while changing the name and script portions for each one. I’m sure this could be condensed in some manner with arguments - but this gets things started (remember to change your path names to the correct path for your scripts!):
{
menus: {sysopMainMenu: { desc: SysOp Maintenance art: SYSOPMENU prompt: menuCommand config: { cls: true art: SYSOPMENU interrupt: realtime } submit: [ { value: { command: "UL" } action: @menu:sysopUserList } { value: { command: "UI" } action: @menu:sysopUserInformation } { value: { command: "UP" } action: @menu:sysopUpgradeUser } { value: { command: "DD" } action: @menu:sysopUpgradeDahlgrenite } { value: { command: "R" } action: @menu:sysopUserRestrict } { value: { command: "L" } action: @menu:sysopLockUser } { value: { command: "PO" } action: @menu:sysopPollBink } { value: { command: "DU" } action: @menu:sysopDeleteUser } { value: { command: "CP" } action: @menu:sysopUserPassword } { value: { command: "SL" } action: @menu:sysopShowLog } { value: { command: "BU" } action: @menu:sysopBackupWW } { value: { command: "DIR" } action: @menu:sysopShowDir } { value: { command: "NANO" } action: @menu:sysopNANO } { value: { command: "FB" } action: @menu:sysopFB } { value: { command: "DG" } action: @menu:sysopDG } { value: { command: "BL" } action: @menu:sysopBinkLog } { value: { command: "Q" } action: @systemMethod:prevMenu } { value: { command: "G" } action: @menu:fullLogoffSequence } ] } // sysop main menu sysopUserList: { desc: Sysop Operations UL module: abracadabra config: { name: User Listing cmd: /home/nuke/enigma-bbs/userlist.sh io: stdio } } sysopDeleteUser: { desc: Sysop Operations DU module: abracadabra config: { name: delete user cmd: /home/nuke/enigma-bbs/deleteauser.sh io: stdio } } sysopUserInformation: { desc: Sysop Operations UI module: abracadabra config: { name: user information cmd: /home/nuke/enigma-bbs/userinfo.sh io: stdio } } sysopUpgradeUser: { desc: Sysop Operations UP module: abracadabra config: { name: user upgrade cmd: /home/nuke/enigma-bbs/upgradeuser.sh io: stdio } } sysopUpgradeDahlgrenite: { desc: Sysop Operations UP DD module: abracadabra config: { name: user upgrade dahlgrenite cmd: /home/nuke/enigma-bbs/upgradeuserdd.sh io: stdio } } sysopUserRestrict: { desc: Sysop Operations RE module: abracadabra config: { name: user restrict cmd: /home/nuke/enigma-bbs/restrictuser.sh io: stdio } } sysopLockUser: { desc: Sysop Operations LK module: abracadabra config: { name: user lock cmd: /home/nuke/enigma-bbs/lockuser.sh io: stdio } } sysopPollBink: { desc: Sysop Operations POLL module: abracadabra config: { name: execute poll bink cmd: /home/nuke/enigma-bbs/misc/poll_bink.sh io: stdio } } sysopDeleteUser: { desc: Sysop Operations DEL module: abracadabra config: { name: user delete cmd: /home/nuke/enigma-bbs/removeuser.sh io: stdio } } sysopUserPassword: { desc: Sysop Operations PSWD module: abracadabra config: { name: user password change cmd: /home/nuke/enigma-bbs/userpassword.sh io: stdio } } sysopShowLog: { desc: Sysop Operations LOG module: abracadabra config: { name: monitor log cmd: /home/nuke/enigma-bbs/showlog.sh io: stdio } } sysopBinkLog: { desc: Sysop Operations BINKD LOG module: abracadabra config: { name: monitor bink log cmd: /home/nuke/enigma-bbs/showbinkd.sh io: stdio } } sysopBackupWW: { desc: Sysop Operations BU module: abracadabra config: { name: backing up system cmd: /home/nuke/backupww.sh io: stdio } } sysopShowDir: { desc: Sysop maint dir module: abracadabra config: { name: file maintenance cmd: /home/nuke/enigma-bbs/showdir.sh io: stdio } } sysopNANO: { desc: Sysop maint nano module: abracadabra config: { name: sysop editing files cmd: /home/nuke/enigma-bbs/systemnano.sh io: stdio } } sysopFB: { desc: Sysop Filebase Maint module: abracadabra config: { name: sysop filebase maint cmd: /home/nuke/enigma-bbs/updatefb.sh io: stdio } } sysopDG: { desc: Sysop User Maint DG module: abracadabra config: { name: sysop user maint dg cmd: /home/nuke/enigma-bbs/downgradeuser.sh io: stdio } }
}
}
Finally, at least for LINUX users, make sure all commands are executable. Go to your directory with your SH commands, and perform CHMOD +X against them all.
Here are some examples of my shell commands:
- SHOW Enigma BBS Log
#!/bin/sh
tail -F /home/nuke/enigma-bbs/logs/enigma-bbs.log | bunyan
- Show BINKD Log
#!/bin/sh
tail -F /var/log/binkd/binkd.log | bunyan
- Show User Information
#!/bin/sh
echo “***************************** SYSOP RETRIEVE USER INFORMATION ****************************”
echo “---------------------------- ---------------------------”
echo " "
echo " "
echo “Enter user name to query:”
read THE_USER
./oputil.js user info “$THE_USER”
echo " "
echo “operation executed. press enter.”
read DUMMY
- Remove a User
#!/bin/sh
echo “***************************** SYSOP REMOVE USER ****************************”
echo “---------------------------- ---------------------------”
echo " "
echo " "
echo “Enter user name to REMOVE:”
read THE_USER
./oputil.js user rm “$THE_USER”
echo “operation executed. press enter.”
read DUMMY
- Update FIlebase
#!/bin/bash
echo “enter the following”
echo “1 - Ansi Art”
echo “2 - bbs stuff”
echo “3 - coleco suff”
echo “4 - Commodore”
echo “5 - crap”
echo “6 - dox box stuff”
echo “7 - flight sim stuff”
echo “8 - linux stuff”
echo “9 - mame stuff”
echo “10 - misc stuff”
echo “11 - terminals”
echo “12 - atari”
echo “13 - TIC Files”
echo “14 - All”
echo “don’t forget uploads!”
read text
case $text in
“1”)
./oputil.js fb scan ansi_art “"
;;
“2”)
./oputil.js fb scan bbs_stuff "”
;;
“3”)
./oputil.js fb scan coleco_1 ""
;;
“4”)
./oputil.js fb scan commodore “"
;;
“5”)
./oputil.js fb scan crap_1 "”
;;
“6”)
./oputil.js fb scan dos_box “"
;;
“7”)
./oputil.js fb scan flight_sim "”
;;
“8”)
./oputil.js fb scan linux_stuff “"
;;
“9”)
./oputil.js fb scan mame "”
;;
“10”)
./oputil.js fb scan misc_1 “"
;;
“11”)
./oputil.js fb scan terminals_1 "”
;;
“12”)
./oputil.js fb scan atari_1 “"
;;
“13”)
./oputil.js fb scan msg_network "”
;;
“14”)
./oputil.js fb scan * “*”
;;
*)
echo “incorrect entry”
esac
echo “Press enter to exit”
read DUMMY
Again - play with this idea! Take the simple steps here and make it as complex as you desire, but the baby steps here are REMARKABLY simple; why did it take me two years to think of, don’t ask me.
Another cool feature as a side note: I use the above methods to invoke the use of LYNX web browser for the user to see this Discourse web area from the BBS. I wish I could use the W3M browser, but it doesn’t offer lockdown features that LYNX has. The use of abracadabra as we did above remains exactly the same, calling out a shell script with the following lynx command:
lynx -anonymous -noprint -ftp -homepage=https://westwoodbbs.net -nobrowse -noexec -nolog /
-nolist -rlogin -telnet -restrictions=default,inside_telnet,outside_telnet,inside_news, /
inside_ftp,outside_ftp,inside_rlogin,outside_rlogin,jump,mail,goto https://westwoodbbs.net
If you think about all of the above, you don’t have to become a JSON expert to add killer and unique functionality to your Enigma 1/2 BBS!
I hope this helps - send me your sysop screens when you give it a go!
~-Nuke-~