summaryrefslogtreecommitdiff
path: root/update-ddns.in
blob: 3d005c1a5b5fba389f2bb352f4adcea69f904365 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/bin/bash

# version #VERSION#

cd /

stty &> /dev/null || \
  sleep $[$RANDOM%60]

if ! ipCmd=$(which ip 2> /dev/null); then
  for p1 in / /usr/; do
    for p2 in bin/ sbin/; do
      ipCmd="${p1}${p2}ip"
      [ -x "${ipCmd}" ] && break
    done
    [ -x "${ipCmd}" ] && break
  done
fi

if [ "x$1" = 'x-f' ]; then
  force_update=true
  shift
else
  force_update=false
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=$(
      printf '%s\n' "${ignoreIps}" "${updateUrl}" "${dnsName}" \
      | grep -vxF '' \
      | sort -u
    )
    continue
  fi

  if [ -z "${ipVer##*!}" ]; then
    ipVer="${ipVer%!}"
  else
    [ -z "$(${ipCmd} -o -${ipVer} addr show scope global)" ] && continue
  fi

  if [ "${ipVer}" == '4' ]; then
    dnsVer='A'
    inetVer='inet'
    ipRegex='[0-9.]\+'
  elif [ "${ipVer}" == '6' ]; then
    dnsVer='AAAA'
    inetVer='inet6'
    ipRegex='[0-9a-f:]\+'
  else
    >&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

  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
      updateIps=$(
        printf '%s\n' "${ips}" \
        | tr '\n' ',' \
        | sed 's/,$//'
      )
    fi
  fi

  ! "${force_update}" && [ "${dnsIps}" = "${ips}" ] && continue

  if [ -z "${updateUrl##*?*}" ]; then
    updateIps='&address='"${updateIps}"
  else
    updateIps='?address='"${updateIps}"
  fi
  curl -${ipVer} -sS "${updateUrl}${updateIps}" 2>/dev/null || err=$?
done

exit ${err}