2 # /usr/lib/dynamic_dns/dynamic_dns_updater.sh
4 # Written by Eric Paul Bishop, Janary 2008
5 # Distributed under the terms of the GNU General Public License (GPL) version 2.0
7 # This script is (loosely) based on the one posted by exobyte in the forums here:
8 # http://forum.openwrt.org/viewtopic.php?id=14040
11 .
/usr
/lib
/ddns
/dynamic_dns_functions.sh
15 if [ -z "$service_id" ]
17 echo "ERRROR: You must specify a service id (the section name in the /etc/config/ddns file) to initialize dynamic DNS."
21 #default mode is verbose_mode, but easily turned off with second parameter
28 ###############################################################
29 # Leave this comment here, to clearly document variable names
30 # that are expected/possible
32 # Now use load_all_config_options to load config
33 # options, which is a much more flexible solution.
38 #config_get enabled $service_id enabled
39 #config_get service_name $service_id service_name
40 #config_get update_url $service_id update_url
43 #config_get username $service_id username
44 #config_get password $service_id password
45 #config_get domain $service_id domain
48 #config_get use_https $service_id use_https
49 #config_get cacert $service_id cacert
51 #config_get ip_source $service_id ip_source
52 #config_get ip_interface $service_id ip_interface
53 #config_get ip_network $service_id ip_network
54 #config_get ip_url $service_id ip_url
56 #config_get force_interval $service_id force_interval
57 #config_get force_unit $service_id force_unit
59 #config_get check_interval $service_id check_interval
60 #config_get check_unit $service_id check_unit
61 #########################################################
62 load_all_config_options
"ddns" "$service_id"
66 if [ -z "$check_interval" ]
71 if [ -z "$check_unit" ]
77 if [ -z "$force_interval" ]
82 if [ -z "$force_unit" ]
87 if [ -z "$use_https" ]
96 if [ "x$use_https" = "x1" ]
98 retrieve_prog
="/usr/bin/curl "
101 retrieve_prog
="${retrieve_prog}--cacert $cacert "
102 elif [ -d "$cacert" ]
104 retrieve_prog
="${retrieve_prog}--capath $cacert "
107 retrieve_prog
="/usr/bin/wget -O - ";
110 service_file
="/usr/lib/ddns/services"
112 ip_regex
="[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}"
118 #determine what update url we're using if the service_name is supplied
119 if [ -n "$service_name" ]
121 #remove any lines not containing data, and then make sure fields are enclosed in double quotes
122 quoted_services
=$
(cat $service_file |
grep "^[\t ]*[^#]" |
awk ' gsub("\x27", "\"") { if ($1~/^[^\"]*$/) $1="\""$1"\"" }; { if ( $NF~/^[^\"]*$/) $NF="\""$NF"\"" }; { print $0 }' )
125 #echo "quoted_services = $quoted_services"
128 for service_line
in $quoted_services
130 #grep out proper parts of data and use echo to remove quotes
131 next_name
=$
(echo $service_line |
grep -o "^[\t ]*\"[^\"]*\"" |
xargs -r -n1 echo)
132 next_url
=$
(echo $service_line |
grep -o "\"[^\"]*\"[\t ]*$" |
xargs -r -n1 echo)
134 if [ "$next_name" = "$service_name" ]
142 if [ "x$use_https" = x1
]
144 update_url
=$
(echo $update_url |
sed -e 's/^http:/https:/')
148 verbose_echo
"update_url=$update_url"
152 #if this service isn't enabled then quit
153 if [ "$enabled" != "1" ]
162 #compute update interval in seconds
163 case "$force_unit" in
165 force_interval_seconds
=$
(($force_interval*60*60*24))
168 force_interval_seconds
=$
(($force_interval*60*60))
171 force_interval_seconds
=$
(($force_interval*60))
174 force_interval_seconds
=$force_interval
178 force_interval_seconds
=$
(($force_interval*60*60))
184 #compute check interval in seconds
185 case "$check_unit" in
187 check_interval_seconds
=$
(($check_interval*60*60*24))
190 check_interval_seconds
=$
(($check_interval*60*60))
193 check_interval_seconds
=$
(($check_interval*60))
196 check_interval_seconds
=$check_interval
200 check_interval_seconds
=$check_interval
206 verbose_echo
"force seconds = $force_interval_seconds"
207 verbose_echo
"check seconds = $check_interval_seconds"
209 #kill old process if it exists & set new pid file
210 if [ -d /var
/run
/dynamic_dns
]
212 #if process is already running, stop it
213 if [ -e "/var/run/dynamic_dns/$service_id.pid" ]
215 old_pid
=$
(cat /var
/run
/dynamic_dns
/$service_id.pid
)
216 test_match
=$
(ps |
grep "^[\t ]*$old_pid")
217 verbose_echo
"old process id (if it exists) = \"$test_match\""
218 if [ -n "$test_match" ]
225 #make dir since it doesn't exist
226 mkdir
/var
/run
/dynamic_dns
228 echo $$
> /var
/run
/dynamic_dns
/$service_id.pid
233 #determine when the last update was
234 current_time
=$
(monotonic_time
)
235 last_update
=$
(( $current_time - (2*$force_interval_seconds) ))
236 if [ -e "/var/run/dynamic_dns/$service_id.update" ]
238 last_update
=$
(cat /var
/run
/dynamic_dns
/$service_id.update
)
240 time_since_update
=$
(($current_time - $last_update))
243 human_time_since_update
=$
(( $time_since_update / ( 60 * 60 ) ))
244 verbose_echo
"time_since_update = $human_time_since_update hours"
249 registered_ip
=$
(echo $
(nslookup "$domain" 2>/dev
/null
) |
grep -o "Name:.*" |
grep -o "$ip_regex")
252 #do update and then loop endlessly, checking ip every check_interval and forcing an updating once every force_interval
256 current_ip
=$
(get_current_ip
)
259 current_time
=$
(monotonic_time
)
260 time_since_update
=$
(($current_time - $last_update))
263 verbose_echo
"Running IP check..."
264 verbose_echo
"current system ip = $current_ip"
265 verbose_echo
"registered domain ip = $registered_ip"
268 if [ "$current_ip" != "$registered_ip" ] ||
[ $force_interval_seconds -lt $time_since_update ]
270 verbose_echo
"update necessary, performing update ..."
273 final_url
=$update_url
274 for option_var
in $ALL_OPTION_VARIABLES
276 if [ "$option_var" != "update_url" ]
278 replace_name
=$
(echo "\[$option_var\]" |
tr 'a-z' 'A-Z')
279 replace_value
=$
(eval echo "\$$option_var")
280 replace_value
=$
(echo $replace_value |
sed -f /usr
/lib
/ddns
/url_escape.
sed)
281 final_url
=$
(echo $final_url |
sed s^
"$replace_name"^
"$replace_value"^g
)
284 final_url
=$
(echo $final_url |
sed s
/"\[HTTPAUTH\]"/"$username${password:+:$password}"/g
)
285 final_url
=$
(echo $final_url |
sed s
/"\[IP\]"/"$current_ip"/g
)
288 verbose_echo
"updating with url=\"$final_url\""
290 #here we actually connect, and perform the update
291 update_output
=$
( $retrieve_prog "$final_url" )
293 verbose_echo
"Update Output:"
294 verbose_echo
"$update_output"
297 #save the time of the update
298 current_time
=$
(monotonic_time
)
299 last_update
=$current_time
300 time_since_update
='0'
301 registered_ip
=$current_ip
304 verbose_echo
"update complete, time is: $human_time"
306 echo "$last_update" > "/var/run/dynamic_dns/$service_id.update"
309 human_time_since_update
=$
(( $time_since_update / ( 60 * 60 ) ))
310 verbose_echo
"update unnecessary"
311 verbose_echo
"time since last update = $human_time_since_update hours"
312 verbose_echo
"the time is now $human_time"
315 #sleep for 10 minutes, then re-check ip && time since last update
316 sleep $check_interval_seconds
319 #should never get here since we're a daemon, but I'll throw it in anyway