| get_version() { |
| #sed -En 's/^ *"?rncn-config-version"? *: *([0-9]+),?$/\1/p' |
| jq --exit-status --raw-output '.["rncn-config-version"]' |
| } |
| |
| # Usage: check_and_update_config <dns-port> <remote-url> <local-path> [<service-name>] |
| check_and_update_config() { |
| if [ $# != 3 ] && [ $# != 4 ]; then |
| echo "Wrong usage" 1>&2 |
| #return 255 |
| exit 255 |
| fi |
| local cfg remote_version local_version |
| cfg="`wget --no-verbose \"$2\" -O -`" || return |
| cfg="`printf '%s\\n' \"$cfg\" | grep -Ev '^[[:space:]]*#' | cpp -P -fpreprocessed`" || return |
| if ! remote_version="`printf '%s\\n' "$cfg" | get_version`" || [ -z "$remote_version" ]; then |
| echo "Newly fetched configuration file has no version field?!" 1>&2 |
| return 1 |
| fi |
| [ -f "$3" ] && local_version="`get_version < \"$3\"`" && [ -n "$local_version" ] && [ "$local_version" -ge "$remote_version" ] && return |
| rm -f -- "$3.old" || return |
| if [ -f "$3" ]; then |
| mv -f -- "$3" "$3.old" || return |
| fi |
| rm -f -- "$3" || return |
| printf %s "$cfg" | jq '$default_global_config + {"geo-auto-update", "geo-update-interval", "geox-url", "hosts", "dns":(.dns+$dns_config)}' \ |
| --argjson default_global_config " |
| { |
| \"rncn-config-version\":$remote_version, |
| \"log-level\":\"error\", |
| \"geodata-mode\":false |
| }" \ |
| --argjson dns_config " |
| { |
| \"enable\":true, |
| \"use-system-hosts\":false, |
| \"use-hosts\":true, |
| \"prefer-h3\":false, |
| \"respect-rules\":false, |
| \"listen\":\"10.10.10.10:$1\", |
| \"enhanced-mode\":\"normal\" |
| }" \ |
| > "$3" || return |
| [ $# = 3 ] && return |
| if ! service "$4" restart; then |
| printf "Failed to restart %s, rollback to old version\\n" "$3" |
| mv "$3.old" "$3" |
| service "$4" restart |
| return |
| fi |
| echo "Newer configuration has been found and updated." 1>&2 |
| } |