1
0
mirror of https://github.com/AG7GN/nexus-utilities.git synced 2025-05-21 17:00:12 -07:00

Added FSQ search script

This commit is contained in:
Steve Magnuson 2020-02-06 12:35:09 -08:00
parent 15e215ecac
commit edde93bee7
9 changed files with 1558 additions and 292 deletions

View File

@ -33,6 +33,9 @@ Some scripts are specific to the [Nexus DR-X](http://wb7fhc.com/nexus-dr-x.html)
[Edit Desktop Text script](#edit-desktop-text-script) [Edit Desktop Text script](#edit-desktop-text-script)
[fsq_search.sh](#fsq-search-script)
## Installation ## Installation
### Install ### Install
@ -189,3 +192,13 @@ If your image is older than 20191214 and you want to install the customizable Ne
pcmanfm --reconfigure pcmanfm --reconfigure
After you start the script (__Raspberry > Preferences > Edit Desktop Background Text__), enter the text you want to display and optionally check the box to show your Pi's host name, then click __OK__. The script won't close until you Cancel, so click __Cancel__ when you're satisfied with your new desktop. After you start the script (__Raspberry > Preferences > Edit Desktop Background Text__), enter the text you want to display and optionally check the box to show your Pi's host name, then click __OK__. The script won't close until you Cancel, so click __Cancel__ when you're satisfied with your new desktop.
## FSQ Search script
This script monitors the `fsq_audit_log.text` file and optionally runs a user specified script upon locating a string provided by the user as search criteria. It also prints (with an optional timestamp) messages matching the user's search string to stdout. This script has no GUI and is designed to run in a terminal or as an autostart app in Fldigi. Only one instance of the script runs at a time and it monitors messages for both the left and right radios simultaneously. It will kill itself if no more instances of Fldigi are running.
For usage information, run this command in the Terminal:
fsq_search.sh -h

View File

@ -1,10 +1,93 @@
#!/bin/bash #!/bin/bash
#================================================================
# HEADER
#================================================================
#% SYNOPSIS
#+ ${SCRIPT_NAME} [-hv]
#%
#% DESCRIPTION
#% This script checks the status of 4 GPIO pins and runs a script corresponding
#% to those settings as described below. This script is called by initialize-pi.sh,
#% which is run a bootup via cron @reboot.
#%
#% OPTIONS
#% -h, --help Print this help
#% -v, --version Print script information
#%
#================================================================
#- IMPLEMENTATION
#- version ${SCRIPT_NAME} 1.1.0
#- author Steve Magnuson, AG7GN
#- license CC-BY-SA Creative Commons License
#- script_id 0
#-
#================================================================
# HISTORY
# 20190620 : Steve Magnuson : Script creation
# 20200204 : Steve Magnuson : Added script template
#
#================================================================
# DEBUG OPTION
# set -n # Uncomment to check your syntax, without execution.
# set -x # Uncomment to debug this shell script
#
#================================================================
# END_OF_HEADER
#================================================================
VERSION="1.0.0" SYNTAX=false
DEBUG=false
# This script checks the status of 4 GPIO pins and runs a script corresponding #============================
# to those settings as described below. This script is called by initialize-pi.sh, # FUNCTIONS
# which is run a bootup via cron @reboot. #============================
function TrapCleanup() {
[[ -d "${TMPDIR}" ]] && rm -rf "${TMPDIR}/"
exit 0
}
function SafeExit() {
# Delete temp files, if any
[[ -d "${TMPDIR}" ]] && rm -rf "${TMPDIR}/"
trap - INT TERM EXIT
exit
}
function ScriptInfo() {
HEAD_FILTER="^#-"
[[ "$1" = "usage" ]] && HEAD_FILTER="^#+"
[[ "$1" = "full" ]] && HEAD_FILTER="^#[%+]"
[[ "$1" = "version" ]] && HEAD_FILTER="^#-"
head -${SCRIPT_HEADSIZE:-99} ${0} | grep -e "${HEAD_FILTER}" | \
sed -e "s/${HEAD_FILTER}//g" \
-e "s/\${SCRIPT_NAME}/${SCRIPT_NAME}/g" \
-e "s/\${SPEED}/${SPEED}/g" \
-e "s/\${DEFAULT_PORTSTRING}/${DEFAULT_PORTSTRING}/g"
}
function Usage() {
printf "Usage: "
ScriptInfo usage
exit
}
function Die () {
echo "${*}"
SafeExit
}
#============================
# FILES AND VARIABLES
#============================
#== general variables ==#
SCRIPT_NAME="$(basename ${0})" # scriptname without path
SCRIPT_DIR="$( cd $(dirname "$0") && pwd )" # script directory
SCRIPT_FULLPATH="${SCRIPT_DIR}/${SCRIPT_NAME}"
SCRIPT_ID="$(ScriptInfo | grep script_id | tr -s ' ' | cut -d' ' -f3)"
SCRIPT_HEADSIZE=$(grep -sn "^# END_OF_HEADER" ${0} | head -1 | cut -f1 -d:)
VERSION="$(ScriptInfo version | grep version | tr -s ' ' | cut -d' ' -f 4)"
GPIO="$(command -v gpio) -g" GPIO="$(command -v gpio) -g"
@ -15,6 +98,86 @@ P[2]=13
P[3]=6 P[3]=6
P[4]=5 P[4]=5
#============================
# PARSE OPTIONS WITH GETOPTS
#============================
#== set short options ==#
SCRIPT_OPTS=':hv-:'
#== set long options associated with short one ==#
typeset -A ARRAY_OPTS
ARRAY_OPTS=(
[help]=h
[version]=v
)
# Parse options
while getopts ${SCRIPT_OPTS} OPTION ; do
# Translate long options to short
if [[ "x$OPTION" == "x-" ]]; then
LONG_OPTION=$OPTARG
LONG_OPTARG=$(echo $LONG_OPTION | grep "=" | cut -d'=' -f2)
LONG_OPTIND=-1
[[ "x$LONG_OPTARG" = "x" ]] && LONG_OPTIND=$OPTIND || LONG_OPTION=$(echo $OPTARG | cut -d'=' -f1)
[[ $LONG_OPTIND -ne -1 ]] && eval LONG_OPTARG="\$$LONG_OPTIND"
OPTION=${ARRAY_OPTS[$LONG_OPTION]}
[[ "x$OPTION" = "x" ]] && OPTION="?" OPTARG="-$LONG_OPTION"
if [[ $( echo "${SCRIPT_OPTS}" | grep -c "${OPTION}:" ) -eq 1 ]]; then
if [[ "x${LONG_OPTARG}" = "x" ]] || [[ "${LONG_OPTARG}" = -* ]]; then
OPTION=":" OPTARG="-$LONG_OPTION"
else
OPTARG="$LONG_OPTARG";
if [[ $LONG_OPTIND -ne -1 ]]; then
[[ $OPTIND -le $Optnum ]] && OPTIND=$(( $OPTIND+1 ))
shift $OPTIND
OPTIND=1
fi
fi
fi
fi
# Options followed by another option instead of argument
if [[ "x${OPTION}" != "x:" ]] && [[ "x${OPTION}" != "x?" ]] && [[ "${OPTARG}" = -* ]]; then
OPTARG="$OPTION" OPTION=":"
fi
# Finally, manage options
case "$OPTION" in
h)
ScriptInfo full
exit 0
;;
v)
ScriptInfo version
exit 0
;;
:)
Die "${SCRIPT_NAME}: -$OPTARG: option requires an argument"
;;
?)
Die "${SCRIPT_NAME}: -$OPTARG: unknown option"
;;
esac
done
shift $((${OPTIND} - 1)) ## shift options
#============================
# MAIN SCRIPT
#============================
# Trap bad exits with cleanup function
trap TrapCleanup EXIT INT TERM
# Exit on error. Append '||true' when you run the script if you expect an error.
set -o errexit
# Check Syntax if set
$SYNTAX && set -n
# Run in debug mode, if set
$DEBUG && set -x
# String $PIANO will identify which levers are in the DOWN position # String $PIANO will identify which levers are in the DOWN position
PIANO="" PIANO=""
for I in 1 2 3 4 for I in 1 2 3 4
@ -33,4 +196,4 @@ done
# $HOME/piano24.sh will run whenever the Raspberry Pi starts. # $HOME/piano24.sh will run whenever the Raspberry Pi starts.
#echo "running piano$PIANO.sh" #echo "running piano$PIANO.sh"
[ -s $HOME/piano$PIANO.sh ] && $HOME/piano$PIANO.sh [ -s $HOME/piano$PIANO.sh ] && $HOME/piano$PIANO.sh
SafeExit

View File

