Merge pull request #1 from wimpunk/master

Catch up to wimpunk/ddclient
This commit is contained in:
Harry-Xue 2016-05-24 21:07:01 -07:00
commit 1d848de60c
15 changed files with 785 additions and 181 deletions

View file

@ -2,7 +2,7 @@
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

139
ChangeLog
View file

@ -1,3 +1,137 @@
2015-05-28 wimpunk
* [r183] ., release: Removing unneeded release directory
2015-03-23 wimpunk
* [r182] ddclient: Reverting to the old perl requirements like
suggested in #75
The new requirements were added when adding support for cloudflare. By the
simple fix suggested by Roy Tam we could revert the requirements which make
ddclient back usable on CentOS and RHEL.
* [r181] ddclient: ddclient: made json optional
As suggested in pull 7 on github by @abelbeck and @Bugsbane it is
better to make the
use of JSON related to the use of cloudflare.
* [r180] ddclient: ddclient: reindenting cloudflare
Indenting cloudflare according to the vim tags
* [r179] ddclient: ddclient: correction after duckdns merge
Correcting duckdns configuration after commit r178
* [r178] ddclient: Added simple support for Duckdns www.duckdns.org
Patch provided by gkranis on github.
Merge branch 'gkranis'
2015-03-21 wimpunk
* [r177] README.md: Added duckDNS to the README.md
* [r176] sample-etc_rc.d_init.d_ddclient.ubuntu: update ubuntu init.d script
Merge pull request #9 from gottaloveit/master
* [r175] Changelog, Changelog.old: Renamed Changelog to
Changelog.old
Avoiding conflicts on case insensitive filesystems
* [r174] ddclient: Add missing config line for CloudFlare
Merge pull request #19 from shikasta-net/fixes
* [r173] ddclient: Merge pull request #22 from reddyr/patch-1
loopia.se changed the "Current Address:" output string to "Current IP
Address:"
* [r172] ddclient: fixed missing ) for cloudflare service hash
Merge pull request #16 from adepretis/master
2015-01-20 wimpunk
* [r171] README.md, ddclient, sample-etc_ddclient.conf: Adding
support for google domain
Patch gently provided through github on
https://github.com/wimpunk/ddclient/pull/13
2014-10-08 wimpunk
* [r170] README.md, ddclient, sample-etc_ddclient.conf: Added
support for Cloudflare and multi domain support for namecheap
Pull request #7 from @roberthawdon
See https://github.com/wimpunk/ddclient/pull/7 for more info.
2014-09-09 wimpunk
* [r169] ddclient: Bugfix: allowing long username-password
combinations
Patch provided by @dirdi through github.
2014-08-20 wimpunk
* [r166] ddclient: Fixing bug #72: Account info revealed during
noip update
* [r165] ddclient: Interfaces can be named almost anything on
modern systems.
Patch provided by Stephen Couchman through github
2014-06-30 wimpunk
* [r164] ddclient: Only delete A RR, not any RR for the FQDN
Make the delete command specific to A RRs. This prevents ddclient
from deleting other RRs unrelated to the dynamic address, but on the
same FQDN. This can be specifically a problem with KEY RRs when using
SIG(0) instead of symmetric keys.
Reported by: Wellie Chao
Bug report: http://sourceforge.net/p/ddclient/bugs/71/
Fixes #71
2014-06-02 wimpunk
* [r163] README.md, ddclient: Adding support for nsupdate.
Patch provided by Daniel Roethlisberger <daniel@roe.ch> through
github.
2014-04-29 wimpunk
* [r162] README.md, README.ssl, ddclient: Removed revision
information
Revision information isn't very usable when switching to git.
2014-03-20 wimpunk
* [r161] README.md, README.ssl, ddclient,
sample-etc_rc.d_init.d_ddclient.alpine: Added Alpine Linux init
script
Patch send by Tal on github.
* [r160] RELEASENOTE: Corrected release note
2013-12-26 wimpunk
* [r159] release/readme.txt: Commiting updated release information
* [r158] README.md, RELEASENOTE: Committing release notes and
readme information to trunk
2013-11-05 wimpunk
* [r156] patches: Moving patching to the root of the repository.
@ -10,8 +144,8 @@
* [r155] ddclient: Fallback to iproute if ifconfig doesn't work.
This fix applies the patch provided by Maccied Grela in
[bugs:#26]
This fix applies the patch provided by Maccied Grela in [bugs:#26]
* [r154] ddclient: preventing deep sleep - see [bugs:#46]
Fixing [bugs:#46] by applying the provided patch.
@ -424,4 +558,3 @@
2006-05-22 wimpunk
* [r2] Reorganise

View file

@ -299,6 +299,4 @@ Changelog
This feature can be used to reissue updates that may have failed due to
network connectivity problems or a DynDNS server outage
-------------------------------------------------------------------------------
$Id: Changelog 96 2008-06-13 20:24:24Z wimpunk $
------------------------------------------------------------------------

View file

@ -1,4 +1,3 @@
$Id: README.cisco 96 2008-06-13 20:24:24Z wimpunk $
Method 1 ------------------------------------------------------
The following config will allow the Linux machine (10.1.1.2) to read

View file

@ -1,5 +1,5 @@
===============================================================================
# DDCLIENT v3.8.2
# DDCLIENT v3.8.3
ddclient is a Perl client used to update dynamic DNS entries for accounts
on many dynamic DNS services.
@ -25,6 +25,8 @@ Dynamic DNS services currently supported include:
nsupdate - See nsupdate(1) and ddns-confgen(8) for details
CloudFlare - See https://www.cloudflare.com/ for details
Google - See http://www.google.com/domains for details
Duckdns - See https://duckdns.org/ for details
woima.fi - See https://woima.fi/ for details
DDclient now supports many of cable/dsl broadband routers.
@ -40,8 +42,9 @@ REQUIREMENTS:
- one or more accounts from one of the dynamic DNS services
- Perl 5.014 or later
(you need the IO::Socket::SSL perl library for ssl-support
and JSON::Any perl library for JSON support)
(you need the IO::Socket::SSL perl library for ssl-support,
JSON::Any perl library for JSON support and
IO::Socket:INET6 perl library for ipv6-support)
- Linux or probably any common Unix system
@ -72,6 +75,15 @@ INSTALLATION:
## start the first time by hand
rc-service ddclient start
## For those using Ubuntu style rc files and using daemon-mode:
cp sample-etc_rc.d_init.d_ddclient.ubuntu /etc/init.d/ddclient
## enable automatic startup when booting
update-rc.d ddclient defaults
## make sure you have perl installed
apt-get install perl
## start the first time by hand
service ddclient start
## If you are not using daemon-mode, configure cron and dhcp or ppp
## as described below.

View file

@ -1,11 +1,12 @@
It's been a while and has been announced a while ago but here is new release of
ddclient. There are some important changes and some documentation is modified.
Yet again it's been a while but here is new release of ddclient. As usual,
there are some important changes and some documentation is modified.
A detailed overview can be found in ChangeLog but here's a quick overview:
* adding support by ChangeIP - patch send by Michele Giorato
* sha-1 patch send by pirast to allow Digest::SHA
* allow reuse of use - patch send by Rodrigo Araujo
* preventing deep sleep - see [bugs:#46]
* Fallback to iproute if ifconfig doesn't work send by Maccied Grela
* added Alpine Linux init scritp - patch send by @Tal on github.
* adding support for nsupdate - patch send by @droe on github
* allow log username-password combinations - patch send by @dirdi on github
* adding support for cloudflare - patch send by @roberthawdon on github
* adding support for duckdns - patch send by @gkranis
A very big thank you for everyone who created a pull request on github and
for everyone who helped to fix the little issues caused by the new providers.

671
ddclient
View file

@ -1,7 +1,6 @@
#!/usr/bin/perl -w
#!/usr/local/bin/perl -w
######################################################################
# $Id: ddclient 161 2014-03-20 20:02:14Z wimpunk $
#
# DDCLIENT - a Perl client for updating DynDNS information
#
@ -20,16 +19,14 @@
#
#
######################################################################
require 5.014;
require 5.004;
use strict;
use Getopt::Long;
use Sys::Hostname;
use IO::Socket;
use JSON::Any;
use Data::Validate::IP;
# my ($VERSION) = q$Revision: 161 $ =~ /(\d+)/;
my $version = "3.8.2";
my $version = "3.8.3";
my $programd = $0;
$programd =~ s%^.*/%%;
my $program = $programd;
@ -72,7 +69,7 @@ my %builtinweb = (
'dyndns' => { 'url' => 'http://checkip.dyndns.org/', 'skip' =>
'Current IP Address:', },
'dnspark' => { 'url' => 'http://ipdetect.dnspark.com/', 'skip' => 'Current Address:', },
'loopia' => { 'url' => 'http://dns.loopia.se/checkip/checkip.php', 'skip' => 'Current Address:', },
'loopia' => { 'url' => 'http://dns.loopia.se/checkip/checkip.php', 'skip' => 'Current IP Address:', },
);
my %builtinfw = (
'watchguard-soho' => {
@ -339,6 +336,7 @@ my %variables = (
'web-skip' => setv(T_STRING,1, 0, 1, '', undef),
'fw' => setv(T_ANY, 0, 0, 1, '', undef),
'fw-skip' => setv(T_STRING,1, 0, 1, '', undef),
'fw-banlocal' => setv(T_BOOL, 0, 0, 1, 0, undef),
'fw-login' => setv(T_LOGIN, 1, 0, 1, '', undef),
'fw-password' => setv(T_PASSWD,1, 0, 1, '', undef),
'cmd' => setv(T_PROG, 0, 0, 1, '', undef),
@ -348,12 +346,12 @@ my %variables = (
'retry' => setv(T_BOOL, 0, 0, 0, 0, undef),
'force' => setv(T_BOOL, 0, 0, 0, 0, undef),
'ssl' => setv(T_BOOL, 0, 0, 0, 0, undef),
'ipv6' => setv(T_BOOL, 0, 0, 0, 0, undef),
'syslog' => setv(T_BOOL, 0, 0, 1, 0, undef),
'facility' => setv(T_STRING,0, 0, 1, 'daemon', undef),
'priority' => setv(T_STRING,0, 0, 1, 'notice', undef),
'mail' => setv(T_EMAIL, 0, 0, 1, '', undef),
'mail-failure' => setv(T_EMAIL, 0, 0, 1, '', undef),
'mail' => setv(T_EMAIL, 0, 0, 1, '', undef),
'mail-failure' => setv(T_EMAIL, 0, 0, 1, '', undef),
'exec' => setv(T_BOOL, 0, 0, 1, 1, undef),
'debug' => setv(T_BOOL, 0, 0, 1, 0, undef),
@ -378,11 +376,12 @@ my %variables = (
'web-skip' => setv(T_STRING,0, 0, 1, '', undef),
'fw' => setv(T_ANY, 0, 0, 1, '', undef),
'fw-skip' => setv(T_STRING,0, 0, 1, '', undef),
'fw-banlocal' => setv(T_BOOL, 0, 0, 1, 0, undef),
'fw-login' => setv(T_LOGIN, 0, 0, 1, '', undef),
'fw-password' => setv(T_PASSWD,0, 0, 1, '', undef),
'cmd' => setv(T_PROG, 0, 0, 1, '', undef),
'cmd-skip' => setv(T_STRING,0, 0, 1, '', undef),
'ipv6' => setv(T_BOOL, 0, 0, 0, 0, undef),
'ip' => setv(T_IP, 0, 1, 0, undef, undef),
'wtime' => setv(T_DELAY, 0, 1, 1, 0, interval('30s')),
'mtime' => setv(T_NUMBER, 0, 1, 0, 0, undef),
@ -439,17 +438,46 @@ my %variables = (
'nsupdate-common-defaults' => {
'ttl' => setv(T_NUMBER, 0, 1, 0, 600, undef),
'zone' => setv(T_STRING, 1, 1, 1, '', undef),
'tcp' => setv(T_BOOL, 0, 1, 1, 0, undef),
},
'cloudflare-common-defaults' => {
'server' => setv(T_FQDNP, 1, 0, 1, 'www.cloudflare.com', undef),
'zone' => setv(T_FQDN, 1, 0, 1, '', undef),
'static' => setv(T_BOOL, 0, 1, 1, 0, undef),
'wildcard' => setv(T_BOOL, 0, 1, 1, 0, undef),
'mx' => setv(T_OFQDN, 0, 1, 1, '', undef),
'backupmx' => setv(T_BOOL, 0, 1, 1, 0, undef),
},
'cloudflare-common-defaults' => {
'server' => setv(T_FQDNP, 1, 0, 1, 'www.cloudflare.com', undef),
'zone' => setv(T_FQDN, 1, 0, 1, '', undef),
'static' => setv(T_BOOL, 0, 1, 1, 0, undef),
'wildcard' => setv(T_BOOL, 0, 1, 1, 0, undef),
'mx' => setv(T_OFQDN, 0, 1, 1, '', undef),
'backupmx' => setv(T_BOOL, 0, 1, 1, 0, undef),
'ttl' => setv(T_NUMBER, 1, 0, 1, 1, undef),
},
'googledomains-common-defaults' => {
'server' => setv(T_FQDNP, 1, 0, 1, 'domains.google.com', undef),
},
'duckdns-common-defaults' => {
'server' => setv(T_FQDNP, 1, 0, 1, 'www.duckdns.org', undef),
'login' => setv(T_LOGIN, 0, 0, 0, 'unused', undef),
},
'woima-common-defaults' => {
'static' => setv(T_BOOL, 0, 1, 1, 0, undef),
'wildcard' => setv(T_BOOL, 0, 1, 1, 0, undef),
'mx' => setv(T_OFQDN, 0, 1, 1, '', undef),
'backupmx' => setv(T_BOOL, 0, 1, 1, 0, undef),
'custom' => setv(T_BOOL, 0, 1, 1, 0, undef),
'script' => setv(T_STRING, 1, 1, 1, '/nic/update', undef),
},
'woima-service-common-defaults' => {
'server' => setv(T_FQDNP, 1, 0, 1, 'dyn.woima.fi', undef),
'login' => setv(T_LOGIN, 1, 0, 1, '', undef),
'password' => setv(T_PASSWD, 1, 0, 1, '', undef),
'ip' => setv(T_IP, 0, 1, 0, undef, undef),
'wtime' => setv(T_DELAY, 0, 1, 1, 0, interval('30s')),
'mtime' => setv(T_NUMBER, 0, 1, 0, 0, undef),
'atime' => setv(T_NUMBER, 0, 1, 0, 0, undef),
'status' => setv(T_ANY, 0, 1, 0, '', undef),
'min-interval' => setv(T_DELAY, 0, 0, 1, interval('30s'), 0),
'max-interval' => setv(T_DELAY, 0, 0, 1, interval('25d'), 0),
'min-error-interval' => setv(T_DELAY, 0, 0, 1, interval('5m'), 0),
'warned-min-interval' => setv(T_ANY, 0, 1, 0, 0, undef),
'warned-min-error-interval' => setv(T_ANY, 0, 1, 0, 0, undef),
},
);
my %services = (
@ -613,6 +641,7 @@ my %services = (
{ 'server' => setv(T_FQDNP, 1, 0, 1, 'www.cloudflare.com', undef) },
{ 'min-interval' => setv(T_DELAY, 0, 0, 1, interval('5m'), 0),},
$variables{'cloudflare-common-defaults'},
$variables{'service-common-defaults'},
),
},
'googledomains' => {
@ -625,6 +654,24 @@ my %services = (
$variables{'service-common-defaults'},
),
},
'duckdns' => {
'updateable' => undef,
'update' => \&nic_duckdns_update,
'examples' => \&nic_duckdns_examples,
'variables' => merge(
$variables{'duckdns-common-defaults'},
$variables{'service-common-defaults'},
),
},
'woima' => {
'updateable' => undef,
'update' => \&nic_woima_update,
'examples' => \&nic_woima_examples,
'variables' => merge(
$variables{'woima-common-defaults'},
$variables{'woima-service-common-defaults'},
),
},
);
$variables{'merged'} = merge($variables{'global-defaults'},
$variables{'service-common-defaults'},
@ -636,7 +683,7 @@ my @opt = (
"usage: ${program} [options]",
"options are:",
[ "daemon", "=s", "-daemon delay : run as a daemon, specify delay as an interval." ],
[ "foreground", "!", "-foreground : do not fork" ],
[ "foreground", "!", "-foreground : do not fork" ],
[ "proxy", "=s", "-proxy host : use 'host' as the HTTP proxy" ],
[ "server", "=s", "-server host : update DNS information on 'host'" ],
[ "protocol", "=s", "-protocol type : update protocol used" ],
@ -657,6 +704,7 @@ my @opt = (
"",
[ "fw", "=s", "-fw address|url : obtain IP address from firewall at 'address'" ],
[ "fw-skip", "=s", "-fw-skip pattern : skip any IP addresses before 'pattern' on the firewall address|url" ],
[ "fw-banlocal", "!", "-fw-banlocal : ignore local IP addresses on the firewall address|url" ],
[ "fw-login", "=s", "-fw-login login : use 'login' when getting IP from fw" ],
[ "fw-password", "=s", "-fw-password secret : use password 'secret' when getting IP from fw" ],
"",
@ -683,6 +731,7 @@ my @opt = (
[ "debug", "!", "-{no}debug : print {no} debugging information" ],
[ "verbose", "!", "-{no}verbose : print {no} verbose information" ],
[ "quiet", "!", "-{no}quiet : print {no} messages for unnecessary updates" ],
[ "ipv6", "!", "-{no}ipv6 : use ipv6" ],
[ "help", "", "-help : this message" ],
[ "postscript", "", "-postscript : script to run after updating ddclient, has new IP as param" ],
@ -857,8 +906,10 @@ sub update_nics {
next;
}
if ($ip !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) {
warning("malformed IP address (%s)", $ip);
next;
if( !ipv6_match($ip) ) {
warning("malformed IP address (%s)", $ip);
next;
}
}
$iplist{$use}{$arg_ip}{$arg_fw}{$arg_if}{$arg_web}{$arg_cmd} = $ip;
}
@ -1000,7 +1051,7 @@ sub parse_assignment {
my ($c, $name, $value);
my ($escape, $quote) = (0, '');
if ($rest =~ /^\s*([a-z][a-z_-]*)=(.*)/i) {
if ($rest =~ /^\s*([a-z][0-9a-z_-]*)=(.*)/i) {
($name, $rest, $value) = ($1, $2, '');
while (length($c = substr($rest,0,1))) {
@ -1113,7 +1164,7 @@ sub _read_config {
## verify that keywords are valid...and check the value
foreach my $k (keys %locals) {
$locals{$k} = $passwords{$k} if defined $passwords{$k};
$locals{$k} = $passwords{$k} if defined $passwords{$k};
if (!exists $variables{'merged'}{$k}) {
warning("unrecognized keyword '%s' (ignored)", $k);
delete $locals{$k};
@ -1210,14 +1261,14 @@ sub init_config {
## and those in -options=...
if (exists $options{'host'}) {
foreach my $h (split_by_comma($options{'host'})) {
push @hosts, $h;
push @hosts, $h;
}
delete $options{'host'};
}
## merge options into host definitions or globals
if (@hosts) {
foreach my $h (@hosts) {
$config{$h} = merge(\%options, $config{$h});
$config{$h} = merge(\%options, $config{$h});
}
$opt{'host'} = join(',', @hosts);
} else {
@ -1227,14 +1278,14 @@ sub init_config {
## override global options with those on the command-line.
foreach my $o (keys %opt) {
if (defined $opt{$o} && exists $variables{'global-defaults'}{$o}) {
$globals{$o} = $opt{$o};
}
if (defined $opt{$o} && exists $variables{'global-defaults'}{$o}) {
$globals{$o} = $opt{$o};
}
}
## sanity check
if (defined $opt{'host'} && defined $opt{'retry'}) {
usage("options -retry and -host (or -option host=..) are mutually exclusive");
usage("options -retry and -host (or -option host=..) are mutually exclusive");
}
## determine hosts to update (those on the cmd-line, config-file, or failed cached)
@ -1264,14 +1315,14 @@ sub init_config {
## make sure config entries have all defaults and they meet minimums
## first the globals...
foreach my $k (keys %globals) {
my $def = $variables{'merged'}{$k};
my $ovalue = define($globals{$k}, $def->{'default'});
my $value = check_value($ovalue, $def);
if ($def->{'required'} && !defined $value) {
$value = default($k);
warning("'%s=%s' is an invalid %s. (using default of %s)", $k, $ovalue, $def->{'type'}, $value);
}
$globals{$k} = $value;
my $def = $variables{'merged'}{$k};
my $ovalue = define($globals{$k}, $def->{'default'});
my $value = check_value($ovalue, $def);
if ($def->{'required'} && !defined $value) {
$value = default($k);
warning("'%s=%s' is an invalid %s. (using default of %s)", $k, $ovalue, $def->{'type'}, $value);
}
$globals{$k} = $value;
}
## now the host definitions...
@ -1282,6 +1333,7 @@ sub init_config {
$proto = opt('protocol') if !defined($proto);
load_sha1_support() if ($proto eq "freedns");
load_json_support() if ($proto eq "cloudflare");
if (!exists($services{$proto})) {
warning("skipping host: %s: unrecognized protocol '%s'", $h, $proto);
@ -1803,7 +1855,9 @@ sub check_value {
# return undef if $value =~ /:/;
} elsif ($type eq T_IP) {
return undef if $value !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
if( !ipv6_match($value) ) {
return undef if $value !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
}
}
return $value;
}
@ -1842,6 +1896,24 @@ EOM
import IO::Socket::SSL;
{ no warnings; $IO::Socket::SSL::DEBUG = 0; }
}
######################################################################
## load_ipv6_support
######################################################################
sub load_ipv6_support {
my $ipv6_loaded = eval {require IO::Socket::INET6};
unless ($ipv6_loaded) {
fatal(<<"EOM");
Error loading the Perl module IO::Socket::INET6 needed for ipv6 connect.
On Debian, the package libio-socket-inet6-perl must be installed.
On Red Hat, the package perl-IO-Socket-INET6 must be installed.
On Alpine, the package perl-io-socket-inet6 must be installed.
EOM
}
import IO::Socket::INET6;
{ no warnings; $IO::Socket::INET6::DEBUG = 0; }
}
######################################################################
## load_sha1_support
######################################################################
@ -1861,6 +1933,18 @@ EOM
}
}
######################################################################
## load_json_support
######################################################################
sub load_json_support {
my $json_loaded = eval {require JSON::Any};
unless ($json_loaded) {
fatal(<<"EOM");
Error loading the Perl module JSON::Any needed for cloudflare update.
EOM
}
import JSON::Any;
}
######################################################################
## geturl
######################################################################
sub geturl {
@ -1925,8 +2009,8 @@ sub geturl {
# local $^W = 0;
$0 = sprintf("%s - connecting to %s port %s", $program, $peer, $port);
if (! opt('exec')) {
debug("skipped network connection");
verbose("SENDING:", "%s", $request);
debug("skipped network connection");
verbose("SENDING:", "%s", $request);
} elsif ($use_ssl) {
$sd = IO::Socket::SSL->new(
PeerAddr => $peer,
@ -1936,6 +2020,16 @@ sub geturl {
Timeout => opt('timeout'),
);
defined $sd or warning("cannot connect to $peer:$port socket: $@ " . IO::Socket::SSL::errstr());
} elsif ($globals{'ipv6'}) {
load_ipv6_support;
$sd = IO::Socket::INET6->new(
PeerAddr => $peer,
PeerPort => $port,
Proto => 'tcp',
MultiHomed => 1,
Timeout => opt('timeout'),
);
defined $sd or warning("cannot connect to $peer:$port socket: $@");
} else {
$sd = IO::Socket::INET->new(
PeerAddr => $peer,
@ -1996,6 +2090,48 @@ sub geturl {
return $reply;
}
######################################################################
## un_zero_pad
######################################################################
sub un_zero_pad {
my $in_str = shift(@_);
my @out_str = ();
if ($in_str eq '0.0.0.0') {
return $in_str;
}
foreach my $block (split /\./, $in_str) {
$block =~ s/^0+//;
if ($block eq '') {
$block = '0';
}
push @out_str, $block;
}
return join('.', @out_str);
}
######################################################################
## filter_local
######################################################################
sub filter_local {
my $in_ip = shift(@_);
if ($in_ip eq '0.0.0.0') {
return $in_ip;
}
my @guess_local = (
'^10\.',
'^172\.(?:1[6-9]|2[0-9]|3[01])\.',
'^192\.168'
);
foreach my $block (@guess_local) {
if ($in_ip =~ /$block/) {
return '0.0.0.0';
}
}
return $in_ip;
}
######################################################################
## get_ip
######################################################################
sub get_ip {
@ -2036,62 +2172,69 @@ sub get_ip {
}
} elsif (($use eq 'cisco')) {
# Stuff added to support Cisco router ip http daemon
# User fw-login should only have level 1 access to prevent
# password theft. This is pretty harmless.
my $queryif = opt('if', $h);
$skip = opt('fw-skip', $h) || '';
# Stuff added to support Cisco router ip http daemon
# User fw-login should only have level 1 access to prevent
# password theft. This is pretty harmless.
my $queryif = opt('if', $h);
$skip = opt('fw-skip', $h) || '';
# Convert slashes to protected value "\/"
$queryif =~ s%\/%\\\/%g;
# Convert slashes to protected value "\/"
$queryif =~ s%\/%\\\/%g;
# Protect special HTML characters (like '?')
$queryif =~ s/([\?&= ])/sprintf("%%%02x",ord($1))/ge;
# Protect special HTML characters (like '?')
$queryif =~ s/([\?&= ])/sprintf("%%%02x",ord($1))/ge;
$url = "http://".opt('fw', $h)."/level/1/exec/show/ip/interface/brief/${queryif}/CR";
$reply = geturl('', $url, opt('fw-login', $h), opt('fw-password', $h)) || '';
$arg = $url;
$url = "http://".opt('fw', $h)."/level/1/exec/show/ip/interface/brief/${queryif}/CR";
$reply = geturl('', $url, opt('fw-login', $h), opt('fw-password', $h)) || '';
$arg = $url;
} elsif (($use eq 'cisco-asa')) {
# Stuff added to support Cisco ASA ip https daemon
# User fw-login should only have level 1 access to prevent
# password theft. This is pretty harmless.
my $queryif = opt('if', $h);
$skip = opt('fw-skip', $h) || '';
# Stuff added to support Cisco ASA ip https daemon
# User fw-login should only have level 1 access to prevent
# password theft. This is pretty harmless.
my $queryif = opt('if', $h);
$skip = opt('fw-skip', $h) || '';
# Convert slashes to protected value "\/"
$queryif =~ s%\/%\\\/%g;
# Convert slashes to protected value "\/"
$queryif =~ s%\/%\\\/%g;
# Protect special HTML characters (like '?')
$queryif =~ s/([\?&= ])/sprintf("%%%02x",ord($1))/ge;
# Protect special HTML characters (like '?')
$queryif =~ s/([\?&= ])/sprintf("%%%02x",ord($1))/ge;
$url = "https://".opt('fw', $h)."/exec/show%20interface%20${queryif}";
$reply = geturl('', $url, opt('fw-login', $h), opt('fw-password', $h)) || '';
$arg = $url;
$url = "https://".opt('fw', $h)."/exec/show%20interface%20${queryif}";
$reply = geturl('', $url, opt('fw-login', $h), opt('fw-password', $h)) || '';
$arg = $url;
} else {
$url = opt('fw', $h) || '';
$skip = opt('fw-skip', $h) || '';
$url = opt('fw', $h) || '';
$skip = opt('fw-skip', $h) || '';
if (exists $builtinfw{$use}) {
$skip = $builtinfw{$use}->{'skip'} unless $skip;
$url = "http://${url}" . $builtinfw{$use}->{'url'} unless $url =~ /\//;
}
$arg = $url;
if ($url) {
$reply = geturl('', $url, opt('fw-login', $h), opt('fw-password', $h)) || '';
if (exists $builtinfw{$use}) {
$skip = $builtinfw{$use}->{'skip'} unless $skip;
$url = "http://${url}" . $builtinfw{$use}->{'url'} unless $url =~ /\//;
}
}
if (!defined $reply) {
$reply = '';
$arg = $url;
if ($url) {
$reply = geturl('', $url, opt('fw-login', $h), opt('fw-password', $h)) || '';
}
}
if (!defined $reply) {
$reply = '';
}
if ($skip) {
$skip =~ s/ /\\s/is;
$reply =~ s/^.*?${skip}//is;
$skip =~ s/ /\\s/is;
$reply =~ s/^.*?${skip}//is;
}
if ($reply =~ /^.*?\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b.*/is) {
$ip = $1;
$ip = $1;
$ip = un_zero_pad($ip);
$ip = filter_local($ip) if opt('fw-banlocal', $h);
} elsif ( $ip = ipv6_match($reply) ) {
$ip = un_zero_pad($ip);
$ip = filter_local($ip) if opt('fw-banlocal', $h);
} else {
warning("found neither ipv4 nor ipv6 address");
}
if (($use ne 'ip') && (define($ip,'') eq '0.0.0.0')) {
$ip = undef;
@ -2101,6 +2244,34 @@ sub get_ip {
return $ip;
}
######################################################################
## ipv6_match determine ipv6 address from given string and return them
######################################################################
sub ipv6_match {
my $content = shift;
my $omits;
my $ip = "";
my $linenumbers = 0;
my @values = split('\n', $content);
foreach my $val (@values) {
next unless $val =~ /((:{0,2}[A-F0-9]{1,4}){0,7}:{1,2}[A-F0-9]{1,4})/ai; # invalid char
my $parsed = $1;
# check for at least 7 colons
my $count_colon = () = $parsed =~ /:/g;
if ($count_colon != 7) {
# or one double colon
my $count_double_colon = () = $parsed =~ /::/g;
if ($count_double_colon != 1) {
next
}
}
return $parsed;
}
return;
}
######################################################################
## group_hosts_by
######################################################################
@ -3601,10 +3772,7 @@ EoEXAMPLE
##
######################################################################
sub nic_freedns_update {
debug("\nnic_freedns_update -------------------");
## First get the list of updatable hosts
my $url;
$url = "http://$config{$_[0]}{'server'}/api/?action=getdyndns&sha=".&sha1_hex("$config{$_[0]}{'login'}|$config{$_[0]}{'password'}");
@ -3630,34 +3798,40 @@ sub nic_freedns_update {
info("setting IP address to %s for %s", $ip, $h);
verbose("UPDATE:","updating %s", $h);
if($ip eq $freedns_hosts{$h}->[1]) {
$config{$h}{'ip'} = $ip;
$config{$h}{'mtime'} = $now;
$config{$h}{'status'} = 'good';
success("update not necessary %s: good: IP address already set to %s", $h, $ip);
} else {
my $reply = geturl(opt('proxy'), $freedns_hosts{$h}->[2]);
if (!defined($reply) || !$reply) {
failed("updating %s: Could not connect to %s.", $h, $freedns_hosts{$h}->[2]);
last;
}
if(!header_ok($h, $reply)) {
$config{$h}{'status'} = 'failed';
last;
}
if($ip eq $freedns_hosts{$h}->[1]) {
$config{$h}{'ip'} = $ip;
$config{$h}{'mtime'} = $now;
$config{$h}{'status'} = 'good';
success("update not necessary %s: good: IP address already set to %s", $h, $ip);
} else {
my $reply = geturl(opt('proxy'), $freedns_hosts{$h}->[2]);
if (!defined($reply) || !$reply) {
failed("updating %s: Could not connect to %s.", $h, $freedns_hosts{$h}->[2]);
last;
}
if(!header_ok($h, $reply)) {
$config{$h}{'status'} = 'failed';
last;
}
if($reply =~ /Updated.*$h.*to.*$ip/) {
$config{$h}{'ip'} = $ip;
$config{$h}{'mtime'} = $now;
$config{$h}{'status'} = 'good';
success("updating %s: good: IP address set to %s", $h, $ip);
} else {
$config{$h}{'status'} = 'failed';
warning("SENT: %s", $freedns_hosts{$h}->[2]) unless opt('verbose');
warning("REPLIED: %s", $reply);
failed("updating %s: Invalid reply.", $h);
}
}
if ($reply =~ /Updated.*$h.*to.*$ip/) {
$config{$h}{'ip'} = $ip;
$config{$h}{'mtime'} = $now;
$config{$h}{'status'} = 'good';
success("updating %s: good: IP address set to %s", $h, $ip);
} elsif ($reply =~ /Address (\d+\.\d+\.\d+\.\d+) has not changed/) {
$ip = $1;
$config{$h}{'mtime'} = $now;
$config{$h}{'status'} = 'good';
$config{$h}{'ip'} = $ip;
success("updating %s: good: IP address %s has not changed", $h, $ip);
} else {
$config{$h}{'status'} = 'failed';
warning("SENT: %s", $freedns_hosts{$h}->[2]) unless opt('verbose');
warning("REPLIED: %s", $reply);
failed("updating %s: Invalid reply.", $h);
}
}
}
}
@ -3919,6 +4093,10 @@ Configuration variables applicable to the 'nsupdate' protocol are:
zone=dyn.example.com ## forward zone that is to be updated
ttl=600 ## time to live of the record;
## defaults to 600 seconds
tcp=off|on ## nsupdate uses UDP by default, and switches to
## TCP if the update is too large to fit in a
## UDP datagram; this setting forces TCP;
## defaults to off
login=/usr/bin/nsupdate ## path and name of nsupdate binary;
## defaults to '/usr/bin/nsupdate'
<hostname> ## fully qualified hostname to update
@ -3955,6 +4133,12 @@ sub nic_nsupdate_update {
my $server = $config{$h}{'server'};
my $zone = $config{$h}{'zone'};
my $ip = $config{$h}{'wantip'};
my $recordtype = '';
if (is_ipv6($ip)) {
$recordtype = 'AAAA';
} else {
$recordtype = 'A';
}
delete $config{$_}{'wantip'} foreach @hosts;
info("setting IP address to %s for %s", $ip, $hosts);
@ -3967,14 +4151,15 @@ zone $zone.
EoINSTR1
foreach (@hosts) {
$instructions .= <<EoINSTR2;
update delete $_. A
update add $_. $config{$_}{'ttl'} A $ip
update delete $_. $recordtype
update add $_. $config{$_}{'ttl'} $recordtype $ip
EoINSTR2
}
$instructions .= <<EoINSTR3;
send
EoINSTR3
my $command = "$binary -k $keyfile";
$command .= " -v" if ynu($config{$h}{'tcp'}, 1, 0, 0);
$command .= " -d" if (opt('debug'));
verbose("UPDATE:", "nsupdate command is: %s", $command);
verbose("UPDATE:", "nsupdate instructions are:\n%s", $instructions);
@ -4049,7 +4234,7 @@ sub nic_cloudflare_update {
# FQDNs
for my $domain (@hosts) {
my $hostname = $domain =~ s/\.$config{$key}{zone}$//r;
(my $hostname = $domain) =~ s/\.$config{$key}{zone}$//;
delete $config{$domain}{'wantip'};
info("setting IP address to %s for %s", $ip, $domain);
@ -4084,7 +4269,8 @@ sub nic_cloudflare_update {
}
# Set domain
$url = "https://$config{$key}{'server'}/api_json.html?a=rec_edit&type=A&ttl=1";
$url = "https://$config{$key}{'server'}/api_json.html?a=rec_edit&type=A";
$url .= "&ttl=".$config{$key}{'ttl'};
$url .= "&name=$hostname";
$url .= "&z=".$config{$key}{'zone'};
$url .= "&id=".$id;
@ -4118,6 +4304,261 @@ sub nic_cloudflare_update {
}
}
######################################################################
## nic_duckdns_examples
######################################################################
sub nic_duckdns_examples {
return <<EoEXAMPLE;
o 'duckdns'
The 'duckdns' protocol is used by the free
dynamic DNS service offered by www.duckdns.org.
Check http://www.duckdns.org/install.jsp?tab=linux-cron for API
Configuration variables applicable to the 'duckdns' protocol are:
protocol=duckdns ##
server=www.fqdn.of.service ## defaults to www.duckdns.org
password=service-password ## password (token) registered with the service
non-fully.qualified.host ## the host registered with the service.
Example ${program}.conf file entries:
## single host update
protocol=duckdns, \\
password=z0mgs3cjur3p4ss \\
myhost
EoEXAMPLE
}
######################################################################
## nic_duckdns_update
## by George Kranis (copypasta from nic_dtdns_update)
## http://www.duckdns.org/update?domains=mydomain1,mydomain2&token=xxxx-xxx-xx-x&ip=x.x.x.x
## response contains OK or KO
######################################################################
sub nic_duckdns_update {
debug("\nnic_duckdns_update -------------------");
## update each configured host
## should improve to update in one pass
foreach my $h (@_) {
my $ip = delete $config{$h}{'wantip'};
info("setting IP address to %s for %s", $ip, $h);
verbose("UPDATE:","updating %s", $h);
# Set the URL that we're going to to update
my $url;
$url = "http://$config{$h}{'server'}/update";
$url .= "?domains=";
$url .= $h;
$url .= "&token=";
$url .= $config{$h}{'password'};
$url .= "&ip=";
$url .= $ip;
# Try to get URL
my $reply = geturl(opt('proxy'), $url);
# No response, declare as failed
if (!defined($reply) || !$reply) {
failed("updating %s: Could not connect to %s.", $h, $config{$h}{'server'});
last;
}
last if !header_ok($h, $reply);
my @reply = split /\n/, $reply;
my $returned = pop(@reply);
if ($returned =~ /OK/)
{
$config{$h}{'ip'} = $ip;
$config{$h}{'mtime'} = $now;
$config{$h}{'status'} = 'good';
success("updating %s: good: IP address set to %s", $h, $ip);
}
else
{
$config{$h}{'status'} = 'failed';
failed("updating %s: Server said: '$returned'", $h);
}
}
}
######################################################################
## nic_woima_examples
######################################################################
sub nic_woima_examples {
return <<EoEXAMPLE;
o 'woima'
The 'woima' protocol is used by the free
dynamic DNS service offered by woima.fi.
It offers also nameservers for own domains for free.
Dynamic DNS service for own domains is not free.
Configuration variables applicable to the 'woima' protocol are:
protocol=woima ##
server=fqdn.of.service ## defaults to dyn.woima.fi
script=/path/to/script ## defaults to /nic/update
backupmx=no|yes ## indicates that this host is the primary MX for the domain.
static=no|yes ## indicates that this host has a static IP address.
custom=no|yes ## indicates that this host is a 'custom' top-level domain name.
mx=any.host.domain ## a host MX'ing for this host definition.
wildcard=no|yes ## add a DNS wildcard CNAME record that points to {host}
login=service-login ## login name and password registered with the service
password=service-password ##
fully.qualified.host ## the host registered with the service.
Example ${program}.conf file entries:
## single host update
protocol=woima, \\
login=my-dyndns.org-login, \\
password=my-dyndns.org-password \\
myhost.dyndns.org
## multiple host update with wildcard'ing mx, and backupmx
protocol=woima, \\
login=my-dyndns.org-login, \\
password=my-dyndns.org-password, \\
mx=a.host.willing.to.mx.for.me,backupmx=yes,wildcard=yes \\
myhost.dyndns.org,my2ndhost.dyndns.org
## multiple host update to the custom DNS service
protocol=woima, \\
login=my-dyndns.org-login, \\
password=my-dyndns.org-password \\
my-toplevel-domain.com,my-other-domain.com
EoEXAMPLE
}
######################################################################
## nic_woima_update
######################################################################
sub nic_woima_update {
debug("\nnic_woima_update -------------------");
my %errors = (
'badauth' => 'Bad authorization (username or password)',
'badsys' => 'The system parameter given was not valid',
'notfqdn' => 'A Fully-Qualified Domain Name was not provided',
'nohost' => 'The hostname specified does not exist in the database',
'!yours' => 'The hostname specified exists, but not under the username currently being used',
'!donator' => 'The offline setting was set, when the user is not a donator',
'!active' => 'The hostname specified is in a Custom DNS domain which has not yet been activated.',
'abuse', => 'The hostname specified is blocked for abuse; you should receive an email notification ' .
'which provides an unblock request link. More info can be found on ' .
'https://www.dyndns.com/support/abuse.html',
'numhost' => 'System error: Too many or too few hosts found. Contact support@dyndns.org',
'dnserr' => 'System error: DNS error encountered. Contact support@dyndns.org',
'nochg' => 'No update required; unnecessary attempts to change to the current address are considered abusive',
);
my @hosts = @_;
foreach my $key (keys @hosts) {
my $h = $hosts[$key];
my $ip = $config{$h}{'wantip'};
delete $config{$h}{'wantip'};
info("setting IP address to %s for %s", $ip, $h);
verbose("UPDATE:","updating %s", $h);
## Select the DynDNS system to update
my $url = "http://$config{$h}{'server'}$config{$h}{'script'}?system=";
if ($config{$h}{'custom'}) {
warning("updating %s: 'custom' and 'static' may not be used together. ('static' ignored)", $h)
if $config{$h}{'static'};
# warning("updating %s: 'custom' and 'offline' may not be used together. ('offline' ignored)", $h)
# if $config{$h}{'offline'};
$url .= 'custom';
} elsif ($config{$h}{'static'}) {
# warning("updating %s: 'static' and 'offline' may not be used together. ('offline' ignored)", $h)
# if $config{$h}{'offline'};
$url .= 'statdns';
} else {
$url .= 'dyndns';
}
$url .= "&hostname=$h";
$url .= "&myip=";
$url .= $ip if $ip;
## some args are not valid for a custom domain.
$url .= "&wildcard=ON" if ynu($config{$h}{'wildcard'}, 1, 0, 0);
if ($config{$h}{'mx'}) {
$url .= "&mx=$config{$h}{'mx'}";
$url .= "&backmx=" . ynu($config{$h}{'backupmx'}, 'YES', 'NO');
}
my $reply = geturl(opt('proxy'), $url, $config{$h}{'login'}, $config{$h}{'password'});
if (!defined($reply) || !$reply) {
failed("updating %s: Could not connect to %s.", $h, $config{$h}{'server'});
last;
}
last if !header_ok($h, $reply);
my @reply = split /\n/, $reply;
my $state = 'header';
my $returnedip = $ip;
foreach my $line (@reply) {
if ($state eq 'header') {
$state = 'body';
} elsif ($state eq 'body') {
$state = 'results' if $line eq '';
} elsif ($state =~ /^results/) {
$state = 'results2';
# bug #10: some dyndns providers does not return the IP so
# we can't use the returned IP
my ($status, $returnedip) = split / /, lc $line;
$ip = $returnedip if (not $ip);
#my $h = shift @hosts;
$config{$h}{'status'} = $status;
if ($status eq 'good') {
$config{$h}{'ip'} = $ip;
$config{$h}{'mtime'} = $now;
success("updating %s: %s: IP address set to %s", $h, $status, $ip);
} elsif (exists $errors{$status}) {
if ($status eq 'nochg') {
warning("updating %s: %s: %s", $h, $status, $errors{$status});
$config{$h}{'ip'} = $ip;
$config{$h}{'mtime'} = $now;
$config{$h}{'status'} = 'good';
} else {
failed("updating %s: %s: %s", $h, $status, $errors{$status});
}
} elsif ($status =~ /w(\d+)(.)/) {
my ($wait, $units) = ($1, lc $2);
my ($sec, $scale) = ($wait, 1);
($scale, $units) = (1, 'seconds') if $units eq 's';
($scale, $units) = (60, 'minutes') if $units eq 'm';
($scale, $units) = (60*60, 'hours') if $units eq 'h';
$sec = $wait * $scale;
$config{$h}{'wtime'} = $now + $sec;
warning("updating %s: %s: wait $wait $units before further updates", $h, $status, $ip);
} else {
failed("updating %s: %s: unexpected status (%s)", $h, $line);
}
}
}
failed("updating %s: Could not connect to %s.", $h, $config{$h}{'server'})
if $state ne 'results2';
}
}
######################################################################
# vim: ai ts=4 sw=4 tw=78 :

View file

@ -1,6 +1,5 @@
######################################################################
## ddclient is an IP address updater for www.dyndns.org
## $Id: sample-etc_cron.d_ddclient 96 2008-06-13 20:24:24Z wimpunk $
######################################################################
## minute 0-59
## hour 0-23

View file

@ -1,7 +1,5 @@
######################################################################
##
## $Id: sample-etc_ddclient.conf 150 2013-04-28 14:55:34Z wimpunk $
##
## Define default global variables with lines like:
## var=value [, var=value]*
## These values will be used for each following host unless overridden
@ -204,7 +202,8 @@ ssl=yes # use ssl-support. Works with
#zone=domain.tld, \
#server=www.cloudflare.com, \
#login=your-login-email, \
#password=APIKey \
#password=APIKey, \
#ttl=1 \
#domain.tld,my.domain.tld
##
@ -214,3 +213,23 @@ ssl=yes # use ssl-support. Works with
# login=my-auto-generated-username,
# password=my-auto-generated-password
# my.domain.tld, otherhost.domain.tld
##
## Duckdns (http://www.duckdns.org/)
##
#
# password=my-auto-generated-password
# protocol=duckdns hostwithoutduckdnsorg
##
## MyOnlinePortal (http://myonlineportal.net)
##
# protocol=dyndns2
# ssl=yes
# # ipv6=yes # optional
# use=web, web=myonlineportal.net/checkip
# # use=if, if=eth0 # alternative to use=web
# # if-skip=Scope:Link # alternative to use=web
# login=your-myonlineportal-username
# password=your-myonlineportal-password
# domain.myonlineportal.net

View file

@ -1,7 +1,5 @@
#!/bin/sh
######################################################################
## $Id: sample-etc_dhclient-exit-hooks 96 2008-06-13 20:24:24Z wimpunk $
######################################################################
# The /etc/dhclient-enter-hooks script is run by the ISC DHCP client's standard
# update script whenever dhclient obtains or renews an address.

View file

@ -1,7 +1,5 @@
#!/bin/sh
######################################################################
## $Id: sample-etc_dhcpc_dhcpcd-eth0.exe 96 2008-06-13 20:24:24Z wimpunk $
######################################################################
PATH=/usr/sbin:${PATH}
## update the DNS server unless the IP address is a private address

View file

@ -1,7 +1,5 @@
#!/bin/sh
######################################################################
## $Id: sample-etc_ppp_ip-up.local 128 2011-07-11 20:24:43Z wimpunk $
######################################################################
##
## On my host, pppd invokes this script with args:
## /etc/ppp/ip-up.local ppp0 /dev/pts/1 115200 192.168.2.1 192.168.2.3

View file

@ -21,8 +21,6 @@
# can be used on many types of firewalls
### END INIT INFO
#
# $Id: sample-etc_rc.d_init.d_ddclient.lsb 96 2008-06-13 20:24:24Z wimpunk $
#
###
[ -f /etc/ddclient/ddclient.conf ] || exit 0

View file

@ -1,5 +1,5 @@
#!/bin/sh
# $Id: sample-etc_rc.d_init.d_ddclient.redhat 96 2008-06-13 20:24:24Z wimpunk $
#
# ddclient This shell script takes care of starting and stopping
# ddclient.
#

View file

@ -1,8 +1,13 @@
#!/bin/sh
#
# Start ddclient that provides support for updating dynamic DNS services.
#
# Submitted by paolo martinelli
### BEGIN INIT INFO
# Provides: ddclient
# Required-Start: $remote_fs $syslog $network
# Required-Stop: $remote_fs $syslog $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start ddclient daemon at boot time
# Description: Start ddclient that provides support for updating dynamic DNS services. Originally submitted by paolo martinelli, updated by joe passavanti
### END INIT INFO
DDCLIENT=/usr/sbin/ddclient
CONF=/etc/ddclient/ddclient.conf
@ -14,34 +19,39 @@ test -f $CONF || exit 0
. /lib/lsb/init-functions
case "$1" in
start)
log_begin_msg "Starting ddclient..."
DELAY=`grep -v '^\s*#' $CONF | grep -i -m 1 "daemon" | awk -F '=' '{print $2}'`
if [ -z "$DELAY" ] ; then
DELAY="-daemon 300"
else
DELAY=''
fi
start-stop-daemon -S -q -p $PIDFILE -x $DDCLIENT -- $DELAY
log_end_msg $?
;;
stop)
if [ -f $PIDFILE ] ; then
log_begin_msg "Stopping ddclient..."
start-stop-daemon -K -q -p $PIDFILE
log_end_msg $?
rm -f $PIDFILE
fi
;;
restart|reload|force-reload)
$0 stop
$0 start
;;
*)
log_success_msg "Usage: $0 {start|stop|restart|reload|force-reload}"
exit 1
;;
start)
if [ ! -f $PIDFILE ]; then
log_begin_msg "Starting ddclient..."
DELAY=`grep -v '^\s*#' $CONF | grep -i -m 1 "daemon" | awk -F '=' '{print $2}'`
if [ -z "$DELAY" ] ; then
DELAY="-daemon 300"
else
DELAY=''
fi
start-stop-daemon -S -q -p $PIDFILE -x $DDCLIENT -- $DELAY
log_end_msg $?
else
log_warning_msg "Service ddclient already running..."
fi
;;
stop)
if [ -f $PIDFILE ] ; then
log_begin_msg "Stopping ddclient..."
start-stop-daemon -K -q -p $PIDFILE
log_end_msg $?
rm -f $PIDFILE
else
log_warning_msg "No ddclient running..."
fi
;;
restart|reload|force-reload)
$0 stop
$0 start
;;
*)
log_success_msg "Usage: $0 {start|stop|restart|reload|force-reload}"
exit 1
;;
esac
exit 0