From 66bb07450f941d1432b18d53a5931f2cfbf83c34 Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Fri, 28 Jun 2024 04:16:01 -0400 Subject: [PATCH 1/9] nfsn: Fix spelling of `min-interval` variable name --- ddclient.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ddclient.in b/ddclient.in index c1e168b..f91e290 100755 --- a/ddclient.in +++ b/ddclient.in @@ -954,7 +954,7 @@ my %protocols = ( 'examples' => \&nic_nfsn_examples, 'variables' => { %{$variables{'protocol-common-defaults'}}, - 'min_interval' => setv(T_FQDNP, 0, 0, 0, interval('5m')), + 'min-interval' => setv(T_FQDNP, 0, 0, 0, interval('5m')), 'server' => setv(T_FQDNP, 1, 0, 'api.nearlyfreespeech.net', undef), 'ttl' => setv(T_NUMBER, 1, 0, 300, undef), 'zone' => setv(T_FQDN, 1, 0, undef, undef), From e32b9436fb6cbd0f66bc753d35d17e8bc3840970 Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Fri, 28 Jun 2024 04:17:34 -0400 Subject: [PATCH 2/9] nfsn: Fix type of `min-interval` variable --- ddclient.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ddclient.in b/ddclient.in index f91e290..6381757 100755 --- a/ddclient.in +++ b/ddclient.in @@ -954,7 +954,7 @@ my %protocols = ( 'examples' => \&nic_nfsn_examples, 'variables' => { %{$variables{'protocol-common-defaults'}}, - 'min-interval' => setv(T_FQDNP, 0, 0, 0, interval('5m')), + 'min-interval' => setv(T_DELAY, 0, 0, 0, interval('5m')), 'server' => setv(T_FQDNP, 1, 0, 'api.nearlyfreespeech.net', undef), 'ttl' => setv(T_NUMBER, 1, 0, 300, undef), 'zone' => setv(T_FQDN, 1, 0, undef, undef), From be9e305e737160b0a7db5337c10b5dc4e85103de Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Fri, 28 Jun 2024 04:10:33 -0400 Subject: [PATCH 3/9] Fix definition of `wtime` variable --- ddclient.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ddclient.in b/ddclient.in index 6381757..c6d22d0 100755 --- a/ddclient.in +++ b/ddclient.in @@ -668,7 +668,7 @@ my %variables = ( # Timestamp (seconds since epoch) indicating the earliest time the next update is # permitted. # TODO: Create a timestamp type and change this to that type. - 'wtime' => setv(T_DELAY, 0, 1, 0, interval('30s')), + 'wtime' => setv(T_NUMBER,0, 1, undef, undef), # Timestamp (seconds since epoch) indicating when an IP address was last sent to the DDNS # service, even if the IP address was not different from what was already stored. # TODO: Create a timestamp type and change this to that type. From b8a0a264413255891e3699a3414188a952c528cd Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Fri, 28 Jun 2024 02:33:33 -0400 Subject: [PATCH 4/9] Remove defaults from required variables without sensible defaults Required variables with defaults don't make sense; remove the default values on variables that don't have sensible defaults, such as login and password. --- ddclient.in | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/ddclient.in b/ddclient.in index c6d22d0..0a86822 100755 --- a/ddclient.in +++ b/ddclient.in @@ -587,8 +587,8 @@ my %variables = ( 'fwv4-skip' => setv(T_STRING,0, 0, undef, undef), 'fwv6' => setv(T_ANY, 0, 0, '', undef), 'fwv6-skip' => setv(T_STRING,0, 0, undef, undef), - 'fw-login' => setv(T_LOGIN, 1, 0, '', undef), - 'fw-password' => setv(T_PASSWD,1, 0, '', undef), + 'fw-login' => setv(T_LOGIN, 1, 0, undef, undef), + 'fw-password' => setv(T_PASSWD,1, 0, undef, undef), 'cmd' => setv(T_PROG, 0, 0, '', undef), 'cmd-skip' => setv(T_STRING,0, 0, undef, undef), 'cmdv4' => setv(T_PROG, 0, 0, '', undef), @@ -620,9 +620,9 @@ my %variables = ( }, 'protocol-common-defaults' => { 'server' => setv(T_FQDNP, 1, 0, 'members.dyndns.org', undef), - 'login' => setv(T_LOGIN, 1, 0, '', undef), - 'password' => setv(T_PASSWD,1, 0, '', undef), - 'host' => setv(T_STRING,1, 1, '', undef), + 'login' => setv(T_LOGIN, 1, 0, undef, undef), + 'password' => setv(T_PASSWD,1, 0, undef, undef), + 'host' => setv(T_STRING,1, 1, undef, undef), 'use' => setv(T_USE, 0, 0, 'ip', undef), 'usev4' => setv(T_USEV4, 0, 0, 'disabled', undef), @@ -741,7 +741,7 @@ my %protocols = ( 'static' => setv(T_BOOL, 0, 1, 0, undef), 'ttl' => setv(T_NUMBER, 1, 0, 1, undef), 'wildcard' => setv(T_BOOL, 0, 1, 0, undef), - 'zone' => setv(T_FQDN, 1, 0, '', undef), + 'zone' => setv(T_FQDN, 1, 0, undef, undef), }, }, 'cloudns' => { @@ -763,7 +763,7 @@ my %protocols = ( %{$variables{'protocol-common-defaults'}}, 'login' => undef, 'server' => setv(T_FQDNP, 1, 0, 'api.digitalocean.com', undef), - 'zone' => setv(T_FQDN, 1, 0, '', undef), + 'zone' => setv(T_FQDN, 1, 0, undef, undef), }, }, 'dinahosting' => { @@ -902,7 +902,7 @@ my %protocols = ( 'min-interval' => setv(T_DELAY, 0, 0, interval('5m'), 0), 'server' => setv(T_FQDNP, 1, 0, 'api.godaddy.com/v1/domains', undef), 'ttl' => setv(T_NUMBER, 1, 0, 600, undef), - 'zone' => setv(T_FQDN, 1, 0, '', undef), + 'zone' => setv(T_FQDN, 1, 0, undef, undef), }, }, 'googledomains' => { @@ -925,7 +925,7 @@ my %protocols = ( 'min-interval' => setv(T_DELAY, 0, 0, interval('1m'), 0), 'server' => setv(T_FQDNP, 1, 0, 'dns.hetzner.com/api/v1', undef), 'ttl' => setv(T_NUMBER, 0, 0, 60, 60), - 'zone' => setv(T_FQDN, 1, 0, '', undef), + 'zone' => setv(T_FQDN, 1, 0, undef, undef), }, }, 'mythicdyn' => { @@ -991,7 +991,7 @@ my %protocols = ( 'login' => setv(T_LOGIN, 1, 0, '/usr/bin/nsupdate', undef), 'tcp' => setv(T_BOOL, 0, 1, 0, undef), 'ttl' => setv(T_NUMBER, 0, 1, 600, undef), - 'zone' => setv(T_STRING, 1, 1, '', undef), + 'zone' => setv(T_STRING, 1, 1, undef, undef), }, }, 'ovh' => { @@ -1012,8 +1012,8 @@ my %protocols = ( %{$variables{'protocol-common-defaults'}}, 'login' => undef, 'password' => undef, - 'apikey' => setv(T_PASSWD, 1, 0, '', undef), - 'secretapikey' => setv(T_PASSWD, 1, 0, '', undef), + 'apikey' => setv(T_PASSWD, 1, 0, undef, undef), + 'secretapikey' => setv(T_PASSWD, 1, 0, undef, undef), 'root-domain' => setv(T_OFQDN, 0, 0, '', undef), 'on-root-domain' => setv(T_BOOL, 0, 0, 0, undef), }, From ba6a27918625a59207c9a2355d8fb62dd4a0775b Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Fri, 28 Jun 2024 03:40:35 -0400 Subject: [PATCH 5/9] Convert unnecessarily required variables to optional Users are not required to provide values for these variables; either the default is reasonable or the variable can be left unset. --- ddclient.in | 90 ++++++++++++++++++++++++++--------------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/ddclient.in b/ddclient.in index 0a86822..578847f 100755 --- a/ddclient.in +++ b/ddclient.in @@ -587,8 +587,8 @@ my %variables = ( 'fwv4-skip' => setv(T_STRING,0, 0, undef, undef), 'fwv6' => setv(T_ANY, 0, 0, '', undef), 'fwv6-skip' => setv(T_STRING,0, 0, undef, undef), - 'fw-login' => setv(T_LOGIN, 1, 0, undef, undef), - 'fw-password' => setv(T_PASSWD,1, 0, undef, undef), + 'fw-login' => setv(T_LOGIN, 0, 0, undef, undef), + 'fw-password' => setv(T_PASSWD,0, 0, undef, undef), 'cmd' => setv(T_PROG, 0, 0, '', undef), 'cmd-skip' => setv(T_STRING,0, 0, undef, undef), 'cmdv4' => setv(T_PROG, 0, 0, '', undef), @@ -619,7 +619,7 @@ my %variables = ( 'redirect' => setv(T_NUMBER,0, 0, 0, undef) }, 'protocol-common-defaults' => { - 'server' => setv(T_FQDNP, 1, 0, 'members.dyndns.org', undef), + 'server' => setv(T_FQDNP, 0, 0, 'members.dyndns.org', undef), 'login' => setv(T_LOGIN, 1, 0, undef, undef), 'password' => setv(T_PASSWD,1, 0, undef, undef), 'host' => setv(T_STRING,1, 1, undef, undef), @@ -714,7 +714,7 @@ my %protocols = ( 'variables' => { %{$variables{'protocol-common-defaults'}}, 'login' => undef, - 'server' => setv(T_FQDNP, 1, 0, 'api.1984.is', undef), + 'server' => setv(T_FQDNP, 0, 0, 'api.1984.is', undef), }, }, 'changeip' => { @@ -724,7 +724,7 @@ my %protocols = ( 'variables' => { %{$variables{'protocol-common-defaults'}}, 'min-interval' => setv(T_DELAY, 0, 0, 0, interval('5m')), - 'server' => setv(T_FQDNP, 1, 0, 'nic.changeip.com', undef), + 'server' => setv(T_FQDNP, 0, 0, 'nic.changeip.com', undef), }, }, 'cloudflare' => { @@ -737,9 +737,9 @@ my %protocols = ( 'login' => setv(T_LOGIN, 0, 0, 'token', undef), 'min-interval' => setv(T_DELAY, 0, 0, interval('5m'), 0), 'mx' => setv(T_OFQDN, 0, 1, '', undef), - 'server' => setv(T_FQDNP, 1, 0, 'api.cloudflare.com/client/v4', undef), + 'server' => setv(T_FQDNP, 0, 0, 'api.cloudflare.com/client/v4', undef), 'static' => setv(T_BOOL, 0, 1, 0, undef), - 'ttl' => setv(T_NUMBER, 1, 0, 1, undef), + 'ttl' => setv(T_NUMBER, 0, 0, 1, undef), 'wildcard' => setv(T_BOOL, 0, 1, 0, undef), 'zone' => setv(T_FQDN, 1, 0, undef, undef), }, @@ -762,7 +762,7 @@ my %protocols = ( 'variables' => { %{$variables{'protocol-common-defaults'}}, 'login' => undef, - 'server' => setv(T_FQDNP, 1, 0, 'api.digitalocean.com', undef), + 'server' => setv(T_FQDNP, 0, 0, 'api.digitalocean.com', undef), 'zone' => setv(T_FQDN, 1, 0, undef, undef), }, }, @@ -774,7 +774,7 @@ my %protocols = ( %{$variables{'protocol-common-defaults'}}, 'min-error-interval' => setv(T_DELAY, 0, 0, interval('8m'), 0), 'script' => setv(T_STRING, 0, 1, '/special/api.php', undef), - 'server' => setv(T_FQDNP, 1, 0, 'dinahosting.com', undef), + 'server' => setv(T_FQDNP, 0, 0, 'dinahosting.com', undef), }, }, 'dnsmadeeasy' => { @@ -783,8 +783,8 @@ my %protocols = ( 'examples' => \&nic_dnsmadeeasy_examples, 'variables' => { %{$variables{'protocol-common-defaults'}}, - 'script' => setv(T_STRING, 1, 1, '/servlet/updateip', undef), - 'server' => setv(T_FQDNP, 1, 0, 'cp.dnsmadeeasy.com', undef), + 'script' => setv(T_STRING, 0, 1, '/servlet/updateip', undef), + 'server' => setv(T_FQDNP, 0, 0, 'cp.dnsmadeeasy.com', undef), }, }, 'dondominio' => { @@ -793,7 +793,7 @@ my %protocols = ( 'examples' => \&nic_dondominio_examples, 'variables' => { %{$variables{'protocol-common-defaults'}}, - 'server' => setv(T_FQDNP, 1, 0, 'dondns.dondominio.com', undef), + 'server' => setv(T_FQDNP, 0, 0, 'dondns.dondominio.com', undef), }, }, 'dslreports1' => { @@ -802,7 +802,7 @@ my %protocols = ( 'examples' => \&nic_dslreports1_examples, 'variables' => { %{$variables{'protocol-common-defaults'}}, - 'server' => setv(T_FQDNP, 1, 0, 'www.dslreports.com', undef), + 'server' => setv(T_FQDNP, 0, 0, 'www.dslreports.com', undef), }, }, 'domeneshop' => { @@ -811,7 +811,7 @@ my %protocols = ( 'examples' => \&nic_domeneshop_examples, 'variables' => { %{$variables{'protocol-common-defaults'}}, - 'server' => setv(T_FQDNP, 1, 0, 'api.domeneshop.no', undef), + 'server' => setv(T_FQDNP, 0, 0, 'api.domeneshop.no', undef), }, }, 'duckdns' => { @@ -821,7 +821,7 @@ my %protocols = ( 'variables' => { %{$variables{'protocol-common-defaults'}}, 'login' => undef, - 'server' => setv(T_FQDNP, 1, 0, 'www.duckdns.org', undef), + 'server' => setv(T_FQDNP, 0, 0, 'www.duckdns.org', undef), }, }, 'dyndns1' => { @@ -841,7 +841,7 @@ my %protocols = ( %{$variables{'protocol-common-defaults'}}, %{$variables{'dyndns-common-defaults'}}, 'custom' => setv(T_BOOL, 0, 1, 0, undef), - 'script' => setv(T_STRING, 1, 1, '/nic/update', undef), + 'script' => setv(T_STRING, 0, 1, '/nic/update', undef), }, }, 'easydns' => { @@ -853,8 +853,8 @@ my %protocols = ( 'backupmx' => setv(T_BOOL, 0, 1, 0, undef), 'min-interval' => setv(T_DELAY, 0, 0, interval('5m'), 0), 'mx' => setv(T_OFQDN, 0, 1, '', undef), - 'server' => setv(T_FQDNP, 1, 0, 'api.cp.easydns.com', undef), - 'script' => setv(T_STRING, 1, 1, '/dyn/generic.php', undef), + 'server' => setv(T_FQDNP, 0, 0, 'api.cp.easydns.com', undef), + 'script' => setv(T_STRING, 0, 1, '/dyn/generic.php', undef), 'wildcard' => setv(T_BOOL, 0, 1, 0, undef), }, }, @@ -865,7 +865,7 @@ my %protocols = ( 'variables' => { %{$variables{'protocol-common-defaults'}}, 'min-interval' => setv(T_DELAY, 0, 0, 0, interval('5m')), - 'server' => setv(T_FQDNP, 1, 0, 'freedns.afraid.org', undef), + 'server' => setv(T_FQDNP, 0, 0, 'freedns.afraid.org', undef), }, }, 'freemyip' => { @@ -875,7 +875,7 @@ my %protocols = ( 'variables' => { %{$variables{'protocol-common-defaults'}}, 'login' => undef, - 'server' => setv(T_FQDNP, 1, 0, 'freemyip.com', undef), + 'server' => setv(T_FQDNP, 0, 0, 'freemyip.com', undef), }, }, 'gandi' => { @@ -886,8 +886,8 @@ my %protocols = ( %{$variables{'protocol-common-defaults'}}, 'login' => undef, 'min-interval' => setv(T_DELAY, 0, 0, 0, interval('5m')), - 'server' => setv(T_FQDNP, 1, 0, 'api.gandi.net', undef), - 'script' => setv(T_STRING, 1, 1, '/v5', undef), + 'server' => setv(T_FQDNP, 0, 0, 'api.gandi.net', undef), + 'script' => setv(T_STRING, 0, 1, '/v5', undef), 'use-personal-access-token' => setv(T_BOOL, 0, 0, 0, undef), 'ttl' => setv(T_DELAY, 0, 0, undef, interval('5m')), 'zone' => setv(T_FQDN, 1, 0, undef, undef), @@ -900,8 +900,8 @@ my %protocols = ( 'variables' => { %{$variables{'protocol-common-defaults'}}, 'min-interval' => setv(T_DELAY, 0, 0, interval('5m'), 0), - 'server' => setv(T_FQDNP, 1, 0, 'api.godaddy.com/v1/domains', undef), - 'ttl' => setv(T_NUMBER, 1, 0, 600, undef), + 'server' => setv(T_FQDNP, 0, 0, 'api.godaddy.com/v1/domains', undef), + 'ttl' => setv(T_NUMBER, 0, 0, 600, undef), 'zone' => setv(T_FQDN, 1, 0, undef, undef), }, }, @@ -912,7 +912,7 @@ my %protocols = ( 'variables' => { %{$variables{'protocol-common-defaults'}}, 'min-interval' => setv(T_DELAY, 0, 0, interval('5m'), 0), - 'server' => setv(T_FQDNP, 1, 0, 'domains.google.com', undef), + 'server' => setv(T_FQDNP, 0, 0, 'domains.google.com', undef), }, }, 'hetzner' => { @@ -923,7 +923,7 @@ my %protocols = ( %{$variables{'protocol-common-defaults'}}, 'login' => setv(T_LOGIN, 0, 0, 'token', undef), 'min-interval' => setv(T_DELAY, 0, 0, interval('1m'), 0), - 'server' => setv(T_FQDNP, 1, 0, 'dns.hetzner.com/api/v1', undef), + 'server' => setv(T_FQDNP, 0, 0, 'dns.hetzner.com/api/v1', undef), 'ttl' => setv(T_NUMBER, 0, 0, 60, 60), 'zone' => setv(T_FQDN, 1, 0, undef, undef), }, @@ -935,7 +935,7 @@ my %protocols = ( 'variables' => { %{$variables{'protocol-common-defaults'}}, 'min-interval' => setv(T_DELAY, 0, 0, interval('5m'), 0), - 'server' => setv(T_FQDNP, 1, 0, 'api.mythic-beasts.com', undef), + 'server' => setv(T_FQDNP, 0, 0, 'api.mythic-beasts.com', undef), }, }, 'namecheap' => { @@ -945,7 +945,7 @@ my %protocols = ( 'variables' => { %{$variables{'protocol-common-defaults'}}, 'min-interval' => setv(T_DELAY, 0, 0, 0, interval('5m')), - 'server' => setv(T_FQDNP, 1, 0, 'dynamicdns.park-your-domain.com', undef), + 'server' => setv(T_FQDNP, 0, 0, 'dynamicdns.park-your-domain.com', undef), }, }, 'nfsn' => { @@ -955,8 +955,8 @@ my %protocols = ( 'variables' => { %{$variables{'protocol-common-defaults'}}, 'min-interval' => setv(T_DELAY, 0, 0, 0, interval('5m')), - 'server' => setv(T_FQDNP, 1, 0, 'api.nearlyfreespeech.net', undef), - 'ttl' => setv(T_NUMBER, 1, 0, 300, undef), + 'server' => setv(T_FQDNP, 0, 0, 'api.nearlyfreespeech.net', undef), + 'ttl' => setv(T_NUMBER, 0, 0, 300, undef), 'zone' => setv(T_FQDN, 1, 0, undef, undef), }, }, @@ -967,7 +967,7 @@ my %protocols = ( 'variables' => { %{$variables{'protocol-common-defaults'}}, 'login' => undef, - 'server' => setv(T_FQDNP, 1, 0, 'njal.la', undef), + 'server' => setv(T_FQDNP, 0, 0, 'njal.la', undef), 'quietreply' => setv(T_BOOL, 0, 1, 0, undef), }, }, @@ -978,7 +978,7 @@ my %protocols = ( 'variables' => { %{$variables{'protocol-common-defaults'}}, 'custom' => setv(T_BOOL, 0, 1, 0, undef), - 'server' => setv(T_FQDNP, 1, 0, 'dynupdate.no-ip.com', undef), + 'server' => setv(T_FQDNP, 0, 0, 'dynupdate.no-ip.com', undef), 'static' => setv(T_BOOL, 0, 1, 0, undef), }, }, @@ -988,7 +988,7 @@ my %protocols = ( 'examples' => \&nic_nsupdate_examples, 'variables' => { %{$variables{'protocol-common-defaults'}}, - 'login' => setv(T_LOGIN, 1, 0, '/usr/bin/nsupdate', undef), + 'login' => setv(T_LOGIN, 0, 0, '/usr/bin/nsupdate', undef), 'tcp' => setv(T_BOOL, 0, 1, 0, undef), 'ttl' => setv(T_NUMBER, 0, 1, 600, undef), 'zone' => setv(T_STRING, 1, 1, undef, undef), @@ -1000,8 +1000,8 @@ my %protocols = ( 'examples' => \&nic_ovh_examples, 'variables' => { %{$variables{'protocol-common-defaults'}}, - 'script' => setv(T_STRING, 1, 1, '/nic/update', undef), - 'server' => setv(T_FQDNP, 1, 0, 'www.ovh.com', undef), + 'script' => setv(T_STRING, 0, 1, '/nic/update', undef), + 'server' => setv(T_FQDNP, 0, 0, 'www.ovh.com', undef), }, }, 'porkbun' => { @@ -1024,7 +1024,7 @@ my %protocols = ( 'examples' => \&nic_sitelutions_examples, 'variables' => { %{$variables{'protocol-common-defaults'}}, - 'server' => setv(T_FQDNP, 1, 0, 'www.sitelutions.com', undef), + 'server' => setv(T_FQDNP, 0, 0, 'www.sitelutions.com', undef), 'min-interval' => setv(T_DELAY, 0, 0, 0, interval('5m')), }, }, @@ -1037,8 +1037,8 @@ my %protocols = ( 'backupmx' => setv(T_BOOL, 0, 1, 0, undef), 'custom' => setv(T_BOOL, 0, 1, 0, undef), 'mx' => setv(T_OFQDN, 0, 1, '', undef), - 'script' => setv(T_STRING, 1, 1, '/nic/update', undef), - 'server' => setv(T_FQDNP, 1, 0, 'dyn.woima.fi', undef), + 'script' => setv(T_STRING, 0, 1, '/nic/update', undef), + 'server' => setv(T_FQDNP, 0, 0, 'dyn.woima.fi', undef), 'static' => setv(T_BOOL, 0, 1, 0, undef), 'wildcard' => setv(T_BOOL, 0, 1, 0, undef), }, @@ -1050,7 +1050,7 @@ my %protocols = ( 'variables' => { %{$variables{'protocol-common-defaults'}}, 'min-interval' => setv(T_DELAY, 0, 0, interval('5m'), 0), - 'server' => setv(T_FQDNP, 1, 0, 'pddimp.yandex.ru', undef), + 'server' => setv(T_FQDNP, 0, 0, 'pddimp.yandex.ru', undef), }, }, 'zoneedit1' => { @@ -1060,7 +1060,7 @@ my %protocols = ( 'variables' => { %{$variables{'protocol-common-defaults'}}, 'min-interval' => setv(T_DELAY, 0, 0, interval('10m'), 0), - 'server' => setv(T_FQDNP, 1, 0, 'dynamic.zoneedit.com', undef), + 'server' => setv(T_FQDNP, 0, 0, 'dynamic.zoneedit.com', undef), 'zone' => setv(T_OFQDN, 0, 0, undef, undef), }, }, @@ -1071,7 +1071,7 @@ my %protocols = ( 'variables' => { %{$variables{'protocol-common-defaults'}}, 'login' => undef, - 'server' => setv(T_FQDNP, 1, 0, 'dynamicdns.key-systems.net', undef), + 'server' => setv(T_FQDNP, 0, 0, 'dynamicdns.key-systems.net', undef), }, }, 'dnsexit2' => { @@ -1082,9 +1082,9 @@ my %protocols = ( %{$variables{'protocol-common-defaults'}}, 'login' => undef, 'ssl' => setv(T_BOOL, 0, 0, 1, undef), - 'server' => setv(T_FQDNP, 1, 0, 'api.dnsexit.com', undef), + 'server' => setv(T_FQDNP, 0, 0, 'api.dnsexit.com', undef), 'path' => setv(T_STRING, 0, 0, '/dns/', undef), - 'ttl' => setv(T_NUMBER, 1, 0, 5, 0), + 'ttl' => setv(T_NUMBER, 0, 0, 5, 0), 'zone' => setv(T_STRING, 0, 0, undef, undef), }, }, @@ -1095,7 +1095,7 @@ my %protocols = ( 'variables' => { %{$variables{'protocol-common-defaults'}}, 'login' => undef, - 'server' => setv(T_FQDNP, 1, 0, 'dyndns.regfish.de', undef), + 'server' => setv(T_FQDNP, 0, 0, 'dyndns.regfish.de', undef), }, }, 'enom' => { @@ -1104,7 +1104,7 @@ my %protocols = ( 'examples' => \&nic_enom_examples, 'variables' => { %{$variables{'protocol-common-defaults'}}, - 'server' => setv(T_FQDNP, 1, 0, 'dynamic.name-services.com', undef), + 'server' => setv(T_FQDNP, 0, 0, 'dynamic.name-services.com', undef), 'min-interval' => setv(T_DELAY, 0, 0, 0, interval('5m')), }, }, From 88eb2ed4fe9879670ff808dc0703834aac654181 Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Fri, 28 Jun 2024 03:43:41 -0400 Subject: [PATCH 6/9] Use `undef` as the default of truly optional variables --- ddclient.in | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/ddclient.in b/ddclient.in index 578847f..6f0a34a 100755 --- a/ddclient.in +++ b/ddclient.in @@ -132,7 +132,7 @@ my $last_emailbody = ''; ## If run as *d (e.g., ddclientd) then daemonize by default (but allow ## flags and options to override). -my $daemon_default = ($programd =~ /d$/) ? interval('5m') : 0; +my $daemon_default = ($programd =~ /d$/) ? interval('5m') : undef; use vars qw($file $lineno); local $file = ''; @@ -562,7 +562,7 @@ my %variables = ( 'foreground' => setv(T_BOOL, 0, 0, 0, undef), 'file' => setv(T_FILE, 0, 0, "$etc/$program.conf", undef), 'cache' => setv(T_FILE, 0, 0, "$cachedir/$program.cache", undef), - 'pid' => setv(T_FILE, 0, 0, "", undef), + 'pid' => setv(T_FILE, 0, 0, undef, undef), 'proxy' => setv(T_FQDNP, 0, 0, undef, undef), 'protocol' => setv(T_PROTO, 0, 0, 'dyndns2', undef), @@ -581,18 +581,18 @@ my %variables = ( 'webv4-skip' => setv(T_STRING,0, 0, undef, undef), 'webv6' => setv(T_STRING,0, 0, 'ipify-ipv6', undef), 'webv6-skip' => setv(T_STRING,0, 0, undef, undef), - 'fw' => setv(T_ANY, 0, 0, '', undef), + 'fw' => setv(T_ANY, 0, 0, undef, undef), 'fw-skip' => setv(T_STRING,0, 0, undef, undef), - 'fwv4' => setv(T_ANY, 0, 0, '', undef), + 'fwv4' => setv(T_ANY, 0, 0, undef, undef), 'fwv4-skip' => setv(T_STRING,0, 0, undef, undef), - 'fwv6' => setv(T_ANY, 0, 0, '', undef), + 'fwv6' => setv(T_ANY, 0, 0, undef, undef), 'fwv6-skip' => setv(T_STRING,0, 0, undef, undef), 'fw-login' => setv(T_LOGIN, 0, 0, undef, undef), 'fw-password' => setv(T_PASSWD,0, 0, undef, undef), - 'cmd' => setv(T_PROG, 0, 0, '', undef), + 'cmd' => setv(T_PROG, 0, 0, undef, undef), 'cmd-skip' => setv(T_STRING,0, 0, undef, undef), - 'cmdv4' => setv(T_PROG, 0, 0, '', undef), - 'cmdv6' => setv(T_PROG, 0, 0, '', undef), + 'cmdv4' => setv(T_PROG, 0, 0, undef, undef), + 'cmdv6' => setv(T_PROG, 0, 0, undef, undef), 'timeout' => setv(T_DELAY, 0, 0, interval('120s'), interval('120s')), 'retry' => setv(T_BOOL, 0, 0, 0, undef), @@ -601,8 +601,8 @@ my %variables = ( 'syslog' => setv(T_BOOL, 0, 0, 0, undef), 'facility' => setv(T_STRING,0, 0, 'daemon', undef), 'priority' => setv(T_STRING,0, 0, 'notice', undef), - 'mail' => setv(T_EMAIL, 0, 0, '', undef), - 'mail-failure' => setv(T_EMAIL, 0, 0, '', undef), + 'mail' => setv(T_EMAIL, 0, 0, undef, undef), + 'mail-failure' => setv(T_EMAIL, 0, 0, undef, undef), 'max-warn' => setv(T_NUMBER,0, 0, 1, undef), 'exec' => setv(T_BOOL, 0, 0, 1, undef), @@ -611,9 +611,9 @@ my %variables = ( 'quiet' => setv(T_BOOL, 0, 0, 0, undef), 'help' => setv(T_BOOL, 0, 0, 0, undef), 'test' => setv(T_BOOL, 0, 0, 0, undef), - 'geturl' => setv(T_STRING,0, 0, '', undef), + 'geturl' => setv(T_STRING,0, 0, undef, undef), - 'postscript' => setv(T_POSTS, 0, 0, '', undef), + 'postscript' => setv(T_POSTS, 0, 0, undef, undef), 'ssl_ca_dir' => setv(T_FILE, 0, 0, undef, undef), 'ssl_ca_file' => setv(T_FILE, 0, 0, undef, undef), 'redirect' => setv(T_NUMBER,0, 0, 0, undef) @@ -637,19 +637,19 @@ my %variables = ( 'webv4-skip' => setv(T_STRING,0, 0, undef, undef), 'webv6' => setv(T_STRING,0, 0, 'ipify-ipv6', undef), 'webv6-skip' => setv(T_STRING,0, 0, undef, undef), - 'fw' => setv(T_ANY, 0, 0, '', undef), + 'fw' => setv(T_ANY, 0, 0, undef, undef), 'fw-skip' => setv(T_STRING,0, 0, undef, undef), - 'fw-login' => setv(T_LOGIN, 0, 0, '', undef), - 'fw-password' => setv(T_PASSWD,0, 0, '', undef), + 'fw-login' => setv(T_LOGIN, 0, 0, undef, undef), + 'fw-password' => setv(T_PASSWD,0, 0, undef, undef), 'fw-ssl-validate' => setv(T_BOOL, 0, 0, 1, undef), - 'fwv4' => setv(T_ANY, 0, 0, '', undef), + 'fwv4' => setv(T_ANY, 0, 0, undef, undef), 'fwv4-skip' => setv(T_STRING,0, 0, undef, undef), - 'fwv6' => setv(T_ANY, 0, 0, '', undef), + 'fwv6' => setv(T_ANY, 0, 0, undef, undef), 'fwv6-skip' => setv(T_STRING,0, 0, undef, undef), - 'cmd' => setv(T_PROG, 0, 0, '', undef), + 'cmd' => setv(T_PROG, 0, 0, undef, undef), 'cmd-skip' => setv(T_STRING,0, 0, undef, undef), - 'cmdv4' => setv(T_PROG, 0, 0, '', undef), - 'cmdv6' => setv(T_PROG, 0, 0, '', undef), + 'cmdv4' => setv(T_PROG, 0, 0, undef, undef), + 'cmdv6' => setv(T_PROG, 0, 0, undef, undef), 'min-interval' => setv(T_DELAY, 0, 0, interval('30s'), 0), 'max-interval' => setv(T_DELAY, 0, 0, interval('25d'), 0), 'min-error-interval' => setv(T_DELAY, 0, 0, interval('5m'), 0), @@ -701,7 +701,7 @@ my %variables = ( }, 'dyndns-common-defaults' => { 'backupmx' => setv(T_BOOL, 0, 1, 0, undef), - 'mx' => setv(T_OFQDN, 0, 1, '', undef), + 'mx' => setv(T_OFQDN, 0, 1, undef, undef), 'static' => setv(T_BOOL, 0, 1, 0, undef), 'wildcard' => setv(T_BOOL, 0, 1, 0, undef), }, @@ -736,7 +736,7 @@ my %protocols = ( 'backupmx' => setv(T_BOOL, 0, 1, 0, undef), 'login' => setv(T_LOGIN, 0, 0, 'token', undef), 'min-interval' => setv(T_DELAY, 0, 0, interval('5m'), 0), - 'mx' => setv(T_OFQDN, 0, 1, '', undef), + 'mx' => setv(T_OFQDN, 0, 1, undef, undef), 'server' => setv(T_FQDNP, 0, 0, 'api.cloudflare.com/client/v4', undef), 'static' => setv(T_BOOL, 0, 1, 0, undef), 'ttl' => setv(T_NUMBER, 0, 0, 1, undef), @@ -852,7 +852,7 @@ my %protocols = ( %{$variables{'protocol-common-defaults'}}, 'backupmx' => setv(T_BOOL, 0, 1, 0, undef), 'min-interval' => setv(T_DELAY, 0, 0, interval('5m'), 0), - 'mx' => setv(T_OFQDN, 0, 1, '', undef), + 'mx' => setv(T_OFQDN, 0, 1, undef, undef), 'server' => setv(T_FQDNP, 0, 0, 'api.cp.easydns.com', undef), 'script' => setv(T_STRING, 0, 1, '/dyn/generic.php', undef), 'wildcard' => setv(T_BOOL, 0, 1, 0, undef), @@ -1014,7 +1014,7 @@ my %protocols = ( 'password' => undef, 'apikey' => setv(T_PASSWD, 1, 0, undef, undef), 'secretapikey' => setv(T_PASSWD, 1, 0, undef, undef), - 'root-domain' => setv(T_OFQDN, 0, 0, '', undef), + 'root-domain' => setv(T_OFQDN, 0, 0, undef, undef), 'on-root-domain' => setv(T_BOOL, 0, 0, 0, undef), }, }, @@ -1036,7 +1036,7 @@ my %protocols = ( %{$variables{'protocol-common-defaults'}}, 'backupmx' => setv(T_BOOL, 0, 1, 0, undef), 'custom' => setv(T_BOOL, 0, 1, 0, undef), - 'mx' => setv(T_OFQDN, 0, 1, '', undef), + 'mx' => setv(T_OFQDN, 0, 1, undef, undef), 'script' => setv(T_STRING, 0, 1, '/nic/update', undef), 'server' => setv(T_FQDNP, 0, 0, 'dyn.woima.fi', undef), 'static' => setv(T_BOOL, 0, 1, 0, undef), @@ -7216,7 +7216,7 @@ sub nic_porkbun_update { for my $host (@_) { my ($sub_domain, $domain); - if ($config{$host}{'root-domain'} ne '') { + if ($config{$host}{'root-domain'}) { # Process 'root-domain' option $domain = $config{$host}{'root-domain'}; $sub_domain = $host; From 399f8a8b32f8bae079799ddc6c6330d7f4f3c6c4 Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Fri, 28 Jun 2024 01:51:21 -0400 Subject: [PATCH 7/9] Adjust variable defaults to pass validity checks Change the default of every variable whose default (non-`undef`) doesn't pass through `check_value` unmodified. --- ddclient.in | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ddclient.in b/ddclient.in index 6f0a34a..5e08e3a 100755 --- a/ddclient.in +++ b/ddclient.in @@ -723,7 +723,7 @@ my %protocols = ( 'examples' => \&nic_changeip_examples, 'variables' => { %{$variables{'protocol-common-defaults'}}, - 'min-interval' => setv(T_DELAY, 0, 0, 0, interval('5m')), + 'min-interval' => setv(T_DELAY, 0, 0, interval('5m'), interval('5m')), 'server' => setv(T_FQDNP, 0, 0, 'nic.changeip.com', undef), }, }, @@ -864,7 +864,7 @@ my %protocols = ( 'examples' => \&nic_freedns_examples, 'variables' => { %{$variables{'protocol-common-defaults'}}, - 'min-interval' => setv(T_DELAY, 0, 0, 0, interval('5m')), + 'min-interval' => setv(T_DELAY, 0, 0, interval('5m'), interval('5m')), 'server' => setv(T_FQDNP, 0, 0, 'freedns.afraid.org', undef), }, }, @@ -885,7 +885,7 @@ my %protocols = ( 'variables' => { %{$variables{'protocol-common-defaults'}}, 'login' => undef, - 'min-interval' => setv(T_DELAY, 0, 0, 0, interval('5m')), + 'min-interval' => setv(T_DELAY, 0, 0, interval('5m'), interval('5m')), 'server' => setv(T_FQDNP, 0, 0, 'api.gandi.net', undef), 'script' => setv(T_STRING, 0, 1, '/v5', undef), 'use-personal-access-token' => setv(T_BOOL, 0, 0, 0, undef), @@ -944,7 +944,7 @@ my %protocols = ( 'examples' => \&nic_namecheap_examples, 'variables' => { %{$variables{'protocol-common-defaults'}}, - 'min-interval' => setv(T_DELAY, 0, 0, 0, interval('5m')), + 'min-interval' => setv(T_DELAY, 0, 0, interval('5m'), interval('5m')), 'server' => setv(T_FQDNP, 0, 0, 'dynamicdns.park-your-domain.com', undef), }, }, @@ -954,7 +954,7 @@ my %protocols = ( 'examples' => \&nic_nfsn_examples, 'variables' => { %{$variables{'protocol-common-defaults'}}, - 'min-interval' => setv(T_DELAY, 0, 0, 0, interval('5m')), + 'min-interval' => setv(T_DELAY, 0, 0, interval('5m'), interval('5m')), 'server' => setv(T_FQDNP, 0, 0, 'api.nearlyfreespeech.net', undef), 'ttl' => setv(T_NUMBER, 0, 0, 300, undef), 'zone' => setv(T_FQDN, 1, 0, undef, undef), @@ -1025,7 +1025,7 @@ my %protocols = ( 'variables' => { %{$variables{'protocol-common-defaults'}}, 'server' => setv(T_FQDNP, 0, 0, 'www.sitelutions.com', undef), - 'min-interval' => setv(T_DELAY, 0, 0, 0, interval('5m')), + 'min-interval' => setv(T_DELAY, 0, 0, interval('5m'), interval('5m')), }, }, 'woima' => { @@ -1105,7 +1105,7 @@ my %protocols = ( 'variables' => { %{$variables{'protocol-common-defaults'}}, 'server' => setv(T_FQDNP, 0, 0, 'dynamic.name-services.com', undef), - 'min-interval' => setv(T_DELAY, 0, 0, 0, interval('5m')), + 'min-interval' => setv(T_DELAY, 0, 0, interval('5m'), interval('5m')), }, }, 'infomaniak' => { From eab72ef6d7044ac7d638d0ab071570d2618db3aa Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Fri, 28 Jun 2024 02:41:22 -0400 Subject: [PATCH 8/9] Require a defined value if the variable is required --- ddclient.in | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ddclient.in b/ddclient.in index 5e08e3a..3cd9a0c 100755 --- a/ddclient.in +++ b/ddclient.in @@ -2562,6 +2562,10 @@ sub check_value { if (!defined $value && !$required) { ; + } elsif (!defined($value) && $required) { + # None of the types have 'undef' as a valid value, so check definedness once here for + # convenience. + die("$type is required\n"); } elsif ($type eq T_DELAY) { $value = interval($value); From 49f555176460be3238ecfe8fb8ad3ac3dfae021e Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Fri, 28 Jun 2024 01:51:21 -0400 Subject: [PATCH 9/9] Add variable default value tests --- Makefile.am | 1 + ddclient.in | 4 ++-- t/variable_defaults.pl | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 t/variable_defaults.pl diff --git a/Makefile.am b/Makefile.am index 0426025..90d3597 100644 --- a/Makefile.am +++ b/Makefile.am @@ -77,6 +77,7 @@ handwritten_tests = \ t/parse_assignments.pl \ t/skip.pl \ t/ssl-validate.pl \ + t/variable_defaults.pl \ t/write_recap.pl generated_tests = \ t/version.pl diff --git a/ddclient.in b/ddclient.in index 3cd9a0c..a415b2a 100755 --- a/ddclient.in +++ b/ddclient.in @@ -556,7 +556,7 @@ sub setv { 'minimum' => shift, }; } -my %variables = ( +our %variables = ( 'global-defaults' => { 'daemon' => setv(T_DELAY, 0, 0, $daemon_default, interval('60s')), 'foreground' => setv(T_BOOL, 0, 0, 0, undef), @@ -706,7 +706,7 @@ my %variables = ( 'wildcard' => setv(T_BOOL, 0, 1, 0, undef), }, ); -my %protocols = ( +our %protocols = ( '1984' => { 'force_update' => undef, 'update' => \&nic_1984_update, diff --git a/t/variable_defaults.pl b/t/variable_defaults.pl new file mode 100644 index 0000000..09dc92c --- /dev/null +++ b/t/variable_defaults.pl @@ -0,0 +1,32 @@ +use Test::More; +SKIP: { eval { require Test::Warnings; } or skip($@, 1); } +eval { require 'ddclient'; } or BAIL_OUT($@); + +my %variable_collections = ( + map({ ($_ => $ddclient::variables{$_}) } grep($_ ne 'merged', keys(%ddclient::variables))), + map({ ("protocol=$_" => $ddclient::protocols{$_}{variables}); } keys(%ddclient::protocols)), +); +my %seen; +my @test_cases = ( + map({ + my $vcn = $_; + my $vc = $variable_collections{$_}; + map({ + my $def = $vc->{$_}; + my $seen = exists($seen{$def}); + $seen{$def} = undef; + ({desc => "$vcn $_", def => $vc->{$_}}) x !$seen; + } sort(keys(%$vc))); + } sort(keys(%variable_collections))), +); +for my $tc (@test_cases) { + if ($tc->{def}{required}) { + is($tc->{def}{default}, undef, "'$tc->{desc}' (required) has no default"); + } else { + my $norm; + my $valid = eval { $norm = ddclient::check_value($tc->{def}{default}, $tc->{def}); 1; }; + ok($valid, "'$tc->{desc}' (optional) has a valid default"); + is($norm, $tc->{def}{default}, "'$tc->{desc}' default normalizes to itself") if $valid; + } +} +done_testing();