@ -1,9 +1,93 @@
#!/bin/bash #!/bin/bash
#================================================================
# HEADER
#================================================================
#% SYNOPSIS
#+ ${SCRIPT_NAME} [-hv]
#%
#% DESCRIPTION
#% This script allows you to edit the text on the default Nexus DR-X Desktop.
#% You can, for example add your call sign and select whether or not to include
#% the Pi's hostname.
#%
#% OPTIONS
#% -h, --help Print this help
#% -v, --version Print script information
#%
#================================================================
#- IMPLEMENTATION
#- version ${SCRIPT_NAME} 1.1.4
#- author Steve Magnuson, AG7GN
#- license CC-BY-SA Creative Commons License
#- script_id 0
#-
#================================================================
# HISTORY
# 20191115 : Steve Magnuson : Script creation
# 20200204 : Steve Magnuson : Added script template
#
#================================================================
# DEBUG OPTION
# set -n # Uncomment to check your syntax, without execution.
# set -x # Uncomment to debug this shell script
#
#================================================================
# END_OF_HEADER
#================================================================
VERSION="1.0.2" SYNTAX=false
DEBUG=false
# This script allows the user to change the text of the default Nexus desktop background #============================
# FUNCTIONS
#============================
function TrapCleanup() {
[[ -d "${TMPDIR}" ]] && rm -rf "${TMPDIR}/"
exit 0
}
function SafeExit() {
# Delete temp files, if any
[[ -d "${TMPDIR}" ]] && rm -rf "${TMPDIR}/"
trap - INT TERM EXIT
exit
}
function ScriptInfo() {
HEAD_FILTER="^#-"
[[ "$1" = "usage" ]] && HEAD_FILTER="^#+"
[[ "$1" = "full" ]] && HEAD_FILTER="^#[%+]"
[[ "$1" = "version" ]] && HEAD_FILTER="^#-"
head -${SCRIPT_HEADSIZE:-99} ${0} | grep -e "${HEAD_FILTER}" | \
sed -e "s/${HEAD_FILTER}//g" \
-e "s/\${SCRIPT_NAME}/${SCRIPT_NAME}/g" \
-e "s/\${SPEED}/${SPEED}/g" \
-e "s/\${DEFAULT_PORTSTRING}/${DEFAULT_PORTSTRING}/g"
}
function Usage() {
printf "Usage: "
ScriptInfo usage
exit
}
function Die () {
echo "${*}"
SafeExit
}
#============================
# FILES AND VARIABLES
#============================
#== general variables ==#
SCRIPT_NAME="$(basename ${0})" # scriptname without path
SCRIPT_DIR="$( cd $(dirname "$0") && pwd )" # script directory
SCRIPT_FULLPATH="${SCRIPT_DIR}/${SCRIPT_NAME}"
SCRIPT_ID="$(ScriptInfo | grep script_id | tr -s ' ' | cut -d' ' -f3)"
SCRIPT_HEADSIZE=$(grep -sn "^# END_OF_HEADER" ${0} | head -1 | cut -f1 -d:)
VERSION="$(ScriptInfo version | grep version | tr -s ' ' | cut -d' ' -f 4)"
TITLE="Desktop Text Editor $VERSION" TITLE="Desktop Text Editor $VERSION"
CONFIG_FILE="$HOME/desktop-text.conf" CONFIG_FILE="$HOME/desktop-text.conf"
@ -11,31 +95,92 @@ PICTURE_DIR="$HOME/Pictures"
DEFAULT_BACKGROUND_IMAGE="$PICTURE_DIR/NexusDeskTop.jpg" DEFAULT_BACKGROUND_IMAGE="$PICTURE_DIR/NexusDeskTop.jpg"
MESSAGE="Enter the text you want displayed below.\nDon't use any single or double quotation marks." MESSAGE="Enter the text you want displayed below.\nDon't use any single or double quotation marks."
trap errorReport INT #============================
# PARSE OPTIONS WITH GETOPTS
#============================
function errorReport () { #== set short options ==#
echo SCRIPT_OPTS=':hv-:'
if [[ $1 == "" ]]
then #== set long options associated with short one ==#
typeset -A ARRAY_OPTS
ARRAY_OPTS=(
[help]=h
[version]=v
)
# Parse options
while getopts ${SCRIPT_OPTS} OPTION ; do
# Translate long options to short
if [[ "x$OPTION" == "x-" ]]; then
LONG_OPTION=$OPTARG
LONG_OPTARG=$(echo $LONG_OPTION | grep "=" | cut -d'=' -f2)
LONG_OPTIND=-1
[[ "x$LONG_OPTARG" = "x" ]] && LONG_OPTIND=$OPTIND || LONG_OPTION=$(echo $OPTARG | cut -d'=' -f1)
[[ $LONG_OPTIND -ne -1 ]] && eval LONG_OPTARG="\$$LONG_OPTIND"
OPTION=${ARRAY_OPTS[$LONG_OPTION]}
[[ "x$OPTION" = "x" ]] && OPTION="?" OPTARG="-$LONG_OPTION"
if [[ $( echo "${SCRIPT_OPTS}" | grep -c "${OPTION}:" ) -eq 1 ]]; then
if [[ "x${LONG_OPTARG}" = "x" ]] || [[ "${LONG_OPTARG}" = -* ]]; then
OPTION=":" OPTARG="-$LONG_OPTION"
else
OPTARG="$LONG_OPTARG";
if [[ $LONG_OPTIND -ne -1 ]]; then
[[ $OPTIND -le $Optnum ]] && OPTIND=$(( $OPTIND+1 ))
shift $OPTIND
OPTIND=1
fi
fi
fi
fi
# Options followed by another option instead of argument
if [[ "x${OPTION}" != "x:" ]] && [[ "x${OPTION}" != "x?" ]] && [[ "${OPTARG}" = -* ]]; then
OPTARG="$OPTION" OPTION=":"
fi
# Finally, manage options
case "$OPTION" in
h)
ScriptInfo full
exit 0 exit 0
else ;;
if [[ $2 == "" ]] v)
then ScriptInfo version
echo >&2 "$1" exit 0
exit 1 ;;
else :)
echo >&2 "$1" Die "${SCRIPT_NAME}: -$OPTARG: option requires an argument"
exit $2 ;;
fi ?)
fi Die "${SCRIPT_NAME}: -$OPTARG: unknown option"
} ;;
esac
done
shift $((${OPTIND} - 1)) ## shift options
#============================
# MAIN SCRIPT
#============================
# Trap bad exits with cleanup function
trap SafeExit EXIT INT TERM
# Exit on error. Append '||true' when you run the script if you expect an error.
set -o errexit
# Check Syntax if set
$SYNTAX && set -n
# Run in debug mode, if set
$DEBUG && set -x
[ -s $DEFAULT_BACKGROUND_IMAGE ] || errorReport "Default Nexus image not in $DEFAULT_BACKGROUND_IMAGE" 1 [ -s $DEFAULT_BACKGROUND_IMAGE ] || errorReport "Default Nexus image not in $DEFAULT_BACKGROUND_IMAGE" 1
if ! command -v convert >/dev/null if ! command -v convert >/dev/null
then then
sudo apt update sudo apt update || die "Could not run 'sudo apt update'"
sudo apt install -y imagemagick sudo apt install -y imagemagick || die "Could not run 'sudo apt install -y imagemagick'"
fi fi
if [ -s "$CONFIG_FILE" ] if [ -s "$CONFIG_FILE" ]
@ -70,7 +215,7 @@ $MESSAGE</b>\n" \
[[ $? == 1 || $? == 252 ]] && errorReport # User has cancelled. [[ $? == 1 || $? == 252 ]] && errorReport # User has cancelled.
[[ $ANS == "" ]] && errorReport "Error." 1 [[ $ANS == "" ]] && Die "Unexpected input from dialog"
IFS='|' read -r -a TF <<< "$ANS" IFS='|' read -r -a TF <<< "$ANS"
@ -93,3 +238,4 @@ $MESSAGE</b>\n" \
fi fi
$(command -v pcmanfm) --set-wallpaper="$TARGET" $(command -v pcmanfm) --set-wallpaper="$TARGET"
done done
SafeExit

345
fsq_search.sh Executable file
View File

