Running Interactive External Scripts as an Application in LinBPQ

intro

The BPQ suite is missing a fairly useful function that might eventually be improved – the ability to interrogate the node table with searches. No less than 6 hours after creating and publishing this system and documentation, the feature was put into the actual BPQ32 node code enabling searching via wildcards, therefore making this script obsolete (good work John!). This document however remains as an excellent template for setting up external applications via interactive scripts running on a linux system. Enjoy!

A couple of scripts have been put together that welds the linbpq application interface with a standard inetd service that once accessed launches a login to the node’s own telnet interface and retrieves the node table for interrogation.

Setting up the script is not straight forward unless one has experience with the OpenBSD or Linux operating systems.

Scripts

The scripts are in two parts, one is the main script handling the user interaction and the other is a special ’expect’ script that takes on the role of interacting with the node via the telnet interface as if it were an actual user.

File name: nonodes.sh

Set Permission: chmod 755 nonodes.sh
!/bin/bash
script="/home/pi/linbpq/scripts/nonodes.expect"
user="YOUR BPQ LOGIN"
pass="YOUR BPQ PASSWORD"
host="127.0.0.1"
port="8010"

#——-no changes needed below——-

OldIFS=$IFS
QuitCommandRegex='^(B|b|q|Q)$'

echo "one moment please..."
NodeListString=`$script $host $port $user $pass`

declare -a NodeArray=( $NodeListString )

IFS=" "
IFS=$OldIFS

for i in "${NodeArray[@]}"
do
        CleanupString=`echo $i | sed -e 's/\n//g' | sed -e 's/\r//g' | sed -e 's/ //g'`
        CleanedArray+=("$CleanupString")
