|
|
@ -1,67 +1,263 @@ |
|
|
|
#!/bin/sh |
|
|
|
|
|
|
|
g_pslfile=/usr/share/public_suffix_list.dat.gz |
|
|
|
[ -f "$g_pslfile" ] || g_pslfile="$(dirname $0)/public_suffix_list.dat.gz" |
|
|
|
|
|
|
|
g_pslerr=0 |
|
|
|
g_cfgfile="ddns" |
|
|
|
|
|
|
|
# modify "cloudflare.com-v1" domain to new syntax |
|
|
|
# returns "host[.subdom]@domain.TLD" of given FQDN ############################# |
|
|
|
mod_cloudflare_v1_domain() { |
|
|
|
# $1 entry to validate/split |
|
|
|
[ -f "$g_pslfile" ] || return 1 |
|
|
|
|
|
|
|
[ $# -ne 1 -o -z "$1" ] && \ |
|
|
|
{ printf "%s\\n" "mod_cloudflare_v1_domain() - Invalid number of parameters" >&2; return 1; } |
|
|
|
|
|
|
|
local mcd_fqdn=$1 |
|
|
|
local mcd_fsub="" |
|
|
|
local mcd_fdom="" |
|
|
|
local mcd_ctld="" |
|
|
|
local mcd_ftld="" |
|
|
|
|
|
|
|
# check if already new syntax, "@" inside string |
|
|
|
if [ $( printf "%s" "$mcd_fqdn" | grep -cF "@" 2>/dev/null ) -gt 0 ]; then |
|
|
|
# already done |
|
|
|
printf "%s" "$mcd_fqdn" |
|
|
|
return 0 |
|
|
|
fi |
|
|
|
|
|
|
|
# we need to do in one line because otherwise sh doesn't work correctly |
|
|
|
# to lower | replace "." to " " | awk invert word order |
|
|
|
set -- $(printf %s "$mcd_fqdn" | tr [A-Z] [a-z] | tr "." " " \ |
|
|
|
| awk '{do printf "%s"(NF>1?OFS:ORS),$NF;while (--NF)}' ) |
|
|
|
|
|
|
|
while [ -n "${1:-}" ] ; do # as long we have parameters |
|
|
|
if [ -z "$mcd_ctld" ]; then # first loop |
|
|
|
mcd_ctld="$1" # CURRENT TLD to look at |
|
|
|
shift |
|
|
|
else |
|
|
|
mcd_ctld="$1.$mcd_ctld" # Next TLD to look at |
|
|
|
shift |
|
|
|
fi |
|
|
|
# check if TLD exact match in public_suffix_name.dat, save TLD |
|
|
|
zcat $g_pslfile | grep -E "^$mcd_ctld$" >/dev/null 2>&1 && { |
|
|
|
mcd_ftld="$mcd_ctld" # save found |
|
|
|
mcd_fdom="${1:-}" # save domain next step might be invalid |
|
|
|
continue |
|
|
|
} |
|
|
|
# check if match any "*" in public_suffix_name.dat, |
|
|
|
zcat $g_pslfile | grep -E "^\*.$mcd_ctld$" >/dev/null 2>&1 && { |
|
|
|
[ -z "${1:-}" ] && break # no more data break |
|
|
|
# check if next level TLD match excludes "!" in tld_names.dat |
|
|
|
if zcat $g_pslfile | grep -E "^!$1.$mcd_ctld$" >/dev/null 2>&1 ; then |
|
|
|
mcd_ftld="$mcd_ctld" # Yes |
|
|
|
else |
|
|
|
mcd_ftld="$1.$mcd_ctld" |
|
|
|
shift |
|
|
|
fi |
|
|
|
mcd_fdom="$1"; shift |
|
|
|
} |
|
|
|
[ -n "$mcd_ftld" ] && break # we have something valid, break |
|
|
|
done |
|
|
|
|
|
|
|
# the leftover parameters are the HOST/SUBDOMAIN |
|
|
|
while [ -n "${1:-}" ]; do |
|
|
|
mcd_fsub="${1}${mcd_fsub:+.$mcd_fsub}" # remember we need to invert |
|
|
|
shift # and insert dot if mcd_fsub not empty |
|
|
|
done |
|
|
|
|
|
|
|
# now validate found data |
|
|
|
[ -z "$mcd_ftld" ] && { printf "%s\\n" "mod_cloudflare_v1_domain() - no TLD not found in '$mcd_fqdn'" >&1; return 1; } |
|
|
|
[ -z "$mcd_fdom" ] && { printf "%s\\n" "mod_cloudflare_v1_domain() - no registrable Domain not found in '$mcd_fqdn'" >&1; return 1; } |
|
|
|
|
|
|
|
# return data |
|
|
|
printf "%s" "${mcd_fsub:+${mcd_fsub}@}${mcd_fdom}.${mcd_ftld}" |
|
|
|
return 0 |
|
|
|
} |
|
|
|
|
|
|
|
# modify timer settings from interval and unit to dhms format |
|
|
|
timer2dhms() { |
|
|
|
# $1 Number and |
|
|
|
# $2 Unit of time interval |
|
|
|
local t=0 |
|
|
|
case $2 in |
|
|
|
days) t=$(( $1 * 86400 ));; |
|
|
|
hours) t=$(( $1 * 3600 ));; |
|
|
|
minutes) t=$(( $1 * 60 ));; |
|
|
|
*) t=$1;; |
|
|
|
esac |
|
|
|
|
|
|
|
local d=$(( $t / 86400 )) |
|
|
|
local h=$(( $t % 86400 / 3600 )) |
|
|
|
local m=$(( $t % 3600 / 60 )) |
|
|
|
local s=$(( $t % 60 )) |
|
|
|
if [ $d -gt 0 ]; then printf "%dd %02dh %02dm %02ds" "$d" "$h" "$m" "$s" |
|
|
|
elif [ $h -gt 0 ]; then printf "%dh %02dm %02ds" "$h" "$m" "$s" |
|
|
|
elif [ $m -gt 0 ]; then printf "%dm %02ds" "$m" "$s" |
|
|
|
else printf "%ds" "$s"; fi |
|
|
|
|
|
|
|
unset d h m s t |
|
|
|
return 0 |
|
|
|
} |
|
|
|
|
|
|
|
# using function to not confuse function calls with existing ones inside /lib/functions.sh |
|
|
|
update_ddns_config() { |
|
|
|
udc_uci="$(which uci) -q" # ignore errors |
|
|
|
udc_pkg="ddns" |
|
|
|
udc_cfg="" |
|
|
|
udc_name="" |
|
|
|
udc_var="" |
|
|
|
udc_val="" |
|
|
|
update_config() { |
|
|
|
uc_uci="$(which uci) -q" # ignore errors |
|
|
|
uc_cfg="" |
|
|
|
uc_name="" |
|
|
|
uc_var="" |
|
|
|
uc_val="" |
|
|
|
package() { return 0; } |
|
|
|
config () { |
|
|
|
udc_cfg="$1" |
|
|
|
udc_name="$2" |
|
|
|
uc_cfg="$1" |
|
|
|
uc_name="$2" |
|
|
|
|
|
|
|
# Type = ddns Name = global |
|
|
|
if [ "$udc_cfg" = "$udc_pkg" -a "$udc_name" = "global" ]; then |
|
|
|
option() { return 0; } |
|
|
|
# rename options |
|
|
|
$udc_uci rename $udc_pkg.$udc_name.allow_local_ip="upd_privateip" |
|
|
|
$udc_uci rename $udc_pkg.$udc_name.date_format="ddns_dateformat" |
|
|
|
$udc_uci rename $udc_pkg.$udc_name.log_dir="ddns_logdir" |
|
|
|
$udc_uci rename $udc_pkg.$udc_name.log_lines="ddns_loglines" |
|
|
|
$udc_uci rename $udc_pkg.$udc_name.run_dir="ddns_rundir" |
|
|
|
if [ "$uc_cfg" = "$g_cfgfile" -a "$uc_name" = "global" ]; then |
|
|
|
option() { |
|
|
|
uc_var="$1"; shift |
|
|
|
uc_val="$*" |
|
|
|
case "$uc_var" in |
|
|
|
allow_local_ip) $uc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_privateip";; |
|
|
|
date_format) $uc_uci rename $g_cfgfile.$uc_name.$uc_var="ddns_dateformat";; |
|
|
|
log_lines) $uc_uci rename $g_cfgfile.$uc_name.$uc_var="ddns_loglines";; |
|
|
|
log_dir) $uc_uci rename $g_cfgfile.$uc_name.$uc_var="ddns_logdir";; |
|
|
|
run_dir) $uc_uci rename $g_cfgfile.$uc_name.$uc_var="ddns_rundir";; |
|
|
|
# leave all other options currently unchanged |
|
|
|
*) ;; |
|
|
|
esac |
|
|
|
} |
|
|
|
|
|
|
|
# Type = service Name = ??? |
|
|
|
elif [ "$udc_cfg" = "service" ]; then |
|
|
|
elif [ "$uc_cfg" = "service" ]; then |
|
|
|
option() { |
|
|
|
udc_var="$1"; shift |
|
|
|
udc_val="$*" |
|
|
|
# fix some option service_name values |
|
|
|
case "$udc_var" in |
|
|
|
service_name) |
|
|
|
case "$udc_val" in |
|
|
|
uc_var="$1"; shift |
|
|
|
uc_val="$*" |
|
|
|
case "$uc_var" in |
|
|
|
# fix some option service_name values |
|
|
|
# and some settings for specific providers |
|
|
|
service_name|upd_provider) |
|
|
|
case "$uc_val" in |
|
|
|
freedns\.afraid\.org|afraid\.org) |
|
|
|
$udc_uci set $udc_pkg.$udc_name.$udc_var="afraid.org-keyauth";; |
|
|
|
$uc_uci set $g_cfgfile.$uc_name.$uc_var="afraid.org-keyauth";; |
|
|
|
Bind-nsupdate) |
|
|
|
$udc_uci set $udc_pkg.$udc_name.$udc_var="bind-nsupdate";; |
|
|
|
CloudFlare|cloudflare\.com) |
|
|
|
$udc_uci set $udc_pkg.$udc_name.$udc_var="cloudflare.com-v1";; |
|
|
|
$uc_uci set $g_cfgfile.$uc_name.$uc_var="bind-nsupdate";; |
|
|
|
CloudFlare|cloudflare\.com|cloudflare\.com-v1) |
|
|
|
# verify if lookup_host is set |
|
|
|
$uc_uci get $g_cfgfile.$uc_name.lookup_host >/dev/null 2>&1 || { |
|
|
|
ucv_domain=$($uc_uci get $g_cfgfile.$uc_name.domain 2>/dev/null) |
|
|
|
$uc_uci set $g_cfgfile.$uc_name.lookup_host="$ucv_domain" |
|
|
|
} |
|
|
|
if [ -f "$g_pslfile" ]; then |
|
|
|
# change value of domain/upd_object to new syntax |
|
|
|
# there is no sort order inside uci data so we need multiple checks |
|
|
|
ucv_domain=$($uc_uci get $g_cfgfile.$uc_name.domain 2>/dev/null) |
|
|
|
ucv_object=$($uc_uci get $g_cfgfile.$uc_name.upd_object 2>/dev/null) |
|
|
|
# still old option domain |
|
|
|
if [ -n "$ucv_domain" ]; then |
|
|
|
ucv_new=$(mod_cloudflare_v1_domain "$ucv_domain") || g_pslerr=1 |
|
|
|
# no error save data save data |
|
|
|
[ $g_pslerr -eq 0 ] && \ |
|
|
|
$uc_uci set $g_cfgfile.$uc_name.domain="$ucv_new" |
|
|
|
fi |
|
|
|
# already new option upd_object |
|
|
|
if [ -n "$ucv_object" ]; then |
|
|
|
ucv_new=$(mod_cloudflare_v1_domain "$ucv_object") || g_pslerr=1 |
|
|
|
# no error save data save data |
|
|
|
[ $g_pslerr -eq 0 ] && \ |
|
|
|
$uc_uci set $g_cfgfile.$uc_name.upd_object="$ucv_new" |
|
|
|
fi |
|
|
|
fi |
|
|
|
unset ucv_domain ucv_object ucv_new |
|
|
|
# set new option value |
|
|
|
$uc_uci set $g_cfgfile.$uc_name.$uc_var="cloudflare.com-v1" |
|
|
|
;; |
|
|
|
dyndns\.org|dyndns\.com) |
|
|
|
$udc_uci set $udc_pkg.$udc_name.$udc_var="dyn.com";; |
|
|
|
$uc_uci set $g_cfgfile.$uc_name.$uc_var="dyn.com";; |
|
|
|
free\.editdns\.net) |
|
|
|
$udc_uci set $udc_pkg.$udc_name.$udc_var="editdns.net";; |
|
|
|
$uc_uci set $g_cfgfile.$uc_name.$uc_var="editdns.net";; |
|
|
|
domains\.google\.com) |
|
|
|
$udc_uci set $udc_pkg.$udc_name.$udc_var="google.com";; |
|
|
|
$uc_uci set $g_cfgfile.$uc_name.$uc_var="google.com";; |
|
|
|
loopia\.com) |
|
|
|
$udc_uci set $udc_pkg.$udc_name.$udc_var="loopia.se";; |
|
|
|
$uc_uci set $g_cfgfile.$uc_name.$uc_var="loopia.se";; |
|
|
|
NoIP\.com|No-IP\.com) |
|
|
|
$udc_uci set $udc_pkg.$udc_name.$udc_var="no-ip.com";; |
|
|
|
$uc_uci set $g_cfgfile.$uc_name.$uc_var="no-ip.com";; |
|
|
|
spdns\.de) |
|
|
|
$udc_uci set $udc_pkg.$udc_name.$udc_var="spdyn.de";; |
|
|
|
$uc_uci set $g_cfgfile.$uc_name.$uc_var="spdyn.de";; |
|
|
|
strato\.de) |
|
|
|
$udc_uci set $udc_pkg.$udc_name.$udc_var="strato.com";; |
|
|
|
$uc_uci set $g_cfgfile.$uc_name.$uc_var="strato.com";; |
|
|
|
*) |
|
|
|
# all others leave unchanged |
|
|
|
;; |
|
|
|
esac |
|
|
|
# rename option service_name to option upd_provider |
|
|
|
# $udc_uci rename $udc_pkg.$udc_name.$udc_var="upd_provider" |
|
|
|
# $uc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_provider" |
|
|
|
;; |
|
|
|
*) |
|
|
|
# leave all other options currently unchanged |
|
|
|
domain|upd_object) |
|
|
|
# verify if lookup_host is set |
|
|
|
$uc_uci get $g_cfgfile.$uc_name.lookup_host >/dev/null 2>&1 || \ |
|
|
|
$uc_uci set $g_cfgfile.$uc_name.lookup_host="$uc_val" |
|
|
|
if [ -f "$g_pslfile" ]; then |
|
|
|
# if service_name/upd_provider cloudflare_v1 then change domain/upd_object to new syntax |
|
|
|
# there is no sort order inside uci data so we need multiple checks |
|
|
|
uco_provider=$($uc_uci get $g_cfgfile.$uc_name.upd_provider 2>/dev/null) || \ |
|
|
|
uco_provider=$($uc_uci get $g_cfgfile.$uc_name.service_name 2>/dev/null) |
|
|
|
if [ "$uco_provider" = "CloudFlare" \ |
|
|
|
-o "$uco_provider" = "cloudflare.com" \ |
|
|
|
-o "$uco_provider" = "cloudflare.com-v1" ]; then |
|
|
|
ucv_new=$(mod_cloudflare_v1_domain "$uc_val") || g_pslerr=1 |
|
|
|
# no error save data save data |
|
|
|
[ $g_pslerr -eq 0 ] && \ |
|
|
|
$uc_uci set $g_cfgfile.$uc_name.$uc_var="$ucv_new" |
|
|
|
unset ucv_new |
|
|
|
fi |
|
|
|
unset uco_provider |
|
|
|
fi |
|
|
|
# rename option domain to option upd_object |
|
|
|
# $uc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_object" |
|
|
|
;; |
|
|
|
# dns_server) |
|
|
|
# # if bind-nsupdate takeover old "dns_server" value as new "upd_nsupd_server" value |
|
|
|
# uco_provider=$($uc_uci get $g_cfgfile.$uc_name.upd_provider 2>/dev/null) || \ |
|
|
|
# uco_provider=$($uc_uci get $g_cfgfile.$uc_name.service_name 2>/dev/null) |
|
|
|
# [ "$uco_provider" = "Bind-nsupdate" -o \ |
|
|
|
# "$uco_provider" = "bind-nsupdate" ] && \ |
|
|
|
# $uc_uci set $g_cfgfile.$uc_name.upd_nsupd_server="$uc_val" |
|
|
|
# # rename option dns_server to new option global_dnssvr |
|
|
|
# $udc_uci rename $g_cfgfile.$uc_name.$uc_var="global_dnssvr" |
|
|
|
# ;; |
|
|
|
# bind_network) |
|
|
|
# $udc_uci set $g_cfgfile.$uc_name.upd_url_bindnet="$uc_val" |
|
|
|
# $udc_uci rename $g_cfgfile.$uc_name.$uc_var="lip_url_bindnet" |
|
|
|
# ;; |
|
|
|
# proxy) |
|
|
|
# # proxy value must include protocoll |
|
|
|
# $udc_uci set $g_cfgfile.$uc_name.$uc_var="http://$uc_val" |
|
|
|
# $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_url_proxy" |
|
|
|
# ;; |
|
|
|
# use_ipv6) |
|
|
|
# $udc_uci set $g_cfgfile.$uc_name.$uc_var="$(( 4 + ( 2 * $uc_val ) ))" |
|
|
|
# $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_ipversion" |
|
|
|
# TODO update_url) |
|
|
|
# TODO update_script) |
|
|
|
# other renames |
|
|
|
# TODO lookup_host) -> rip_host |
|
|
|
# enabled) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_enabled";; |
|
|
|
# force_dnstcp) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="rip_host_dnstcp";; |
|
|
|
# is_glue) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="rip_host_isglue";; |
|
|
|
# ip_interface) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="lip_iface";; |
|
|
|
# ip_network) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="lip_net";; |
|
|
|
# use_https) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_url_secure";; |
|
|
|
# cacert) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_url_cacert";; |
|
|
|
# username) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_username";; |
|
|
|
# password) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_password";; |
|
|
|
# param_opt) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_paramopt";; |
|
|
|
# param_enc) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_paramenc";; |
|
|
|
|
|
|
|
# leave all other options currently unchanged |
|
|
|
*) ;; |
|
|
|
esac |
|
|
|
return 0 |
|
|
|
} |
|
|
@ -73,27 +269,41 @@ update_ddns_config() { |
|
|
|
fi |
|
|
|
} |
|
|
|
|
|
|
|
# read package config file |
|
|
|
udc_data=$($udc_uci -S -n export "$udc_pkg") |
|
|
|
udc_ret="$?" |
|
|
|
# No error and udc_data then execute (eval) |
|
|
|
# read config file |
|
|
|
uc_data=$($uc_uci -S -n export "$g_cfgfile") |
|
|
|
uc_ret="$?" |
|
|
|
# Error then create config file |
|
|
|
[ $uc_ret -ne 0 ] && { |
|
|
|
touch /etc/config/$uc_cfgfile |
|
|
|
chmod 644 /etc/config/$uc_cfgfile |
|
|
|
} |
|
|
|
# No error and uc_data then execute (eval) |
|
|
|
# this will call functions defined above |
|
|
|
[ "$udc_ret" -eq 0 -a -n "$udc_data" ] && eval "$udc_data" |
|
|
|
[ $uc_ret -eq 0 -a -n "$uc_data" ] && eval "$uc_data" |
|
|
|
|
|
|
|
# add config ddns "global" (ignore error if exists) |
|
|
|
$udc_uci set ddns.global="$udc_pkg" |
|
|
|
$uc_uci set ddns.global="$g_cfgfile" |
|
|
|
|
|
|
|
# write changes to config file |
|
|
|
$udc_uci commit "$udc_pkg" |
|
|
|
$uc_uci commit "$g_cfgfile" |
|
|
|
|
|
|
|
unset udc_uci udc_pkg udc_cfg udc_name udc_var udc_val udc_ret udc_data |
|
|
|
unset uc_uci uc_cfg uc_name uc_var uc_val uc_ret uc_data |
|
|
|
return 0 |
|
|
|
} |
|
|
|
|
|
|
|
# do existing config update |
|
|
|
update_ddns_config |
|
|
|
|
|
|
|
# clear Ludc_uci indexcache |
|
|
|
# clear LuCI indexcache |
|
|
|
rm -f /tmp/luci-indexcache >/dev/null 2>&1 |
|
|
|
|
|
|
|
# do config update |
|
|
|
update_config |
|
|
|
|
|
|
|
#cleanup |
|
|
|
[ $g_pslerr -ne 0 ] && { |
|
|
|
unset g_pslfile g_pslerr g_cfgfile |
|
|
|
return 1 |
|
|
|
} |
|
|
|
|
|
|
|
[ -f "$g_pslfile" ] && rm -f "$g_pslfile" |
|
|
|
unset g_pslfile g_pslerr g_cfgfile |
|
|
|
return 0 |
|
|
|
|