@ -0,0 +1,345 @@
#!/bin/bash
#================================================================
# HEADER
#================================================================
#% SYNOPSIS
#+ ${SCRIPT_NAME} [-hv] [-s file] [-w seconds] [-t date_format] [search_string]
#%
#% DESCRIPTION
#% Searches for text in messages logged in ${FSQ_AUDIT_FILE}.
#% The script will print matching lines, with optional timestamp, to stdout
#% and will optionally launch a script on a match. search_string can be a
#% regular expression. If no search_string is supplied, all messages will match.
#%
#% Only one instance of this script will run at a time and only if at least one
#% instance of Fldigi is running. The script will kill itself when no more
#% instances of Fldigi are running. This script can be used as an autostart in
#% Fldigi.
#%
#% Messages logged in ${FSQ_AUDIT_FILE} are in a specific format. In the following
#% non-relayed message example w7ecg is the sending station, followed by a colon
#% and a 2 character checksum, followed the called station (ag7gn) followed by the
#% message.
#%
#% w7ecg:81ag7gn this is my message.
#%
#% OPTIONS
#% -s file, --script=file Launch the script/app in file if a match is found.
#% Wrap in double quotes if arguments to app are supplied.
#% See EXAMPLES below.
#% -t date_format, --timestamp=date_format
#% Precede each message printed to stdout with a
#% timestamp in date_format. Run 'man date' for
#% available formats. -t "" will use the default date
#% format. Example: -t "+%Y%m%dT%H%M%S"
#% -w seconds, --wait=seconds
#% Minimum time in seconds between -s script executions.
#% Higher values reduce number of script executions.
#% Range: ${MIN_WAIT}-${MAX_WAIT} Default: ${WAIT}
#% -h, --help Print this help
#% -v, --version Print script information
#%
#% EXAMPLES
#%
#% Match all messages and print them to stdout with no timestamp:
#%
#% ${SCRIPT_NAME}
#%
#% Match messages where callsign ag7gn appears anywhere in the message. Run script
#% alert.sh on a match, but don't launch alert.sh again if another match occurs
#% within 60 seconds:
#%
#% ${SCRIPT_NAME} -w 60 -s alert.sh ag7gn
#%
#% Match messages where callsign ag7gn or wc7hq or n7bel appears anywhere in the
#% message. Matching lines will be printed to stdout prepended with the default
#% timestamp:
#%
#% ${SCRIPT_NAME} -t "" "ag7gn|wc7hq|n7bel"
#%
#% Match messages where the called station is any of ag7gn or wc7hq or n7bel.
#% Play a WAV file on match. Don't print matching messages to stdout:
#%
#% ${SCRIPT_NAME} -s "aplay -q alert.wav" ":..(ag7gn|wc7hq|n7bel)" >/dev/null
#%
#% Match messages where the calling station is either wc7hq or n7bel. Prepend
#% the messages printed to stdout with a specific timestamp format:
#%
#% ${SCRIPT_NAME} -t "+%Y%m%dT%H%M%S" "^(wc7hq|n7bel)"
#%
#================================================================
#- IMPLEMENTATION
#- version ${SCRIPT_NAME} 1.1.7
#- author Steve Magnuson, AG7GN
#- license CC-BY-SA Creative Commons License
#- script_id 0
#-
#================================================================
# HISTORY
# 20200203 : Steve Magnuson : Script creation
#
#================================================================
# DEBUG OPTION
# set -n # Uncomment to check your syntax, without execution.
# set -x # Uncomment to debug this shell script
#
#================================================================
# END_OF_HEADER
#================================================================
SYNTAX=false
DEBUG=false
#============================
# FUNCTIONS
#============================
function TrapCleanup() {
[[ -d "${TMPDIR}" ]] && rm -rf "${TMPDIR}/"
exit 0
}
function SafeExit() {
# Delete temp files, if any
[[ -d "${TMPDIR}" ]] && rm -rf "${TMPDIR}/"
trap - INT TERM EXIT
exit
}
function ScriptInfo() {
HEAD_FILTER="^#-"
[[ "$1" = "usage" ]] && HEAD_FILTER="^#+"
[[ "$1" = "full" ]] && HEAD_FILTER="^#[%+]"
[[ "$1" = "version" ]] && HEAD_FILTER="^#-"
head -${SCRIPT_HEADSIZE:-99} ${0} | grep -e "${HEAD_FILTER}" | \
sed -e "s/${HEAD_FILTER}//g" \
-e "s/\${SCRIPT_NAME}/${SCRIPT_NAME}/g" \
-e "s/\${MIN_WAIT}/${MIN_WAIT}/g" \
-e "s/\${MAX_WAIT}/${MAX_WAIT}/g" \
-e "s/\${WAIT}/${WAIT}/g" \
-e "s/\${FSQ_AUDIT_FILE}/${FSQ_AUDIT_FILE}/g"
}
function Usage() {
printf "Usage: "
ScriptInfo usage
exit
}
function Die () {
echo "${*} Exiting."
SafeExit
}
#----------------------------
function ProcessMessage () {
if [[ $LINE =~ $SEARCH_STRING ]]
then
LINE="$(echo $LINE | sed -e "s/$EOM_RE//")"
[[ $DATE_CMD != "" ]] && LINE="$($DATE_CMD) $LINE"
echo "$LINE"
if (( $(( $(date +%s) - LAST )) >= $WAIT ))
then # It's been more than $WAIT seconds since last match. OK to run user script.
$SCRIPT &
LAST=$(date +%s) # Reset timer
fi
fi
}
#============================
# FILES AND VARIABLES
#============================
#== general variables ==#
SCRIPT_NAME="$(basename ${0})" # scriptname without path
SCRIPT_DIR="$( cd $(dirname "$0") && pwd )" # script directory
SCRIPT_FULLPATH="${SCRIPT_DIR}/${SCRIPT_NAME}"
SCRIPT_ID="$(ScriptInfo | grep script_id | tr -s ' ' | cut -d' ' -f3)"
SCRIPT_HEADSIZE=$(grep -sn "^# END_OF_HEADER" ${0} | head -1 | cut -f1 -d:)
# Set Temp Directory
# -----------------------------------
# Create temp directory with three random numbers and the process ID
# in the name. This directory is removed automatically at exit.
# -----------------------------------
#TMPDIR="/tmp/${SCRIPT_NAME}.$RANDOM.$RANDOM.$RANDOM.$$"
#(umask 077 && mkdir "${TMPDIR}") || {
# Die "Could not create temporary directory! Exiting."
#}
FSQ_AUDIT_FILE="fsq_audit_log.txt"
TAIL_FILES="$HOME/.fldigi-left/temp/$FSQ_AUDIT_FILE $HOME/.fldigi-right/temp/$FSQ_AUDIT_FILE $HOME/.fldigi/temp/$FSQ_AUDIT_FILE"
WAV_FILE="/usr/lib/libreoffice/share/gallery/sounds/untie.wav"
declare -i WAIT=0
declare -i MIN_WAIT=0
declare -i MAX_WAIT=300
#============================
# PARSE OPTIONS WITH GETOPTS
#============================
#== set short options ==#
SCRIPT_OPTS=':hs:w:t:v-:'
#== set long options associated with short one ==#
typeset -A ARRAY_OPTS
ARRAY_OPTS=(
[help]=h
[version]=v
[man]=h
[script]=s
[timestamp]=t
[wait]=w
)
# Parse options
while getopts ${SCRIPT_OPTS} OPTION
do
# Translate long options to short
if [[ "x$OPTION" == "x-" ]]
then
LONG_OPTION=$OPTARG
LONG_OPTARG=$(echo $LONG_OPTION | grep "=" | cut -d'=' -f2)
LONG_OPTIND=-1
[[ "x$LONG_OPTARG" = "x" ]] && LONG_OPTIND=$OPTIND || LONG_OPTION=$(echo $OPTARG | cut -d'=' -f1)
[[ $LONG_OPTIND -ne -1 ]] && eval LONG_OPTARG="\$$LONG_OPTIND"
OPTION=${ARRAY_OPTS[$LONG_OPTION]}
[[ "x$OPTION" = "x" ]] && OPTION="?" OPTARG="-$LONG_OPTION"
if [[ $( echo "${SCRIPT_OPTS}" | grep -c "${OPTION}:" ) -eq 1 ]]
then
if [[ "x${LONG_OPTARG}" = "x" ]] || [[ "${LONG_OPTARG}" = -* ]]
then
OPTION=":" OPTARG="-$LONG_OPTION"
else
OPTARG="$LONG_OPTARG";
if [[ $LONG_OPTIND -ne -1 ]]
then
[[ $OPTIND -le $Optnum ]] && OPTIND=$(( $OPTIND+1 ))
shift $OPTIND
OPTIND=1
fi
fi
fi
fi
# Options followed by another option instead of argument
if [[ "x${OPTION}" != "x:" ]] && [[ "x${OPTION}" != "x?" ]] && [[ "${OPTARG}" = -* ]]
then
OPTARG="$OPTION" OPTION=":"
fi
# Finally, manage options
case "$OPTION" in
h)
ScriptInfo full
exit 0
;;
s)
SCRIPT="$OPTARG"
#[[ -s "$SCRIPT" ]] || Die "${SCRIPT_NAME}: \""$SCRIPT"\" not found."
;;
t)
DATE_FORMAT="$OPTARG"
DATE_CMD=""
if [[ $DATE_FORMAT != "" ]]
then
date "$DATE_FORMAT" >/dev/null 2>&1 || Die "${SCRIPT_NAME}: Invalid timestamp date format. See 'man date'"
DATE_CMD="date "$DATE_FORMAT""
else
DATE_CMD="date"
fi
;;
w)
WAIT=$OPTARG
(( WAIT>=MIN_WAIT )) && (( WAIT<=MAX_WAIT )) || Die "${SCRIPT_NAME}: Wait time must be between $MIN_WAIT and $MAX_WAIT"
;;
v)
ScriptInfo version
exit 0
;;
:)
Die "${SCRIPT_NAME}: -$OPTARG: option requires an argument"
;;
?)
Die "${SCRIPT_NAME}: -$OPTARG: unknown option"
;;
esac
done
shift $((${OPTIND} - 1)) ## shift options
#============================
# MAIN SCRIPT
#============================
# Trap bad exits with cleanup function
trap SafeExit EXIT INT TERM
# Exit on error. Append '||true' when you run the script if you expect an error.
set -o errexit
# Check Syntax if set
$SYNTAX && set -n
# Run in debug mode, if set
$DEBUG && set -x
# Don't run this script again if it's already running
pgrep -f "tail --pid=.*fsq_audit_log.txt" >/dev/null 2>&1 && SafeExit
VERSION="$(ScriptInfo version | grep version | tr -s ' ' | cut -d' ' -f 4)"
SEARCH_STRING="${1:-.*}" # Match anything if no search_string supplied.
#SCRIPT="${SCRIPT:-aplay -q $WAV_FILE}"
declare -i LAST=$(( $(date +%s) - WAIT ))
PID="$(pgrep -n fldigi)"
# Start Of Message Regular Expression
SOM_RE="^[a-z]{1,2}[0-9].*:..[a-z]{1,2}[0-9]"
# End Of Message Regular Expression. FSQ end in '<BS>'. read cmd chops off trailing '>'
EOM_RE="<BS$"
COMPLETE_MESSAGE_RE="${SOM_RE}.*${EOM_RE}"
while [[ $PID != "" ]]
do # At least one fldigi instance is running. Check messages until that process stops.
TAIL="$(command -v tail) --pid=$PID -q -F -n 0 $TAIL_FILES"
PARTIAL_MSG=""
while IFS= read -d '>' -r LINE # Use '>' as line delimiter rather than '\n'
do
if [[ $LINE =~ $COMPLETE_MESSAGE_RE ]]
then # Complete message found. Process it.
ProcessMessage
PARTIAL_MSG=""
continue
fi
if [[ $LINE =~ $SOM_RE ]]
then
# Start of message found. Start constructing a PARTIAL_MSG and restore
# the '>' that read chopped off.
PARTIAL_MSG="${PARTIAL_MSG}${LINE}>"
continue
fi
if [[ $PARTIAL_MSG != "" ]]
then # PARTIAL_MSG under construction
if [[ $LINE =~ $EOM_RE ]]
then
# LINE contains EOM_RE, so append it to PARTIAL_MSG and see if it's a
# complete message
PARTIAL_MSG="${PARTIAL_MSG}${LINE}"
if [[ $PARTIAL_MSG =~ $COMPLETE_MESSAGE_RE ]]
then # PARTIAL_MSG now appears to be a valid message. Process it.
LINE="$PARTIAL_MSG"
ProcessMessage
fi
PARTIAL_MSG=""
else
# EOM_RE not found, but there is an embedded '>' in LINE.
# Add LINE to PARTIAL_MSG and restore '>' that read chopped off.
PARTIAL_MSG="${PARTIAL_MSG}${LINE}>"
fi
fi
done < <($TAIL 2>/dev/null | stdbuf -o0 tr -cd '\11\12\15\40-\176' | stdbuf -o0 tr -d '\n')
#done < <($TAIL 2>/dev/null | cat -v | stdbuf -o0 tr -d '\n')
# Get most recent fldigi PID
PID="$(pgrep -n fldigi)"
done
SafeExit

View File

@ -1 +1 @@
VERSION="1.9.4" VERSION="2.0.0"

View File

