+#!/bin/sh
+# /usr/lib/dynamic_dns/dynamic_dns_updater.sh
+#
+# Written by Eric Paul Bishop, Janary 2008
+# Distributed under the terms of the GNU General Public License (GPL) version 2.0
+#
+# This script is (loosely) based on the one posted by exobyte in the forums here:
+# http://forum.openwrt.org/viewtopic.php?id=14040
+#
+
+. /usr/lib/ddns/dynamic_dns_functions.sh
+. /usr/lib/ddns/shell_get.sh
+
+
+
+
+
+
+service_id=$1
+if [ -z "$service_id" ]
+then
+ echo "ERRROR: You must specify a service id (the section name in the /etc/config/ddns file) to initialize dynamic DNS."
+ return 1
+fi
+
+#default mode is verbose_mode, but easily turned off with second parameter
+verbose_mode="1"
+if [ -n "$2" ]
+then
+ verbose_mode="$2"
+fi
+
+###############################################################
+# Leave this comment here, to clearly document variable names
+# that are expected/possible
+#
+# Now use load_all_config_options to load config
+# options, which is a much more flexible solution.
+#
+#
+#config_load "ddns"
+#
+#config_get enabled $service_id enabled
+#config_get service_name $service_id service_name
+#config_get update_url $service_id update_url
+#
+#
+#config_get username $service_id username
+#config_get password $service_id password
+#config_get domain $service_id domain
+#
+#
+#config_get ip_source $service_id ip_source
+#config_get ip_interface $service_id ip_interface
+#config_get ip_network $service_id ip_network
+#config_get ip_url $service_id ip_url
+#
+#config_get force_interval $service_id force_interval
+#config_get force_unit $service_id force_unit
+#
+#config_get check_interval $service_id check_interval
+#config_get check_unit $service_id check_unit
+#########################################################
+load_all_config_options "ddns" "$service_id"
+
+
+#some defaults
+if [ -z "$check_interval" ]
+then
+ check_interval=600
+fi
+
+if [ -z "$check_unit" ]
+then
+ check_unit="seconds"
+fi
+
+
+if [ -z "$force_interval" ]
+then
+ force_interval=72
+fi
+
+if [ -z "$force_unit" ]
+then
+ force_unit="hours"
+fi
+
+
+
+#some constants
+
+retrieve_prog="/usr/bin/wget --no-check-certificate -O - ";
+if [ -h "/usr/bin/wget" ]
+then
+ busybox_wget=$(ls -l /usr/bin/wget | awk ' { if ($0~/busybox/) { print "BUSYBOX"}} ')
+ if [ -n "$busybox_wget" ]; then
+ retrieve_prog="shell_get"
+ fi
+fi
+
+verbose_echo "retrieve_prog=\"$retrieve_prog\""
+
+service_file="/usr/lib/ddns/services"
+
+ip_regex="[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}"
+
+NEWLINE_IFS='
+'
+
+
+#determine what update url we're using if the service_name is supplied
+if [ -n "$service_name" ]
+then
+ #remove any lines not containing data, and then make sure fields are enclosed in double quotes
+ quoted_services=$(cat $service_file | grep "^[\t ]*[^#]" | awk ' gsub("\x27", "\"") { if ($1~/^[^\"]*$/) $1="\""$1"\"" }; { if ( $NF~/^[^\"]*$/) $NF="\""$NF"\"" }; { print $0 }' )
+
+
+ #echo "quoted_services = $quoted_services"
+ OLD_IFS=$IFS
+ IFS=$NEWLINE_IFS
+ for service_line in $quoted_services
+ do
+ #grep out proper parts of data and use echo to remove quotes
+ next_name=$(echo $service_line | grep -o "^[\t ]*\"[^\"]*\"" | xargs -r -n1 echo)
+ next_url=$(echo $service_line | grep -o "\"[^\"]*\"[\t ]*$" | xargs -r -n1 echo)
+
+ if [ "$next_name" = "$service_name" ]
+ then
+ update_url=$next_url
+ fi
+ done
+ IFS=$OLD_IFS
+fi
+
+
+
+verbose_echo "update_url=$update_url"
+
+
+
+#if this service isn't enabled then quit
+if [ "$enabled" != "1" ]
+then
+ return 0
+fi
+
+
+
+
+
+#compute update interval in seconds
+case "$force_unit" in
+ "days" )
+ force_interval_seconds=$(($force_interval*60*60*24))
+ ;;
+ "hours" )
+ force_interval_seconds=$(($force_interval*60*60))
+ ;;
+ "minutes" )
+ force_interval_seconds=$(($force_interval*60))
+ ;;
+ "seconds" )
+ force_interval_seconds=$force_interval
+ ;;
+ * )
+ #default is hours
+ force_interval_seconds=$(($force_interval*60*60))
+ ;;
+esac
+
+
+
+#compute check interval in seconds
+case "$check_unit" in
+ "days" )
+ check_interval_seconds=$(($check_interval*60*60*24))
+ ;;
+ "hours" )
+ check_interval_seconds=$(($check_interval*60*60))
+ ;;
+ "minutes" )
+ check_interval_seconds=$(($check_interval*60))
+ ;;
+ "seconds" )
+ check_interval_seconds=$check_interval
+ ;;
+ * )
+ #default is seconds
+ check_interval_seconds=$check_interval
+ ;;
+esac
+
+
+
+verbose_echo "force seconds = $force_interval_seconds"
+verbose_echo "check seconds = $check_interval_seconds"
+
+#kill old process if it exists & set new pid file
+if [ -d /var/run/dynamic_dns ]
+then
+ #if process is already running, stop it
+ if [ -e "/var/run/dynamic_dns/$service_id.pid" ]
+ then
+ old_pid=$(cat /var/run/dynamic_dns/$service_id.pid)
+ test_match=$(ps | grep "^[\t ]*$old_pid")
+ verbose_echo "old process id (if it exists) = \"$test_match\""
+ if [ -n "$test_match" ]
+ then
+ kill $old_pid
+ fi
+ fi
+
+else
+ #make dir since it doesn't exist
+ mkdir /var/run/dynamic_dns
+fi
+echo $$ > /var/run/dynamic_dns/$service_id.pid
+
+
+
+
+#determine when the last update was
+current_time=$(date +%s)
+last_update=$(( $current_time - (2*$force_interval_seconds) ))
+if [ -e "/var/run/dynamic_dns/$service_id.update" ]
+then
+ last_update=$(cat /var/run/dynamic_dns/$service_id.update)
+fi
+time_since_update=$(($current_time - $last_update))
+
+
+human_time_since_update=$(( $time_since_update / ( 60 * 60 ) ))
+verbose_echo "time_since_update = $human_time_since_update hours"
+
+
+
+
+registered_ip=$(echo $(nslookup "$domain" 2>/dev/null) | grep -o "Name:.*" | grep -o "$ip_regex")
+
+
+#do update and then loop endlessly, checking ip every check_interval and forcing an updating once every force_interval
+
+while [ true ]
+do
+ current_ip=$(get_current_ip)
+
+
+ current_time=$(date +%s)
+ time_since_update=$(($current_time - $last_update))
+
+
+ verbose_echo "Running IP check..."
+ verbose_echo "current system ip = $current_ip"
+ verbose_echo "registered domain ip = $registered_ip"
+
+
+ if [ "$current_ip" != "$registered_ip" ] || [ $force_interval_seconds -lt $time_since_update ]
+ then
+ verbose_echo "update necessary, performing update ..."
+
+ #do replacement
+ final_url=$update_url
+ for option_var in $ALL_OPTION_VARIABLES
+ do
+ replace_name=$(echo "\[$option_var\]" | tr 'a-z' 'A-Z')
+ replace_value=$(eval echo "\$$option_var")
+ final_url=$(echo $final_url | sed s/"$replace_name"/"$replace_value"/g )
+ done
+ final_url=$(echo $final_url | sed s/"\[IP\]"/"$current_ip"/g )
+
+
+ verbose_echo "updating with url=\"$final_url\""
+
+ #here we actually connect, and perform the update
+ update_output=$( $retrieve_prog "$final_url" )
+
+ verbose_echo "Update Output:"
+ verbose_echo "$update_output"
+ verbose_echo ""
+
+ #save the time of the update
+ current_time=$(date +%s)
+ last_update=$current_time
+ time_since_update='0'
+ registered_ip=$current_ip
+
+ human_time=$(date)
+ verbose_echo "update complete, time is: $human_time"
+
+ echo "$last_update" > "/var/run/dynamic_dns/$service_id.update"
+ else
+ human_time=$(date)
+ human_time_since_update=$(( $time_since_update / ( 60 * 60 ) ))
+ verbose_echo "update unnecessary"
+ verbose_echo "time since last update = $human_time_since_update hours"
+ verbose_echo "the time is now $human_time"
+ fi
+
+ #sleep for 10 minutes, then re-check ip && time since last update
+ sleep $check_interval_seconds
+done
+
+#should never get here since we're a daemon, but I'll throw it in anyway
+return 0
+
+
+
+