You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
4.4 KiB

  1. #!/bin/sh
  2. # Check inputs
  3. [ -z "$username" ] && write_log 14 "Configuration error! [User name] cannot be empty"
  4. [ -z "$password" ] && write_log 14 "Configuration error! [Password] cannot be empty"
  5. # Check external tools
  6. [ -n "$CURL_SSL" ] || write_log 13 "Dnspod communication require cURL with SSL support. Please install"
  7. [ -n "$CURL_PROXY" ] || write_log 13 "cURL: libcurl compiled without Proxy support"
  8. # Declare variables
  9. #local __URLBASE __HOST __DOMAIN __TYPE __CMDBASE __POST __POST1 __RECIP __RECID __TTL
  10. __URLBASE="https://dnsapi.cn"
  11. # Get host and domain from $domain
  12. [ "${domain:0:2}" = "@." ] && domain="${domain/./}" # host
  13. [ "$domain" = "${domain/@/}" ] && domain="${domain/./@}" # host with no sperator
  14. __HOST="${domain%%@*}"
  15. __DOMAIN="${domain#*@}"
  16. [ -z "$__HOST" -o "$__HOST" = "$__DOMAIN" ] && __HOST=@
  17. # Set record type
  18. [ $use_ipv6 = 0 ] && __TYPE=A || __TYPE=AAAA
  19. # Build base command
  20. build_command() {
  21. __CMDBASE="$CURL -Ss"
  22. # bind host/IP
  23. if [ -n "$bind_network" ]; then
  24. local __DEVICE
  25. network_get_physdev __DEVICE $bind_network || write_log 13 "Can not detect local device using 'network_get_physdev $bind_network' - Error: '$?'"
  26. write_log 7 "Force communication via device '$__DEVICE'"
  27. __CMDBASE="$__CMDBASE --interface $__DEVICE"
  28. fi
  29. # Force IP version
  30. if [ $force_ipversion = 1 ]; then
  31. [ $use_ipv6 = 0 ] && __CMDBASE="$__CMDBASE -4" || __CMDBASE="$__CMDBASE -6"
  32. fi
  33. # Set CA
  34. if [ $use_https = 1 ]; then
  35. if [ "$cacert" = IGNORE ]; then
  36. __CMDBASE="$__CMDBASE --insecure"
  37. elif [ -f "$cacert" ]; then
  38. __CMDBASE="$__CMDBASE --cacert $cacert"
  39. elif [ -d "$cacert" ]; then
  40. __CMDBASE="$__CMDBASE --capath $cacert"
  41. elif [ -n "$cacert" ]; then
  42. write_log 14 "No valid certificate(s) found at '$cacert' for HTTPS communication"
  43. fi
  44. fi
  45. # Set if no proxy (might be an error with .wgetrc or env)
  46. [ -z "$proxy" ] && __CMDBASE="$__CMDBASE --noproxy '*'"
  47. __CMDBASE="$__CMDBASE -d"
  48. }
  49. # Dnspod API
  50. dnspod_transfer() {
  51. __CNT=0
  52. case "$1" in
  53. 0) __A="$__CMDBASE '$__POST' $__URLBASE/Record.List" ;;
  54. 1) __A="$__CMDBASE '$__POST1' $__URLBASE/Record.Create" ;;
  55. 2) __A="$__CMDBASE '$__POST1&record_id=$__RECID&ttl=$__TTL' $__URLBASE/Record.Modify" ;;
  56. esac
  57. write_log 7 "#> $__A"
  58. while ! __TMP=$(eval $__A 2>&1); do
  59. write_log 3 "[$__TMP]"
  60. if [ $VERBOSE -gt 1 ]; then
  61. write_log 4 "Transfer failed - detailed mode: $VERBOSE - Do not try again after an error"
  62. return 1
  63. fi
  64. __CNT=$(($__CNT + 1))
  65. [ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && write_log 14 "Transfer failed after $retry_count retries"
  66. write_log 4 "Transfer failed - $__CNT Try again in $RETRY_SECONDS seconds"
  67. sleep $RETRY_SECONDS &
  68. PID_SLEEP=$!
  69. wait $PID_SLEEP
  70. PID_SLEEP=0
  71. done
  72. __ERR=$(jsonfilter -s "$__TMP" -e "@.status.code")
  73. [ $__ERR = 1 ] && return 0
  74. [ $__ERR = 10 ] && [ $1 = 0 ] && return 0
  75. __TMP=$(jsonfilter -s "$__TMP" -e "@.status.message")
  76. local A="$(date +%H%M%S) ERROR : [$__TMP] - Terminate process"
  77. logger -p user.err -t ddns-scripts[$$] $SECTION_ID: ${A:15}
  78. printf "%s\n" " $A" >>$LOGFILE
  79. exit 1
  80. }
  81. # Add record
  82. add_domain() {
  83. dnspod_transfer 1
  84. printf "%s\n" " $(date +%H%M%S) : Record add successfully: [$([ "$__HOST" = @ ] || echo $__HOST.)$__DOMAIN],[IP:$__IP]" >>$LOGFILE
  85. return 0
  86. }
  87. # Modify record
  88. update_domain() {
  89. dnspod_transfer 2
  90. printf "%s\n" " $(date +%H%M%S) : Record modified successfully: [$([ "$__HOST" = @ ] || echo $__HOST.)$__DOMAIN],[IP:$__IP],[TTL:$__TTL]" >>$LOGFILE
  91. return 0
  92. }
  93. # Get DNS record
  94. describe_domain() {
  95. ret=0
  96. __POST="login_token=$username,$password&format=json&domain=$__DOMAIN&sub_domain=$__HOST"
  97. __POST1="$__POST&value=$__IP&record_type=$__TYPE&record_line_id=0"
  98. dnspod_transfer 0
  99. __TMP=$(jsonfilter -s "$__TMP" -e "@.records[@.type='$__TYPE' && @.line_id='0']")
  100. if [ -z "$__TMP" ]; then
  101. printf "%s\n" " $(date +%H%M%S) : Record not exist: [$([ "$__HOST" = @ ] || echo $__HOST.)$__DOMAIN]" >>$LOGFILE
  102. ret=1
  103. else
  104. __RECIP=$(jsonfilter -s "$__TMP" -e "@.value")
  105. if [ "$__RECIP" != "$__IP" ]; then
  106. __RECID=$(jsonfilter -s "$__TMP" -e "@.id")
  107. __TTL=$(jsonfilter -s "$__TMP" -e "@.ttl")
  108. printf "%s\n" " $(date +%H%M%S) : Record needs to be updated: [Record IP:$__RECIP] [Local IP:$__IP]" >>$LOGFILE
  109. ret=2
  110. fi
  111. fi
  112. }
  113. build_command
  114. describe_domain
  115. if [ $ret = 1 ]; then
  116. sleep 3
  117. add_domain
  118. elif [ $ret = 2 ]; then
  119. sleep 3
  120. update_domain
  121. else
  122. printf "%s\n" " $(date +%H%M%S) : Record needs not update: [Record IP:$__RECIP] [Local IP:$__IP]" >>$LOGFILE
  123. fi
  124. return 0