done
function Prompt {
        echo "nonodesearch 0.0 by pe1rrr"
        echo "search--->"
        read  UserQuery
        CleanString=${UserQuery//[$'\t\r\n']} && UserQuery=${UserQuery%%*( )}
        CleanString=${CleanString//_/}
        CleanString=${CleanString// /_}
        CleanString=${CleanString//[^a-zA-Z0-9_\-]/}
        echo "you entered: $CleanString"
        if [[ $CleanString =~ $QuitCommandRegex ]]
        then
                Quit
        elif [[ -z $CleanString ]]
        then
                echo "thats empty!"
                Prompt
        else
                DoSearch
        fi
}

function Quit() {
        echo "Exiting... Bye!"
        exit
}

function DoSearch {
        printf '%s\n' "${CleanedArray[@]}" | grep -i -- "$CleanString"
        Prompt
}

# Main loop
Prompt


File name: nonodes.expect

Set Permission: chmod 755 nonodes.expect
#!/usr/bin/expect 
log_user 0

set host [lindex $argv 0]
set port [lindex $argv 1]
set login [lindex $argv 2]
set password [lindex $argv 3]

spawn telnet $host $port
set timeout 5


expect "callsign:"
send "$login\r"

expect "password:"
send "$password\r"

expect "Connected," { send "nodes\r" }

expect {
"Nodes"
}


log_user 1
expect eof


Potential Gotchas: The above expect script will wait 5 seconds for the node table before forcing itself to quit. The interface with the node is a live session and therefore there isn’t an end-of-file signal or any other way of detecting the end of the node list.

If your node has a very large table, you may need to increase the set timeout variable if during your testing phase you discover there are broken node callsigns or not near enough listed to be true.

Additionally, the expect script depends upon the detection of certain key words to perform actions, in some cases a sysop (that’s you) may have changed their node’s CTEXT, the Connected, portion may need to be adjusted to match your node’s connect text.

Packages Required

sudo apt install expect
sudo apt install openbsd-inetd

Inetd Service Configuration

sudo systemctl enable inetd
sudo service inetd start

Inetd configuration

The inetd daemon turns the script into a connectable internet service, using a simple telnet program it is then possible to log into the configured listening port for the script to access the script’s function. The daemon takes care of starting and stopping the script’s execution when a connection begins and ends.

File Name: /etc/inetd.conf

Add the below line to the /etc/inetd.conf file, be sure to maintain the spacing between the fields of the line (how many spaces isn’t important but the fields must be separated). This is one line, make sure you do not include any carriage returns or newlines.


nonodes  stream  tcp     nowait  pi  /home/pi/linbpq/scripts/nonodes.sh

The fields that will need your attention are the ones ’pi’ and ‘/home/pi/linbpq/scripts’ as these must reflect the user ID that linbpq runs under on your system, and the path to your linbpq directory, you may need to create the ‘scripts’ subdirectory.

The service requires a TCP port number, add a new line for ‘nonodes’ to /etc/services, make sure the port does not already exist, if the port number is already defined in the file then that means the port has already been taken by another service. Make sure the one you choose is above 1024 but below 65535.

File Name: /etc/services

The first word ’nonodes’ must match with its sibling configuration in inetd.conf

Example:

nonodes  63010/tcp # Node Search

Restart the inetd service to load the new configuration changes:

sudo service inetd restart

Modifying linbpq configuration

Prerequisites: bpq32.cfg should already have a telnet port defined. The port is required for BPQ to create a loop-back connection to the host it is running on.

The documentation has an example provided at the very bottom, should the website be offline, below is a PDF backup.

CMDPORT

A list of up to 32 ports. These ports are used for connections to applications running on the same machine. This was originally intended to connect to a command shell to enable basic configuration editing, but has been generalised to allow connects to other tcp ports, thus providing an additional API option. 

BPQ32 Documentation.

Put the port number that you chose in the /etc/services setup in the CMDPORT= list within the bpq32.cfg telnet port configuration. There may already be a port defined there for normal telnet access to the node (default 8010), add your port to the list and make a note of its position in the list. The position of the nonodes port in the list will be needed later. The offset begins at zero (0) for the first port defined on the CMDPORT= line.

Example CMDPORT parameters:


CMDPORT=8010 2323 2424 63010


Port 63010 (highlighted) is positioned at offset #3.

The next part focuses on a different segment of the bpq32.cfg configuration file, the APPLICATION definitions- these provide the different commands on the node command interface that users can use to do things on the node, such as access the BBS or log into the CHAT. Each application is defined with a number from 1-32.

Locate the existing APPLICATION definitions and pick the next available APPLICATION number.

Example APPLICATION definition:


APPLICATION 7,NS,C 10 HOST 3 S NOCALL

In the example above, #7 is selected for the application, followed by the word ”NS”- the alias or command a user uses on the node command line to start the node search.

C 10 – 10 in this example is the number associated with the BPQ Telnet Port, this can vary system to system so be sure to check your own to make sure the number matches. The ‘C’ refers to the internal node command ”connect”. When a user accesses the command ”NS”, the node begins a connection on BPQ port 10.

The keyword HOST with a number following tells BPQ to initiate a loopback connection to itself on the port defined in CMDPORT= at offset #3.

The following keys ”S” and ”NOCALL” refer to ”Stay” and ”Don’t send my callsign” when executing the command. This lets a user stay connected to the node.

As the nonodes script doesn’t require a login, then there is no purpose in sending the user’s callsign along with the initial connection.

Configuring the login for the expect script

See the documentation for the Telnet Port for defining Telnet users in BPQ.

Example:

USER=nonodes,heythatsmypassword,PE1RRR,,

Testing

After restarting linbpq the ‘NS’ command should now work from within the node. If it does not, then check to see if you can access the script running on the inetd by using the telnet command (you may need to install the telnet package first).

telnet localhost 63010

You should then be presented with this prompt:

Trying ::1…
Trying 127.0.0.1…
Connected to localhost.
Escape character is '^]'.
one moment please…
nonodesearch 0.0 by pe1rrr
search--->

If this yields an error, go back and ensure that the file permissions, paths and file ownerships match your linbpq system. Double check that there are no errors in the /etc/inetd.conf including possibly incorrectly copy and pasted characters.

Check that the nonodes.expect script has matching login, password and that the host is set to 127.0.0.1 and TCP port matches the one listed within the bpq32.cfg telnet port configuration.

If you have an error similar to:

/home/pi/linbpq//nonodes.sh: line 13: nonodes.expect: command not found

Edit the second line of the nonodes.sh script to the full path location of nonodes.expect. This can vary system to system- but wherever you created the script files within the linbpq directory will be where you need to point the path. In the above example, the scripts subdirectory was literally missing from the path.

Usage

Just enter anything you want to search for. You can even search for SSIDs. Invalid characters are automatically purged and (hopefully) there are no bugs.
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
one moment please...
nonodesearch 0.0 by pe1rrr
search--->
bpq
you entered: bpq
FKABPQ:IK5FKA-2
NASBPQ:VE6NAS-7
NOTCHT:G8BPQ-4
POGO:GM8BPQ-9
POGO4:G8BPQ-9
nonodesearch 0.0 by pe1rrr
search--->
-7
you entered: -7
COSCO:KE0GB-7
DATNOD:K5DAT-7
FOG0:WB4WPF-7
GMNOD:W9GM-7
GYBNOD:EI2GYB-7
KAUNOD:KC9UHI-7
LAPNOD:PI1LAP-7
LPBNOD:KD5LPB-7
MELNOD:N3MEL-7
MLBNOD:N3MLB-7
MNMSP:WG0A-7
NASBPQ:VE6NAS-7
NCDE:KA3VSP-7
OHCLEV:KM8V-7
OHSLY:KC8SLY-7
OKINC:N0NJY-7
PENFLD:NS2B-7
PERCHT:GM3YEW-7
PHXAZ:N2UEM-7
PHYLNS:W0ARP-7
RCNOD:TI0RC-7
SCNNOD:VE3SCN-7
UIMXRP:VE3UIM-7
WICOL:W9IKU-7
WILOW:KB9PVH-7
WUENOD:DK0WUE-7
YVRASS:VE7ASS-7
nonodesearch 0.0 by pe1rrr
search--->
:  
you entered: 
thats empty!
nonodesearch 0.0 by pe1rrr
search--->
£$%^&*&
you entered: 
thats empty!
nonodesearch 0.0 by pe1rrr
search--->

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s