1
0
mirror of https://github.com/AG7GN/nexus-utilities.git synced 2025-05-21 00:40: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)
[fsq_search.sh](#fsq-search-script)
## Installation
### Install
@ -189,3 +192,13 @@ If your image is older than 20191214 and you want to install the customizable Ne
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.
## 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
#================================================================
# 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,
# which is run a bootup via cron @reboot.
#============================
# 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)"
GPIO="$(command -v gpio) -g"
@ -15,6 +98,86 @@ P[2]=13
P[3]=6
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
PIANO=""
for I in 1 2 3 4
@ -33,4 +196,4 @@ done
# $HOME/piano24.sh will run whenever the Raspberry Pi starts.
#echo "running piano$PIANO.sh"
[ -s $HOME/piano$PIANO.sh ] && $HOME/piano$PIANO.sh
SafeExit

View File

@ -1,9 +1,93 @@
#!/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"
CONFIG_FILE="$HOME/desktop-text.conf"
@ -11,31 +95,92 @@ PICTURE_DIR="$HOME/Pictures"
DEFAULT_BACKGROUND_IMAGE="$PICTURE_DIR/NexusDeskTop.jpg"
MESSAGE="Enter the text you want displayed below.\nDon't use any single or double quotation marks."
trap errorReport INT
#============================
# PARSE OPTIONS WITH GETOPTS
#============================
#== set short options ==#
SCRIPT_OPTS=':hv-:'
function errorReport () {
echo
if [[ $1 == "" ]]
then
exit 0
else
if [[ $2 == "" ]]
then
echo >&2 "$1"
exit 1
else
echo >&2 "$1"
exit $2
fi
fi
}
#== 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
[ -s $DEFAULT_BACKGROUND_IMAGE ] || errorReport "Default Nexus image not in $DEFAULT_BACKGROUND_IMAGE" 1
if ! command -v convert >/dev/null
then
sudo apt update
sudo apt install -y imagemagick
sudo apt update || die "Could not run 'sudo apt update'"
sudo apt install -y imagemagick || die "Could not run 'sudo apt install -y imagemagick'"
fi
if [ -s "$CONFIG_FILE" ]
@ -70,7 +215,7 @@ $MESSAGE</b>\n" \
[[ $? == 1 || $? == 252 ]] && errorReport # User has cancelled.
[[ $ANS == "" ]] && errorReport "Error." 1
[[ $ANS == "" ]] && Die "Unexpected input from dialog"
IFS='|' read -r -a TF <<< "$ANS"
@ -93,3 +238,4 @@ $MESSAGE</b>\n" \
fi
$(command -v pcmanfm) --set-wallpaper="$TARGET"
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
#================================================================
# 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"
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
# exit.
if [ -e "$INIT_DONE_FILE" ] && [ -f "$INIT_DONE_FILE" ] && [ -s "$INIT_DONE_FILE" ]

View File

@ -1,31 +1,175 @@
#!/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"
CONFIG_FILE="$HOME/radionames.conf"
trap errorReport INT
#============================
# PARSE OPTIONS WITH GETOPTS
#============================
#== set short options ==#
SCRIPT_OPTS=':hv-:'
function errorReport () {
echo
if [[ $1 == "" ]]
then
exit 0
else
if [[ $2 == "" ]]
then
echo >&2 "$1"
exit 1
else
echo >&2 "$1"
exit $2
fi
fi
}
#== 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
if [ -s "$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"
fi
ANS=""
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 \
$MESSAGE</b>\n" \
--text="<b><big><big>Name Your Radios</big></big></b>\n" \
--item-separator="!" \
--center \
--buttons-layout=center \
@ -55,9 +197,9 @@ $MESSAGE</b>\n" \
--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"
@ -71,5 +213,5 @@ for F in `ls $D/*-left.template` `ls $D/*-right.template`
do
sudo sed -e "s/_LEFT_RADIO_/$LEFT_RADIO_NAME/" -e "s/_RIGHT_RADIO_/$RIGHT_RADIO_NAME/g" $F > ${F%.*}.desktop
done
SafeExit

View File

@ -1,54 +1,226 @@
#!/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 () {
echo
echo "ERROR: $1"
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
function TrapCleanup() {
[[ -d "${TMPDIR}" ]] && rm -rf "${TMPDIR}/"
exit 0
}
(( $# != 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)"
[[ $? == 0 ]] || Usage "pat winlink client is not installed."
[[ $? == 0 ]] || Die "pat winlink client is not installed."
UNIX2DOS="$(command -v unix2dos)"
[[ $UNIX2DOS == "" ]] && Usage "dos2unix tools are not installed."
[[ $UNIX2DOS == "" ]] && Die "dos2unix tools are not installed."
PATDIR="$HOME/.wl2k"
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"
TO="$1"
@ -57,10 +229,10 @@ SUBJECT="$2"
[[ $TO =~ "," ]] || TO="$TO\n"
export EDITOR=ed
TFILE="$(mktemp)"
TFILE="${TMPDIR}/message"
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 == "" ]] && Usage "Could not find the MID (Message ID)"
[[ $MSG == "" ]] && Die "Could not find the MID (Message ID)"
MSG="$OUTDIR/$MSG.b2f"
sed -i -e 's/<No message body>//' $MSG
$UNIX2DOS -q $MSG
@ -68,7 +240,7 @@ cat - > $TFILE
$UNIX2DOS -q $TFILE
COUNT="$(wc -c $TFILE | cut -d' ' -f1)"
cat $TFILE >> $MSG
rm $TFILE
#rm $TFILE
sed -i -e "s/^Body: .*/Body: $COUNT/" $MSG
$PAT --send-only --event-log /dev/null connect $3 >/dev/null 2>&1
exit $?

486
tnc.sh
View File

@ -1,109 +1,171 @@
#!/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
#
#================================================================
# DEBUG OPTION
# set -n # Uncomment to check your syntax, without execution.
# set -x # Uncomment to debug this shell script
#
# Script Name: tnc.sh
# Author: Steve Magnuson AG7GN
# Date Created: 20180601
#
# 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.
# 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"
#================================================================
# END_OF_HEADER
#================================================================
# Functions ################################################################################
SYNTAX=false
DEBUG=false
function Usage() {
echo
echo "Version $VERSION"
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
}
#============================
# FUNCTIONS
#============================
function ctrl_c () {
# Do cleanup if Ctrl-C is pressed. Stop all the screens.
$0 stop
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() {
printf "Usage:\n"
ScriptInfo usage
exit 1
}
function Die () {
echo "${*}"
SafeExit
}
#---------------------------------------
function checkApp () {
APP="$(command -v $1 2>/dev/null)"
if [[ $APP == "" ]]
then
echo >&2 "Error: $1 is required but not installed."
exit 1
Die "Error: $1 is required but not installed."
fi
echo "$APP"
}
@ -130,15 +192,12 @@ function checkSoundCard () {
CAP_DEV="$AUDIO_DEV"
elif [[ $AUDIO_DEV_SEARCH_STRING == "" ]]
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."
exit 1
Die "Error: You must set either the AUDIO_DEV or AUDIO_DEV_SEARCH_STRING variables in this script to select the sound card."
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:])"
if [[ $CAP_DEV == "" ]]
then
echo >&2 "Error: Unable to find audio interface using string $AUDIO_DEV_SEARCH_STRING."
sleep 5
exit 1
Die "Error: Unable to find audio interface using string $AUDIO_DEV_SEARCH_STRING."
fi
CAP_DEV="plughw:$CAP_DEV"
fi
@ -266,8 +325,7 @@ EOF
esac
;;
*)
echo >&2 "Error: Valid baud settings are 1200 or 9600."
exit 1
Die "Error: Valid baud settings are 1200 or 9600."
;;
esac
;;
@ -290,8 +348,7 @@ function checkSerial () {
grep "$DEVSTRING" | cut -d' ' -f3 | tr -d './')"
if [[ $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\"."
exit 1
Die "Error: Could not locate serial device with name containing \"$DEVSTRING\"."
fi
DEVICE="/dev/$SERIAL_PORT"
if [[ $RIGCTL_RADIO != "" ]]
@ -303,10 +360,16 @@ function checkSerial () {
fi
}
# Initializations ##########################################################################
#============================
# FILES AND VARIABLES
#============================
# trap ctrl-c and call ctrl_c()
trap ctrl_c INT
#== 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:)
TNC_CONFIG_FILE=""
LOGFILE="/tmp/tnc.log"
@ -319,50 +382,112 @@ logtstamp after 60
log on
logtstamp string "[ %n:%t ] ---- TIMESTAMP ---- %Y-%m-%d %c:%s ---- Press Ctrl-C to Quit\012"
EOF
VERSION="$(ScriptInfo version | grep version | tr -s ' ' | cut -d' ' -f 4)"
# Check if user supplied configuration file with '-c' option
declare -a ARGS
while [ $# -gt 0 ]
#============================
# PARSE OPTIONS WITH GETOPTS
#============================
#== 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
unset OPTIND
unset OPTARG
#while getopts as:c: OPTIONS
while getopts c: OPTIONS
do
case $OPTIONS in
c)
TNC_CONFIG_FILE="$OPTARG"
;;
*)
;;
esac
done
shift $((OPTIND-1))
ARGS+=($1)
shift
# 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
;;
c)
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
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
# No configuration file supplied, so use the default
[[ $TNC_CONFIG_FILE == "" ]] && TNC_CONFIG_FILE="$HOME/tnc.conf"
if [ -s "$TNC_CONFIG_FILE" ]
then
MYCALL=""
source $TNC_CONFIG_FILE
if [[ $MYCALL =~ N0CALL || $MYCALL =~ N0ONE || $MYCALL == "" ]]
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
source $TNC_CONFIG_FILE
[[ $MYCALL =~ N0CALL || $MYCALL =~ N0ONE || $MYCALL == "" ]] && Die "You must set the MYCALL variable in $TNC_CONFIG_FILE."
ACTION="${ARGS[0],,}" # start|stop
DMODE="${ARGS[1],,}" # direwolf mode: digi,igate,digi+igate,ax25,ax25+pat
SPEED="${ARGS[2],,}" # speed. No value implies 1200. Otherwise, allowed values are 300 or 9600.
AUDIO_CHANNELS="${ARGS[3]}"
ACTION="${1,,}" # start|stop
DMODE="${2,,}" # direwolf mode: digi,igate,digi+igate,ax25,ax25+pat
SPEED="${3,,}" # speed. No value implies 1200. Otherwise, allowed values are 300 or 9600.
AUDIO_CHANNELS="${4}"
[[ $SPEED == "" ]] && SPEED="1200"
[[ $AUDIO_CHANNELS == "" ]] && AUDIO_CHANNELS="1"
@ -371,13 +496,12 @@ declare -a ORDERS
declare -A CMDS
CMDS[direwolf]="$(command -v direwolf) -a $AUDIOSTATS -t $COLORS -r $ARATE"
# Main #########################################################################################
SCREEN="$(checkApp screen)"
ARECORD="$(checkApp arecord)"
WGET="$(checkApp wget)"
case "$ACTION" in
start)
[[ $DMODE == "" ]] && Usage
checkSoundCard
echo "" > $LOGFILE
echo
@ -462,18 +586,18 @@ case "$ACTION" in
for i in ${!ORDERS[@]}
do
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
SCR="$($SCREEN -list | grep ${ORDERS[$i]} | tr -d ' \t' | cut -d'(' -f1 | tr -d '\n')"
[[ "$SCR" != "" ]] && { pkill piardop2; $SCREEN -S $SCR -X quit; }
done
## Kill existing session if it exists
sudo killall kissattach 2>/dev/null
pgrep kissattach >/dev/null && kill $(pgrep kissattach)
## Are the apps installed?
for i in kissattach kissparms
do
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
CONFFILE="$(makeConfig ax25)"
CMDS[direwolf]+=" -p -d u -c $CONFFILE"
@ -502,19 +626,16 @@ case "$ACTION" in
done
if [ $COUNTER -ge $MAXWAIT ]
then
echo >&2 "Direwolf failed to allocate a PTY! Aborting."
echo >&2 "Is ADEVICE set to your sound card?"
ctrl_c
exit 1
Die "Direwolf failed to allocate a PTY! Aborting. Is ADEVICE set to your sound card?"
fi
echo "Direwolf started."
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"
echo "Setting $(command -v kissparms) $KISSPARMS"
sleep 2
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]}]}
@ -551,7 +672,7 @@ case "$ACTION" in
for i in ${!ORDERS[@]}
do
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
SCR="$($SCREEN -list | grep ${ORDERS[$i]} | tr -d ' \t' | cut -d'(' -f1 | tr -d '\n')"
[[ "$SCR" != "" ]] && { pkill piardop2; $SCREEN -S $SCR -X quit; }
@ -594,7 +715,7 @@ case "$ACTION" in
for i in ${!ORDERS[@]}
do
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
SCR="$($SCREEN -list | grep ${ORDERS[$i]} | tr -d ' \t' | cut -d'(' -f1 | tr -d '\n')"
[[ "$SCR" != "" ]] && $SCREEN -S $SCR -X quit
@ -602,8 +723,7 @@ case "$ACTION" in
CMDS[piardop2]="$(command -v piardop2) $ARDOP_PORT $ARDOP_DEV"
if [[ $ARDOP_PTT == "" ]]
then
echo >&2 "Error: Please set PTT type (variable ARDOP_PTT) for ARDOP in this script."
exit 1
Die "Error: Please set PTT type (variable ARDOP_PTT) for ARDOP in this script."
else
CMDS[piardop2]+=" $ARDOP_PTT"
fi
@ -618,39 +738,39 @@ case "$ACTION" in
tail -n 150 -F $LOGFILE
;;
*)
Usage
Die "Invalid mode requested. Run ${SCRIPT_NAME} -h for instructions."
;;
esac
;;
stop)
ORDERS=( rigctld piardop2 direwolf pat )
#ORDERS=( rigctld direwolf )
echo
for i in ${!ORDERS[@]}
do
SCR="$($SCREEN -list | grep ${ORDERS[$i]} | tr -d ' \t' | cut -d'(' -f1 | tr -d '\n')"
if [[ "$SCR" != "" ]]
then
echo -n "Stopping $SCR..."
$SCREEN -S $SCR -X quit
echo "done."
else
echo "Stopping ${ORDERS[$i]}: ${ORDERS[$i]} not running"
fi
done
pgrep piardop2 >/dev/null && kill -9 $(pgrep piardop2)
KISSATTACHPID="$(pgrep kissattach)"
if [[ $KISSATTACHPID != "" ]]
then
echo -n "Stopping kissattach..."
sudo killall kissattach
rm -f /tmp/kisstnc
echo "done."
fi
rm -f /tmp/tnc*
ORDERS=( rigctld piardop2 direwolf pat )
#ORDERS=( rigctld direwolf )
echo
for i in ${!ORDERS[@]}
do
SCR="$($SCREEN -list | grep ${ORDERS[$i]} | tr -d ' \t' | cut -d'(' -f1 | tr -d '\n')"
if [[ "$SCR" != "" ]]
then
echo -n "Stopping $SCR..."
$SCREEN -S $SCR -X quit
echo "done."
else
echo "Stopping ${ORDERS[$i]}: ${ORDERS[$i]} not running"
fi
done
pgrep piardop2 >/dev/null && kill -9 $(pgrep piardop2)
KISSATTACHPID="$(pgrep kissattach)"
if [[ $KISSATTACHPID != "" ]]
then
echo -n "Stopping kissattach..."
sudo killall kissattach
rm -f /tmp/kisstnc
echo "done."
fi
;;
*)
Usage
;;
esac
SafeExit