diff --git a/CHANGELOG.md b/CHANGELOG.md index d036562..2eaed41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ ### New +* :sparkles: add loop mode. [Eduard Veit] + * :sparkles: add support for Duck DNS as DynDNS2 provider. [Eduard Veit] * :sparkles: add support for deSEC as DynDNS2 provider. [Eduard Veit] @@ -33,6 +35,8 @@ ### Documentation +* :memo: update example of .env in README.md. [Eduard Veit] + * :memo: add CHANGELOG.md. [Eduard Veit] * :memo: add example.env. [Eduard Veit] @@ -41,6 +45,8 @@ ### Other +* :recycle: refactor: rename environment variables. [Eduard Veit] + * :recycle: refactor, fix and debug error handling. [Eduard Veit] * :recycle: refactor main code. [Eduard Veit] diff --git a/_dynb.sh b/_dynb.sh index db92f12..e945158 100755 --- a/_dynb.sh +++ b/_dynb.sh @@ -12,10 +12,10 @@ _dynb_sh () COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" - all_long_opts="--version --link --reset --debug --update-method --ip-mode --domain --service-provider --username --password --token --help " + all_long_opts="--version --link --reset --debug --update-method --ip-mode --domain --service-provider --username --password --token --interval --help " all_short_opts="-v -l -r -m -i -d -s -u -p -t -h " case "$prev" in - --update-method|-m|--ip-mode|-i|--domain|-d|--service-provider|-s|--username|-u|--password|-p|--token|-t) + --update-method|-m|--ip-mode|-i|--domain|-d|--service-provider|-s|--username|-u|--password|-p|--token|-t|--interval) COMPREPLY=( $(compgen -o bashdefault -o default -- "${cur}") ) return 0 ;; @@ -37,5 +37,5 @@ _dynb_sh () esac } -complete -F _dynb_sh dynb.sh dynb +complete -F _dynb_sh dynb.sh ### END OF CODE GENERATED BY Argbash (sortof) ### ]) diff --git a/dynb.sh b/dynb.sh index 202a956..e94d16b 100755 --- a/dynb.sh +++ b/dynb.sh @@ -10,23 +10,23 @@ ## Configuration ## ################### -DYNB_DYN_DOMAIN= +#DYNB_DYN_DOMAIN= ## service provider could be deSEC, duckdns, dynv6, inwx -DYNB_SERVICE_PROVIDER= +#DYNB_SERVICE_PROVIDER= ## update method options: domrobot, dyndns -DYNB_UPDATE_METHOD= +#DYNB_UPDATE_METHOD= ## ip mode could be either: 4, 6 or dual for dualstack -DYNB_IP_MODE= +#DYNB_IP_MODE= ## If you are using the DomRobot RPC-API enter your credentials for the web interface login here ## If you are using the DynDNS2 protocol enter your credentials here -DYNB_USERNAME= -DYNB_PASSWORD= +#DYNB_USERNAME= +#DYNB_PASSWORD= ## or use a token -DYNB_TOKEN= +#DYNB_TOKEN= ## TTL (time to live) for the DNS record ## This setting is only relevant for API based record updates (not DnyDNS2!) @@ -36,7 +36,7 @@ TTL=300 ## The IP-Check sites (some sites have different urls for v4 and v6) ## Pro tip: use your own ip check server for privacy ## it could be as simple as that... -## create an index.php with +## create an index.php with _ipv4_checker=api64.ipify.org _ipv6_checker=api64.ipify.org @@ -65,11 +65,13 @@ _response= _statusHostname= _statusUsername= _statusPassword= -_version=0.0.1 +_version=0.1.0 _userAgent="DynB/$_version github.com/EV21/dynb" _configFile=$HOME/.local/share/dynb/.env _statusFile=/tmp/dynb.status _debug=0 +_minimum_looptime=60 +_loopMode=0 # Created by argbash-init v2.10.0 # Rearrange the order of options below according to what you would like to see in the help message. @@ -84,6 +86,7 @@ _debug=0 # ARG_OPTIONAL_SINGLE([username],[u],[depends on your selected update method and your provider],[]) # ARG_OPTIONAL_SINGLE([password],[p],[depends on your selected update method and your provider],[]) # ARG_OPTIONAL_SINGLE([token],[t],[depends on your selected update method and your provider],[]) +# ARG_OPTIONAL_SINGLE([interval],[],[choose the seconds interval to run the script in a loop, minimum is 60],[]) # ARG_HELP([DynB - dynamic DNS update script for bash]) # ARGBASH_GO() # needed because of Argbash --> m4_ignore([ @@ -120,12 +123,13 @@ _arg_service_provider= _arg_username= _arg_password= _arg_token= +_arg_interval= print_help() { printf '%s\n' "DynB - dynamic DNS update script for bash" - printf 'Usage: %s [-v|--(no-)version] [-l|--(no-)link] [-r|--(no-)reset] [--(no-)debug] [-m|--update-method ] [-i|--ip-mode ] [-d|--domain ] [-s|--service-provider ] [-u|--username ] [-p|--password ] [-t|--token ] [-h|--help]\n' "$0" + printf 'Usage: %s [-v|--(no-)version] [-l|--(no-)link] [-r|--(no-)reset] [--(no-)debug] [-m|--update-method ] [-i|--ip-mode ] [-d|--domain ] [-s|--service-provider ] [-u|--username ] [-p|--password ] [-t|--token ] [--interval ] [-h|--help]\n' "$0" printf '\t%s\n' "-v, --version, --no-version: outputs the client version (off by default)" printf '\t%s\n' "-l, --link, --no-link: links to your script at ~/.local/bin/dynb (off by default)" printf '\t%s\n' "-r, --reset, --no-reset: deletes the client blocking status file (off by default)" @@ -137,6 +141,7 @@ print_help() printf '\t%s\n' "-u, --username: depends on your selected update method and your provider (no default)" printf '\t%s\n' "-p, --password: depends on your selected update method and your provider (no default)" printf '\t%s\n' "-t, --token: depends on your selected update method and your provider (no default)" + printf '\t%s\n' "--interval: choose the seconds interval to run the script in a loop, minimum is 60 (no default)" printf '\t%s\n' "-h, --help: Prints help" } @@ -264,6 +269,14 @@ parse_commandline() -t*) _arg_token="${_key##-t}" ;; + --interval) + test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 + _arg_interval="$2" + shift + ;; + --interval=*) + _arg_interval="${_key##--interval=}" + ;; -h|--help) print_help exit 0 @@ -316,6 +329,14 @@ dynb --ip-mode dual --update-method dyndns --service-provider inwx --domain dynd EOF )" +function loopMode() { + if [[ $_loopMode -eq 1 ]]; then + return 0 + else + return 1 + fi +} + function debugMode() { if [[ $_debug -eq 1 ]]; then return 0 @@ -493,7 +514,7 @@ function dynupdate() { esac case $_response in - good* | OK* ) + good* | OK* | "addresses updated" ) if [[ $_response == "good 127.0.0.1" ]]; then echoerr "Error: $_response: Request ignored." return 1 @@ -706,6 +727,36 @@ function handleParameters() { if [[ $_arg_token != "" ]]; then DYNB_TOKEN=$_arg_token fi + if [[ $_arg_interval != "" ]]; then + DYNB_INTERVAL=$_arg_interval + fi + + if [[ -z $DYNB_INTERVAL ]]; then + _loopMode=0 + elif [[ $DYNB_INTERVAL -lt _minimum_looptime ]]; then + DYNB_INTERVAL=$_minimum_looptime + _loopMode=1 + else + _loopMode=1 + fi + if [[ $_network_interface != "" ]]; then + _interface_str="--interface $_network_interface" + fi + + if [[ $DYNB_IP_MODE == d* ]]; then + _is_IPv4_enabled=true + _is_IPv6_enabled=true + fi + if [[ $DYNB_IP_MODE == *4* ]]; then + _is_IPv4_enabled=true + fi + if [[ $DYNB_IP_MODE == *6* ]]; then + _is_IPv6_enabled=true + fi + + if [[ $DYNB_DEBUG == true ]]; then + _debug=1 + fi return 0 } @@ -751,49 +802,7 @@ function doUnsets() { unset _version } -################# -## MAIN method ## -################# -function dynb() { - ## parameters and checks - checkDependencies - - # shellcheck source=.env - if test -f "$_configFile"; then - # shellcheck disable=SC1091 - source "$_configFile" - else - alternativeConfig="$(dirname "$(realpath "$0")")/.env" - if test -f "$alternativeConfig"; then - # shellcheck disable=SC1091 - source "$alternativeConfig" - fi - fi - if test -f "$_statusFile"; then - debugMessage "read previous status file" - # shellcheck disable=SC1090 - source "$_statusFile" - fi - - handleParameters - - if [[ $_network_interface != "" ]]; then - _interface_str="--interface $_network_interface" - fi - - if [[ $DYNB_IP_MODE == d* ]]; then - _is_IPv4_enabled=true - _is_IPv6_enabled=true - fi - if [[ $DYNB_IP_MODE == *4* ]]; then - _is_IPv4_enabled=true - fi - if [[ $DYNB_IP_MODE == *6* ]]; then - _is_IPv6_enabled=true - fi - - ## execute operations - +function doUpdates() { if [[ $DYNB_UPDATE_METHOD == "domrobot" ]]; then getMainDomain fetchDNSRecords @@ -801,12 +810,16 @@ function dynb() { ipHasChanged 4 if [[ $? == 1 ]]; then updateRecord 4 + else + debugMessage "Skip IPv4 record update, it is already up to date" fi fi if [[ $_is_IPv6_enabled == true ]]; then ipHasChanged 6 if [[ $? == 1 ]]; then updateRecord 6 + else + debugMessage "Skip IPv6 record update, it is already up to date" fi fi fi @@ -837,6 +850,47 @@ function dynb() { debugMessage "Skip DynDNS2 update, IPs are up to date" fi fi +} + +################# +## MAIN method ## +################# +function dynb() { + ## parameters and checks + checkDependencies + + # shellcheck source=.env + if test -f "$_configFile"; then + # shellcheck disable=SC1091 + source "$_configFile" + else + alternativeConfig="$(dirname "$(realpath "$0")")/.env" + if test -f "$alternativeConfig"; then + # shellcheck disable=SC1091 + source "$alternativeConfig" + fi + fi + if test -f "$_statusFile"; then + debugMessage "read previous status file" + # shellcheck disable=SC1090 + source "$_statusFile" + fi + + handleParameters + + ## execute operations + + + if loopMode; then + while checkStatus + do + doUpdates + sleep $DYNB_INTERVAL + done + else + doUpdates + fi + doUnsets return 0 } diff --git a/man/dynb.1 b/man/dynb.1 index 5b47c7c..ef6f9d5 100644 --- a/man/dynb.1 +++ b/man/dynb.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH MAN 1 "2021-04-03" "" "" +.TH MAN 1 "2021-04-21" "" "" .SH NAME man \- DynB - dynamic DNS update script for bash . @@ -32,7 +32,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .. .SH SYNOPSIS .sp -\fBman [\-\-version] [\-\-link] [\-\-reset] [\-\-debug] [\-\-update\-method UPDATE\-METHOD] [\-\-ip\-mode IP\-MODE] [\-\-domain DOMAIN] [\-\-service\-provider SERVICE\-PROVIDER] [\-\-username USERNAME] [\-\-password PASSWORD] [\-\-token TOKEN] [\-\-help]\fP +\fBman [\-\-version] [\-\-link] [\-\-reset] [\-\-debug] [\-\-update\-method UPDATE\-METHOD] [\-\-ip\-mode IP\-MODE] [\-\-domain DOMAIN] [\-\-service\-provider SERVICE\-PROVIDER] [\-\-username USERNAME] [\-\-password PASSWORD] [\-\-token TOKEN] [\-\-interval INTERVAL] [\-\-help]\fP .SH DESCRIPTION .sp IPv4 (A) and IPv6 (AAAA) record updates are supported. @@ -97,6 +97,11 @@ e.g. SuperSecretPassword depends on your selected update method and your provider. .sp YourProviderGivenToken +.TP +.BI \-\-interval \ INTERVAL +choose the seconds interval to run the script in a loop, minimum is 60. +.sp + .TP .B \-h\fP,\fB \-\-help Prints help. diff --git a/man/man-defs.rst b/man/man-defs.rst index 5527bf4..8968484 100644 --- a/man/man-defs.rst +++ b/man/man-defs.rst @@ -30,4 +30,6 @@ .. |OPTION_TOKEN| replace:: YourProviderGivenToken +.. |OPTION_INTERVAL| replace:: \ + .. |OPTION_HELP| replace:: \ diff --git a/man/man-template.rst b/man/man.rst similarity index 91% rename from man/man-template.rst rename to man/man.rst index 50089f1..183dfc9 100644 --- a/man/man-template.rst +++ b/man/man.rst @@ -11,7 +11,7 @@ DynB - dynamic DNS update script for bash ----------------------------------------- :Author: |AUTHOR| -:Date: 2021-04-03 +:Date: 2021-04-21 :Version: |VERSION| :Manual section: |MAN_SECTION| @@ -19,7 +19,7 @@ DynB - dynamic DNS update script for bash SYNOPSIS ======== -``man [--version] [--link] [--reset] [--debug] [--update-method UPDATE-METHOD] [--ip-mode IP-MODE] [--domain DOMAIN] [--service-provider SERVICE-PROVIDER] [--username USERNAME] [--password PASSWORD] [--token TOKEN] [--help]`` +``man [--version] [--link] [--reset] [--debug] [--update-method UPDATE-METHOD] [--ip-mode IP-MODE] [--domain DOMAIN] [--service-provider SERVICE-PROVIDER] [--username USERNAME] [--password PASSWORD] [--token TOKEN] [--interval INTERVAL] [--help]`` DESCRIPTION @@ -79,6 +79,10 @@ ARGUMENTS |OPTION_TOKEN| +--interval INTERVAL choose the seconds interval to run the script in a loop, minimum is 60. + + |OPTION_INTERVAL| + -h, --help Prints help. |OPTION_HELP|