@ -1,23 +1,188 @@
#!/bin/bash #!/bin/bash
#================================================================
# HEADER
#================================================================
#% SYNOPSIS
#+ ${SCRIPT_NAME} [-hv]
#%
#% DESCRIPTION
#% This script generates new VNC server and SSH server and client keys and restores
#% certain ham radio application configurations to default values at boot time
#% if a file named DO_NOT_DELETE_THIS_FILE file does not exist in the user's
#% home directory.
#%
#% Run this script whenever the Pi boots by adding a crontab entry, like this:
#%
#% 1) Run crontab -e
#% 2) Add the following line to the end:
#%
#% @reboot sleep 5 && /usr/local/bin/initialize-pi.sh
#%
#% 3) Save and exit the crontab editor
#%
#% OPTIONS
#% -h, --help Print this help
#% -v, --version Print script information
#%
#================================================================
#- IMPLEMENTATION
#- version ${SCRIPT_NAME} 1.16.3
#- author Steve Magnuson, AG7GN
#- license CC-BY-SA Creative Commons License
#- script_id 0
#-
#================================================================
# HISTORY
# 20181220 : Steve Magnuson : Script creation
# 20200204 : Steve Magnuson : Added script template
#
#================================================================
# DEBUG OPTION
# set -n # Uncomment to check your syntax, without execution.
# set -x # Uncomment to debug this shell script
#
#================================================================
# END_OF_HEADER
#================================================================
VERSION="1.15.2" SYNTAX=false
DEBUG=false
#============================
# FUNCTIONS
#============================
function TrapCleanup() {
[[ -d "${TMPDIR}" ]] && rm -rf "${TMPDIR}/"
exit 0
}
function SafeExit() {
# Delete temp files, if any
[[ -d "${TMPDIR}" ]] && rm -rf "${TMPDIR}/"
trap - INT TERM EXIT
exit
}
function ScriptInfo() {
HEAD_FILTER="^#-"
[[ "$1" = "usage" ]] && HEAD_FILTER="^#+"
[[ "$1" = "full" ]] && HEAD_FILTER="^#[%+]"
[[ "$1" = "version" ]] && HEAD_FILTER="^#-"
head -${SCRIPT_HEADSIZE:-99} ${0} | grep -e "${HEAD_FILTER}" | \
sed -e "s/${HEAD_FILTER}//g" \
-e "s/\${SCRIPT_NAME}/${SCRIPT_NAME}/g" \
-e "s/\${SPEED}/${SPEED}/g" \
-e "s/\${DEFAULT_PORTSTRING}/${DEFAULT_PORTSTRING}/g"
}
function Usage() {
printf "Usage: "
ScriptInfo usage
exit
}
function Die () {
echo "${*}"
SafeExit
}
#============================
# FILES AND VARIABLES
#============================
#== general variables ==#
SCRIPT_NAME="$(basename ${0})" # scriptname without path
SCRIPT_DIR="$( cd $(dirname "$0") && pwd )" # script directory
SCRIPT_FULLPATH="${SCRIPT_DIR}/${SCRIPT_NAME}"
SCRIPT_ID="$(ScriptInfo | grep script_id | tr -s ' ' | cut -d' ' -f3)"
SCRIPT_HEADSIZE=$(grep -sn "^# END_OF_HEADER" ${0} | head -1 | cut -f1 -d:)
VERSION="$(ScriptInfo version | grep version | tr -s ' ' | cut -d' ' -f 4)"
#
# Script to generate new VNC server and SSH server keys at boot time if a certain
# file does not exist. Run this script whenever the Pi boots by adding a crontab
# entry, like this:
#
# 1) Run crontab -e
# 2) Add the following line to the end:
#
# @reboot sleep 5 && /usr/local/bin/initialize-pi.sh
#
# 3) Save and exit the crontab editor
#
DIR="$HOME" DIR="$HOME"
INIT_DONE_FILE="$DIR/DO_NOT_DELETE_THIS_FILE" INIT_DONE_FILE="$DIR/DO_NOT_DELETE_THIS_FILE"
#============================
# PARSE OPTIONS WITH GETOPTS
#============================
#== set short options ==#
SCRIPT_OPTS=':hv-:'
#== set long options associated with short one ==#
typeset -A ARRAY_OPTS
ARRAY_OPTS=(
[help]=h
[version]=v
)
# Parse options
while getopts ${SCRIPT_OPTS} OPTION ; do
# Translate long options to short
if [[ "x$OPTION" == "x-" ]]; then
LONG_OPTION=$OPTARG
LONG_OPTARG=$(echo $LONG_OPTION | grep "=" | cut -d'=' -f2)
LONG_OPTIND=-1
[[ "x$LONG_OPTARG" = "x" ]] && LONG_OPTIND=$OPTIND || LONG_OPTION=$(echo $OPTARG | cut -d'=' -f1)
[[ $LONG_OPTIND -ne -1 ]] && eval LONG_OPTARG="\$$LONG_OPTIND"
OPTION=${ARRAY_OPTS[$LONG_OPTION]}
[[ "x$OPTION" = "x" ]] && OPTION="?" OPTARG="-$LONG_OPTION"
if [[ $( echo "${SCRIPT_OPTS}" | grep -c "${OPTION}:" ) -eq 1 ]]; then
if [[ "x${LONG_OPTARG}" = "x" ]] || [[ "${LONG_OPTARG}" = -* ]]; then
OPTION=":" OPTARG="-$LONG_OPTION"
else
OPTARG="$LONG_OPTARG";
if [[ $LONG_OPTIND -ne -1 ]]; then
[[ $OPTIND -le $Optnum ]] && OPTIND=$(( $OPTIND+1 ))
shift $OPTIND
OPTIND=1
fi
fi
fi
fi
# Options followed by another option instead of argument
if [[ "x${OPTION}" != "x:" ]] && [[ "x${OPTION}" != "x?" ]] && [[ "${OPTARG}" = -* ]]; then
OPTARG="$OPTION" OPTION=":"
fi
# Finally, manage options
case "$OPTION" in
h)
ScriptInfo full
exit 0
;;
v)
ScriptInfo version
exit 0
;;
:)
Die "${SCRIPT_NAME}: -$OPTARG: option requires an argument"
;;
?)
Die "${SCRIPT_NAME}: -$OPTARG: unknown option"
;;
esac
done
shift $((${OPTIND} - 1)) ## shift options
#============================
# MAIN SCRIPT
#============================
# Trap bad exits with cleanup function
trap SafeExit EXIT INT TERM
# Exit on error. Append '||true' when you run the script if you expect an error.
set -o errexit
# Check Syntax if set
$SYNTAX && set -n
# Run in debug mode, if set
$DEBUG && set -x
# Does $INIT_DONE_FILE exist? Is it a regular file? Is it not empty? If YES to all, then # Does $INIT_DONE_FILE exist? Is it a regular file? Is it not empty? If YES to all, then
# exit. # exit.
if [ -e "$INIT_DONE_FILE" ] && [ -f "$INIT_DONE_FILE" ] && [ -s "$INIT_DONE_FILE" ] if [ -e "$INIT_DONE_FILE" ] && [ -f "$INIT_DONE_FILE" ] && [ -s "$INIT_DONE_FILE" ]

View File

@ -1,31 +1,175 @@
#!/bin/bash #!/bin/bash
#================================================================
# HEADER
#================================================================
#% SYNOPSIS
#+ ${SCRIPT_NAME} [-hv]
#%
#% DESCRIPTION
#% This script allows the user to change the title bar of Fldigi suite and Direwolf
#% applications so they say something other than "Left Radio" or "Right Radio".
#%
#% OPTIONS
#% -h, --help Print this help
#% -v, --version Print script information
#%
#================================================================
#- IMPLEMENTATION
#- version ${SCRIPT_NAME} 1.3.2
#- author Steve Magnuson, AG7GN
#- license CC-BY-SA Creative Commons License
#- script_id 0
#-
#================================================================
# HISTORY
# 20190327 : Steve Magnuson : Script creation
# 20200204 : Steve Magnuson : Added script template
#
#================================================================
# DEBUG OPTION
# set -n # Uncomment to check your syntax, without execution.
# set -x # Uncomment to debug this shell script
#
#================================================================
# END_OF_HEADER
#================================================================
VERSION="1.0.4" SYNTAX=false
DEBUG=false
# This script allows the user to change the title bar of Fldigi suite and Direwolf #============================
# applications so they say something other than "Left Radio" or "Right Radio" # FUNCTIONS
#============================
function TrapCleanup() {
[[ -d "${TMPDIR}" ]] && rm -rf "${TMPDIR}/"
exit 0
}
function SafeExit() {
# Delete temp files, if any
[[ -d "${TMPDIR}" ]] && rm -rf "${TMPDIR}/"
trap - INT TERM EXIT
exit
}
function ScriptInfo() {
HEAD_FILTER="^#-"
[[ "$1" = "usage" ]] && HEAD_FILTER="^#+"
[[ "$1" = "full" ]] && HEAD_FILTER="^#[%+]"
[[ "$1" = "version" ]] && HEAD_FILTER="^#-"
head -${SCRIPT_HEADSIZE:-99} ${0} | grep -e "${HEAD_FILTER}" | \
sed -e "s/${HEAD_FILTER}//g" \
-e "s/\${SCRIPT_NAME}/${SCRIPT_NAME}/g" \
-e "s/\${SPEED}/${SPEED}/g" \
-e "s/\${DEFAULT_PORTSTRING}/${DEFAULT_PORTSTRING}/g"
}
function Usage() {
printf "Usage: "
ScriptInfo usage
exit
}
function Die () {
echo "${*}"
SafeExit
}
#============================
# FILES AND VARIABLES
#============================
#== general variables ==#
SCRIPT_NAME="$(basename ${0})" # scriptname without path
SCRIPT_DIR="$( cd $(dirname "$0") && pwd )" # script directory
SCRIPT_FULLPATH="${SCRIPT_DIR}/${SCRIPT_NAME}"
SCRIPT_ID="$(ScriptInfo | grep script_id | tr -s ' ' | cut -d' ' -f3)"
SCRIPT_HEADSIZE=$(grep -sn "^# END_OF_HEADER" ${0} | head -1 | cut -f1 -d:)
VERSION="$(ScriptInfo version | grep version | tr -s ' ' | cut -d' ' -f 4)"
TITLE="Left/Right Radio Name Editor $VERSION" TITLE="Left/Right Radio Name Editor $VERSION"
CONFIG_FILE="$HOME/radionames.conf" CONFIG_FILE="$HOME/radionames.conf"
trap errorReport INT #============================
# PARSE OPTIONS WITH GETOPTS
#============================
function errorReport () { #== set short options ==#
echo SCRIPT_OPTS=':hv-:'
if [[ $1 == "" ]]
then #== set long options associated with short one ==#
typeset -A ARRAY_OPTS
ARRAY_OPTS=(
[help]=h
[version]=v
)
# Parse options
while getopts ${SCRIPT_OPTS} OPTION ; do
# Translate long options to short
if [[ "x$OPTION" == "x-" ]]; then
LONG_OPTION=$OPTARG
LONG_OPTARG=$(echo $LONG_OPTION | grep "=" | cut -d'=' -f2)
LONG_OPTIND=-1
[[ "x$LONG_OPTARG" = "x" ]] && LONG_OPTIND=$OPTIND || LONG_OPTION=$(echo $OPTARG | cut -d'=' -f1)
[[ $LONG_OPTIND -ne -1 ]] && eval LONG_OPTARG="\$$LONG_OPTIND"
OPTION=${ARRAY_OPTS[$LONG_OPTION]}
[[ "x$OPTION" = "x" ]] && OPTION="?" OPTARG="-$LONG_OPTION"
if [[ $( echo "${SCRIPT_OPTS}" | grep -c "${OPTION}:" ) -eq 1 ]]; then
if [[ "x${LONG_OPTARG}" = "x" ]] || [[ "${LONG_OPTARG}" = -* ]]; then
OPTION=":" OPTARG="-$LONG_OPTION"
else
OPTARG="$LONG_OPTARG";
if [[ $LONG_OPTIND -ne -1 ]]; then
[[ $OPTIND -le $Optnum ]] && OPTIND=$(( $OPTIND+1 ))
shift $OPTIND
OPTIND=1
fi
fi
fi
fi
# Options followed by another option instead of argument
if [[ "x${OPTION}" != "x:" ]] && [[ "x${OPTION}" != "x?" ]] && [[ "${OPTARG}" = -* ]]; then
OPTARG="$OPTION" OPTION=":"
fi
# Finally, manage options
case "$OPTION" in
h)
ScriptInfo full
exit 0 exit 0
else ;;
if [[ $2 == "" ]] v)
then ScriptInfo version
echo >&2 "$1" exit 0
exit 1 ;;
else :)
echo >&2 "$1" Die "${SCRIPT_NAME}: -$OPTARG: option requires an argument"
exit $2 ;;
fi ?)
fi Die "${SCRIPT_NAME}: -$OPTARG: unknown option"
} ;;
esac
done
shift $((${OPTIND} - 1)) ## shift options
#============================
# MAIN SCRIPT
#============================
# Trap bad exits with cleanup function
trap SafeExit EXIT INT TERM
# Exit on error. Append '||true' when you run the script if you expect an error.
set -o errexit
# Check Syntax if set
$SYNTAX && set -n
# Run in debug mode, if set
$DEBUG && set -x
if [ -s "$CONFIG_FILE" ] if [ -s "$CONFIG_FILE" ]
then # There is a config file then # There is a config file
@ -38,11 +182,9 @@ else # Set some default values in a new config file
source "$CONFIG_FILE" source "$CONFIG_FILE"
fi fi
ANS="" ANS=""
ANS="$(yad --title="$TITLE" \ ANS="$(yad --title="$TITLE" \
--text="<b><big><big>Name Your Radios</big></big>\n\n</b>Status: <b><span color='blue'>$STATUS</span>\n\n \ --text="<b><big><big>Name Your Radios</big></big></b>\n" \
$MESSAGE</b>\n" \
--item-separator="!" \ --item-separator="!" \
--center \ --center \
--buttons-layout=center \ --buttons-layout=center \
@ -55,9 +197,9 @@ $MESSAGE</b>\n" \
--focus-field 1 \ --focus-field 1 \
)" )"
[[ $? == 1 || $? == 252 ]] && errorReport # User has cancelled. [[ $? == 1 || $? == 252 ]] && SafeExit # User has cancelled.
[[ $ANS == "" ]] && errorReport "Error." 1 [[ $ANS == "" ]] && Die "No input supplied."
IFS='|' read -r -a TF <<< "$ANS" IFS='|' read -r -a TF <<< "$ANS"
@ -71,5 +213,5 @@ for F in `ls $D/*-left.template` `ls $D/*-right.template`
do do
sudo sed -e "s/_LEFT_RADIO_/$LEFT_RADIO_NAME/" -e "s/_RIGHT_RADIO_/$RIGHT_RADIO_NAME/g" $F > ${F%.*}.desktop sudo sed -e "s/_LEFT_RADIO_/$LEFT_RADIO_NAME/" -e "s/_RIGHT_RADIO_/$RIGHT_RADIO_NAME/g" $F > ${F%.*}.desktop
done done
SafeExit

