aboutsummaryrefslogtreecommitdiff
path: root/net/ddns-scripts/files/usr/lib/ddns/update_dnspod_cn.sh
blob: 2091be132b2f5deb32f51d91c8acb4c748306a33 (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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/bin/sh

# Check inputs
[ -z "$username" ] && write_log 14 "Configuration error! [User name] cannot be empty"
[ -z "$password" ] && write_log 14 "Configuration error! [Password] cannot be empty"

# Check external tools
[ -n "$CURL_SSL" ] || write_log 13 "Dnspod communication require cURL with SSL support. Please install"
[ -n "$CURL_PROXY" ] || write_log 13 "cURL: libcurl compiled without Proxy support"

# Declare variables
#local __URLBASE __HOST __DOMAIN __TYPE __CMDBASE __POST __POST1 __RECIP __RECID __TTL
__URLBASE="https://dnsapi.cn"

# Get host and domain from $domain
[ "${domain:0:2}" = "@." ] && domain="${domain/./}"      # host
[ "$domain" = "${domain/@/}" ] && domain="${domain/./@}" # host with no sperator
__HOST="${domain%%@*}"
__DOMAIN="${domain#*@}"
[ -z "$__HOST" -o "$__HOST" = "$__DOMAIN" ] && __HOST=@

# Set record type
[ $use_ipv6 = 0 ] && __TYPE=A || __TYPE=AAAA

# Build base command
build_command() {
	__CMDBASE="$CURL -Ss"
	# bind host/IP
	if [ -n "$bind_network" ]; then
		local __DEVICE
		network_get_physdev __DEVICE $bind_network || write_log 13 "Can not detect local device using 'network_get_physdev $bind_network' - Error: '$?'"
		write_log 7 "Force communication via device '$__DEVICE'"
		__CMDBASE="$__CMDBASE --interface $__DEVICE"
	fi
	# Force IP version
	if [ $force_ipversion = 1 ]; then
		[ $use_ipv6 = 0 ] && __CMDBASE="$__CMDBASE -4" || __CMDBASE="$__CMDBASE -6"
	fi
	# Set CA
	if [ $use_https = 1 ]; then
		if [ "$cacert" = IGNORE ]; then
			__CMDBASE="$__CMDBASE --insecure"
		elif [ -f "$cacert" ]; then
			__CMDBASE="$__CMDBASE --cacert $cacert"
		elif [ -d "$cacert" ]; then
			__CMDBASE="$__CMDBASE --capath $cacert"
		elif [ -n "$cacert" ]; then
			write_log 14 "No valid certificate(s) found at '$cacert' for HTTPS communication"
		fi
	fi
	# Set if no proxy (might be an error with .wgetrc or env)
	[ -z "$proxy" ] && __CMDBASE="$__CMDBASE --noproxy '*'"
	__CMDBASE="$__CMDBASE -d"
}

# Dnspod API
dnspod_transfer() {
	__CNT=0
	case "$1" in
	0) __A="$__CMDBASE '$__POST' $__URLBASE/Record.List" ;;
	1) __A="$__CMDBASE '$__POST1' $__URLBASE/Record.Create" ;;
	2) __A="$__CMDBASE '$__POST1&record_id=$__RECID&ttl=$__TTL' $__URLBASE/Record.Modify" ;;
	esac

	write_log 7 "#> $__A"
	while ! __TMP=$(eval $__A 2>&1); do
		write_log 3 "[$__TMP]"
		if [ $VERBOSE -gt 1 ]; then
			write_log 4 "Transfer failed - detailed mode: $VERBOSE - Do not try again after an error"
			return 1
		fi
		__CNT=$(($__CNT + 1))
		[ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && write_log 14 "Transfer failed after $retry_count retries"
		write_log 4 "Transfer failed - $__CNT Try again in $RETRY_SECONDS seconds"
		sleep $RETRY_SECONDS &
		PID_SLEEP=$!
		wait $PID_SLEEP
		PID_SLEEP=0
	done
	__ERR=$(jsonfilter -s "$__TMP" -e "@.status.code")
	[ $__ERR = 1 ] && return 0
	[ $__ERR = 10 ] && [ $1 = 0 ] && return 0
	__TMP=$(jsonfilter -s "$__TMP" -e "@.status.message")
	local A="$(date +%H%M%S) ERROR : [$__TMP] - Terminate process"
	logger -p user.err -t ddns-scripts[$$] $SECTION_ID: ${A:15}
	printf "%s\n" " $A" >>$LOGFILE
	exit 1
}

# Add record
add_domain() {
	dnspod_transfer 1
	printf "%s\n" " $(date +%H%M%S)       : Record add successfully: [$([ "$__HOST" = @ ] || echo $__HOST.)$__DOMAIN],[IP:$__IP]" >>$LOGFILE
	return 0
}

# Modify record
update_domain() {
	dnspod_transfer 2
	printf "%s\n" " $(date +%H%M%S)       : Record modified successfully: [$([ "$__HOST" = @ ] || echo $__HOST.)$__DOMAIN],[IP:$__IP],[TTL:$__TTL]" >>$LOGFILE
	return 0
}

# Get DNS record
describe_domain() {
	ret=0
	__POST="login_token=$username,$password&format=json&domain=$__DOMAIN&sub_domain=$__HOST"
	__POST1="$__POST&value=$__IP&record_type=$__TYPE&record_line_id=0"
	dnspod_transfer 0
	__TMP=$(jsonfilter -s "$__TMP" -e "@.records[@.type='$__TYPE' && @.line_id='0']")
	if [ -z "$__TMP" ]; then
		printf "%s\n" " $(date +%H%M%S)       : Record not exist: [$([ "$__HOST" = @ ] || echo $__HOST.)$__DOMAIN]" >>$LOGFILE
		ret=1
	else
		__RECIP=$(jsonfilter -s "$__TMP" -e "@.value")
		if [ "$__RECIP" != "$__IP" ]; then
			__RECID=$(jsonfilter -s "$__TMP" -e "@.id")
			__TTL=$(jsonfilter -s "$__TMP" -e "@.ttl")
			printf "%s\n" " $(date +%H%M%S)       : Record needs to be updated: [Record IP:$__RECIP] [Local IP:$__IP]" >>$LOGFILE
			ret=2
		fi
	fi
}

build_command
describe_domain
if [ $ret = 1 ]; then
	sleep 3
	add_domain
elif [ $ret = 2 ]; then
	sleep 3
	update_domain
else
	printf "%s\n" " $(date +%H%M%S)       : Record needs not update: [Record IP:$__RECIP] [Local IP:$__IP]" >>$LOGFILE
fi

return 0