summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--update-ddns.in177
1 files changed, 60 insertions, 117 deletions
diff --git a/update-ddns.in b/update-ddns.in
index 7aef624..bd86294 100644
--- a/update-ddns.in
+++ b/update-ddns.in
@@ -15,143 +15,86 @@ if ! ipCmd=$(which ip 2> /dev/null); then
done
fi
-unset ignoreIps
-
-i=0
-
-while read -r ipVer updateUrl dnsName; do
-
- if [[ "${ipVer}" = '#'* ]] || [ -z "${ipVer}" ]; then
- continue
- fi
+sed '
+ /^\(#\|\s\)/ d
+ s/^\([46]!\?\)\([46]!\?\)\(\s.*$\)/\1\3\n\2\3/
+' #ETCDIR#/update-ddns.conf \
+| while read -r ipVer updateUrl dnsName; do
if [[ "${ipVer}" == 'ignore' ]]; then
- ignoreIps="${ignoreIps} ${updateUrl} ${dnsName}"
+ ignoreIps=$(
+ printf '%s\n' "${ignoreIps}" "${updateUrl}" "${dnsName}" \
+ | grep -vxF '' \
+ | sort -u
+ )
continue
fi
- if [[ "${ipVer}" == *"?" ]]; then
- ipVer="${ipVer%?}"
+ if [ -z "${ipVer##*!}" ]; then
+ ipVer="${ipVer%!}"
+ else
[ -z "$(${ipCmd} -o -${ipVer} addr show scope global)" ] && continue
fi
if [ "${ipVer}" == '4' ]; then
- dnsVers[${i}]='A'
- inetVers[${i}]='inet'
- ipCmdVers[${i}]='-4'
+ dnsVer='A'
+ inetVer='inet'
+ ipRegex='[0-9.]\+'
elif [ "${ipVer}" == '6' ]; then
- dnsVers[${i}]='AAAA'
- inetVers[${i}]='inet6'
- ipCmdVers[${i}]='-6'
- elif [ "${ipVer}" == '46' ] || [ "${ipVer}" == '64' ]; then
- dnsVers[${i}]='A'
- inetVers[${i}]='inet'
- ipCmdVers[${i}]='-4'
-
- updateUrls[${i}]="${updateUrl}"
- dnsNamen[${i}]="${dnsName}"
- i=$[${i}+1]
-
- dnsVers[${i}]='AAAA'
- inetVers[${i}]='inet6'
- ipCmdVers[${i}]='-6'
+ dnsVer='AAAA'
+ inetVer='inet6'
+ ipRegex='[0-9a-f:]\+'
else
- >&2 echo 'Error: First column in "#ETCDIR#/update-ddns.conf" needs to be "4", "6", "46" or "64"!'
+ >&2 echo 'Syntax error in "#ETCDIR#/update-ddns.conf"!'
+ >&2 echo 'Syntax should be:'
+ >&2 echo '# comments start with "#" or white space'
+ >&2 echo '4/6/46/64 update-url dns-name/check-url'
+ >&2 echo 'digits in the first column may be followed by "!" to indicate'
+ >&2 echo 'that this ip version should be updated regardless of whether'
+ >&2 echo 'an according global ip was found (mostly useful with "auto")'
exit 1
fi
- updateUrls[${i}]="${updateUrl}"
- dnsNamen[${i}]="${dnsName}"
-
- i=$[${i}+1]
-
-done < #ETCDIR#/update-ddns.conf
-
-ignoreIps='^\('"$(
- echo ${ignoreIps} | \
- tr '[:space:]' '\n' | \
- grep -vxF '' | \
- sort -u | \
- sed '
- s@$@\\|@
- ' | \
- tr -d '\n' | \
- sed '
- s@\\|$@@
- '
-)"'\)$'
-
-err=0
-
-for dnsName in $( \
- echo "${dnsNamen[@]}" | \
- tr ' ' '\n' | \
- sort -u
-); do
- unset updateIps
- unset updateUrl
- unset curlForceIpVer
- needsUpdate=false
-
- for ((j=0; j<${i}; j++)); do
- [ "${dnsName}" != "${dnsNamen[${j}]}" ] && continue
-
- updateUrl="${updateUrls[${j}]}"
-
- if [[ "${dnsName}" == *'/'* ]]; then
- dnsIps=$(
- curl ${ipCmdVers[${j}]} "${dnsName}" 2> /dev/null
- )
- ips='1'
- updateIps="${updateIps}"',auto'
- if [ -n "${curlForceIpVer}" ] && [ "${curlForceIpVer}" != "${ipCmdVers[${j}]}" ]; then
- >&2 echo 'Error: I cannot determine two different ip versions automatically (because Erich didn'"'"'t need it).'
- exit 1
- fi
- curlForceIpVer="${ipCmdVers[${j}]}"
+ if [ -z "${dnsName##*/*}" ]; then
+ dnsIps=$(
+ # this test yields 1 if the dns record is already properly set
+ curl -s${ipVer} "${dnsName}"
+ )
+ ips='1'
+ updateIps='auto'
+ else
+ dnsIps=$(
+ dig +short $1 "${dnsName}" ${dnsVers[${j}]} \
+ | grep -x "${ipRegex}" \
+ |sort -u
+ )
+ ips=$(
+ "${ipCmd}" -o -${ipVer} addr show scope global | \
+ awk '{print $4}' | \
+ cut -d/ -f1 | \
+ grep -vx "${ignoreIps}" | \
+ sort -u
+ )
+
+ if [ -z "${ips}" ]; then
+ updateIps='auto'
else
- dnsIps=$(
- dig $1 "${dnsName}" ${dnsVers[${j}]} | \
- sed '/^;; AUTHORITY SECTION:$/Q' | \
- grep '^[^;]' | \
- grep "\s${dnsVers[${j}]}\s" | \
- awk '{print $5}' | \
- sort -u
+ updateIps=$(
+ printf '%s\n' "${ips}" \
+ | tr '\n' ',' \
+ | sed 's/,$//'
)
-
- ips=$(
- "${ipCmd}" -o ${ipCmdVers[${j}]} addr show scope global | \
- awk '{print $4}' | \
- cut -d/ -f1 | \
- grep -vx "${ignoreIps}" | \
- sort -u
- )
-
- if [ $(echo "${ips}" | grep -c '.') -eq 0 ]; then
- updateIps="${updateIps}"',auto'
- if [ -n "${curlForceIpVer}" ] && [ "${curlForceIpVer}" != "${ipCmdVers[${j}]}" ]; then
- >&2 echo 'Error: I cannot determine two different ip versions automatically (because Erich didn'"'"'t need it).'
- exit 1
- fi
- curlForceIpVer="${ipCmdVers[${j}]}"
- else
- updateIps="${updateIps},$(echo -n "${ips}" | tr '\n' ',')"
- fi
fi
+ fi
- if [ "${dnsIps}" != "${ips}" ]; then
- needsUpdate=true
- fi
- done
+ [ "${dnsIps}" = "${ips}" ] && continue
- if ${needsUpdate}; then
- if [[ "${updateUrl}" = *'?'* ]]; then
- updateIps='&address='"${updateIps#,}"
- else
- updateIps='?address='"${updateIps#,}"
- fi
- curl ${curlForceIpVer} -sS "${updateUrl}${updateIps}" 2> /dev/null || err=$?
+ if [ -z "${updateUrl##*?*}" ]; then
+ updateIps='&address='"${updateIps}"
+ else
+ updateIps='?address='"${updateIps}"
fi
+ curl -${ipVer} -sS "${updateUrl}${updateIps}" 2>/dev/null || err=$?
done
exit ${err}