View File

@ -1,54 +1,226 @@
#!/bin/bash #!/bin/bash
#================================================================
# HEADER
#================================================================
#% SYNOPSIS
#+ ${SCRIPT_NAME} [-hv] TO SUBECT TRANSPORT
#%
#% DESCRIPTION
#% This script allows sending Winlink messages via the command line or script.
#% It requires pat (a Winlink client) and the dos2unix program.
#% The body of the message is supplied to the script from STDIN. See EXAMPLES below.
#%
#% OPTIONS
#% -h, --help Print this help
#% -v, --version Print script information
#%
#% COMMANDS (All 3 COMMANDS are required)
#% TO One or more recipient comma separated email addresses.
#% Winlink email addresses (CALL@winlink.org)
#% do not need to include '@winlink.org', just the
#% call sign.
#%
#% SUBJECT Email subject enclosed in "double quotes".
#%
#% TRANSPORT pat transport method. For example:
#% telnet
#% ax25:///call-ssid
#% where call-ssid is the RMS gateway. Example:
#% ax25:///W7ECG-10
#%
#% Run 'pat connect help' to see more transport
#% types.
#%
#% EXAMPLES
#% Send two lines of text to callsign N0ONE@winlink.org via telnet:
#%
#% echo -e "1st line\n2nd line" | ${SCRIPT_NAME} N0ONE "My Subject" telnet
#%
#% Send the contents of file 'myfile.txt' to me@example.com and W7ABC@winlink.org
#% via telnet:
#%
#% cat myfile.txt | ${SCRIPT_NAME} me@example.com,W7ABC "My Important Message" telnet
#%
#% Send the contents of 'myfile.txt' to me@example.com and W7ABC@winlink.org using
#% packet radio via RMS gateway ax25:///W7ECG-10
#%
#% ${SCRIPT_NAME} me@example.com,W7ABC "My Important Message" ax25:///W7ECG-10 < myfile.txt
#%
#================================================================
#- IMPLEMENTATION
#- version ${SCRIPT_NAME} 2.1.2
#- author Steve Magnuson, AG7GN
#- license CC-BY-SA Creative Commons License
#- script_id 0
#-
#================================================================
# HISTORY
# 20190920 : Steve Magnuson : Script creation
# 20200204 : Steve Magnuson : Added script template
#
#================================================================
# DEBUG OPTION
# set -n # Uncomment to check your syntax, without execution.
# set -x # Uncomment to debug this shell script
#
#================================================================
# END_OF_HEADER
#================================================================
VERSION="1.0.8" SYNTAX=false
DEBUG=false
# This script allows sending Winlink messages via the command line or script. #============================
# It requires pat (a Winlink client) and the dos2unix programs. # FUNCTIONS
#============================
function Usage () { function TrapCleanup() {
echo [[ -d "${TMPDIR}" ]] && rm -rf "${TMPDIR}/"
echo "ERROR: $1" exit 0
echo
echo "$(basename $0) version $VERSION"
echo
echo "Usage: $(basename $0) To Subject Transport"
echo
echo "Where:"
echo
echo " To One or more destination email addresses, separated"
echo " by a comma. Winlink addresses need only be the call sign,"
echo " no need to include '@winlink.org'."
echo
echo " Subject The subject of the message. Put double quotes"
echo " around it if it contains spaces."
echo
echo " Transport The pat transport type. Examples:"
echo
echo " telnet"
echo " ax25:///call-ssid"
echo " where call-ssid is the RMS Gateway. Example: W7ECG-10"
echo
echo " Run 'pat connect help' for more examples."
echo
echo "Pass the body of the message to the script from stdin. Examples:"
echo
echo " echo -e \"1st line of body\\n2nd line\" | $(basename $0) N0ONE \"My Subject\" telnet"
echo " cat myfile.txt | $(basename $0) me@example.com,W7ABC \"My Important Message\" telnet"
echo " $(basename $0) me@example.com,W7ABC \"My Important Message\" telnet < myfile.txt"
echo
exit 1
} }
(( $# != 3 )) && Usage "3 arguments are required." function SafeExit() {
# Delete temp files, if any
[[ -d "${TMPDIR}" ]] && rm -rf "${TMPDIR}/"
trap - INT TERM EXIT
exit
}
function ScriptInfo() {
HEAD_FILTER="^#-"
[[ "$1" = "usage" ]] && HEAD_FILTER="^#+"
[[ "$1" = "full" ]] && HEAD_FILTER="^#[%+]"
[[ "$1" = "version" ]] && HEAD_FILTER="^#-"
head -${SCRIPT_HEADSIZE:-99} ${0} | grep -e "${HEAD_FILTER}" | \
sed -e "s/${HEAD_FILTER}//g" \
-e "s/\${SCRIPT_NAME}/${SCRIPT_NAME}/g" \
-e "s/\${SPEED}/${SPEED}/g" \
-e "s/\${DEFAULT_PORTSTRING}/${DEFAULT_PORTSTRING}/g"
}
function Usage() {
printf "Usage: "
ScriptInfo usage
exit
}
function Die () {
echo "${*}"
SafeExit
}
#============================
# FILES AND VARIABLES
#============================
# Set Temp Directory
# -----------------------------------
# Create temp directory with three random numbers and the process ID
# in the name. This directory is removed automatically at exit.
# -----------------------------------
TMPDIR="/tmp/${SCRIPT_NAME}.$RANDOM.$RANDOM.$RANDOM.$$"
(umask 077 && mkdir "${TMPDIR}") || {
Die "Could not create temporary directory! Exiting."
}
#== general variables ==#
SCRIPT_NAME="$(basename ${0})" # scriptname without path
SCRIPT_DIR="$( cd $(dirname "$0") && pwd )" # script directory
SCRIPT_FULLPATH="${SCRIPT_DIR}/${SCRIPT_NAME}"
SCRIPT_ID="$(ScriptInfo | grep script_id | tr -s ' ' | cut -d' ' -f3)"
SCRIPT_HEADSIZE=$(grep -sn "^# END_OF_HEADER" ${0} | head -1 | cut -f1 -d:)
VERSION="$(ScriptInfo version | grep version | tr -s ' ' | cut -d' ' -f 4)"
#============================
# PARSE OPTIONS WITH GETOPTS
#============================
#== set short options ==#
SCRIPT_OPTS=':hv-:'
#== set long options associated with short one ==#
typeset -A ARRAY_OPTS
ARRAY_OPTS=(
[help]=h
[version]=v
)
# Parse options
while getopts ${SCRIPT_OPTS} OPTION ; do
# Translate long options to short
if [[ "x$OPTION" == "x-" ]]; then
LONG_OPTION=$OPTARG
LONG_OPTARG=$(echo $LONG_OPTION | grep "=" | cut -d'=' -f2)
LONG_OPTIND=-1
[[ "x$LONG_OPTARG" = "x" ]] && LONG_OPTIND=$OPTIND || LONG_OPTION=$(echo $OPTARG | cut -d'=' -f1)
[[ $LONG_OPTIND -ne -1 ]] && eval LONG_OPTARG="\$$LONG_OPTIND"
OPTION=${ARRAY_OPTS[$LONG_OPTION]}
[[ "x$OPTION" = "x" ]] && OPTION="?" OPTARG="-$LONG_OPTION"
if [[ $( echo "${SCRIPT_OPTS}" | grep -c "${OPTION}:" ) -eq 1 ]]; then
if [[ "x${LONG_OPTARG}" = "x" ]] || [[ "${LONG_OPTARG}" = -* ]]; then
OPTION=":" OPTARG="-$LONG_OPTION"
else
OPTARG="$LONG_OPTARG";
if [[ $LONG_OPTIND -ne -1 ]]; then
[[ $OPTIND -le $Optnum ]] && OPTIND=$(( $OPTIND+1 ))
shift $OPTIND
OPTIND=1
fi
fi
fi
fi
# Options followed by another option instead of argument
if [[ "x${OPTION}" != "x:" ]] && [[ "x${OPTION}" != "x?" ]] && [[ "${OPTARG}" = -* ]]; then
OPTARG="$OPTION" OPTION=":"
fi
# Finally, manage options
case "$OPTION" in
h)
ScriptInfo full
exit 0
;;
v)
ScriptInfo version
exit 0
;;
:)
Die "${SCRIPT_NAME}: -$OPTARG: option requires an argument"
;;
?)
Die "${SCRIPT_NAME}: -$OPTARG: unknown option"
;;
esac
done
shift $((${OPTIND} - 1)) ## shift options
#============================
# MAIN SCRIPT
#============================
# Trap bad exits with cleanup function
trap SafeExit EXIT INT TERM
# Exit on error. Append '||true' when you run the script if you expect an error.
set -o errexit
# Check Syntax if set
$SYNTAX && set -n
# Run in debug mode, if set
$DEBUG && set -x
(( $# != 3 )) && Die "3 commands, TO, SUBJECT and TRANSPORT are required."
PAT="$(command -v pat)" PAT="$(command -v pat)"
[[ $? == 0 ]] || Usage "pat winlink client is not installed." [[ $? == 0 ]] || Die "pat winlink client is not installed."
UNIX2DOS="$(command -v unix2dos)" UNIX2DOS="$(command -v unix2dos)"
[[ $UNIX2DOS == "" ]] && Usage "dos2unix tools are not installed." [[ $UNIX2DOS == "" ]] && Die "dos2unix tools are not installed."
PATDIR="$HOME/.wl2k" PATDIR="$HOME/.wl2k"
CALL="$(cat $PATDIR/config.json | grep "\"mycall\":" | tr -d ' ",' | cut -d: -f2)" CALL="$(cat $PATDIR/config.json | grep "\"mycall\":" | tr -d ' ",' | cut -d: -f2)"
[[ $CALL == "" ]] && Usage "Could not obtain call sign from $PATDIR/config.json. Is pat configured?" [[ $CALL == "" ]] && Die "Could not obtain call sign from $PATDIR/config.json. Is pat configured?"
OUTDIR="$PATDIR/mailbox/$CALL/out" OUTDIR="$PATDIR/mailbox/$CALL/out"
TO="$1" TO="$1"
@ -57,10 +229,10 @@ SUBJECT="$2"
[[ $TO =~ "," ]] || TO="$TO\n" [[ $TO =~ "," ]] || TO="$TO\n"
export EDITOR=ed export EDITOR=ed
TFILE="$(mktemp)" TFILE="${TMPDIR}/message"
echo -e "$CALL\n$TO\n\n$SUBJECT" | $PAT compose 2>/dev/null 1> $TFILE echo -e "$CALL\n$TO\n\n$SUBJECT" | $PAT compose 2>/dev/null 1> $TFILE
MSG="$(grep "MID:" $TFILE | tr -d ' \t' | cut -d':' -f3)" MSG="$(grep "MID:" $TFILE | tr -d ' \t' | cut -d':' -f3)"
[[ $MSG == "" ]] && Usage "Could not find the MID (Message ID)" [[ $MSG == "" ]] && Die "Could not find the MID (Message ID)"
MSG="$OUTDIR/$MSG.b2f" MSG="$OUTDIR/$MSG.b2f"
sed -i -e 's/<No message body>//' $MSG sed -i -e 's/<No message body>//' $MSG
$UNIX2DOS -q $MSG $UNIX2DOS -q $MSG
@ -68,7 +240,7 @@ cat - > $TFILE
$UNIX2DOS -q $TFILE $UNIX2DOS -q $TFILE
COUNT="$(wc -c $TFILE | cut -d' ' -f1)" COUNT="$(wc -c $TFILE | cut -d' ' -f1)"
cat $TFILE >> $MSG cat $TFILE >> $MSG
rm $TFILE #rm $TFILE
sed -i -e "s/^Body: .*/Body: $COUNT/" $MSG sed -i -e "s/^Body: .*/Body: $COUNT/" $MSG
$PAT --send-only --event-log /dev/null connect $3 >/dev/null 2>&1 $PAT --send-only --event-log /dev/null connect $3 >/dev/null 2>&1
exit $? exit $?

420
tnc.sh
View File

@ -1,109 +1,171 @@
#!/bin/bash #!/bin/bash
#================================================================
# HEADER
#================================================================
#% SYNOPSIS
#+ ${SCRIPT_NAME} [-hv]
#+ ${SCRIPT_NAME} [-c FILE] start COMMAND [COMMAND ...]
#+ ${SCRIPT_NAME} stop
#%
#% DESCRIPTION
#% This script will start direwolf in one of 3 APRS modes: igate, digipeater,
#% or igate + digipeater, OR in AX.25 mode as a TNC for Winlink or other apps.
#% Use the companion script watchdog-tnc.sh in crontab to launch this script
#% and keep it running.
#%
#% OPTIONS
#% -c FILE, --config=FILE
#% Override using the default configuration file.
#% Default configuration file is $HOME/tnc.conf
#%
#% -h, --help Print this help
#% -v, --version Print script information
#%
#% COMMANDS
#% ${SCRIPT_NAME} [-c FILE] start ax25|ax25+pat [1200|9600 [2]]
#% Starts the ax25 TNC or the ax25 TNC and pat email
#% client."
#% Note that pat requires configuration in
#% $HOME/.wl2k/config.json.
#%
#% Direwolf baud set to 1200 bps (for V/UHF) on a single
#% audio channel by default.
#% You can optionally specify baud (1200 or 9600) and
#% number of audio channels. 9600 might work on V/UHF
#% with another 9600 station depending on conditions and
#% the capabilities of your soundcard. 9600 will likely
#% not work with a Signalink.
#% If you specify the baud, you can optionally also
#% specify '2' to tell Direwolf to use both channels.
#% '2' assumes" you have a stereo audio card *and* direwolf
#% is configured to use both channels of the stereo sound
#% card.
#% Winlink clients can access Direwolf's second channel by
#% selecting Packet TNC Type 'KISS Port 2' in Winlink.
#% Default is a single channel.
#% 1200 baud uses Direwolf's AFSK 1200 & 2200 Hz modem.
#% 9600 baud uses Direwolf's K9NG/G3RUH modem.
#%
#% ${SCRIPT_NAME} [-c FILE] start pat
#% Starts pat email client in telnet mode only (niether
#% ax25 nor ARDOP TNC is started).
#% Note that pat requires configuration in
#% $HOME/.wl2k/config.json.
#%
#% ${SCRIPT_NAME} [-c FILE] start ardop|ardop+pat
#% Starts the ARDOP TNC (piardop2) or the ARDOP TNC and
#% pat. Note that pat requires configuration in
#% $HOME/.wl2k/config.json.
#%
#% ${SCRIPT_NAME} [-c FILE] start digiigate [both]
#% Starts the Direwolf APRS digipeater and iGate.
#% If you specify 'both', Direwolf will decode audio on
#% channel 1 (stereo left) and channel 2 (stereo right)
#% on stereo sound cards only.
#%
#% ${SCRIPT_NAME} [-c FILE] start digi [both]
#% Starts the Direwolf APRS digipeater (only).
#% If you specify 'both', Direwolf will decode audio on
#% channel 1 (stereo left) and channel 2 (stereo right)
#% on stereo sound cards only.
#%
#% ${SCRIPT_NAME} [-c FILE] start igate [both]
#% Starts the Direwolf APRS iGate (only).
#% If you specify 'both', Direwolf will decode audio on
#% channel 1 (stereo left) and channel 2 (stereo right)
#% on stereo sound cards only.
#%
#% ${SCRIPT_NAME} stop
#% Stops all the apps. Same as pressing Ctrl-C.
#%
#% EXAMPLES
#%
#% Locate serial port file name containing ${DEFAULT_PORTSTRING} (default search string),
#% then set APO to 30 minutes:
#%
#% ${SCRIPT_NAME} set apo 30
#%
#% Override the default search string ${DEFAULT_PORTSTRING} to locate serial port
#% connected to radio, then get radio information:
#%
#% ${SCRIPT_NAME} -s Prolific_Technology get info
#%
#% Specify the serial port used to connect to your radio then set radio TX timeout
#% to 3 minutes:
#%
#% ${SCRIPT_NAME} -p /dev/ttyUSB0 set timeout 3
#%
#================================================================
#- IMPLEMENTATION
#- version ${SCRIPT_NAME} 3.3.2
#- author Steve Magnuson, AG7GN
#- license CC-BY-SA Creative Commons License
#- script_id 0
#-
#================================================================
# HISTORY
# 20180125 : Steve Magnuson : Script creation
# 20200203 : Steve Magnuson : New script template
# #
# Script Name: tnc.sh #================================================================
# Author: Steve Magnuson AG7GN # DEBUG OPTION
# Date Created: 20180601 # set -n # Uncomment to check your syntax, without execution.
# set -x # Uncomment to debug this shell script
# #
# Description: This script will start direwolf in one of 3 APRS modes: igate, digipeater, #================================================================
# or igate + digipeater, OR in AX.25 mode as a TNC for Winlink or other apps. # END_OF_HEADER
# Run tnc.sh with no arguments for instructions. #================================================================
#
# Usage: tnc.sh start digi|igate|digiigate|ax25
# tnc.sh stop
#
# Use the companion script watchdog-tnc.sh in crontab to launch this script
# to keep it running.
#
#=========================================================================================
VERSION="3.2.3"
# Functions ################################################################################ SYNTAX=false
DEBUG=false
#============================
# FUNCTIONS
#============================
function TrapCleanup() {
${SCRIPT_NAME} stop
rm -f /tmp/tnc*
rm -f $CONFFILE
exit 0
}
function SafeExit() {
${SCRIPT_NAME} stop
rm -f /tmp/tnc*
rm -f $CONFFILE
trap - INT TERM EXIT
exit
}
function ScriptInfo() {
HEAD_FILTER="^#-"
[[ "$1" = "usage" ]] && HEAD_FILTER="^#+"
[[ "$1" = "full" ]] && HEAD_FILTER="^#[%+]"
[[ "$1" = "version" ]] && HEAD_FILTER="^#-"
head -${SCRIPT_HEADSIZE:-99} ${0} | grep -e "${HEAD_FILTER}" | \
sed -e "s/${HEAD_FILTER}//g" \
-e "s/\${SCRIPT_NAME}/${SCRIPT_NAME}/g"
}
function Usage() { function Usage() {
echo printf "Usage:\n"
echo "Version $VERSION" ScriptInfo usage
echo
echo "Usage:"
echo
echo "$(basename $0) [-c CONFIG_FILE] start|stop APPLICATION(s) [OPTIONS]"
echo
echo "Examples:"
echo
echo "$(basename $0) start ax25|ax25+pat [1200|9600 [2]]"
echo " Starts the ax25 TNC or the ax25 TNC and pat email client."
echo " Note that pat requires configuration in"
echo " $HOME/.wl2k/config.json."
echo
echo " Direwolf baud set to 1200 bps (for V/UHF) on a single"
echo " audio channel by default."
echo " You can optionally specify baud (1200 or 9600) and number"
echo " of audio channels. 9600 might work on V/UHF"
echo " with another 9600 station depending on conditions and"
echo " the capabilities of your soundcard. 9600 will likely"
echo " not work with a Signalink."
echo " If you specify the baud, you can optionally also specify"
echo " 2 to tell Direwolf to use both channels. '2' assumes"
echo " you have a stereo audio card *and* direwolf is configured"
echo " to use *both* channels of the stereo sound card."
echo " Winlink clients can access Direwolf's second channel by"
echo " selecting Packet TNC Type 'KISS Port 2' in Winlink."
echo " Default is a single channel."
echo " 1200 baud uses Direwolf's AFSK 1200 & 2200 Hz modem."
echo " 9600 baud uses Direwolf's K9NG/G3RUH modem."
echo
echo "$(basename $0) start pat"
echo " Starts pat email client in telnet mode only (niether ax25"
echo " nor ARDOP TNC is started)."
echo " Note that pat requires configuration in"
echo " $HOME/.wl2k/config.json."
echo
echo "$(basename $0) start ardop|ardop+pat"
echo " Starts the ARDOP TNC (piardop2) or the ARDOP TNC and pat."
echo " Note that pat requires configuration in"
echo " $HOME/.wl2k/config.json."
echo
echo "$(basename $0) start digiigate [both]"
echo " Starts the Direwolf APRS digipeater and iGate."
echo " If you specify 'both', Direwolf will decode audio on"
echo " channel 1 (stereo left) and channel 2 (stereo right)"
echo " on stereo sound cards only."
echo
echo "$(basename $0) start digi [both]"
echo " Starts the Direwolf APRS digipeater (only)."
echo " If you specify 'both', Direwolf will decode audio on"
echo " channel 1 (stereo left) and channel 2 (stereo right)"
echo " on stereo sound cards only."
echo
echo "$(basename $0) start igate [both]"
echo " Starts the Direwolf APRS iGate (only)."
echo " If you specify 'both', Direwolf will decode audio on"
echo " channel 1 (stereo left) and channel 2 (stereo right)"
echo " on stereo sound cards only."
echo
echo "$(basename $0) stop"
echo " Stops all the apps. Same as pressing Ctrl-C."
echo
echo "By default, this script will look for the required configuration file in"
echo "$HOME/tnc.conf. You can override this by specifying the configuration file"
echo "with the '-c' option. For example:"
echo
echo " $(basename $0) -c $HOME/myTNCfile.conf start ax25"
echo
exit 1 exit 1
} }
function ctrl_c () { function Die () {
# Do cleanup if Ctrl-C is pressed. Stop all the screens. echo "${*}"
$0 stop SafeExit
exit 0
} }
#---------------------------------------
function checkApp () { function checkApp () {
APP="$(command -v $1 2>/dev/null)" APP="$(command -v $1 2>/dev/null)"
if [[ $APP == "" ]] if [[ $APP == "" ]]
then then
echo >&2 "Error: $1 is required but not installed." Die "Error: $1 is required but not installed."
exit 1
fi fi
echo "$APP" echo "$APP"
} }
@ -130,15 +192,12 @@ function checkSoundCard () {
CAP_DEV="$AUDIO_DEV" CAP_DEV="$AUDIO_DEV"
elif [[ $AUDIO_DEV_SEARCH_STRING == "" ]] elif [[ $AUDIO_DEV_SEARCH_STRING == "" ]]
then then
echo >&2 "Error: You must set either the AUDIO_DEV or AUDIO_DEV_SEARCH_STRING variables in this script to select the sound card." Die "Error: You must set either the AUDIO_DEV or AUDIO_DEV_SEARCH_STRING variables in this script to select the sound card."
exit 1
else else
CAP_DEV="$($ARECORD -l | grep -i "$AUDIO_DEV_SEARCH_STRING" | grep "card [0-9]\|device [0-9]" | sed 's/:.*,/,/;s/:.*$//;s/, /,/;s/ /=/g;s/ice//' | tr -s [:lower:] [:upper:])" CAP_DEV="$($ARECORD -l | grep -i "$AUDIO_DEV_SEARCH_STRING" | grep "card [0-9]\|device [0-9]" | sed 's/:.*,/,/;s/:.*$//;s/, /,/;s/ /=/g;s/ice//' | tr -s [:lower:] [:upper:])"
if [[ $CAP_DEV == "" ]] if [[ $CAP_DEV == "" ]]
then then
echo >&2 "Error: Unable to find audio interface using string $AUDIO_DEV_SEARCH_STRING." Die "Error: Unable to find audio interface using string $AUDIO_DEV_SEARCH_STRING."
sleep 5
exit 1
fi fi
CAP_DEV="plughw:$CAP_DEV" CAP_DEV="plughw:$CAP_DEV"
fi fi
@ -266,8 +325,7 @@ EOF
esac esac
;; ;;
*) *)
echo >&2 "Error: Valid baud settings are 1200 or 9600." Die "Error: Valid baud settings are 1200 or 9600."
exit 1
;; ;;
esac esac
;; ;;
@ -290,8 +348,7 @@ function checkSerial () {
grep "$DEVSTRING" | cut -d' ' -f3 | tr -d './')" grep "$DEVSTRING" | cut -d' ' -f3 | tr -d './')"
if [[ $SERIAL_PORT == "" ]] if [[ $SERIAL_PORT == "" ]]
then # rigctl or ardop CAT control requested, but could not find serial port then # rigctl or ardop CAT control requested, but could not find serial port
echo >&2 "Error: Could not locate serial device with name containing \"$DEVSTRING\"." Die "Error: Could not locate serial device with name containing \"$DEVSTRING\"."
exit 1
fi fi
DEVICE="/dev/$SERIAL_PORT" DEVICE="/dev/$SERIAL_PORT"
if [[ $RIGCTL_RADIO != "" ]] if [[ $RIGCTL_RADIO != "" ]]
@ -303,10 +360,16 @@ function checkSerial () {
fi fi
} }
# Initializations ########################################################################## #============================
# FILES AND VARIABLES
#============================
# trap ctrl-c and call ctrl_c() #== general variables ==#
trap ctrl_c INT SCRIPT_NAME="$(basename ${0})" # scriptname without path
SCRIPT_DIR="$( cd $(dirname "$0") && pwd )" # script directory
SCRIPT_FULLPATH="${SCRIPT_DIR}/${SCRIPT_NAME}"
SCRIPT_ID="$(ScriptInfo | grep script_id | tr -s ' ' | cut -d' ' -f3)"
SCRIPT_HEADSIZE=$(grep -sn "^# END_OF_HEADER" ${0} | head -1 | cut -f1 -d:)
TNC_CONFIG_FILE="" TNC_CONFIG_FILE=""
LOGFILE="/tmp/tnc.log" LOGFILE="/tmp/tnc.log"
@ -319,50 +382,112 @@ logtstamp after 60
log on log on
logtstamp string "[ %n:%t ] ---- TIMESTAMP ---- %Y-%m-%d %c:%s ---- Press Ctrl-C to Quit\012" logtstamp string "[ %n:%t ] ---- TIMESTAMP ---- %Y-%m-%d %c:%s ---- Press Ctrl-C to Quit\012"
EOF EOF
VERSION="$(ScriptInfo version | grep version | tr -s ' ' | cut -d' ' -f 4)"
# Check if user supplied configuration file with '-c' option #============================
declare -a ARGS # PARSE OPTIONS WITH GETOPTS
while [ $# -gt 0 ] #============================
#== set short options ==#
SCRIPT_OPTS=':hc:v-:'
#== set long options associated with short one ==#
typeset -A ARRAY_OPTS
ARRAY_OPTS=(
[help]=h
[version]=v
[man]=h
[script]=s
[timestamp]=t
[wait]=w
)
# Parse options
while getopts ${SCRIPT_OPTS} OPTION
do do
unset OPTIND # Translate long options to short
unset OPTARG if [[ "x$OPTION" == "x-" ]]
#while getopts as:c: OPTIONS then
while getopts c: OPTIONS LONG_OPTION=$OPTARG
do LONG_OPTARG=$(echo $LONG_OPTION | grep "=" | cut -d'=' -f2)
case $OPTIONS in LONG_OPTIND=-1
[[ "x$LONG_OPTARG" = "x" ]] && LONG_OPTIND=$OPTIND || LONG_OPTION=$(echo $OPTARG | cut -d'=' -f1)
[[ $LONG_OPTIND -ne -1 ]] && eval LONG_OPTARG="\$$LONG_OPTIND"
OPTION=${ARRAY_OPTS[$LONG_OPTION]}
[[ "x$OPTION" = "x" ]] && OPTION="?" OPTARG="-$LONG_OPTION"
if [[ $( echo "${SCRIPT_OPTS}" | grep -c "${OPTION}:" ) -eq 1 ]]
then
if [[ "x${LONG_OPTARG}" = "x" ]] || [[ "${LONG_OPTARG}" = -* ]]
then
OPTION=":" OPTARG="-$LONG_OPTION"
else
OPTARG="$LONG_OPTARG";
if [[ $LONG_OPTIND -ne -1 ]]
then
[[ $OPTIND -le $Optnum ]] && OPTIND=$(( $OPTIND+1 ))
shift $OPTIND
OPTIND=1
fi
fi
fi
fi
# Options followed by another option instead of argument
if [[ "x${OPTION}" != "x:" ]] && [[ "x${OPTION}" != "x?" ]] && [[ "${OPTARG}" = -* ]]
then
OPTARG="$OPTION" OPTION=":"
fi
# Finally, manage options
case "$OPTION" in
h)
ScriptInfo full
exit 0
;;
c) c)
TNC_CONFIG_FILE="$OPTARG" TNC_CONFIG_FILE="$OPTARG"
[[ -s "$TNC_CONFIG_FILE" ]] || Die "Configuration file $TNC_CONFIG_FILE is missing or empty."
;; ;;
*) v)
ScriptInfo version
exit 0
;;
:)
Die "${SCRIPT_NAME}: -$OPTARG: option requires an argument"
;;
?)
Die "${SCRIPT_NAME}: -$OPTARG: unknown option"
;; ;;
esac esac
done done
shift $((OPTIND-1)) shift $((${OPTIND} - 1)) ## shift options
ARGS+=($1)
shift #============================
done # MAIN SCRIPT
#============================
# Trap bad exits with cleanup function
trap SafeExit EXIT INT TERM
# Exit on error. Append '||true' when you run the script if you expect an error.
set -o errexit
# Check Syntax if set
$SYNTAX && set -n
# Run in debug mode, if set
$DEBUG && set -x
# No configuration file supplied, so use the default # No configuration file supplied, so use the default
[[ $TNC_CONFIG_FILE == "" ]] && TNC_CONFIG_FILE="$HOME/tnc.conf" [[ $TNC_CONFIG_FILE == "" ]] && TNC_CONFIG_FILE="$HOME/tnc.conf"
if [ -s "$TNC_CONFIG_FILE" ]
then
MYCALL=""
source $TNC_CONFIG_FILE source $TNC_CONFIG_FILE
if [[ $MYCALL =~ N0CALL || $MYCALL =~ N0ONE || $MYCALL == "" ]] [[ $MYCALL =~ N0CALL || $MYCALL =~ N0ONE || $MYCALL == "" ]] && Die "You must set the MYCALL variable in $TNC_CONFIG_FILE."
then
echo >&2 "Error: You must set the MYCALL variable in $TNC_CONFIG_FILE."
exit 1
fi
else
echo >&2 "Error: Configuration file $TNC_CONFIG_FILE is missing or empty."
exit 1
fi
ACTION="${ARGS[0],,}" # start|stop ACTION="${1,,}" # start|stop
DMODE="${ARGS[1],,}" # direwolf mode: digi,igate,digi+igate,ax25,ax25+pat DMODE="${2,,}" # direwolf mode: digi,igate,digi+igate,ax25,ax25+pat
SPEED="${ARGS[2],,}" # speed. No value implies 1200. Otherwise, allowed values are 300 or 9600. SPEED="${3,,}" # speed. No value implies 1200. Otherwise, allowed values are 300 or 9600.
AUDIO_CHANNELS="${ARGS[3]}" AUDIO_CHANNELS="${4}"
[[ $SPEED == "" ]] && SPEED="1200" [[ $SPEED == "" ]] && SPEED="1200"
[[ $AUDIO_CHANNELS == "" ]] && AUDIO_CHANNELS="1" [[ $AUDIO_CHANNELS == "" ]] && AUDIO_CHANNELS="1"
@ -371,13 +496,12 @@ declare -a ORDERS
declare -A CMDS declare -A CMDS
CMDS[direwolf]="$(command -v direwolf) -a $AUDIOSTATS -t $COLORS -r $ARATE" CMDS[direwolf]="$(command -v direwolf) -a $AUDIOSTATS -t $COLORS -r $ARATE"
# Main #########################################################################################
SCREEN="$(checkApp screen)" SCREEN="$(checkApp screen)"
ARECORD="$(checkApp arecord)" ARECORD="$(checkApp arecord)"
WGET="$(checkApp wget)" WGET="$(checkApp wget)"
case "$ACTION" in case "$ACTION" in
start) start)
[[ $DMODE == "" ]] && Usage
checkSoundCard checkSoundCard
echo "" > $LOGFILE echo "" > $LOGFILE
echo echo
@ -462,18 +586,18 @@ case "$ACTION" in
for i in ${!ORDERS[@]} for i in ${!ORDERS[@]}
do do
command -v ${ORDERS[$i]} >/dev/null command -v ${ORDERS[$i]} >/dev/null
[ $? -eq 0 ] && echo "${ORDERS[$i]} found." || { echo >&2 "${ORDERS[$i]} required but not found. Aborting."; exit 1; } [ $? -eq 0 ] && echo "${ORDERS[$i]} found." || Die "${ORDERS[$i]} required but not found. Aborting."
# Kill existing session if it exists # Kill existing session if it exists
SCR="$($SCREEN -list | grep ${ORDERS[$i]} | tr -d ' \t' | cut -d'(' -f1 | tr -d '\n')" SCR="$($SCREEN -list | grep ${ORDERS[$i]} | tr -d ' \t' | cut -d'(' -f1 | tr -d '\n')"
[[ "$SCR" != "" ]] && { pkill piardop2; $SCREEN -S $SCR -X quit; } [[ "$SCR" != "" ]] && { pkill piardop2; $SCREEN -S $SCR -X quit; }
done done
## Kill existing session if it exists ## Kill existing session if it exists
sudo killall kissattach 2>/dev/null pgrep kissattach >/dev/null && kill $(pgrep kissattach)
## Are the apps installed? ## Are the apps installed?
for i in kissattach kissparms for i in kissattach kissparms
do do
command -v $i >/dev/null command -v $i >/dev/null
[ $? -eq 0 ] && echo "$i found." || { echo >&2 "Error: $i required but not found. Aborting."; exit 1; } [ $? -eq 0 ] && echo "$i found." || Die "Error: $i required but not found. Aborting."
done done
CONFFILE="$(makeConfig ax25)" CONFFILE="$(makeConfig ax25)"
CMDS[direwolf]+=" -p -d u -c $CONFFILE" CMDS[direwolf]+=" -p -d u -c $CONFFILE"
@ -502,19 +626,16 @@ case "$ACTION" in
done done
if [ $COUNTER -ge $MAXWAIT ] if [ $COUNTER -ge $MAXWAIT ]
then then
echo >&2 "Direwolf failed to allocate a PTY! Aborting." Die "Direwolf failed to allocate a PTY! Aborting. Is ADEVICE set to your sound card?"
echo >&2 "Is ADEVICE set to your sound card?"
ctrl_c
exit 1
fi fi
echo "Direwolf started." echo "Direwolf started."
sudo $(command -v kissattach) $(readlink -f /tmp/kisstnc) $AX25PORT sudo $(command -v kissattach) $(readlink -f /tmp/kisstnc) $AX25PORT
[ $? -eq 0 ] || { echo "kissattach failed. Aborting."; ctrl_c; exit 1; } [ $? -eq 0 ] || Die "kissattach failed. Aborting."
KISSPARMS="-c 1 -p $AX25PORT -t $TXDelay -l $TXTail -s $Slottime -r $Persist -f n" KISSPARMS="-c 1 -p $AX25PORT -t $TXDelay -l $TXTail -s $Slottime -r $Persist -f n"
echo "Setting $(command -v kissparms) $KISSPARMS" echo "Setting $(command -v kissparms) $KISSPARMS"
sleep 2 sleep 2
sudo $(command -v kissparms) $KISSPARMS sudo $(command -v kissparms) $KISSPARMS
[ $? -eq 0 ] || { echo "kissparms settings failed. Aborting."; ctrl_c; exit 1; } [ $? -eq 0 ] || Die "kissparms settings failed. Aborting."
;; ;;
*) *)
$SCREEN -c $SCREENCONFIG -L -d -m -S ${ORDERS[$i]} ${CMDS[${ORDERS[$i]}]} $SCREEN -c $SCREENCONFIG -L -d -m -S ${ORDERS[$i]} ${CMDS[${ORDERS[$i]}]}
@ -551,7 +672,7 @@ case "$ACTION" in
for i in ${!ORDERS[@]} for i in ${!ORDERS[@]}
do do
command -v ${ORDERS[$i]} >/dev/null command -v ${ORDERS[$i]} >/dev/null
[ $? -eq 0 ] && echo "${ORDERS[$i]} found." || { echo >&2 "${ORDERS[$i]} required but not found. Aborting."; exit 1; } [ $? -eq 0 ] && echo "${ORDERS[$i]} found." || Die "${ORDERS[$i]} required but not found. Aborting."
# Kill existing session if it exists # Kill existing session if it exists
SCR="$($SCREEN -list | grep ${ORDERS[$i]} | tr -d ' \t' | cut -d'(' -f1 | tr -d '\n')" SCR="$($SCREEN -list | grep ${ORDERS[$i]} | tr -d ' \t' | cut -d'(' -f1 | tr -d '\n')"
[[ "$SCR" != "" ]] && { pkill piardop2; $SCREEN -S $SCR -X quit; } [[ "$SCR" != "" ]] && { pkill piardop2; $SCREEN -S $SCR -X quit; }
@ -594,7 +715,7 @@ case "$ACTION" in
for i in ${!ORDERS[@]} for i in ${!ORDERS[@]}
do do
command -v ${ORDERS[$i]} >/dev/null command -v ${ORDERS[$i]} >/dev/null
[ $? -eq 0 ] && echo "${ORDERS[$i]} found." || { echo >&2 "${ORDERS[$i]} required but not found. Aborting."; exit 1; } [ $? -eq 0 ] && echo "${ORDERS[$i]} found." || Die "${ORDERS[$i]} required but not found. Aborting."
# Kill existing session if it exists # Kill existing session if it exists
SCR="$($SCREEN -list | grep ${ORDERS[$i]} | tr -d ' \t' | cut -d'(' -f1 | tr -d '\n')" SCR="$($SCREEN -list | grep ${ORDERS[$i]} | tr -d ' \t' | cut -d'(' -f1 | tr -d '\n')"
[[ "$SCR" != "" ]] && $SCREEN -S $SCR -X quit [[ "$SCR" != "" ]] && $SCREEN -S $SCR -X quit
@ -602,8 +723,7 @@ case "$ACTION" in
CMDS[piardop2]="$(command -v piardop2) $ARDOP_PORT $ARDOP_DEV" CMDS[piardop2]="$(command -v piardop2) $ARDOP_PORT $ARDOP_DEV"
if [[ $ARDOP_PTT == "" ]] if [[ $ARDOP_PTT == "" ]]
then then
echo >&2 "Error: Please set PTT type (variable ARDOP_PTT) for ARDOP in this script." Die "Error: Please set PTT type (variable ARDOP_PTT) for ARDOP in this script."
exit 1
else else
CMDS[piardop2]+=" $ARDOP_PTT" CMDS[piardop2]+=" $ARDOP_PTT"
fi fi
@ -618,7 +738,7 @@ case "$ACTION" in
tail -n 150 -F $LOGFILE tail -n 150 -F $LOGFILE
;; ;;
*) *)
Usage Die "Invalid mode requested. Run ${SCRIPT_NAME} -h for instructions."
;; ;;
esac esac
;; ;;
@ -647,10 +767,10 @@ case "$ACTION" in
rm -f /tmp/kisstnc rm -f /tmp/kisstnc
echo "done." echo "done."
fi fi
rm -f /tmp/tnc*
;; ;;
*) *)
Usage Usage
;; ;;
esac esac
SafeExit