From 00506ed5cb88fcf350679dfdb9efd32d3dcc5dec Mon Sep 17 00:00:00 2001 From: Steve Magnuson Date: Sun, 22 Sep 2019 15:35:45 -0700 Subject: [PATCH] Initial push --- check-piano.sh | 36 +++ hampi-utilities.version | 1 + initialize-pi.sh | 187 ++++++++++++ name-radios.sh | 75 +++++ patmail.sh | 75 +++++ test-piano.sh | 40 +++ tnc.sh | 614 ++++++++++++++++++++++++++++++++++++++++ trim-fldigi-log.sh | 53 ++++ trim-flmsg-log.sh | 56 ++++ trim-flrig-log.sh | 52 ++++ trim-fsq-audit.sh | 80 ++++++ trim-fsq-heard.sh | 62 ++++ 12 files changed, 1331 insertions(+) create mode 100755 check-piano.sh create mode 100644 hampi-utilities.version create mode 100755 initialize-pi.sh create mode 100755 name-radios.sh create mode 100755 patmail.sh create mode 100755 test-piano.sh create mode 100755 tnc.sh create mode 100755 trim-fldigi-log.sh create mode 100755 trim-flmsg-log.sh create mode 100755 trim-flrig-log.sh create mode 100755 trim-fsq-audit.sh create mode 100755 trim-fsq-heard.sh diff --git a/check-piano.sh b/check-piano.sh new file mode 100755 index 0000000..59e78e3 --- /dev/null +++ b/check-piano.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +VERSION="1.0.0" + +# 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. + +GPIO="$(command -v gpio) -g" + +# Array P: Array index is the ID of each individual switch in the piano switch. +# Array element value is the GPIO BCM number. +P[1]=25 +P[2]=13 +P[3]=6 +P[4]=5 + +# String $PIANO will identify which levers are in the DOWN position +PIANO="" +for I in 1 2 3 4 +do + J=$($GPIO read ${P[$I]}) # State of a switch in the piano (0 or 1) + (( $J == 0 )) && PIANO="$PIANO$I" +done + +# Check if the script corresponding to the piano switch setting exists and is not empty. +# +# Scripts must be in the $HOME directory, be marked as executable, and be named +# pianoX.sh where X is one of these: +# 1,12,13,14,123,124,134,1234,2,23,234,24,3,34,4 +# +# Example: When the piano switch levers 2 and 4 are down, the script named +# $HOME/piano24.sh will run whenever the Raspberry Pi starts. +#echo "running piano$PIANO.sh" +[ -s $HOME/piano$PIANO.sh ] && $HOME/piano$PIANO.sh + diff --git a/hampi-utilities.version b/hampi-utilities.version new file mode 100644 index 0000000..a56028d --- /dev/null +++ b/hampi-utilities.version @@ -0,0 +1 @@ +VERSION="1.0.0" \ No newline at end of file diff --git a/initialize-pi.sh b/initialize-pi.sh new file mode 100755 index 0000000..d5cb747 --- /dev/null +++ b/initialize-pi.sh @@ -0,0 +1,187 @@ +#!/bin/bash + +VERSION="1.14" + +# +# 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" + +# Does $INIT_DONE_FILE exist? Is it a regular file? Is it not empty? If YES to all, then +# check the status of the piano switch. +if [ -e "$INIT_DONE_FILE" ] && [ -f "$INIT_DONE_FILE" ] && [ -s "$INIT_DONE_FILE" ] +then + [ -s /usr/local/bin/check-piano.sh ] && /usr/local/bin/check-piano.sh + exit 0 +fi + +# Got this far? Initialze this Pi! +echo "$(date): First time boot. Initializing..." > "$INIT_DONE_FILE" + +# Generate a new VNC key +echo "Generate new VNC server key" >> "$INIT_DONE_FILE" +sudo vncserver-x11 -generatekeys force >> "$INIT_DONE_FILE" 2>&1 +sudo systemctl restart vncserver-x11-serviced >/dev/null 2>&1 + +# Generate new SSH server keys +sudo rm -v /etc/ssh/ssh_host* >> "$INIT_DONE_FILE" 2>&1 +echo "Generate new SSH server keys" >> "$INIT_DONE_FILE" +#sudo dpkg-reconfigure -f noninteractive openssh-server >> "$INIT_DONE_FILE" 2>&1 +cd /etc/ssh +sudo rm -f ssh_host_* +sudo ssh-keygen -A +sudo systemctl restart ssh >/dev/null 2>&1 +cd $HOME +echo "Remove ssh client keys, authorized_keys and known_hosts" >> "$INIT_DONE_FILE" +rm -f $DIR/.ssh/known_hosts +rm -f $DIR/.ssh/authorized_keys +rm -f $DIR/.ssh/id_* +rm -f $DIR/.ssh/*~ + +rm -f $DIR/*~ + +echo "Remove fldigi suite logs and messages and personalized data" >> "$INIT_DONE_FILE" +DIRS=".nbems .nbems-left .nbems-right" +for D in $DIRS +do + rm -f ${DIR}/${D}/*~ + rm -f $DIR/$D/debug* + rm -f $DIR/$D/flmsg.sernbrs + rm -f $DIR/$D/ICS/*.html + rm -f $DIR/$D/ICS/*.csv + rm -f $DIR/$D/ICS/messages/* + rm -f $DIR/$D/ICS/templates/* + rm -f $DIR/$D/ICS/log_files/* + rm -f $DIR/$D/WRAP/auto/* + rm -f $DIR/$D/WRAP/recv/* + rm -f $DIR/$D/WRAP/send/* + rm -f $DIR/$D/TRANSFERS/* + rm -f $DIR/$D/FLAMP/*log* + rm -f $DIR/$D/FLAMP/rx/* + rm -f $DIR/$D/FLAMP/tx/* + rm -f $DIR/$D/ARQ/files/* + rm -f $DIR/$D/ARQ/recv/* + rm -f $DIR/$D/ARQ/send/* + rm -f $DIR/$D/ARQ/mail/in/* + rm -f $DIR/$D/ARQ/mail/out/* + rm -f $DIR/$D/ARQ/mail/sent/* + if [ -f $DIR/$D/FLMSG.prefs ] + then + sed -i -e 's/^mycall:.*/mycall:N0ONE/' \ + -e 's/^mytel:.*/mytel:/' \ + -e 's/^myname:.*/myname:/' \ + -e 's/^myaddr:.*/myaddr:/' \ + -e 's/^mycity:.*/mycity:/' \ + -e 's/^myemail:.*/myemail:/' \ + -e 's/^sernbr:.*/sernbr:1/' \ + -e 's/^rgnbr:.*/rgnbr:1/' \ + -e 's/^rri:.*/rri:1/' \ + -e 's/^sernbr_fname:.*/sernbr_fname:1/' \ + -e 's/^rgnbr_fname:.*/rgnbr_fname:1/' $DIR/$D/FLMSG.prefs + fi +done + +DIRS=".fldigi .fldigi-left .fldigi-right" +for D in $DIRS +do + for F in $(ls -R $DIR/$D/*log* 2>/dev/null) + do + [ -e $F ] && [ -f $F ] && rm -f $F + done + rm -f $DIR/$D/*~ + rm -f $DIR/$D/debug/*txt* + rm -f $DIR/$D/logs/* + rm -f $DIR/$D/LOTW/* + rm -f $DIR/$D/rigs/* + rm -f $DIR/$D/temp/* + rm -f $DIR/$D/kml/* + rm -f $DIR/$D/wrap/* + if [ -f $DIR/$D/fldigi_def.xml ] + then + sed -i -e 's/.*<\/MYCALL>/N0ONE<\/MYCALL>/' \ + -e 's/.*<\/MYQTH>/<\/MYQTH>/' \ + -e 's/.*<\/MYNAME>/<\/MYNAME>/' \ + -e 's/.*<\/MYLOC>/<\/MYLOC>/' \ + -e 's/.*<\/MYANTENNA>/<\/MYANTENNA>/' \ + -e 's/.*<\/OPERCALL>/<\/OPERCALL>/' \ + -e 's/.*<\/PORTINDEVICE>/<\/PORTINDEVICE>/' \ + -e 's/.*<\/PORTININDEX>/-1<\/PORTININDEX>/' \ + -e 's/.*<\/PORTOUTDEVICE>/<\/PORTOUTDEVICE>/' \ + -e 's/.*<\/PORTOUTINDEX>/-1<\/PORTOUTINDEX>/' $DIR/$D/fldigi_def.xml + fi +done + +DIRS=".flrig .flrig-left .flrig-right" +for D in $DIRS +do + if [ -f $DIR/$D/flrig.prefs ] + then + sed -i 's/^xcvr_name:.*/xcvr_name:NONE/' $DIR/$D/flrig.prefs 2>/dev/null + mv $DIR/$D/flrig.prefs $DIR/$D/flrig.prefs.temp + rm -f $DIR/$D/*.prefs + mv $DIR/$D/flrig.prefs.temp $DIR/$D/flrig.prefs + fi + rm -f $DIR/$D/debug* + rm -f ${DIR}/${D}/*~ +done + +# Restore defaults for rmsgw + +echo "Restore defaults for RMS Gateway" >> "$INIT_DONE_FILE" +( systemctl list-units | grep -q "ax25.*loaded" ) && sudo systemctl disable ax25 +[ -L /etc/ax25/ax25-up ] && sudo rm -f /etc/ax25/ax25-up +[ -f /etc/rmsgw/channels.xml ] && sudo rm -f /etc/rmsgw/channels.xml +[ -f /etc/rmsgw/banner ] && sudo rm -f /etc/rmsgw/banner +[ -f /etc/rmsgw/gateway.conf ] && sudo rm -f /etc/rmsgw/gateway.conf +[ -f /etc/rmsgw/sysop.xml ] && sudo rm -f /etc/rmsgw/sysop.xml +[ -f /etc/ax25/ax25d.conf ] && sudo rm -f /etc/ax25/ax25d.conf +[ -f /etc/ax25/ax25-up.new ] && sudo rm -f /etc/ax25/ax25-up.new +[ -f /etc/ax25/ax25-up.new2 ] && sudo rm -f /etc/ax25/ax25-up.new2 +[ -f /etc/ax25/direwolf.conf ] && sudo rm -f /etc/ax25/direwolf.conf +[ -f $HOME/rmsgw.conf ] && rm -f $HOME/rmsgw.conf +id -u rmsgw >/dev/null 2>&1 && sudo crontab -u rmsgw -r 2>/dev/null + +#rm -rf $DIR/.flrig/ +#rm -rf $DIR/.fldigi/ +#rm -rf $DIR/.fltk/ + +# Remove Auto Hot-Spot if configured +echo "Remove Auto-HotSpot" >> "$INIT_DONE_FILE" +rm -f $HOME/autohotspot.conf +sudo sed -i 's|^net.ipv4.ip_forward=1|#net.ipv4.ip_forward=1|' /etc/sysctl.conf +if systemctl | grep -q "autohotspot" +then + sudo systemctl disable autohotspot +fi +if [ -s /etc/dhcpcd.conf ] +then + TFILE="$(mktemp)" + grep -v "^nohook wpa_supplicant" /etc/dhcpcd.conf > $TFILE + sudo mv -f $TFILE /etc/dhcpcd.conf +fi +# Remove cronjob if present +crontab -u $USER -l | grep -v "autohotspotN" | crontab -u $USER - + +# Set radio names to default +rm -f $HOME/radionames.conf +D="/usr/local/share/applications" +for F in `ls $D/*-left.template 2>/dev/null` `ls $D/*-right.template 2>/dev/null` +do + sudo sed -e "s/_LEFT_RADIO_/Left Radio/" -e "s/_RIGHT_RADIO_/Right Radio/g" $F > ${F%.*}.desktop +done + +echo "Raspberry Pi initialization complete" >> "$INIT_DONE_FILE" +sudo shutdown -r now + + diff --git a/name-radios.sh b/name-radios.sh new file mode 100755 index 0000000..6b4335c --- /dev/null +++ b/name-radios.sh @@ -0,0 +1,75 @@ +#!/bin/bash + +VERSION="1.0.3" + +# 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" + +TITLE="Left/Right Radio Name Editor $VERSION" +CONFIG_FILE="$HOME/radionames.conf" + +trap errorReport INT + +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 +} + +if [ -s "$CONFIG_FILE" ] +then # There is a config file + echo "$CONFIG_FILE found." + source "$CONFIG_FILE" +else # Set some default values in a new config file + echo "Config file $CONFIG_FILE not found. Creating a new one with default values." + echo "LEFT_RADIO_NAME=\"Left Radio\"" > "$CONFIG_FILE" + echo "RIGHT_RADIO_NAME=\"Right Radio\"" >> "$CONFIG_FILE" + source "$CONFIG_FILE" +fi + + +ANS="" +ANS="$(yad --title="$TITLE" \ + --text="Auto-HotSpot Configuration Parameters\n\nStatus: $STATUS\n\n \ +$MESSAGE\n" \ + --item-separator="!" \ + --center \ + --buttons-layout=center \ + --text-align=center \ + --align=right \ + --borders=20 \ + --form \ + --field="Left Radio Name" "$LEFT_RADIO_NAME" \ + --field="Right Radio Name" "$RIGHT_RADIO_NAME" \ + --focus-field 1 \ +)" + +[[ $? == 1 || $? == 252 ]] && errorReport # User has cancelled. + +[[ $ANS == "" ]] && errorReport "Error." 1 + +IFS='|' read -r -a TF <<< "$ANS" + +LEFT_RADIO_NAME="${TF[0]}" +RIGHT_RADIO_NAME="${TF[1]}" +echo "LEFT_RADIO_NAME=\"$LEFT_RADIO_NAME\"" > "$CONFIG_FILE" +echo "RIGHT_RADIO_NAME=\"$RIGHT_RADIO_NAME\"" >> "$CONFIG_FILE" + +D="/usr/local/share/applications" +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 + + diff --git a/patmail.sh b/patmail.sh new file mode 100755 index 0000000..3fbe22b --- /dev/null +++ b/patmail.sh @@ -0,0 +1,75 @@ +#!/bin/bash + +VERSION="1.0.7" + +# This script allows sending Winlink messages via the command line or script. +# It requires pat (a Winlink client) and the dos2unix programs. + +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 +} + +(( $# != 3 )) && Usage "3 arguments are required." + +PAT="$(command -v pat)" +[[ $? == 0 ]] || Usage "pat winlink client is not installed." +UNIX2DOS="$(command -v unix2dos)" +[[ $UNIX2DOS == "" ]] && Usage "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?" +OUTDIR="$PATDIR/mailbox/$CALL/out" + +TO="$1" +SUBJECT="$2" + +[[ $TO =~ "," ]] || TO="$TO\n" + +export EDITOR=ed +TFILE="$(mktemp)" +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="$OUTDIR/$MSG.b2f" +sed -i -e 's///' $MSG +$UNIX2DOS -q $MSG +cat - > $TFILE +$UNIX2DOS -q $TFILE +COUNT="$(wc -c $TFILE | cut -d' ' -f1)" +cat $TFILE >> $MSG +rm $TFILE +sed -i -e "s/^Body: .*/Body: $COUNT/" $MSG +$PAT --send-only --event-log /dev/null connect $3 >/dev/null 2>&1 +exit $? + diff --git a/test-piano.sh b/test-piano.sh new file mode 100755 index 0000000..1794141 --- /dev/null +++ b/test-piano.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +VERSION="1.0.1" + +# 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. + +GPIO="$(command -v gpio) -g" + +# Array P: Array index is the ID of each individual switch in the piano switch. +# Array element value is the GPIO BCM number. +P[1]=25 +P[2]=13 +P[3]=6 +P[4]=5 + +# String $PIANO will identify which levers are in the DOWN position +PIANO="" +for I in 1 2 3 4 +do + J=$($GPIO read ${P[$I]}) # State of a switch in the piano (0 or 1) + (( $J == 0 )) && PIANO="$PIANO$I" +done + +# Check if the script corresponding to the piano switch setting exists and is not empty. +# +# Scripts must be in the $HOME directory, be marked as executable, and be named +# pianoX.sh where X is one of these: +# 1,12,13,14,123,124,134,1234,2,23,234,24,3,34,4 +# +# Example: When the piano switch levers 2 and 4 are down, the script named +# $HOME/piano24.sh will run whenever the Raspberry Pi starts. + +[[ $PIANO == "" ]] && MESSAGE="No levers are down." || MESSAGE="Levers $PIANO are down." + +yad --center --title="Test calling pianoX.sh script - version $VERSION" --info --borders=30 \ + --no-wrap --text="$MESSAGE $HOME/piano$PIANO.sh will run." --buttons-layout=center \ +--button=Close:0 + diff --git a/tnc.sh b/tnc.sh new file mode 100755 index 0000000..6a28e00 --- /dev/null +++ b/tnc.sh @@ -0,0 +1,614 @@ +#!/bin/bash +# +# 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.0.2" + +# BEGINNING OF USER CONFIGURATION SECTION ######################################################## + +TNC_CONFIG_FILE="$HOME/tnc.conf" + +if [ -s "$TNC_CONFIG_FILE" ] +then + source $HOME/tnc.conf +else + echo >&2 "Error: Configuration file $TNC_CONFIG_FILE is missing or empty." + exit 1 +fi + +# END OF USER CONFIGURATION SECTION ######################################################## + +# Initializations ########################################################################## + +# trap ctrl-c and call ctrl_c() +trap ctrl_c INT + +LOGFILE="/tmp/tnc.log" +SCREENCONFIG="/tmp/tnc.sh.screenrc" +ACTION="${1,,}" # start|stop +DMODE="${2,,}" # direwolf mode: digi,igate,digi+igate,ax25 +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" +declare -a ORDERS +declare -A CMDS +CMDS[direwolf]="$(which direwolf) -a $AUDIOSTATS -t $COLORS -r $ARATE" +cat > $SCREENCONFIG << EOF +logfile $LOGFILE +logfile flush 1 +logtstamp on +logtstamp after 60 +log on +logtstamp string "[ %n:%t ] ---- TIMESTAMP ---- %Y-%m-%d %c:%s ---- Press Ctrl-C to Quit\012" +EOF + +# Functions ################################################################################ + +function ctrl_c () { + # Do cleanup if Ctrl-C is pressed. Stop all the screens. + $0 stop + exit 0 +} + +function Usage() { + echo + echo "Version $VERSION" + echo + echo "$(basename $0) usage:" + 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 uses both the left" + echo " and right channels. Winlink clients can access Direwolf's" + echo " second channel by selecting Packet TNC Type 'KISS Port 2'" + echo " in Winlink. 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 " not 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 ARDFOP 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." + echo + exit 1 +} + +function checkApp () { + APP="$(which $1)" + if [[ $APP == "" ]] + then + echo >&2 "Error: $1 is required but not installed." + exit 1 + fi + echo "$APP" +} + +function aprsPasscode () { + # Generates the APRS website passcode from the supplied callsign + CALL="$(echo ${1^^} | cut -d'-' -f1)" + H="0x73e2" + declare -i LEN=${#CALL} + declare -i I=0 + while [ $I -lt $LEN ] + do + H=$(( $H ^ $(($(printf '%d' "'${CALL:$I:2}") << 8)) )) + H=$(( $H ^ $(printf '%d' "'${CALL:$(( I+1 )):2}") )) + (( I+=2 )) + done + echo -n $(( $H & 0x7fff )) +} + +function checkSoundCard () { + # Checks for the presence of the requested sound card + if [[ $AUDIO_DEV != "" ]] + then + 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 + 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 + fi + CAP_DEV="plughw:$CAP_DEV" + fi +} + +function makeConfig() { + # direwolf.conf parameters + ADEVICE="$CAP_DEV" + CONFFILE="$(mktemp)" + case "$1" in + digi*|igate) + PASSCODE="$(aprsPasscode $MYCALL)" + case "$SPEED" in + both) # Decode stereo right (channel 1) and stereo left (channel 0) + FROM_CHANNEL="1" + TO_CHANNEL="0" + cat >> $CONFFILE << EOF +ADEVICE $ADEVICE +ACHANNELS 2 +CHANNEL 0 +$PTT0 +MYCALL $MYCALL +MODEM 1200 +CHANNEL 1 +$PTT1 +MYCALL $MYCALL +MODEM 1200 +EOF + ;; + *) # Decode stereo left only + FROM_CHANNEL="0" + TO_CHANNEL="0" + cat >> $CONFFILE << EOF +ADEVICE $ADEVICE +ACHANNELS 1 +CHANNEL 0 +$PTT0 +MYCALL $MYCALL +MODEM 1200 +EOF + ;; + esac + case "$1" in + digi*) # digipeater+igate or digipeater + if [[ $1 == "digi" ]] # digipeat ONLY + then + IGLOGIN="" + PBEACONIG="" + IGTXVIA="" + COMMENT="$COMMENTCALL Digipeater | $LOC" + else # Digipeater + iGate + # IGTXVIA is set at the top of the script + COMMENT="$COMMENTCALL Digipeater+iGate | $LOC" + PBEACONIG="PBEACON sendto=IG delay=$IGDELAY every=$IGEVERY symbol=\"igate\" overlay=T lat=$LAT long=$LONG COMMENT=\"$COMMENT\"" + IGLOGIN="IGLOGIN $MYCALL $PASSCODE" + fi + DIGIPEAT="DIGIPEAT $FROM_CHANNEL $TO_CHANNEL ^WIDE[3-7]-[1-7]$|^TEST$ ^WIDE[12]-[12]$ TRACE" + PBEACON="PBEACON delay=$DIGIPEATDELAY every=$DIGIPEATEVERY symbol=\"digi\" overlay=S lat=$LAT long=$LONG POWER=$POWER HEIGHT=$HEIGHT GAIN=$GAIN COMMENT=\"$COMMENT\" via=$HOPS" + ;; + *) # iGate + PBEACON="" + DIGIPEAT="" + IGTXVIA="" + COMMENT="$COMMENTCALL iGate | $LOC" + PBEACONIG="PBEACON sendto=IG delay=$IGDELAY every=$IGEVERY symbol=\"igate\" overlay=R lat=$LAT long=$LONG COMMENT=\"$COMMENT\"" + IGLOGIN="IGLOGIN $MYCALL $PASSCODE" + ;; + esac + cat >> $CONFFILE << EOF +$AGWPORT +$KISSPORT +$PBEACONIG +$PBEACON +$DIGIPEAT +$IGTXVIA +$IGLOGIN +$FILTER +$IGSERVER +$IGTXLIMIT +$IGFILTER +EOF + ;; + ax25) + case "$SPEED" in + 1200|9600) + case "$AUDIO_CHANNELS" in + 2) # Assumes stereo input - use both channels + if [[ $PTT0 =~ "GPIO" ]] + then # Allow only one radio at a time to transmit + TXINH0="TXINH $(echo $PTT1 | sed 's/PTT //')" + TXINH1="TXINH $(echo $PTT0 | sed 's/PTT //')" + else + TXINH0="" + TXINH1="" + fi + cat > $CONFFILE << EOF +ADEVICE $ADEVICE +ACHANNELS 2 +CHANNEL 0 +MODEM $SPEED +$PTT0 +$TXINH0 +MYCALL $MYCALL +CHANNEL 1 +MODEM $SPEED +$PTT1 +$TXINH1 +MYCALL $MYCALL +$AGWPORT +$KISSPORT +EOF + ;; + *) # Use only left channel + cat > $CONFFILE << EOF +ADEVICE $ADEVICE +ACHANNELS 1 +CHANNEL 0 +MODEM $SPEED +$PTT0 +MYCALL $MYCALL +$AGWPORT +$KISSPORT +EOF + ;; + esac + ;; + *) + echo >&2 "Error: Valid baud settings are 1200 or 9600." + exit 1 + ;; + esac + ;; + ardop) + CONFFILE="" + ;; + *) + ;; + esac + echo "$CONFFILE" +} + + +function checkSerial () { + if [[ $DEVSTRING == "" ]] + then # No rig defined. Don't use rigctld or ARDOP CAT commands to key radio + CMDS[rigctld]="" + else + SERIAL_PORT="$(find -P /dev/serial/by-id -maxdepth 1 -type l -exec echo -n "{} -> " \; -exec readlink {} \; | \ + 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 + fi + DEVICE="/dev/$SERIAL_PORT" + if [[ $RIGCTL_RADIO != "" ]] + then + CMDS[rigctld]="$(which rigctld) -m $RIGCTL_RADIO -r $DEVICE -s $RIGCTL_SPEED" + else + CMDS[rigctld]="" + fi + fi +} + +# Main ############################################################################################# + +SCREEN="$(checkApp screen)" +ARECORD="$(checkApp arecord)" +WGET="$(checkApp wget)" +case "$ACTION" in + start) + checkSoundCard + echo "" > $LOGFILE + echo + echo "Version $VERSION" + echo "Running $0 $ACTION $DMODE $SPEED $AUDIO_CHANNELS" + echo "Mode: $DMODE Speed: $SPEED Audio Device: $CAP_DEV Audio Channels: $AUDIO_CHANNELS" + echo + case "$DMODE" in + pat) + checkSerial + if [[ ${CMDS[rigctld]} == "" ]] + then + echo "rigctld will not be used." + ORDERS=( pat ) + else + echo "rigctld will use radio found on $DEVICE." + ORDERS=( rigctld pat ) + fi + echo "NOTE: If you haven't already done so, you must run 'pat configure' or manually" + echo " configure $HOME/.wl2k/config.json to use pat." + echo + CMDS[pat]="$(which pat) -l telnet http" + for i in ${!ORDERS[@]} + do + $SCREEN -c $SCREENCONFIG -L -d -m -S ${ORDERS[$i]} ${CMDS[${ORDERS[$i]}]} + echo "============================" + done + screen -list + echo + sleep 2 + rm -f $CONFFILE + if [[ $GRID != "" ]] + then + if $WGET -q --tries=2 --timeout=5 --spider http://google.com + then # There is an internet connection, so get local RMS list + GRID="${GRID:0:4}" + GRID="${GRID^^}" + echo + echo "RMS Stations in grid square $GRID:" + $(which pat) rmslist | grep "${GRID}\|callsign" | sort -k 3,3 -n + fi + fi + echo + echo "Tailing $LOGFILE. All apps log to this file. Press Ctrl-C to quit all apps." + echo + tail -n 150 -F $LOGFILE + ;; + *ax25*) + checkSerial + if [[ ${CMDS[rigctld]} == "" ]] + then + echo "rigctld will not be used." + case "$DMODE" in + *pat*) + ORDERS=( direwolf pat ) + ;; + *) + ORDERS=( direwolf ) + ;; + esac + else + case "$DMODE" in + *pat*) + ORDERS=( rigctld direwolf pat ) + ;; + *) + ORDERS=( rigctld direwolf ) + ;; + esac + echo "rigctld will use radio found on $DEVICE." + fi + if [[ $DMODE =~ "pat" ]] + then + echo "NOTE: If you haven't already done so, you must run 'pat configure' or manually" + echo " configure $HOME/.wl2k/config.json to use pat." + echo + CMDS[pat]="$(which pat) -l ax25,telnet http" + fi + # Check that the app is installed. + for i in ${!ORDERS[@]} + do + which ${ORDERS[$i]} >/dev/null + [ $? -eq 0 ] && echo "${ORDERS[$i]} found." || { echo >&2 "${ORDERS[$i]} required but not found. Aborting."; exit 1; } + # 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 + ## Are the apps installed? + for i in kissattach kissparms + do + which $i >/dev/null + [ $? -eq 0 ] && echo "$i found." || { echo >&2 "Error: $i required but not found. Aborting."; exit 1; } + done + CONFFILE="$(makeConfig ax25)" + CMDS[direwolf]+=" -p -d u -c $CONFFILE" + for i in ${!ORDERS[@]} + do + echo + echo "Starting ${CMDS[${ORDERS[$i]}]}" + case "${ORDERS[$i]}" in + direwolf) + if ! grep -q "^$AX25PORT[[:space:]]" $AX25PORTFILE 2>/dev/null + then + echo -n "File $AX25PORTFILE empty or does not contain $AX25PORT. Adding..." + echo "$AX25PORT $MYCALL 0 255 7 Winlink" | sudo tee --append $AX25PORTFILE + echo "done." + fi + rm -f /tmp/kisstnc + $SCREEN -c $SCREENCONFIG -L -d -m -S ${ORDERS[$i]} ${CMDS[${ORDERS[$i]}]} + COUNTER=0 + MAXWAIT=8 + while [ $COUNTER -lt $MAXWAIT ] + do + # Allocate a PTY to ax25 + [ -L /tmp/kisstnc ] && break + sleep 1 + let COUNTER=COUNTER+1 + 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 + fi + echo "Direwolf started." + sudo $(which kissattach) $(readlink -f /tmp/kisstnc) $AX25PORT + [ $? -eq 0 ] || { echo "kissattach failed. Aborting."; ctrl_c; exit 1; } + KISSPARMS="-c 1 -p $AX25PORT -t $TXDelay -l $TXTail -s $Slottime -r $Persist -f n" + echo "Setting $(which kissparms) $KISSPARMS" + sleep 2 + sudo $(which kissparms) $KISSPARMS + [ $? -eq 0 ] || { echo "kissparms settings failed. Aborting."; ctrl_c; exit 1; } + ;; + *) + $SCREEN -c $SCREENCONFIG -L -d -m -S ${ORDERS[$i]} ${CMDS[${ORDERS[$i]}]} + ;; + esac + echo "============================" + done + screen -list + echo + echo "------ ax25 Direwolf configuration file ------" + cat $CONFFILE | grep -v "^$" + echo "----------------------------------------------" + sleep 2 + rm -f $CONFFILE + if [[ $DMODE == "pat" && $GRID != "" ]] + then + if $WGET -q --tries=2 --timeout=5 --spider http://google.com + then # There is an internet connection, so get local RMS list + GRID="${GRID:0:4}" + GRID="${GRID^^}" + echo + echo "RMS Stations in grid square $GRID:" + $(which pat) rmslist | grep "${GRID}\|callsign" | sort -k 3,3 -n + fi + fi + echo + echo "Tailing $LOGFILE. All apps log to this file. Press Ctrl-C to quit all apps." + echo + tail -n 150 -F $LOGFILE + ;; + digi*|igate) + [[ $PTT0 == "" || $PTT0 =~ "GPIO" ]] && ORDERS=( direwolf ) || { checkSerial; ORDERS=( rigctld direwolf ); } + # Check that the app is installed. + for i in ${!ORDERS[@]} + do + which ${ORDERS[$i]} >/dev/null + [ $? -eq 0 ] && echo "${ORDERS[$i]} found." || { echo >&2 "${ORDERS[$i]} required but not found. Aborting."; exit 1; } + # 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; } + #[[ "$SCR" != "" ]] && $SCREEN -S $SCR -X quit + done + CONFFILE="$(makeConfig $DMODE)" + CMDS[direwolf]+=" -d t -c $CONFFILE" + for i in ${!ORDERS[@]} + do + echo + echo "Starting ${CMDS[${ORDERS[$i]}]}" + $SCREEN -c $SCREENCONFIG -L -d -m -S ${ORDERS[$i]} ${CMDS[${ORDERS[$i]}]} + done + screen -list + echo + echo "------ APRS $DMODE Direwolf configuration file ------" + cat $CONFFILE | grep -v "^$" + echo "-----------------------------------------------------" + echo + sleep 2 + rm -f $CONFFILE + echo "Tailing $LOGFILE. All apps log to this file. Press Ctrl-C to quit all apps." + echo + tail -n 150 -F $LOGFILE + ;; + *ardop*) + case "$DMODE" in + *pat*) + ORDERS=( piardop2 pat ) + echo "NOTE: If you haven't already done so, you must run 'pat configure' or manually" + echo " configure $HOME/.wl2k/config.json to use pat." + echo + CMDS[pat]="$(which pat) -l ardop,telnet http" + ;; + *) + ORDERS=( piardop2 ) + ;; + esac + # Check that the app is installed, and kill it if it is already running. + for i in ${!ORDERS[@]} + do + which ${ORDERS[$i]} >/dev/null + [ $? -eq 0 ] && echo "${ORDERS[$i]} found." || { echo >&2 "${ORDERS[$i]} required but not found. Aborting."; exit 1; } + # 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 + done + CMDS[piardop2]="$(which 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 + else + CMDS[piardop2]+=" $ARDOP_PTT" + fi + for i in ${!ORDERS[@]} + do + echo + echo "Starting ${CMDS[${ORDERS[$i]}]}" + $SCREEN -c $SCREENCONFIG -L -d -m -S ${ORDERS[$i]} ${CMDS[${ORDERS[$i]}]} + done + echo "Tailing $LOGFILE. All apps log to this file. Press Ctrl-C to quit all apps." + echo + tail -n 150 -F $LOGFILE + ;; + *) + Usage + ;; + 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* + ;; + *) + Usage + ;; +esac + diff --git a/trim-fldigi-log.sh b/trim-fldigi-log.sh new file mode 100755 index 0000000..b8b7510 --- /dev/null +++ b/trim-fldigi-log.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +VERSION="1.4" + +# +# This script removes log files from the $HOME/.fldigi* folder(s) and subfolders. +# Files with "last modified" timestamps that are before the specified time +# are deleted. Files that match *log*, except for file names containing 'logbook' +# are examined. +# +# Parameter 1 is a date reference e.g. "10 days ago" or "1 hour ago" +# +# DO NOT run this script while Fldigi is running. Likewise, +# DO NOT run this script using Fldigi's autostart feature. It must be run +# prior to starting Fldigi. If you want to run it every time you start +# Fldigi on a Raspberry Pi, change the File Properties +# of the Fldigi menu item to run this script and then Fldigi as follows: +# +# Click on the Raspberry and navigate to the menu containing Fldigi. Right-click +# on the Fldigi menu item, click Properties then select the "Desktop Entry" tab. +# In the Command field, replace 'fldigi' with the following (change the +# time period as desired): +# +# sh -c '/usr/local/bin/trim-fldigi-log.sh "1 week ago"';fldigi +# +# Leave the "Execute in Terminal" box unchecked, then click OK. +# + +DIRS="$HOME/.fldigi $HOME/.fldigi-left $HOME/.fldigi-right" + +# Some error checking +[[ $1 == "" ]] && { echo >&2 "Supply a date reference, e.g. \"10 days ago\" or \"1 hour ago\""; exit 1; } + +if ! date -u --date="$1" 1>/dev/null 2>&1 +then # Invalid date requested + exit 1 +elif [[ ${1^^} != "NOW" && $(($(date -u --date="$1" +%s))) > $(($(date -u +%s))) ]] +then # Date requested is in the future; invalid + echo >&2 "Date requested is in the future." + exit 1 +fi + +for D in $DIRS +do + for F in $(ls -R ${D}/*log* 2>/dev/null) + do + [ -e $F ] && [ -f "$F" ] && ! [[ $F =~ logbook ]] || continue + STAMP="$(stat -c %Y $F)" + [ $STAMP -lt $(date -u --date="$1" +%s) ] && rm -f $F + done +done + + diff --git a/trim-flmsg-log.sh b/trim-flmsg-log.sh new file mode 100755 index 0000000..ff3c858 --- /dev/null +++ b/trim-flmsg-log.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +VERSION="1.5" + +# +# This script removes log files from the $HOME/.flmsg* folder(s) and subfolders. +# Files with "last modified" timestamps that are before the specified time +# are deleted. Files that match the elements of $SDIRS below are examined. +# +# Parameter 1 is a date reference e.g. "10 days ago" or "1 hour ago" +# +# DO NOT run this script while Flmsg is running. It must be run +# prior to starting Flmsg. If you want to run it every time you start +# Flmsg on a Raspberry Pi, change the File Properties +# of the Flmsg menu item to run this script and then Flmsg as follows: +# +# Click on the Raspberry and navigate to the menu containing Flmsg. Right-click +# on the Flmsg menu item, click Properties then select the "Desktop Entry" tab. +# In the Command field, replace 'flmsg' with the following (change the +# time period as desired): +# +# sh -c '/usr/local/bin/trim-flmsg-log.sh "1 week ago"';flmsg +# +# Leave the "Execute in Terminal" box unchecked, then click OK. +# + + +DIRS="$HOME/.nbems $HOME/.nbems-left $HOME/.nbems-right" +SDIRS="/log_files/* /temp_files/* /ICS/*.htm /ICS/*.csv /ICS/messages/* /ICS/messages/archive/* /ICS/log_files/* /WRAP/auto/* /WRAP/recv/* /WRAP/send/* /TRANSFERS/* /FLAMP/*log* /FLAMP/rx/* /FLAMP/tx/* /ARQ/files/* /ARQ/mail/* /ARQ/recv/* /ARQ/send/*" + +# Some error checking +[[ $1 == "" ]] && { echo >&2 "Supply a date reference, e.g. \"10 days ago\" or \"1 hour ago\""; exit 1; } + +if ! date -u --date="$1" 1>/dev/null 2>&1 +then # Invalid date requested + exit 1 +elif [[ ${1^^} != "NOW" && $(($(date -u --date="$1" +%s))) > $(($(date -u +%s))) ]] +then # Date requested is in the future; invalid + echo >&2 "Date requested is in the future." + exit 1 +fi + +for D in $DIRS +do + for S in $SDIRS + do + for F in $(ls -R ${D}${S} 2>/dev/null) + do + [ -e "$F" ] && [ -f "$F" ] || continue + STAMP="$(stat -c %Y $F)" + [ $STAMP -lt $(date -u --date="$1" +%s) ] && rm -f $F + done + done +done + + diff --git a/trim-flrig-log.sh b/trim-flrig-log.sh new file mode 100755 index 0000000..545eb22 --- /dev/null +++ b/trim-flrig-log.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +VERSION="1.4" + +# This script removes log files from the $HOME/.flrig* folder(s) and subfolders. +# Files with "last modified" timestamps that are before the specified time +# are deleted. Files that match *log*, except for file names containing 'logbook' +# are examined. +# +# Parameter 1 is a date reference e.g. "10 days ago" or "1 hour ago" +# +# DO NOT run this script while Flrig is running. It must be run +# prior to starting Flrig. If you want to run it every time you start +# Flrig on a Raspberry Pi, change the File Properties +# of the Flrig menu item to run this script and then Flrig as follows: +# +# Click on the Raspberry and navigate to the menu containing Flrig. Right-click +# on the Flrig menu item, click Properties then select the "Desktop Entry" tab. +# In the Command field, replace 'flrig' with the following (change the +# time period as desired): +# +# sh -c '/usr/local/bin/trim-flrig-log.sh "1 week ago"';flrig +# +# Leave the "Execute in Terminal" box unchecked, then click OK. +# + + +DIRS="$HOME/.flrig $HOME/.flrig-left $HOME/.flrig-right" + +# Some error checking +[[ $1 == "" ]] && { echo >&2 "Supply a date reference, e.g. \"10 days ago\" or \"1 hour ago\""; exit 1; } + +if ! date -u --date="$1" 1>/dev/null 2>&1 +then # Invalid date requested + exit 1 +elif [[ ${1^^} != "NOW" && $(($(date -u --date="$1" +%s))) > $(($(date -u +%s))) ]] +then # Date requested is in the future; invalid + echo >&2 "Date requested is in the future." + exit 1 +fi + +for D in $DIRS +do + for F in $(ls -R ${D}/*txt* 2>/dev/null) + do + [ -e "$F" ] && [ -f "$F" ] || continue + STAMP="$(stat -c %Y $F)" + [ $STAMP -lt $(date -u --date="$1" +%s) ] && rm -f $F + done +done + + diff --git a/trim-fsq-audit.sh b/trim-fsq-audit.sh new file mode 100755 index 0000000..dbe3d73 --- /dev/null +++ b/trim-fsq-audit.sh @@ -0,0 +1,80 @@ +#!/bin/bash + +VERSION="1.4" + +# This script trims the fsq_audit_log.txt file +# in the ~/.fldigi/temp folder by removing content added aded earlier +# than the supplied time (e.g. "10 days ago" or "1 hour ago"). +# +# Parameter 1 is a date reference e.g. "10 days ago" or "1 hour ago" +# +# DO NOT run this script while Fldigi is running. Likewise, +# DO NOT run this script using Fldigi's autostart feature. It must be run +# prior to starting Fldigi. If you want to run it every time you start +# Fldigi on a Raspberry Pi, change the File Properties +# of the Fldigi menu item to run this script and then Fldigi as follows: +# +# Click on the Raspberry and navigate to the menu containing Fldigi. Right-click +# on the Fldigi menu item, click Properties then select the "Desktop Entry" tab. +# In the Command field, replace 'fldigi' with the following (change the +# time period as desired): +# +# sh -c '/usr/local/bin/trim-fsq-audit.sh "30 days ago"';fldigi +# +# Leave the "Execute in terminal" box unchecked, then click OK. +# +# If you want to run both this script and the trim-fsq-heard.sh script in the +# same way, use this line in the Command field instead (change the time period +# as desired): +# +# sh -c '/usr/local/bin/trim-fsq-audit.sh "30 days ago";/usr/local/bin/trim-fsq-heard.sh "1 hour ago"';fldigi +# + + +DIRS="$HOME/.fldigi/temp $HOME/.fldigi-left/temp $HOME/.fldigi-right/temp" + +[[ $1 == "" ]] && { echo >&2 "Supply a date reference, e.g. \"10 days ago\" or \"1 hour ago\""; exit 1; } + +if ! date -u --date="$1" 1>/dev/null +then # Invalid date requested + echo >&2 "Invalid date requested. Supply a date reference, e.g. \"10 days ago\" or \"1 hour ago\"" + exit 1 +elif [[ ${1^^} != "NOW" && $(($(date -u --date="$1" +%s))) > $(($(date -u +%s))) ]] +then # Date requested is in the future; invalid + echo >&2 "Date requested is in the future. No change to file." + exit 1 +fi +TARGET="$(date -u --date="$1" +"%s")" + +for D in $DIRS +do + AUDIT="$D/fsq_audit_log.txt" + + # Some error checking + [ -e "$AUDIT" ] && [ -f "$AUDIT" ] && [ -s "$AUDIT" ] || continue # $AUDIT not found or empty + + T="$(mktemp)" + declare -i LINE=0 + while read -r ATAG1 ATAG2 DTAG TTAG REMAINDER + do + (( LINE++ )) + if [[ "$ATAG1 $ATAG2" == "Audit log:" ]] + then # Determine logged timestamp + TTAG="$(echo $TTAG | tr -d ',')" # strip out comma + DTAG="$(echo $DTAG | tr -d ',')" # strip out comma + # convert to a time format that date command undertands + TTAG="$(echo $TTAG | sed -E 's|([0-9]{2})([0-9]{2})([0-9]{2})|\1:\2:\3|')" + STAMP="$(date -u -d"$DTAG $TTAG" +"%s")" + if (( TARGET < STAMP )) + then # Save everything after this $LINE in $AUDIT + echo "==================================================" > $T + tail -n +$LINE $AUDIT >> $T + break + fi + fi + done < $AUDIT + mv $T $AUDIT + chmod 644 $AUDIT +done + + diff --git a/trim-fsq-heard.sh b/trim-fsq-heard.sh new file mode 100755 index 0000000..8004ea6 --- /dev/null +++ b/trim-fsq-heard.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +VERSION="1.4" + +# This script trims the fsq_heard_log.txt file +# in the ~/.fldigi/temp folder by removing lines with timestamps earlier +# than the supplied time (e.g. "10 days ago" or "1 hour ago"). +# +# Parameter 1 is a date reference e.g. "10 days ago" or "1 hour ago" +# +# DO NOT run this script while Fldigi is running. Likewise, +# DO NOT run this script using Fldigi's autostart feature. It must be run +# prior to starting Fldigi. If you want to run it every time you start +# Fldigi on a Raspberry Pi, change the File Properties +# of the Fldigi menu item to run this script and then Fldigi as follows: +# +# Click on the Raspberry and navigate to the menu containing Fldigi. Right-click +# on the Fldigi menu item, click Properties then select the "Desktop Entry" tab. +# In the Command field, replace 'fldigi' with the following (change the +# time period as desired): +# +# sh -c '/home/pi/trim-fsq-heard.sh "1 week ago"';fldigi +# +# Leave the "Execute in Terminal" box unchecked, then click OK. +# +# If you want to run both this script and the trim-fsq-audit.sh script in the +# same way, use this line in the Command field instead (change the time period as +# desired): +# +# sh -c '/usr/local/bin/trim-fsq-audit.sh "30 days ago";/usr/local/bin/trim-fsq-heard.sh "1 week ago"';fldigi +# + + +DIRS="$HOME/.fldigi/temp $HOME/.fldigi-left/temp $HOME/.fldigi-right/temp" + +[[ $1 == "" ]] && { echo >&2 "Supply a date reference, e.g. \"10 days ago\" or \"1 hour ago\""; exit 1; } +if ! date -u --date="$1" 1>/dev/null +then # Invalid date requested + echo >&2 "Invalid date requested. Supply a date reference, e.g. \"10 days ago\" or \"1 hour ago\"" + exit 1 +elif [[ ${1^^} != "NOW" && $(($(date -u --date="$1" +%s))) > $(($(date -u +%s))) ]] +then # Date requested is in the future; invalid + echo >&2 "Date requested is in the future. No changes made." + exit 1 +fi + +for D in $DIRS +do + HEARD="$D/fsq_heard_log.txt" + [ -e "$HEARD" ] && [ -f "$HEARD" ] && [ -s "$HEARD" ] || continue # $HEARD not found or empty + T="$(mktemp)" + cat > $T << EOF +================================================== +Heard log: $(date -u --date="$1" "+%Y%m%d, %H%M%S") +================================================== +EOF + awk -v d=$(date -u --date="$1" "+%Y%m%d,%H%M%S") '($1 "," $2) > d' $HEARD | grep -v "^Heard\|^===" >> $T + mv $T $HEARD + chmod 644 $HEARD +done + +