Skip to content

Instantly share code, notes, and snippets.

@pavax
Last active February 20, 2024 17:03
Show Gist options
  • Save pavax/48d07c2348a4f3287d11b8556b1d05ec to your computer and use it in GitHub Desktop.
Save pavax/48d07c2348a4f3287d11b8556b1d05ec to your computer and use it in GitHub Desktop.
Bash script to open a port using natpmpc and update the opened port in transmission-daemon
#!/bin/bash
# The gatway to send the natpmp commands
natpmp_ip="10.2.0.1"
# Path to the lock file
lock_file="/tmp/transmission_update.lock"
# Path to the Transmission settings.json file
settings_file="/etc/transmission-daemon/settings.json"
# How long to wait for an retry to open the ports
retry_wait_time=5
# Global variables to store the opened ports
new_tcp_port=""
new_udp_port=""
get_date_time() {
date +'%d.%m.%Y %H:%M'
}
extract_port() {
local output="$1"
# Use grep with a regex to extract the port number
echo "$output" | grep -oE 'Mapped public port [0-9]+' | awk '{print $4}'
}
check_transmission_peer_port() {
local peer_port=$(jq -r '.["peer-port"]' "$settings_file")
if [[ -z "$peer_port" ]]; then
echo "Error: Unable to retrieve peer-port from settings.json."
return 1
else
if [[ $peer_port -eq $1 ]]; then
return 0
else
return 1
fi
fi
}
update_transmission_peer_port() {
/usr/sbin/service transmission-daemon stop
echo "$(get_date_time): tranmission-daemon stopped"
local new_port=$1
sed -i "s/\"peer-port\": [0-9]\+,\?/\"peer-port\": $new_port,/" "$settings_file"
/usr/sbin/service transmission-daemon start
echo "$(get_date_time): transmission-daemon started"
}
open_ports() {
while true; do
# Execute the main functionality
output_tcp=$(natpmpc -a 1 0 tcp 60 -g "$natpmp_ip")
output_udp=$(natpmpc -a 1 0 udp 60 -g "$natpmp_ip")
# Extract the newly opened ports for TCP and UDP
new_tcp_port=$(extract_port "$output_tcp")
new_udp_port=$(extract_port "$output_udp")
# Check if UDP port opening failed
if [[ $output_udp == *"protocol UNKNOWN"* ]]; then
echo "$(get_date_time): Failed to open UDP port. Protocol set to UNKNOWN. Retrying in $retry_wait_time seconds..."
sleep $retry_wait_time
continue
fi
# Check if TCP port opening failed
if [[ $output_tcp == *"protocol UNKNOWN"* ]]; then
echo "$(get_date_time): Failed to open TCP port. Protocol set to UNKNOWN. Retrying in $retry_wait_time seconds..."
sleep $retry_wait_time
continue
fi
# Check if both TCP and UDP ports are successfully opened
if [[ -n $new_tcp_port && -n $new_udp_port ]]; then
# Log the newly opened TCP and UDP ports along with the current date and time
echo "$(get_date_time): Newly opened TCP port: $new_tcp_port"
echo "$(get_date_time): Newly opened UDP port: $new_udp_port"
return 0 # Ports successfully opened, exit loop with success status
else
echo "$(get_date_time): Failed to open both TCP and UDP ports."
#sleep $retry_wait_time
return 1
fi
done
}
remove_lock_file() {
rm -f "$lock_file"
}
####################################################################################################
# Main #
####################################################################################################
# Trap any signals or errors and remove the lock file before exiting
trap 'remove_lock_file' EXIT
# Check if the lock file exists
if [ -e "$lock_file" ]; then
echo "$(get_date_time): Script is already running. Exiting."
exit 1
fi
touch "$lock_file"
# Check if the settings_file exists
if [ ! -e "$settings_file" ]; then
echo "$(get_date_time): ERROR - Transmission settings file '$settings_file' not found. Exiting."
exit 1
fi
# start opening the ports
if open_ports; then
# check tranmission port and update if needed
if check_transmission_peer_port "$new_tcp_port"; then
echo "$(get_date_time): Transmission Daemon's peer_port matches the newly opened TCP port."
else
echo "$(get_date_time): Transmission Daemon's peer_port does not match the newly opened TCP port. Updating settings.json..."
update_transmission_peer_port "$new_tcp_port"
echo "$(get_date_time): peer-port in settings.json updated to $new_tcp_port."
fi
exit 0
else
echo "$(get_date_time): Exit script"
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment