Compare commits

...

1475 commits
v3.8.3 ... main

Author SHA1 Message Date
25d162db91 Aggiorna README.md
Some checks failed
CI / test-debian-like (debian:oldstable) (push) Has been cancelled
CI / test-debian-like (debian:stable) (push) Has been cancelled
CI / test-debian-like (debian:testing) (push) Has been cancelled
CI / test-debian-like (ubuntu:20.04) (push) Has been cancelled
CI / test-debian-like (ubuntu:latest) (push) Has been cancelled
CI / test-fedora-like (almalinux:8) (push) Has been cancelled
CI / test-fedora-like (almalinux:latest) (push) Has been cancelled
CI / test-fedora-like (fedora:39) (push) Has been cancelled
CI / test-fedora-like (fedora:latest) (push) Has been cancelled
CI / test-fedora-like (fedora:rawhide) (push) Has been cancelled
2025-02-05 21:38:17 +08:00
Richard Hansen
50e8d2ed00 Post-release version bump 2025-01-19 14:46:10 -05:00
Richard Hansen
d6da6b878d Release v4.0.0 2025-01-19 14:29:22 -05:00
Richard Hansen
33a86eb556
Merge pull request #801 from insanolanbiri/upnp
Add UPnP example in configuration file
2025-01-16 04:10:59 -05:00
Eren Akgün
10d3561353
Add UPnP example in configuration file
This commit demonstrates a simple way to obtain the
IP address using UPnP in the ddclient configuration file.
2025-01-16 11:02:25 +03:00
Richard Hansen
803f77404d Post-release version bump 2025-01-11 03:30:56 -05:00
Richard Hansen
590d7d91fc Release v4.0.0-rc.3 2025-01-11 03:18:38 -05:00
Richard Hansen
41170b9c08
Merge pull request #684 from rhansen/dnsexit2
dnsexit2: Update multiple hosts at a time when possible
2025-01-11 03:09:48 -05:00
Richard Hansen
63bf3512a4 dnsexit2: Update multiple hosts at a time when possible 2025-01-10 19:20:25 -05:00
Richard Hansen
3b10e37607 tests: dnsexit2: Add test for host outside of zone 2025-01-10 19:20:25 -05:00
Richard Hansen
115f23dead tests: Option to select which log messages to capture 2025-01-10 19:20:25 -05:00
Richard Hansen
009033d476 tests: Factor out duplicate log capture code 2025-01-10 19:20:25 -05:00
Richard Hansen
d18b1cdb27 logging: Move filtering and reactions to Logger class
This increases overhead when the verbose or debug option is disabled,
but makes it possible for tests to intercept debug, info, and fatal
messages.
2025-01-10 19:20:25 -05:00
Richard Hansen
b31e5e2f91 tests: dnsexit2: Add test for two hosts in the same zone 2025-01-09 19:33:57 -05:00
Richard Hansen
3b73350541 tests: dnsexit2 Convert tests to table-driven
This makes the tests easier to read and extend.
2025-01-09 19:33:57 -05:00
Richard Hansen
6bb80cbdaa
Merge pull request #766 from greenius/feature/cmdargs
Enable arguments on cmdv4 and cmdv6
2025-01-09 19:33:11 -05:00
Richard Hansen
6fd9a6f106 tests: Add some tests for use=cmd, usev4=cmdv4, usev6=cmdv6 2025-01-09 19:29:00 -05:00
Richard Hansen
1c178d4c09 Add ChangeLog entry for --cmdv4, --cmdv6 change 2025-01-09 19:29:00 -05:00
steven
ae01ba26c1 Do not use quotemeta on cmdv4 and cmdv6 arguments
`quotemeta` prevents executing commands with arguments.  With this
change, it is now possible to get an IP address with:

    usev4=cmdv4
    cmdv4="dig +short myip.opendns.com @resolver1.opendns.com"
2025-01-09 19:29:00 -05:00
Richard Hansen
17fc4c0a35
Merge pull request #783 from indrajitr/eval-cmd-skip
Make 'cmd-skip' warning message consistent for IPv4 and IPv6
2025-01-08 19:13:17 -05:00
Indrajit Raychaudhuri
8dcea0d779 Make 'cmd-skip' warning message consistent for IPv4 and IPv6 2025-01-08 19:09:29 -05:00
Bodo Eggert
8883641d97 fix ddclient --verbose calling 'p' instead of using $p{foo} 2025-01-08 19:08:19 -05:00
Richard Hansen
741a2345ea
Merge pull request #795 from rhansen/missing-semicolon
tests: Add missing semicolon; prevent similar future bugs
2025-01-08 18:27:35 -05:00
Richard Hansen
8cf322e162 tests: Only skip HTTPD tests if dependencies are unavailable
This prevents the tests from passing due to syntax errors in
the ddclient::t::HTTPD module.
2025-01-08 18:24:04 -05:00
Richard Hansen
ddeaedc136 tests: Add missing semicolon
This should have been in commit
06c47695fc.  The tests that use this
module did not fail because an import failure is assumed to be caused
by a missing dependency, not a genuine bug.
2025-01-08 18:24:04 -05:00
Richard Hansen
9ab038412f
Merge pull request #796 from rhansen/vestigial
tests: Delete vestigial code
2025-01-08 18:23:41 -05:00
Richard Hansen
ecaa05abd3 tests: Delete vestigial code
This deleted code came from a previous unpublished prior draft of the
tests and was accidentally not deleted when the approach changed.
2025-01-08 18:20:39 -05:00
Richard Hansen
6408be6ccc
Merge pull request #792 from rhansen/ssl-validate-tests
tests: Fix t/ssl-validate.pl in minimal test environments
2025-01-08 14:43:14 -05:00
Richard Hansen
06c47695fc tests: Fix t/ssl-validate.pl in minimal test environments 2025-01-08 03:33:30 -05:00
Richard Hansen
c89a2d6186 tests: Enable debug logging in t/ssl-validate.pl 2025-01-08 03:33:30 -05:00
Richard Hansen
3f3b8cf825 tests: Localize config setting
This isn't strictly necessary, but is good practice because it
guarantees that the config is cleaned up after each test case.
2025-01-08 03:00:41 -05:00
Richard Hansen
8decfc4b77 Post-release version bump
We'll probably just release `v4.0.0` without an `-rc.3`, but I'm
setting it to `-rc.3` just in case (decreasing the version number can
break automatically built daily Git snapshots).
2025-01-07 14:37:32 -05:00
Richard Hansen
660bb11c02 Release v4.0.0-rc.2 2025-01-07 04:39:01 -05:00
Richard Hansen
fee71b46be
Merge pull request #789 from rhansen/confdir
Change default location of `ddclient.conf` to `${sysconfdir}/ddclient`
2025-01-07 04:36:37 -05:00
Richard Hansen
7248341ad6 Change default location of ddclient.conf to ${sysconfdir}/ddclient 2025-01-07 04:33:54 -05:00
Richard Hansen
60bedd0fab
Merge pull request #790 from rhansen/autosquash
New GitHub workflow to prohibit autosquash commits
2025-01-07 04:33:15 -05:00
Richard Hansen
56f88e3bab New GitHub workflow to prohibit autosquash commits
This prohibits commits whose commit message starts with "squash!",
"fixup!", or "amend!" unless the PR has the 'pr-permit-autosquash'
label.  Such commits are created via the `--fixup` or `--squash`
options to `git commit`, and cause `git rebase --autosquash` to
automatically adjust the todo list appropriately before performing the
rebase.  Their existence implies that the PR should be rebased with
`--autosquash` before merging.
2025-01-07 04:30:40 -05:00
Indrajit Raychaudhuri
8ffbedd436
Merge pull request #754 from Zorks/patch-1
Correct NearlyFreeSpeech.NET example
2025-01-06 20:38:34 -06:00
Indrajit Raychaudhuri
678b76f7e8 nfsn Rearrange zone property in example
Usually, the zone property is not the last property
in the configuration convention that is followed in
ddclient config examples.
2025-01-06 20:27:21 -06:00
Zorks
e4920373ee Correct NearlyFreeSpeech.NET example
extra spaces in the protocol and a trailing comma caused connection issues if not corrected.
2025-01-06 20:27:21 -06:00
Indrajit Raychaudhuri
4008ccfa2d
Merge pull request #565 from TinfoilSubmarine/feature/mail-from
add mail-from option
2025-01-06 20:24:49 -06:00
Indrajit Raychaudhuri
cf4bad127d fixup! add main-from option
move changelog entry to v4.0.0-rc.2
2025-01-06 20:21:56 -06:00
Richard Hansen
76fccba151 fixup! add mail-from option
add changelog entry
2025-01-06 20:20:26 -06:00
Richard Hansen
d2b1a4dfa6 fixup! add mail-from option
move variable declaration closer to usage
2025-01-06 20:20:26 -06:00
Richard Hansen
d1f81dc9e4 fixup! add mail-from option
factor out duplicate code
2025-01-06 20:20:26 -06:00
Richard Hansen
2de77f17f7 fixup! add mail-from option
default to undef
2025-01-06 20:20:26 -06:00
Richard Hansen
a2e818d6d3 fixup! add mail-from option
refine usage wording
2025-01-06 20:20:26 -06:00
Joel Beckmeyer
8030a46ca3 add mail-from option 2025-01-06 20:20:26 -06:00
Richard Hansen
59f6c2959a Prepare for v4.0.0-rc.2 2025-01-06 21:03:47 -05:00
Richard Hansen
0a687d505b
Merge pull request #782 from indrajitr/typo-fix
Fix small typo in 'nochg' message grammar
2024-12-27 14:47:50 -05:00
Indrajit Raychaudhuri
3da4259a41 Fix small typo in 'nochg' message grammar 2024-12-26 18:26:26 -06:00
Richard Hansen
87a919a715 Release v4.0.0-rc.1 2024-12-25 02:22:24 -05:00
Richard Hansen
59495e99d2
Merge pull request #779 from rhansen/linear-pr
New GitHub workflow to enforce linear pull requests
2024-12-25 02:11:28 -05:00
Richard Hansen
07289d5c48 New GitHub workflow to enforce linear pull requests
When combined with GitHub's "Require branches to be up to date before
merging" setting, this forces semi-linear merging.  This check can be
disabled by adding the "pr-permit-nonlinear" label to the PR.
2024-12-25 02:09:00 -05:00
Richard Hansen
4d7d6ae48e
Merge pull request #777 from rhansen/semver
Use semver 2.0.0 as the human-readable version string format
2024-12-24 19:45:34 -05:00
Richard Hansen
54b6d0cb0d Use semver 2.0.0 as the human-readable version string format
This avoids the need to escape tilde in tag names.
2024-12-23 21:40:07 -05:00
Richard Hansen
9f2d6279d2 Rename master branch to main 2024-12-21 22:00:56 -05:00
Richard Hansen
af4ea14fda
Merge pull request #771 from rhansen/build
Build system improvements
2024-12-19 05:08:06 -05:00
Richard Hansen
a12398c315 Makefile.am: Fix Automake portability warning
This silences:

    Makefile.am:20: warning: escaping \# comment markers is not portable
2024-12-19 05:00:56 -05:00
Richard Hansen
6dfcede81a Ignore build-aux/config.guess, build-aux/config.sub
These currently aren't installed by `autoreconf --install`, but ignore
them anyway as a defensive measure.
2024-12-19 04:49:57 -05:00
Richard Hansen
ceced7e094 Delete checked-in copy of tap-driver.sh
It is not needed now that RHEL 6 and CentOS 6 have reached EOL.
2024-12-19 04:49:57 -05:00
Richard Hansen
8fbf9ed4c8 autogen: Force regeneration of --install files 2024-12-19 04:49:29 -05:00
Richard Hansen
8aedcf47db autogen: Add a comment explaining the mkdir 2024-12-19 04:41:53 -05:00
Richard Hansen
d3e793bf21 Move m4 to build-aux/m4 to reduce clutter 2024-12-19 04:21:25 -05:00
Richard Hansen
b200e0c4e3 Mention #752 in ChangeLog.md 2024-12-19 03:59:25 -05:00
Richard Hansen
aba1df3e6b
Merge pull request #752 from cristian-aldea/master
update porkbun api endpoint domain
2024-12-19 03:51:43 -05:00
Joel Beckmeyer
eb48bb55ae make porkbun endpoint configurable 2024-12-19 03:50:03 -05:00
Cristian Aldea
d9365359bd update porkbun api endpoint domain 2024-12-19 03:50:03 -05:00
Richard Hansen
1c0ba9a126
Merge pull request #742 from rhansen/strategy-dedup
Improve deduplication of redundant `use*` queries
2024-09-06 18:58:09 -04:00
Richard Hansen
ad3cd11446 Improve deduplication of redundant use* queries 2024-09-06 18:53:14 -04:00
Richard Hansen
c71f6f6eae Prefetch the data relevant to the use* strategies
This is a preparatory step to improving the deduplication of queries.
It also makes possible future improvements to config validation and
help usage output.
2024-09-06 18:53:14 -04:00
Richard Hansen
f3678ce119 Don't get host-specific values of global options 2024-09-06 18:53:14 -04:00
Richard Hansen
5d545aae5c Simplify arg assignment for readability 2024-09-06 18:53:14 -04:00
Richard Hansen
490dc16d33
Merge pull request #741 from rhansen/tests
Unit test improvements
2024-09-06 18:51:44 -04:00
Richard Hansen
5ed43a2e4c tests: Factor out duplicate HTTP server code 2024-09-06 18:44:19 -04:00
Richard Hansen
62f3759c54 tests: Factor out duplicate IPv6 support detection code 2024-09-06 18:41:37 -04:00
Richard Hansen
9c7c0e55c1 tests: Refine module loads
* Wrap all conditional loads in `BEGIN {}` to be closer to the
    behavior of `use`.
  * Add missing `Test::Warnings`, `HTTP::Request` loads.
  * Sort by module name, except load `Test::More` first and
    `Test::Warnings` immediately after to maximize checking
    effectiveness.
  * Return truthy from `eval` block to prevent the `or` case from
    executing if the loaded module does not have a final truthy
    statement.  (Except for `ddclient` because we want to test that it
    does have a final truthy statement.)
2024-09-06 18:41:33 -04:00
Richard Hansen
dd7ad1ccf4 tests: dnsexit2: Use reserved IP addresses and domain names 2024-09-06 15:47:05 -04:00
Richard Hansen
d38fcbddb8 tests: dnsexit2: Rename variables to follow got, want pattern 2024-09-06 15:47:05 -04:00
Richard Hansen
d0eb899fc8 tests: dnsexit2: Localize changes to %config 2024-09-06 15:47:05 -04:00
Richard Hansen
e8d79d842c tests: dnsexit2: Inline unnecessary helper function
for readability
2024-09-06 15:47:05 -04:00
Richard Hansen
7653f60058 tests: dnsexit2: Move request to a variable
for readability
2024-09-06 15:46:59 -04:00
Richard Hansen
c768f1350b tests: dnsexit2: Check number of requests 2024-09-06 15:24:16 -04:00
Richard Hansen
e9029b85d5 tests: dnsexit2: Simplify request check 2024-09-06 15:22:55 -04:00
Richard Hansen
bd1e42ac6c tests: dnsexit2: Declare @requests where used
for readability
2024-09-06 15:22:55 -04:00
Richard Hansen
d7861b6d61 tests: Do use parent -norequire instead of modifying ISA 2024-09-06 15:22:55 -04:00
Richard Hansen
6c33ccaa25 tests: Always have a truthy final expression in modules
This ensures that `eval { require Module; } or ...` doesn't execute
the `or` case when loading is successful.
2024-09-06 15:22:55 -04:00
Richard Hansen
2ccdd3b19e tests: Delete obsolete debugging comments
All log output goes to stderr, so turning on `debug` or `verbose` will
not interfere with TAP.  A better way to debug is to add the following
to whatever scope you think is appropriate:

    local $ddclient::globals{debug} = 1;
    local $ddclient::globals{verbose} = 1;
2024-09-06 15:22:55 -04:00
Richard Hansen
8b7581287c tests: update_nics: Test number of web* queries
This will be used in a future commit to test deduplication of of
`use*` strategies.
2024-09-06 15:22:46 -04:00
Richard Hansen
b6ac0e6d05 tests: update_nics: Support multiple hosts
This will be used in a future commit to test deduplication of `use*`
strategies.
2024-09-06 15:22:37 -04:00
Richard Hansen
f32f7fc29a tests: update_nics: Fix tracking of update calls
The tests weren't failing because there was only one host being
updated at a time, but this will change in a future commit.
2024-09-06 15:22:18 -04:00
Richard Hansen
a7abfcb715
Merge pull request #740 from rhansen/recap
Overhaul recap handling
2024-09-02 03:59:15 -04:00
Richard Hansen
695c3c4be8 Separate recap variables from configuration variables 2024-09-02 03:55:09 -04:00
Richard Hansen
76afbb6673 _read_config: Add infrastructure for host-dependent validation
This is a preparatory step for separating recap variables from config
variables.
2024-09-02 03:55:09 -04:00
Richard Hansen
0f1ea65fd7 _read_config: Minor refactor for readability and maintainability 2024-09-02 03:55:09 -04:00
Richard Hansen
ac67c04f13 _read_config: Check host definedness, not existence 2024-09-02 03:55:09 -04:00
Richard Hansen
a18efcbe32 Force an update if a host's protocol changes 2024-09-02 03:55:09 -04:00
Richard Hansen
1e3bebc60d Object-oriented protocol definitions
This improves readability and will make it easier to refactor to fix
issues or add features.
2024-09-02 03:55:09 -04:00
Richard Hansen
2da08cceb9 Convert static list of config change detection vars to per-protocol 2024-09-02 03:55:09 -04:00
Richard Hansen
273af1c821 nic_updateable: Ignore non-recap vars when detecting config change 2024-09-02 03:55:09 -04:00
Richard Hansen
803621a9ee Switch "magic constant" list of change detection vars to a var 2024-09-02 03:55:09 -04:00
Richard Hansen
268369a05e Write update status to %recap, not %config
Status is not configuration so it doesn't belong in `%config`.

`wantip`, `wantipv4`, and `wantipv6` are still passed along in
`%config` because `group_hosts_by` needs access to them like other
settings.
2024-09-02 03:55:09 -04:00
Richard Hansen
0348ded46b write_recap: Move update-specific %recap sync to update_nics
This is a step toward separating `%recap` from `%config`.
2024-09-01 20:10:42 -04:00
Richard Hansen
e478117d4e write_recap: Move warned-min-* recap sync to where they are set
This is a step toward separating `%recap` from `%config`.
2024-09-01 20:10:26 -04:00
Richard Hansen
1a748e7a86 write_recap: Only update variables that could have changed
This is a step toward improving readability of `%config`/`%recap`
synchronization.
2024-09-01 20:10:09 -04:00
Richard Hansen
7660ca52bf write_recap: Remove unnecessary recap existence check 2024-09-01 20:09:52 -04:00
Richard Hansen
2927f205ea update_nics: Move non-config recap var reset to update call
for readability
2024-09-01 20:09:35 -04:00
Richard Hansen
974bba4d93 update_nics: Don't set wantip* if they're all undef
This helps keep `%config` "clean", which helps with testing and
debugging.
2024-09-01 20:09:18 -04:00
Richard Hansen
75552f80f7 nic_updateable: Don't mutate status-ipv* vars if not updating
This simplifies the logic a bit and improves readability.
2024-09-01 20:09:01 -04:00
Richard Hansen
25fac765a0 nic_updateable: Move clearing of update to write_recap
for readability (the logic that uses the `update` boolean should be
responsible for clearing it).
2024-09-01 20:08:44 -04:00
Richard Hansen
5256a1d02c update_nics: Move legacy protocol support to an adapter function 2024-09-01 20:08:27 -04:00
Richard Hansen
a178d40633 update_nics: Combine post-update host loops 2024-09-01 20:08:10 -04:00
Richard Hansen
bf83ba032c update_nics: Move legacy wantip assignment to update call
This consolidates the legacy support with other legacy support logic,
which will make it easier to refactor in a future commit.
2024-09-01 20:07:53 -04:00
Richard Hansen
c5df774b7e update_nics: Change || next to or next (for readability) 2024-09-01 20:07:36 -04:00
Richard Hansen
20439bc130 update_nics: Refine comment 2024-09-01 20:07:19 -04:00
Richard Hansen
cb66870019 update_nics: Refine debug message for consistency/readability 2024-09-01 20:07:02 -04:00
Richard Hansen
78be40fe2c update_nics: Remove unnecessary assertions
These just add cold code paths and impair readability and
maintainability.
2024-09-01 20:06:45 -04:00
Richard Hansen
499318fbe0 update_nics: Always overwrite status-ipv* with value from status 2024-09-01 20:06:28 -04:00
Richard Hansen
94ce6367ec write_recap: Also clear out non-recap and stale values
Before, if a non-`undef` value was in `%recap` and the corresponding
value in `%config` became `undef`, the `%recap` value would remain
untouched.  Now it is deleted to match `%config`.

Also, any `%recap` values without a corresponding recap variable
declaration are deleted.
2024-09-01 20:06:11 -04:00
Richard Hansen
c64e432bf1 write_recap: Update all status recap vars when writing recap 2024-09-01 20:05:54 -04:00
Richard Hansen
f2c9ef6641 read_recap: Scrub recap values without var declarations 2024-09-01 20:05:40 -04:00
Richard Hansen
70e2b51377 read_recap: Don't copy non-recap values to %config 2024-09-01 20:04:45 -04:00
Richard Hansen
8359eff6ea read_recap: Check variable definedness, not existence 2024-09-01 20:03:13 -04:00
Richard Hansen
989f8be8c3 read_recap: Delete from %config any status values missing from recap 2024-09-01 20:02:58 -04:00
Richard Hansen
c9cdb96086 read_recap: Fix copying of recap values into %config 2024-09-01 20:02:34 -04:00
Richard Hansen
fbd7167b94 read_recap: Fix iteration over hosts 2024-09-01 18:08:10 -04:00
Richard Hansen
35cbc8d200 read_recap: Reference %recap directly (for readability)
There's no need to pass a reference to `%recap` as an argument when
that is the only way `read_recap` is ever used.
2024-09-01 18:08:10 -04:00
Richard Hansen
31740006d0 read_recap: Use a named loop variable (for readability) 2024-09-01 18:08:10 -04:00
Richard Hansen
65d2473213 read_recap: Don't load ip from recap
This should have been part of commit
de5d894c91 but I forgot.
2024-09-01 18:08:10 -04:00
Richard Hansen
ce1bcaa68b nic_updateable: Set warned-min-* in %config, not %recap
Currently the semantics of recap variables are that values are updated
in `%config` and propagate to `%recap`.  Before this commit,
`warned-min-interval` and `warned-min-error-interval` were set in
`%recap` instead of `%config`, meaning if they followed the semantics
they would be overwritten or deleted when synced with `%config`.  Now
the values are set in `%config` to match the behavior of other recap
variables.
2024-09-01 18:08:10 -04:00
Richard Hansen
e8b3d9168b Remove unnecessary variables from the recap
The logic does not use the persisted values so they do not need to be
persisted.
2024-09-01 18:08:10 -04:00
Richard Hansen
c943d7c0d9 tests: Add some unit tests for read_recap 2024-09-01 18:05:53 -04:00
Richard Hansen
0a9ee106e4 tests: Debug log when in protocol update callback 2024-09-01 02:44:05 -04:00
Richard Hansen
7181152c78 cloudflare: Delete unused variable declarations 2024-09-01 01:01:33 -04:00
Richard Hansen
4b5f28b2f0 Add/update TODO comments for problematic bits of code 2024-09-01 00:59:55 -04:00
Richard Hansen
cf54da50e4 read_recap: Invert condition (for readability) 2024-09-01 00:54:41 -04:00
Richard Hansen
c2db690efb Whitespace fixes 2024-09-01 00:54:41 -04:00
Richard Hansen
3dafdbf604
Merge pull request #732 from rhansen/legacy-status
Fix handling of legacy `status` value
2024-08-22 04:20:37 -04:00
Richard Hansen
de5d894c91 Fix handling of legacy status value
When a legacy protocol implementation returns, move its `status` and
`ip` results to the new `status-ipv4` and `ipv4` (or `status-ipv6` and
`ipv6`) properties.

Also remove the now-unused `status` variable definition, and remove
`ip` from the recap.
2024-08-22 02:08:39 -04:00
Richard Hansen
4f89492dc0 nic_updateable: Use wantip definedness, not use enabledness
Rather than check whether `use`, `usev4`, or `usev6` is a non-disabled
value, check that `wantip`, `wantipv4`, or `wantipv6` is a defined
value.  This is preparation for removing the `status` variable in a
future commit.
2024-08-22 02:08:39 -04:00
Richard Hansen
a21e215ada Reduce unnecessary values in %config and %recap
* Delete values from `$config{$h}` and `$recap{$h}` when resetting
    values (as opposed to setting a falsy value).
  * Delete values from `$config{$h}` and `$recap{$h}` when they are no
    longer needed.

This is mostly done to improve the tests in `t/update_nics.pl`.
2024-08-22 02:08:39 -04:00
Richard Hansen
acd8dfe47f Don't force use to disabled if usev4 or usev6 is enabled
Now that the default changes depending on `usev4` and `usev6`, this is
no longer necessary.  Removing it simplifies the code a bit and makes
the behavior of unit tests match the overall behavior a bit better.
2024-08-22 02:08:39 -04:00
Richard Hansen
f024bcce34 Dynamically compute default for use based on usev4, usev6
This is mostly to simplify tests, but it also improves readability.

The infrastructure changes in this commit also make it possible to
introduce a new `url` variable that defaults to `opt('server', $h)`
concatenated with `opt('script', $h)` so that we can start migrating
away from those user-unfriendly variables.
2024-08-22 02:08:39 -04:00
Richard Hansen
46bd2f1771 tests: Also test default() return value 2024-08-22 02:08:39 -04:00
Richard Hansen
f23070a114 Change defaults for warned-min{,-error}-interval from 0 to undef
The code already treats `undef` and 0 the same, and `undef` omits them
from the recap which simplifies testing.
2024-08-22 02:08:39 -04:00
Richard Hansen
603a59ffe3 Delete redundant variable declarations from global-defaults 2024-08-22 02:08:39 -04:00
Richard Hansen
533e4735cd init_config: Support any variable as a command-line arg
This doesn't add any new command-line arguments, but it does mean that
a new command-line argument can be added for any variable, not just
those in `$variables{'global-defaults'}`, and its value will be copied
to `%globals`.

My main motivation for this commit is to make it possible to remove
the redundant variable declarations between
`$variables{'global-defaults'}` and
`$variables{'protocol-common-defaults'}`.
2024-08-22 02:08:39 -04:00
Richard Hansen
b9ec2d42a3 Remove the (broken and unused?) --retry option 2024-08-22 02:08:39 -04:00
Richard Hansen
555359dc98 tests: Add unit tests for legacy protocol handling in nic_updateable 2024-08-22 02:08:39 -04:00
Richard Hansen
80bbf1dc43
Merge pull request #734 from rhansen/cache
Don't write undefined recap values to the cache file
2024-08-19 17:35:45 -04:00
Richard Hansen
1631b465d5 Don't write undefined recap values to the cache file
There might be a semantic difference between `undef` and the empty
string, so it is incorrect to write an empty string when the value is
`undef`.
2024-08-19 17:29:59 -04:00
Richard Hansen
ed1d480617 Update PR TODOs in ChangeLog.md
I forgot to update these before merging PR #733.
2024-08-18 01:29:37 -04:00
Richard Hansen
12ff5bfbdc
Merge pull request #733 from rhansen/config
Option processing improvements
2024-08-18 01:27:40 -04:00
Richard Hansen
442eac96c7 Update changelog for recent config fixes 2024-08-18 01:22:53 -04:00
Richard Hansen
3be5b91601 Improve documentation for --host and --options command-line args 2024-08-18 01:22:53 -04:00
Richard Hansen
a06c532394 Call load_sha1_support, load_json_support once 2024-08-18 01:22:53 -04:00
Richard Hansen
42f720df86 Move --options validation to where it is processed 2024-08-18 01:22:53 -04:00
Richard Hansen
967bf2f6e8 Error out if given an unknown per-host option 2024-08-18 01:22:53 -04:00
Richard Hansen
564b315bfa Convert command-line argument warnings into fatal errors 2024-08-18 01:22:53 -04:00
Richard Hansen
18bd312216 Don't initialize $config{$h} entries to undef
There's no need -- if the key doesn't exist the value returned is
already `undef`.  This prevents debug output from being littered with
`undef` lines.
2024-08-18 01:22:53 -04:00
Richard Hansen
e8f0358bbb Rely on opt() fallback if a value is invalid 2024-08-18 01:22:53 -04:00
Richard Hansen
2b65aff56b Use opt() instead of accessing %config directly
This makes it possible to leave `$config{$h}{$var}` undefined to have
it fall back to `%opt`, `%globals`, or the variable's default value.
2024-08-18 01:22:52 -04:00
Richard Hansen
912bc6291a group_hosts_by: Treat undef as unset for consistency with opt
The `opt` function falls back to global/default if the value is
undefined, even if it is explicitly set to `undef`.  `group_hosts_by`
should behave the same.
2024-08-18 01:21:40 -04:00
Richard Hansen
5a66efe79e Delete unnecessary defined() check 2024-08-18 00:45:04 -04:00
Richard Hansen
478f517d53 Delete no-effect option normalization
The alternative is to "fix" the code to match the original intention,
but users haven't been complaining so it's better to avoid the risk of
introducing a new bug in the fix.
2024-08-18 00:45:04 -04:00
Richard Hansen
7fde55c188 Don't initialize %opt entries to undef
There's no need -- if the key doesn't exist the value returned is
already `undef`.  This prevents debug output from being littered with
`undef` lines.
2024-08-18 00:45:04 -04:00
Richard Hansen
fe1768316a Use protocol-specific default when known
Different protocols can have different default values for a particular
variable.  Grab the protocol-specific variable definition if given a
hostname when looking up the variable's default.
2024-08-18 00:45:04 -04:00
Richard Hansen
775b7fcbfe Validate and normalize all command-line arguments 2024-08-18 00:45:04 -04:00
Richard Hansen
bbf98dd031 Use parse_assignments to process --options
This simplifies the code and enables quoting of special characters.
2024-08-18 00:41:28 -04:00
Richard Hansen
270a82dd58 parse_assignments: Support newlines
Allow newlines to be in values, but stop searching for assignments
once an unescaped/unquoted newline is discovered.  This is preparation
to using `parse_assignments` to process the `--options` command-line
argument, which might have embedded newlines.
2024-08-18 00:41:28 -04:00
Richard Hansen
4c7634855b Move *_env processing to parse_assignment
This makes the behavior transparent to the rest of ddclient, which
will make it possible for a future commit to simplify option
processing.
2024-08-18 00:41:28 -04:00
Richard Hansen
19848852a4 check_value: Mention supported values if given an invalid value 2024-08-18 00:41:28 -04:00
Richard Hansen
ed2afde72d check_value: die if the value is invalid
This makes it possible to convey details about why the value was
deemed invalid.  It also allows `undef` to be treated as a valid
value.
2024-08-18 00:41:28 -04:00
Richard Hansen
2f8a4ba00a Use opt() instead of accessing %opt or %globals directly
This is for consistency, and to ensure that all possible ways of
configuring are respected.
2024-08-18 00:41:28 -04:00
Richard Hansen
4d3dcdc7de Move option normalization from usage to load
This avoids bugs if a usage forgets to normalize the value.
2024-08-18 00:41:28 -04:00
Richard Hansen
70858e659f Also warn about non-required values that are invalid
Before, only required values that were invalid produced a warning.
Non-required values were quietly ignored.
2024-08-18 00:41:28 -04:00
Richard Hansen
05dbe7a984 Delete confusing and unnecessary T_OFQDN type
Variable declarations already have a `required` flag, which makes the
type confusing.  What would it mean for a variable to be a required
`T_OFQDN`?  And how would an optional `T_FQDN` differ from an optional
`T_OFQDN`?
2024-08-18 00:41:28 -04:00
Richard Hansen
9e659a18eb Move --help processing to %opt 2024-08-18 00:41:28 -04:00
Richard Hansen
c83dc67039 Remove pointless help setting
This does not affect the `--help` command-line argument.

The `help` setting didn't do anything useful, and it didn't make sense
to set `help=1` in the config file (or pass `--options=help=1`), so
this removal is unlikely to affect anyone.  If the setting does exist,
the user will get a warning and the setting will be ignored.
2024-08-18 00:41:28 -04:00
Richard Hansen
b4c4b5dc54 Move usage generation to a separate function 2024-08-18 00:41:28 -04:00
Richard Hansen
bd688e9750 Add TODO comments for problematic bits of code 2024-08-18 00:41:28 -04:00
Richard Hansen
ab2e0d7999 hetzner: Quote interpolated value in regex
to prevent metacharacter issues.
2024-08-18 00:41:28 -04:00
Richard Hansen
0b79e3bc95 godaddy: Delete redundant condition 2024-08-18 00:41:27 -04:00
Richard Hansen
0c094f6ee8 tests: Fix verbose option for dnsexit2 protocol tests
The `verbose` option is a global option, not a per-host option.
2024-08-18 00:35:44 -04:00
Richard Hansen
a136ba4cdc tests: Fix ssl option for dnsexit2 protocol tests
The `ssl` option is a global option, not a per-host option.  This
commit could instead do:

    local $ddclient::globals{ssl} = 0;

but it's more straightforward to include `http://` in the `server`
option, and it tests that `server` supports the inclusion of the
scheme.
2024-08-18 00:35:44 -04:00
Richard Hansen
598dee50ca
Merge pull request #726 from jeffrego/feature_provider_directnic
Added support for provider Directnic
2024-08-07 00:06:46 -04:00
Jeff Rego
959b5ddc37 Add support for Directnic provider 2024-08-07 00:06:25 -04:00
Jeff Rego
d497422bf9 Add T_URL type for config properties 2024-08-07 00:06:25 -04:00
Richard Hansen
2330543cc8 dyndns2: Add comment explaining why keys are listed in test 2024-08-05 19:57:18 -04:00
Richard Hansen
13a66c79bb
Merge pull request #729 from tamasbakos/master
Removed 5m min-interval from changeip protocol
2024-08-03 18:15:24 -04:00
Tamás
e4d43f0292
Removed min-interval from changeip protocol
Removed the min-interval set to 5 minutes in changeip, because according to my tests, changeip has no problem updating every 30 seconds, which is the default min-interval value in ddclient
2024-08-03 11:11:16 +03:00
Richard Hansen
ab27df6f79
Merge pull request #728 from rhansen/dyndns2
dyndns2: Fix handling of multi-host response, add tests
2024-08-03 03:36:45 -04:00
Richard Hansen
eb281ea47b dnsexit2: Rename test file for consistency 2024-08-03 03:32:35 -04:00
Richard Hansen
3d345ff08b dyndns2: Add tests 2024-08-03 03:32:35 -04:00
Richard Hansen
622abfca2c repr: New utility function to make it easier to dump values
I find Data::Dumper to be awkward to use.  This function wraps it so
that I don't have to keep looking up the perldoc.
2024-08-03 03:25:11 -04:00
Richard Hansen
4f369a3b0b geturl: Simplify headers logic 2024-08-03 03:25:11 -04:00
Richard Hansen
2239b57101 dyndns2: Fix handling of multi-host response 2024-08-03 03:25:11 -04:00
Richard Hansen
7bee2d7c82 dyndns2: Log message improvements 2024-08-03 03:17:52 -04:00
Richard Hansen
143630c7fd dyndns2: Delete rogue comma 2024-08-03 03:17:52 -04:00
Richard Hansen
a99d093eca dyndns2: Whitespace fixes 2024-08-03 03:17:52 -04:00
Richard Hansen
60d1c53a36
Merge pull request #727 from rhansen/logger
Improvements to the new Logger class
2024-08-03 02:44:54 -04:00
Richard Hansen
43ea691e0c Logger: Move log output to parentmost Logger
This makes it possible for tests to redirect log output so that they
can ensure that certain log messages are generated.
2024-08-02 21:37:14 -04:00
Richard Hansen
f4248d0617 Logger: Separate implementation from interface
This makes it easier to override the implementation for testing
purposes.
2024-08-02 21:14:37 -04:00
Richard Hansen
56f8c83d3a Logger: Check label for emptiness, not truthiness 2024-08-02 21:05:42 -04:00
Richard Hansen
0f094ac121 Logger: Check msg and label for definedness 2024-08-02 21:05:41 -04:00
Richard Hansen
15db76f739 Logger: Accept an arrayref of contexts for ctx parameter 2024-08-02 20:42:36 -04:00
Richard Hansen
f36c2f45aa Logger: Always use STDERR as output filehandle
There's no good reason for the caller of the `log` method to control
the output filehandle.
2024-08-02 17:03:56 -04:00
Richard Hansen
439b0fd0e1 Logger: Minimize STDERR override in tests 2024-08-02 17:00:00 -04:00
Richard Hansen
1bdd65e46e Delete unused encode_base64 function 2024-08-02 16:13:56 -04:00
Richard Hansen
dff4cd4854 Logger: Localize override in test 2024-08-02 16:13:56 -04:00
Richard Hansen
37504fe6f2 Logger: Document the log method 2024-08-02 16:13:56 -04:00
Richard Hansen
2e59e86df6
Merge pull request #725 from rhansen/logging
Add context to log messages
2024-07-31 01:03:25 -04:00
Richard Hansen
e036fd0cf6 logging: Use Logger contexts to improve log message readability
This also makes it easier to write useful log messages.
2024-07-31 01:01:00 -04:00
Richard Hansen
9e45aecf20 logging: New Logger class to generally handle context prefixes 2024-07-31 00:39:48 -04:00
Richard Hansen
23bc8cdac3 logging: Move colon from the label to logmsg 2024-07-31 00:39:48 -04:00
Richard Hansen
3262dd0952 logging: Rename pfx to label
This is to prepare for a general log prefix mechanism to improve log
readability.
2024-07-31 00:39:48 -04:00
Richard Hansen
015600d72f logging: Delete unused debug2 function 2024-07-31 00:39:47 -04:00
Richard Hansen
42d635c2df dinahosting: Fix missing argument for log message format specifier
Also use string interpolation for readability and to reduce the
chances of reintroducing a bug like this in the future.
2024-07-31 00:39:47 -04:00
Richard Hansen
706ba713e0 porkbun: Fix IP version in success log message
Fixes a bug introduced in commit:
d8a23ff9a4
2024-07-31 00:39:47 -04:00
Richard Hansen
f5c59c2024 nsupdate: Log success/failure once for all hosts 2024-07-31 00:39:47 -04:00
Richard Hansen
0c2c97123f namecheap: Log message improvements 2024-07-31 00:39:47 -04:00
Richard Hansen
71dc1f92e4 zoneedit1: Fix logged host names 2024-07-31 00:39:47 -04:00
Richard Hansen
9dce53ea4a
Merge pull request #724 from vladmovchan/master
Correct NoIP example
2024-07-31 00:37:41 -04:00
Vladyslav Movchan
af65dd86cf Correct NoIP example
An extra comma in the example causes `401 Unauthorized` / `badauth`
2024-07-31 00:37:04 -04:00
Richard Hansen
9c5160a514 Whitespace fixes 2024-07-30 02:25:05 -04:00
Richard Hansen
5620127c71 Delete unnecessary comments 2024-07-30 02:24:27 -04:00
Richard Hansen
96ada0c79e inwx: Add comment explaining why hostnames are not in update URL 2024-07-29 23:45:55 -04:00
Richard Hansen
32f95526f9
Merge pull request #723 from rhansen/infomaniak
infomaniak: Fix response status processing
2024-07-29 04:09:41 -04:00
Richard Hansen
d380e17aba infomaniak: Fix response status processing
Previously, `nochg` responses were treated as failures and the logged
message for all responses was incorrect (either `undef` or "Unknown
reply from Infomaniak").

Background: Hash values are always scalars, so lists of values can
only be stored in hashes in arrayref form.

The following is legal but does not do what one might expect:

    my %h = (
        a => (1, 2),
        b => (3, 4),
    );

The `=>` operator is just a variant of the comma operator, and lists
in list context are flattened, so the above is equivalent to:

    my %h = ('a', 1, 2, 'b', 3, 4);

which is equivalent to:

    my %h = (
        a => 1,
        2 => 'b',
        3 => 4,
    );

which is obviously not what was intended.
2024-07-29 04:07:15 -04:00
Richard Hansen
3f0fd0f37b infomaniak: Use variable interpolation instead of sprintf
for readability.
2024-07-29 04:02:42 -04:00
Richard Hansen
bb65b64e39 infomaniak: Whitespace fixes 2024-07-29 04:02:42 -04:00
Richard Hansen
2715743ee3
Merge pull request #721 from rhansen/gandi
`gandi` cleanups
2024-07-28 19:15:29 -04:00
Richard Hansen
0b30df4b69 gandi: Fix processing of PUT error responses
Before, the returned JSON wasn't even parsed -- the error handling
code was reusing the parsed response from the earlier `GET`.  Also, it
was reading object properties that were not documented in the Gandi
API documentation.
2024-07-28 19:04:30 -04:00
Richard Hansen
06c3dd5825 gandi: Invert condition to improve readability 2024-07-28 18:24:19 -04:00
Richard Hansen
6f505e6538 gandi: Inline an unnecessary variable 2024-07-28 18:24:19 -04:00
Richard Hansen
5e52f728ad gandi: Use an array for headers for readability 2024-07-28 18:24:19 -04:00
Richard Hansen
a890b08935 gandi: Check for JSON object, not just definedness 2024-07-28 18:24:19 -04:00
Richard Hansen
b1ddaa0ce8 gandi: Log message improvements 2024-07-28 18:24:19 -04:00
Richard Hansen
12d5539abc gandi: Don't ignore HTTP response code 2024-07-28 18:24:19 -04:00
Richard Hansen
325eb10536 gandi: Style fixes for readability 2024-07-28 18:24:19 -04:00
Richard Hansen
2ccdefff93 gandi: Whitespace fixes 2024-07-28 18:24:19 -04:00
Richard Hansen
15595d01ac gandi: Delete unnecessary comment 2024-07-28 18:24:19 -04:00
Richard Hansen
26d7aa500a
Merge pull request #720 from rhansen/delete
Delete some unnecessary code
2024-07-28 18:22:19 -04:00
Richard Hansen
0fa7e132b1 logging: Delete now-unused verbose function 2024-07-28 17:52:42 -04:00
Richard Hansen
54d381a18e nsupdate: Convert some verbase log messages to debug 2024-07-28 17:52:42 -04:00
Richard Hansen
61cc5d66ae logging: Delete unnecessary verbose calls
The same information (or more) is logged in the previous line.
2024-07-28 17:48:58 -04:00
Richard Hansen
ee0940175e Delete redundant calls to failed
`header_ok` already calls `failed` if there's an error.
2024-07-28 03:45:10 -04:00
Richard Hansen
f410b915ce Delete redundant checks
`header_ok` already asserts that the reply is defined and non-empty.
2024-07-28 03:45:10 -04:00
Richard Hansen
228efa7927
Merge pull request #719 from rhansen/cleanups
Various minor cleanups and improvements
2024-07-27 04:46:46 -04:00
Richard Hansen
fc453a0de3 porkbun: Check for JSON object, not just non-null 2024-07-27 04:40:34 -04:00
Richard Hansen
536c7c87a2 porkbun: Invert condition to improve readability 2024-07-27 04:40:34 -04:00
Richard Hansen
d8a23ff9a4 porkbun: Improve log messages 2024-07-27 04:40:34 -04:00
Richard Hansen
e1c8b26f7b porkbun: Simplify string equality check 2024-07-27 04:40:34 -04:00
Richard Hansen
0c31681d35 porkbun: Simplify array length check 2024-07-27 04:40:34 -04:00
Richard Hansen
16b15ea089 porkbun: Remove headers from HTTP response before processing 2024-07-27 04:40:34 -04:00
Richard Hansen
c65d5c1254 porkbun: Don't bother setting status on failure
It's already initialized to a non-success value.
2024-07-27 04:40:34 -04:00
Richard Hansen
bafd5a8715 porkbun: Inline unnecessary variables 2024-07-27 04:40:34 -04:00
Richard Hansen
45d832145f porkbun: Simplify RR set type 2024-07-27 04:40:34 -04:00
Richard Hansen
038b31cf77 porkbun: Simplify zone removal logic 2024-07-27 04:40:34 -04:00
Richard Hansen
630a2d5d49 porkbun: Move "ipv" out of $ipv for consistency
This also makes it possible to change "ipv4" and "ipv6" in log
messages to "IPv4" and "IPv6".
2024-07-27 04:40:34 -04:00
Richard Hansen
4273580bdf porkbun: Consolidate lines to improve readability 2024-07-27 04:40:34 -04:00
Richard Hansen
c6bcfd4644 porkbun: Quote interpolated variable in regex 2024-07-27 04:40:34 -04:00
Richard Hansen
1020145fdf porkbun: Rename variables for brevity and consistency 2024-07-27 04:40:34 -04:00
Richard Hansen
3f740c3e19 porkbun: Whitespace fixes 2024-07-27 04:40:34 -04:00
Richard Hansen
4b5b8ab62d porkbun: Delete unnecessary comments 2024-07-27 04:40:34 -04:00
Richard Hansen
3dae16457a dnsmadeeasy: Consolidate lines for readability 2024-07-27 04:40:34 -04:00
Richard Hansen
2eb0398cf2 dnsmadeeasy: Invert condition to improve readability 2024-07-27 04:40:34 -04:00
Richard Hansen
b07aa91ed5 dnsmadeeasy: Don't bother setting status on failure
It's already initialized to a non-success value.
2024-07-27 04:40:34 -04:00
Richard Hansen
971fe438a3 dnsmadeeasy: Convert string literal to compiled regex
for readability.
2024-07-27 04:40:34 -04:00
Richard Hansen
ca28694dd7 dnsmadeeasy: Don't assume the result code is known 2024-07-27 04:40:34 -04:00
Richard Hansen
11876498d5 dnsmadeeasy: Improve log messages 2024-07-27 04:40:34 -04:00
Richard Hansen
c79d12263e dnsmadeeasy: Whitespace fixes 2024-07-27 04:40:34 -04:00
Richard Hansen
07800a4586 dnsmadeeasy: Delete unnecessary comments 2024-07-27 04:40:34 -04:00
Richard Hansen
f42583c0cf dondominio: Quote interpolated variable in regex 2024-07-27 04:40:34 -04:00
Richard Hansen
6ac5b41a20 dondominio: Invert condition to improve readability 2024-07-27 04:40:34 -04:00
Richard Hansen
d79ef268bd dondominio: Combine regular expressions to improve readability 2024-07-27 04:40:34 -04:00
Richard Hansen
8b58f7bd99 dondominio: Don't bother setting status on error
It's already initialized to a non-success value.
2024-07-27 04:40:34 -04:00
Richard Hansen
2823e47c58 dondominio: The IP address is always provided 2024-07-27 04:40:34 -04:00
Richard Hansen
fe502abcd8 dondominio: Consolidate lines for readability 2024-07-27 04:40:34 -04:00
Richard Hansen
7a43920b99 dondominio: Improve log messages 2024-07-27 04:40:34 -04:00
Richard Hansen
17a002cbd6 dondominio: Whitespace fixes 2024-07-27 04:40:34 -04:00
Richard Hansen
e155e1bf2c dondominio: Delete unnecessary comments 2024-07-27 04:40:34 -04:00
Richard Hansen
d62495c41e ddns.fm: Improve log messages 2024-07-27 04:40:34 -04:00
Richard Hansen
1195a40c45 freemyip: Check entire result body, not just first line
This is simpler, and should be more resilient to bugs.
2024-07-27 04:40:34 -04:00
Richard Hansen
3ece2017e9 freemyip: Skip headers before processing response
This isn't strictly necessary but improves readability and
consistency.
2024-07-27 04:40:34 -04:00
Richard Hansen
a252ff5ebe freemyip: Invert condition to improve readability 2024-07-27 04:40:34 -04:00
Richard Hansen
9343ebec89 freemyip: Don't bother setting status on error
It's not necessary because it's already initialized to a non-success
value.
2024-07-27 04:40:34 -04:00
Richard Hansen
c53f40d205 freemyip: Improve log messages 2024-07-27 04:40:34 -04:00
Richard Hansen
b3006dd6c6 freemyip: Consolidate lines for readability 2024-07-27 04:40:34 -04:00
Richard Hansen
62154f9869 freemyip: Whitespace fixes 2024-07-27 04:40:34 -04:00
Richard Hansen
f8bdc48e42 freemyip: Delete unnecessary comments 2024-07-27 04:40:34 -04:00
Richard Hansen
7bdb554e36 duckdns: Update multiple hosts simultaneously 2024-07-27 04:40:34 -04:00
Richard Hansen
1eccfb8c77 duckdns: Invert condition to improve readability 2024-07-27 04:40:34 -04:00
Richard Hansen
91fd9e3842 duckdns: Simplify response processing 2024-07-27 04:40:34 -04:00
Richard Hansen
971e88452d duckdns: Improve log messages 2024-07-27 04:40:34 -04:00
Richard Hansen
8a334fd9cf duckdns: Consolidate lines to improve readability 2024-07-27 04:40:34 -04:00
Richard Hansen
98ed129b20 duckdns: Whitespace fixes 2024-07-27 04:40:34 -04:00
Richard Hansen
b80fe1b505 duckdns: Delete unnecessary comments 2024-07-27 04:40:34 -04:00
Richard Hansen
459970c5e3 yandex: Check for presence of success, not lack of error
This is more resilient to bugs.
2024-07-27 04:40:34 -04:00
Richard Hansen
f807ba58ac yandex: Don't treat an error as success 2024-07-27 04:40:34 -04:00
Richard Hansen
58c6caa5ff nfsn: Include host in failure message 2024-07-27 04:40:34 -04:00
Richard Hansen
ef8bf634fe domeneshop: Add IPv6 support 2024-07-27 04:40:34 -04:00
Richard Hansen
61fff1c344 domeneshop: Inline an unnecessary variable 2024-07-27 04:40:34 -04:00
Richard Hansen
d391f41074 domeneshop: Treat all 2xx as success 2024-07-27 04:40:34 -04:00
Richard Hansen
b4e08ae3ae domeneshop: Improve log messages 2024-07-27 04:40:34 -04:00
Richard Hansen
231601ae54 domeneshop: Whitespace fixes 2024-07-27 04:40:34 -04:00
Richard Hansen
f0edd7f781 domeneshop: Delete unnecessary comments 2024-07-27 04:40:34 -04:00
Richard Hansen
2534375cfd dyndns1: Move else case up a level for readability 2024-07-27 04:40:34 -04:00
Richard Hansen
02c80fdf09 dslreports1: Move out else case to improve readability 2024-07-27 04:40:34 -04:00
Richard Hansen
95a10e2595 dslreports1: Log message improvements 2024-07-27 04:40:34 -04:00
Richard Hansen
2d60183e93 noip: Log message improvements 2024-07-27 04:40:34 -04:00
Richard Hansen
c0b28f344f noip: Simplify response processing 2024-07-27 04:40:34 -04:00
Richard Hansen
5b433c3cd5 noip: Delete redundant response check 2024-07-27 04:40:34 -04:00
Richard Hansen
27143db56e dnsexit2: Pass an arrayref of headers for readability 2024-07-27 04:40:34 -04:00
Richard Hansen
1c94ed6063 dnsexit2: Check for JSON object, not just truthiness 2024-07-27 04:40:34 -04:00
Richard Hansen
4a394f4562 dnsexit2: Delete rogue semicolon 2024-07-27 04:40:34 -04:00
Richard Hansen
56f0d931a4 dnsexit2: Delete redundant check
`header_ok` already checks whether the response is `undef`.
2024-07-27 04:40:34 -04:00
Richard Hansen
e5b00216ec dnsexit2: Log message improvements 2024-07-27 04:40:34 -04:00
Richard Hansen
073fe5a51d dnsexit2: Delete redundant HTTP status code check
`header_ok` already checks for non-2xx codes.
2024-07-27 04:40:34 -04:00
Richard Hansen
3d894364bf dnsexit2: Delete redundant debug message
`geturl` already debug logs the response.
2024-07-27 04:40:34 -04:00
Richard Hansen
2ac61250e5 dnsexit2: Fix compatibility with old versions of Perl
The non-destructive substitution modifier wasn't added until Perl
v5.14.0.
2024-07-27 04:40:34 -04:00
Richard Hansen
962abfbbc3 use=web, use=<fw>: Don't treat non-2xx results as successes 2024-07-27 04:40:34 -04:00
Richard Hansen
e272caa385 use=web, use=<fw>: Strip HTTP headers before searching for IP 2024-07-27 04:40:34 -04:00
Richard Hansen
b563e9c2fd use=web: Add tests 2024-07-27 04:40:34 -04:00
Richard Hansen
08626482c3 header_ok: Don't assume that it is only used for host updates 2024-07-27 03:59:52 -04:00
Richard Hansen
d48b482269 geturl: Log message improvements 2024-07-27 03:59:52 -04:00
Richard Hansen
b1752c2622 logging: Delete unused msg function 2024-07-27 03:59:29 -04:00
Richard Hansen
6aa68f72a7 logging: Change multi-line log message designation style
Before, the first line of a multi-line log message was prefixed with a
space while all subsequent messages were prefixed with `|`.  Now the
first line is prefixed with `>` and all subsequent lines with a space.
This makes it easier to quickly discern message boundaries.
2024-07-27 03:47:47 -04:00
Richard Hansen
bd437a0abf nic_updateable: Log message improvements 2024-07-26 23:58:20 -04:00
Richard Hansen
8262f112ea nic_updateable: Read option value after loading config 2024-07-26 23:58:20 -04:00
Richard Hansen
1ad9b565bd nic_updateable: Don't warn about success
Why issue a warning that things have suddenly started going well?
It's bizarre.
2024-07-26 23:58:20 -04:00
Richard Hansen
1054e162fa query_cisco: Use host-specific option value 2024-07-26 23:50:14 -04:00
Richard Hansen
0392c5e725 query_cisco: Delete redundant warning
The same message is already logged in `get_ipv4`.
2024-07-26 23:50:14 -04:00
Richard Hansen
e891f53345 update_nics: Consistently use --opt instead of opt 2024-07-26 23:50:04 -04:00
Richard Hansen
5d68b11d78 get_ipv6: Factor out check for deprecated value 2024-07-26 23:50:04 -04:00
Richard Hansen
2530adb39e get_ip: Log message improvements 2024-07-26 23:50:04 -04:00
Richard Hansen
b9d372c12d get_ip: Allow $arg to be undefined
This is simpler, and makes it possible to distinguish unset from set
to an empty string.
2024-07-26 23:49:48 -04:00
Richard Hansen
0ea2f06513 get_ip: Don't mutate $arg
This makes log messages easier to understand.
2024-07-26 19:05:47 -04:00
Richard Hansen
ccc205301a Delete old test code
It's better to start a test HTTP server or override `@curl` from tests
in `t/*.pl`.
2024-07-26 19:05:47 -04:00
Richard Hansen
6ddecb4ecc Replace use vars with our
From the documentation for `vars`:

> NOTE: For use with variables in the current package for a single
> scope, the functionality provided by this pragma has been superseded
> by "our" declarations, available in Perl v5.6.0 or later, and use of
> this pragma is discouraged.
2024-07-26 19:05:47 -04:00
Richard Hansen
356c3354bd
Merge pull request #718 from rhansen/force_update
Cleanups to forced update logic
2024-07-26 19:04:36 -04:00
Richard Hansen
89d7193f69 nic_updateable: Simplify option changed detection logic 2024-07-26 18:15:21 -04:00
Richard Hansen
38a4e9eeef nic_updateable: Remove unnecessary force_update parameter
`nic_updateable` can look up the host's `force_update` function itself
so there's no need to pass it as an argument.
2024-07-26 17:24:49 -04:00
Richard Hansen
0ffffb1400 Delete unnecessary force_update => undef lines 2024-07-26 17:21:11 -04:00
Richard Hansen
5a8bee1e4d Delete unnecessary nic_dyndns2_force_update
The `nic_updateable` function already checks the variables to see if
they have changed, so this function is redundant.
2024-07-26 17:06:09 -04:00
Richard Hansen
2a9abc9d4c Delete unused nic_easydns_force_update function 2024-07-26 17:04:12 -04:00
Richard Hansen
59ff497c1b
Merge pull request #717 from jameskimmel/patch-1
delete unused zoneedit force update
2024-07-24 13:53:42 -04:00
jameskimmel
bcfdf70c34
delete unused zoneedit force update
I think this sub is never used.
2024-07-23 18:53:27 +02:00
Richard Hansen
482be5ce46
Merge pull request #716 from rhansen/defunct
Delete defunct services
2024-07-23 00:12:49 -04:00
Richard Hansen
9996c1b7d4 googledomains: Remove support for defunct service 2024-07-22 23:28:33 -04:00
Richard Hansen
ddfa8663ad woima: Remove support for defunct service 2024-07-22 23:26:41 -04:00
Richard Hansen
cf078017c2
Merge pull request #713 from rhansen/easydns
easydns: Multiple fixes and cleanups
2024-07-21 23:18:49 -04:00
Richard Hansen
3c68abe551 easydns: Fix incorrect status value on success 2024-07-20 03:44:05 -04:00
Richard Hansen
a7feb95091 easydns: Add missing OK and NO_AUTH result codes 2024-07-20 03:44:05 -04:00
Richard Hansen
d8c74169ee easydns: Include the full ILLEGAL INPUT result code in log messages 2024-07-20 03:44:05 -04:00
Richard Hansen
a724084114 easydns: Fix extraction of result code from response body
The server returns a full HTML document, not just the result code.
Change equality check to a regex match that is resilient to
server-side changes.
2024-07-20 03:44:05 -04:00
Richard Hansen
435357ac50 easydns: Invert condition to improve readability 2024-07-20 03:44:04 -04:00
Richard Hansen
da26fe76e0 easydns: Update IPv4 and IPv6 separately
https://kb.easydns.com/knowledge/dynamic-dns/ doesn't say anything
about repeating the `myip` parameter, or that both IPv4 and IPv6
addresses can be included in the same `myip` parameter.

Unfortunately it also doesn't say whether updating the IPv4 address
alone will nuke the IPv6 AAAA record, or whether updating the IPv6
address alone will nuke the IPv4 A record (like Google Domains used to
do).  Here's hoping that the A and AAAA records are truly independent.
2024-07-20 03:44:04 -04:00
Richard Hansen
7a4b96e04e easydns: Delete incorrect handling of TOOSOON error
Before:
  * `$scale` was ignored causing it to set `wtime` to 5s in the
    future, which is too brief.  Fortunately, `min-error-interval`
    applied which prevented overly aggressive retries.
  * The lack of call to `failed` meant that `$result` was not set to
    "FAILED" and thus `mail-failure` recipients were not emailed.

Now `TOOSOON` is treated like any other error and will result in a
retry after `min-error-interval` (default: 5m).
2024-07-20 03:35:56 -04:00
Richard Hansen
fb990208b3 easydns: Consolidate lines for readability 2024-07-20 03:35:56 -04:00
Richard Hansen
6992a34028 easydns: Simplify response processing 2024-07-20 03:35:56 -04:00
Richard Hansen
7a2625b7a7 easydns: Refine log messages
* Consistently use just the hostname as the log message prefix.
  * Delete redundant verbose log message.
  * Log IPv4 and IPv6 separately in case `$ipv4` or `$ipv6` is
    `undef`.
  * Don't log the full line when a known error result is returned.
  * For unknown results, don't wrap the line in parentheses.
  * Use string interpolation for readability.
2024-07-20 03:35:56 -04:00
Richard Hansen
94c304601e easydns: Increase default min-interval to 10m 2024-07-20 03:35:56 -04:00
Richard Hansen
e7ad0e8e6e easydns: Whitespace fixes 2024-07-20 03:35:46 -04:00
Richard Hansen
c57f4b0d56 ChangeLog.md: Fix PR URL 2024-07-20 03:35:45 -04:00
Richard Hansen
2792689c35 ChangeLog.md: Fix PR URLs 2024-07-20 03:06:52 -04:00
Richard Hansen
e142d6a5ac
Merge pull request #712 from rhansen/geturl
Delete `--geturl` command-line argument and `geturl` option
2024-07-19 18:10:19 -04:00
Richard Hansen
3a57ca1374 Delete --geturl command-line argument and geturl option
They are not used in any tests, and `curl` is a better choice anyway.
2024-07-19 18:06:28 -04:00
Richard Hansen
dab67eae69 README.md: Revise troubleshooting section
* Use a bulleted list instead of a numbered list
  * Fix indentation
  * Fix formatting
  * Replace `fw` with `fwv4`
  * Suggest `curl` instead of `ddclient --geturl`
  * etc.
2024-07-19 18:06:28 -04:00
Richard Hansen
dfef6b2e99
Merge pull request #711 from rhansen/godaddy
godaddy: readability improvements
2024-07-19 16:36:24 -04:00
Richard Hansen
12b2c0d03d godaddy: Inline some unnecessary variables 2024-07-19 16:21:37 -04:00
Richard Hansen
bdc69d879f geturl: Accept an arrayref for headers 2024-07-19 16:21:37 -04:00
Richard Hansen
b9144c01c2 godaddy: Use eq for string equality
`==` is for numeric equality.
2024-07-19 16:21:37 -04:00
Richard Hansen
4b2155a43c godaddy: Combine URL lines to improve readability
Also drop unnecessary curly braces for consistency.
2024-07-19 16:18:14 -04:00
Richard Hansen
6e98c0cdb2 godaddy: Invert conditional to improve readability 2024-07-19 16:17:50 -04:00
Richard Hansen
b1c0029604 godaddy: Simplify for loop 2024-07-19 16:17:49 -04:00
Richard Hansen
3258ea34c0 godaddy: Shorten variables for brevity and consistency 2024-07-19 16:17:19 -04:00
Richard Hansen
56f4a2afe2 godaddy: Don't bother setting status on error
It's initialized to a non-'good' value before the function is called,
and ddclient doesn't distinguish between different non-good values, so
it is sufficient to leave it alone.
2024-07-19 16:16:44 -04:00
Richard Hansen
e01ed55a58 godaddy: Simplify and improve error messages 2024-07-19 16:16:21 -04:00
Richard Hansen
c63eb0f060 godaddy: Fix dubious response body check
It doesn't make sense to continue processing if the response body
can't be parsed.  Maybe GoDaddy returned 200 and there's a bug in the
body parsing logic, in which case the `bad` result should actually be
`good`.  But it's better to assume that the update wasn't saved, in
case the server returns 200 with a JSON object that semantically means
"failed to update".
2024-07-19 16:15:37 -04:00
Richard Hansen
f82d2af0f2 godaddy: Whitespace fixes 2024-07-19 16:15:30 -04:00
Richard Hansen
53b373fc9e godaddy: Delete unnecessary comments 2024-07-19 16:08:41 -04:00
Richard Hansen
5ab15b1d53
Merge pull request #690 from Starkstromkonsument/add_INWX_support
Add new protocol inwx
2024-07-19 02:28:30 -04:00
Starkstromkonsument
83ef1fa99a Add new protocol inwx
Adoption of protocol dyndns2 to support their custom URL:

'https://dyndns.inwx.com/nic/update?myip=<ipaddr>&myipv6=<ip6addr>'
2024-07-19 02:26:25 -04:00
Richard Hansen
f6e13f8003
Merge pull request #709 from rhansen/dyndns2
`dyndns2` readability improvements, take 2
2024-07-19 02:25:08 -04:00
Richard Hansen
30a7c5ad78 dyndns2: Delete obsolete custom and static options
<https://help.dyn.com/remote-access-api/perform-update/> says:

> We will accept these parameters without generating error messages:
>
>   * `system`, previously used to identify update type
2024-07-19 02:12:53 -04:00
Richard Hansen
26f57bf36a dyndns2: Delete obsolete(?) "wait" response handling 2024-07-19 01:33:02 -04:00
Richard Hansen
adfd68d5e0 dyndns2: Refine log messages 2024-07-18 05:42:49 -04:00
Richard Hansen
1e73f4a51a dyndns2: Wrap long list of group by attributes 2024-07-18 05:42:49 -04:00
Richard Hansen
90de2f9606 dyndns2: Improve readability of status parsing 2024-07-18 05:42:49 -04:00
Richard Hansen
88f140d470 dyndns2: Invert condition to improve readability 2024-07-18 05:42:48 -04:00
Richard Hansen
8a667e3f57 dyndns2: Treat nochg as good to eliminate duplicate code 2024-07-18 05:42:30 -04:00
Richard Hansen
db3472a7ce dyndns2: Simplify response parsing 2024-07-18 05:42:29 -04:00
Richard Hansen
0892655fd6 dyndns2: Add response handling TODO comments 2024-07-18 05:41:59 -04:00
Richard Hansen
d88e6438ef Revert "Merge pull request #702 from rhansen/dyndns2"
I misread the original code and introduced a bug.  This reverts the
entire PR so that I can redo it.

This reverts commit 9eff7404e3, reversing
changes made to 60f931e7da.
2024-07-18 03:30:34 -04:00
Richard Hansen
23dad564be dyndns2: Expand rationale for not checking returned IP 2024-07-17 22:54:02 -04:00
Richard Hansen
9256096e64
Merge pull request #695 from woolflare/master
Add DDNS.FM support
2024-07-15 03:50:51 -04:00
woolflare
2f4b0859bd Add DDNS.FM support 2024-07-15 03:50:07 -04:00
Richard Hansen
af0035d266
Merge pull request #705 from rhansen/ssl
Enable `--ssl` by default
2024-07-14 19:12:43 -04:00
Richard Hansen
c6581b03f2 Bump version to v4.0.0~alpha
The list of breaking changes has become significant enough to warrant
bumping the major version number.
2024-07-14 19:07:55 -04:00
Richard Hansen
f0de73e8c4 Enable --ssl by default
In this day and age there's no good reason to prefer plain HTTP over
HTTPS, and security is more important than potential compatibility
concerns.
2024-07-14 19:00:53 -04:00
Richard Hansen
13369804a0 Improve documentation for --ssl option
Also move it to the top of the sample config file due to its
importance.
2024-07-14 19:00:24 -04:00
Richard Hansen
430d9026f8
Merge pull request #704 from Bodenhaltung/add-dnshome-de
Add dnsHome.de
2024-07-14 18:20:35 -04:00
Richard Hansen
6284133b1c Add dnsHome.de example config 2024-07-14 18:18:03 -04:00
Bodenhaltung
5931a7150c Add dnsHome.de 2024-07-14 17:11:18 -04:00
Richard Hansen
4c6842e569
Merge pull request #703 from rhansen/tls
Don't force plain HTTP
2024-07-14 16:44:15 -04:00
Richard Hansen
7754c65103 woima: Honor http: or https: scheme in server variable 2024-07-13 18:38:53 -04:00
Richard Hansen
0ed2970852 keysystems: Honor http: or https: scheme in server variable
or fall back to the value of the `ssl` variable if neither `http:` nor
`https:` is present.
2024-07-13 18:38:44 -04:00
Richard Hansen
469c5a072e dnsmadeeasy: Honor http: or https: scheme in server variable 2024-07-13 18:38:36 -04:00
Richard Hansen
6fbb7eb3dc domeneshop: Honor http: or https: scheme in server variable 2024-07-13 18:38:26 -04:00
Richard Hansen
c31668b413 dyndns2: Honor http: or https: scheme in server variable
or fall back to the value of the `ssl` variable if no `http:` or
`https:` scheme is present.
2024-07-13 18:38:18 -04:00
Richard Hansen
a7fef2e1eb
Merge pull request #682 from indrajitr/henet-provider
he.net: Add support for Hurricane Electric provider
2024-07-13 17:53:15 -04:00
Richard Hansen
4d5a416725 Omit deprecated services from --list-web-services
This also makes the handling of deprecated services a bit more
general.
2024-07-13 17:50:10 -04:00
Richard Hansen
efa487bfb3 Note that --web=googledomains is deprecated in changelog 2024-07-13 17:31:52 -04:00
Indrajit Raychaudhuri
0973e9d83c Deprecate 'builtinweb' 'he' for 'he.net' for consistency with protocol 2024-07-13 17:31:52 -04:00
Indrajit Raychaudhuri
ecf935a4e2 he.net: Add support for Hurricane Electric provider
The implementation is based on the existing
dyndns2 protocol with a few differences:
- The IPv4 and IPv6 addresses must be updated in
  separate calls. This is different from most of
  the other providers where both IPv4 and IPv6
  addresses can be updated in a single call. Thus
  the existing dyndns2 protocol implementation
  cannot be reused for dns.he.net.
- Multiple hosts are not supported by the provider.

See: https://dns.he.net/docs.html
2024-07-13 17:31:52 -04:00
Richard Hansen
9eff7404e3
Merge pull request #702 from rhansen/dyndns2
`dyndns2` readability improvements
2024-07-13 04:58:02 -04:00
Richard Hansen
d489cea344 dyndns2: Wrap long list of group by attributes 2024-07-13 04:52:05 -04:00
Richard Hansen
203bf12245 dyndns2: Improve readability of status parsing 2024-07-13 04:45:35 -04:00
Richard Hansen
ad4e3769eb dyndns2: Invert condition to improve readability 2024-07-13 04:45:35 -04:00
Richard Hansen
0882712ec2 dyndns2: Treat nochg as good to eliminate duplicate code 2024-07-13 04:45:35 -04:00
Richard Hansen
45e3603918 dyndns2: Simplify response parsing 2024-07-13 04:45:35 -04:00
Richard Hansen
60f931e7da
Merge pull request #701 from rhansen/group_hosts_by
`group_hosts_by` improvements
2024-07-13 04:45:16 -04:00
Richard Hansen
3ffcdf8317 ci: Pass --skip-broken after install, not before
Apparently dnf was changed in Fedora Rawhide:
https://bugzilla.redhat.com/show_bug.cgi?id=2216055
2024-07-13 04:42:06 -04:00
Richard Hansen
8a65264841 group_hosts_by: Return the common group configuration
This should make it easier to detect missing attribute names passed to
`group_hosts_by`.
2024-07-13 04:09:24 -04:00
Richard Hansen
b8df93febe group_hosts_by: Return a list, not a hashref
The hash key value is an implementation detail that should not be
leaked to the caller.
2024-07-13 04:08:35 -04:00
Richard Hansen
08ccc41650 group_hosts_by: Use arg list instead of arrayref
This is more idiomatic.
2024-07-13 04:08:35 -04:00
Richard Hansen
64af205cfc group_hosts_by: Readability improvements 2024-07-13 04:08:35 -04:00
Richard Hansen
5d2a1e864a yandex: Remove unnecessary host groupings
Each host is already updated individually so there's no point in
grouping the hosts.
2024-07-13 04:08:35 -04:00
Richard Hansen
216c9c6010 hetzner: Remove unnecessary host groupings
Each host is already updated individually so there's no point in
grouping the hosts.
2024-07-13 04:08:35 -04:00
Richard Hansen
5ae0fd3024 hetzner: Delete unused login variable 2024-07-13 04:08:35 -04:00
Richard Hansen
45677c0403 cloudflare: Remove unnecessary attributes from group_hosts_by args 2024-07-13 04:08:35 -04:00
Richard Hansen
8e20185323 googledomains: Remove unnecessary host groupings
Each host is already updated individually so there's no point in
grouping the hosts.
2024-07-13 04:08:35 -04:00
Richard Hansen
40e4aee74f nsupdate: Add missing tcp to group_hosts_by attributes 2024-07-13 04:08:35 -04:00
Richard Hansen
e8a6d1479f godaddy: Remove unnecessary host groupings
Each host is already updated individually so there's no point in
grouping the hosts.
2024-07-13 04:08:35 -04:00
Richard Hansen
5db77f7c31 zoneedit1: Add TODO comments for problematic bits of code 2024-07-13 04:08:35 -04:00
Richard Hansen
217bc998fc easydns: Remove unnecessary single host groupings 2024-07-13 04:08:35 -04:00
Richard Hansen
c8ee25ef82 noip: Remove unused attributes from group_hosts_by arguments 2024-07-13 04:08:35 -04:00
Richard Hansen
1faa315794 noip: Delete unused variables 2024-07-13 04:08:35 -04:00
Richard Hansen
39e3322fc0 dyndns2: Add missing script to group_hosts_by attributes 2024-07-13 04:08:35 -04:00
Richard Hansen
161c623557 Whitespace fixes 2024-07-13 04:08:33 -04:00
Richard Hansen
b488cb2235 Unwrap error message
Normally I prefer lines to be less than 100 characters long, but error
messages are an exception because it makes it easier to search the
source code for the error message.
2024-07-12 18:00:38 -04:00
Richard Hansen
4d9d0646cf Delete unnecessary comments 2024-07-12 18:00:38 -04:00
Richard Hansen
2e26a63c2f
Merge pull request #698 from rhansen/tests
t/get_ip_from_if.pl test improvements
2024-07-11 00:35:22 -04:00
Richard Hansen
fa0bfde3cb Don't assume the default interface has a globally routable IP 2024-07-11 00:18:27 -04:00
Richard Hansen
6af76afde9 Use skip_all if test precondition is not met
Subtests can't have zero checks.
2024-07-11 00:18:27 -04:00
Richard Hansen
01d2db06c1 Invert conditions for readability 2024-07-11 00:18:27 -04:00
Richard Hansen
6e7a4fb460 Split subtest into two subtests
This makes it easier to debug failures.
2024-07-11 00:18:27 -04:00
Richard Hansen
7b6f640c9b ci: Remove Red Hat UBI 7
UBI 7 is at end of maintenance and can't run newer versions of node
used by some workflows.
2024-07-11 00:15:34 -04:00
Richard Hansen
ab9ac65f46
Merge pull request #694 from rhansen/vars
More variable fixes
2024-06-29 04:18:57 -04:00
Richard Hansen
f5b369a7ef Fix undef warning when encountering an unset but required var
This fixes a bug probably introduced in commit
b8a0a26441
2024-06-29 04:14:57 -04:00
Richard Hansen
89c84f9f07 Ignore (with warning) unknown vars in --options 2024-06-29 04:14:35 -04:00
Richard Hansen
1f31b0e570 Prevent autovivification of empty definitions for unknown variables 2024-06-29 04:14:35 -04:00
Richard Hansen
d8317a730d Fix die that should be return undef
I got ahead of myself -- I intend to replace `return undef` with `die`
in a future commit, and somehow this one jumped the gun.

This fixes a bug introduced in commit
eab72ef6d7
2024-06-29 04:14:31 -04:00
Richard Hansen
04bdd68415 Always set the host variable
The `host` variable is required, so always set it to avoid error
messages when validating the host configuration.
2024-06-29 04:14:02 -04:00
Richard Hansen
be3c2060eb Fix undefined hash reference warning
This fixes a bug introduced in commit
5e3e10d32e

For some reason Perl is OK with:

    my $x = undef;
    my @k = keys(%$x);  # empty list, no warnings

but not:

    my $x = undef;
    my %h = %$x;
    my @k = keys(%h);
2024-06-29 04:13:57 -04:00
Richard Hansen
de39ac7bcc Fix undef warning when daemon is unset
This fixes a bug introduced in commit
88eb2ed4fe
2024-06-29 03:10:51 -04:00
Richard Hansen
ae7a9dce2a Fix variable name typo
This fixes a bug introduced in commit
b154d8ef98
2024-06-29 03:10:51 -04:00
Richard Hansen
76900c708c
Merge pull request #693 from rhansen/vars
Variable fixes: required vs. optional, default values
2024-06-28 16:18:26 -04:00
Richard Hansen
49f5551764 Add variable default value tests 2024-06-28 15:53:40 -04:00
Richard Hansen
eab72ef6d7 Require a defined value if the variable is required 2024-06-28 15:53:40 -04:00
Richard Hansen
399f8a8b32 Adjust variable defaults to pass validity checks
Change the default of every variable whose default (non-`undef`)
doesn't pass through `check_value` unmodified.
2024-06-28 15:53:40 -04:00
Richard Hansen
88eb2ed4fe Use undef as the default of truly optional variables 2024-06-28 15:53:39 -04:00
Richard Hansen
ba6a279186 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.
2024-06-28 15:53:06 -04:00
Richard Hansen
b8a0a26441 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.
2024-06-28 15:50:35 -04:00
Richard Hansen
be9e305e73 Fix definition of wtime variable 2024-06-28 15:28:44 -04:00
Richard Hansen
e32b9436fb nfsn: Fix type of min-interval variable 2024-06-28 15:28:44 -04:00
Richard Hansen
66bb07450f nfsn: Fix spelling of min-interval variable name 2024-06-28 15:28:44 -04:00
Richard Hansen
5757f7e07d Restore accidentally deleted --fw command-line argument
This was mistakenly deleted in commit
908b728503.
2024-06-27 00:10:35 -04:00
Richard Hansen
f4c4d974d2
Merge pull request #692 from rhansen/infomaniak
`infomaniak` fixes
2024-06-25 22:56:44 -04:00
Richard Hansen
948567c456 infomaniak: Unrequire server setting
The `infomaniak` protocol doesn't use `server`.
2024-06-25 22:53:23 -04:00
Richard Hansen
9ba583175a infomaniak: Fail if the HTTP status code is not 2xx 2024-06-25 22:53:23 -04:00
Richard Hansen
7d99da77cc header_ok: Fail if the reply is falsy 2024-06-25 22:53:23 -04:00
Richard Hansen
8e24c92b1e infomaniak: Fix response parsing 2024-06-25 22:53:23 -04:00
Richard Hansen
d2f0e042f4 infomaniak: Invert condition to improve readability 2024-06-25 22:47:26 -04:00
Richard Hansen
29e86d9a91 infomaniak: Rename variable for readability 2024-06-25 22:47:25 -04:00
Richard Hansen
a5dedeed3c infomaniak: Fix geturl call
* Pass login and password via `login` and `password` options to
    avoid issues with escaping special characters.
  * Don't attempt twice -- if the first attempt fails, the second will
    almost certainly fail as well.  (The two attempted URLs were
    equivalent, differing only in how the login and password were
    passed.)
2024-06-25 22:47:25 -04:00
Richard Hansen
ac9f937c88 infomaniak: Delete unnecessary defined checks
`undef` is falsy so there's no need to check whether the value is
defined.
2024-06-25 22:46:00 -04:00
Richard Hansen
bab9d9483e infomaniak: Move variable declaration to definition 2024-06-25 21:55:46 -04:00
Richard Hansen
134e47b61d infomaniak: Delete unnecessary newlines 2024-06-25 21:50:51 -04:00
Richard Hansen
e0d9bcc36d
Merge pull request #691 from rhansen/fixes
Fix `regfishde` IPv6 support, repeated `infomaniak` force updates, and other minor issues
2024-06-25 03:00:20 -04:00
Richard Hansen
9d49a33ac6 regfishde: Fix IPv6 support 2024-06-25 02:58:09 -04:00
Richard Hansen
0cde2e3f96 infomaniak: Fix mtime update
`mtime` should always be updated whenever the IP address is updated,
otherwise ddclient will keep force updating over and over.
2024-06-25 02:57:42 -04:00
Richard Hansen
61577d29ae njalla: Fix configuration change during update
If the user enabled `quietreply`, it should not become false after the
first update.

Users might not notice a problem because I think ddclient re-reads the
config file before every check.
2024-06-25 02:52:22 -04:00
Richard Hansen
32bf975bfa Fix call to wrong function name with bad --usev6 2024-06-25 02:52:22 -04:00
Richard Hansen
99dfd7f84d Don't assume that --use is defined 2024-06-25 02:51:58 -04:00
Richard Hansen
b154d8ef98 Fix missing v4, v6 variants in recap update
Fixes an oversight when IPv6 support was added.
2024-06-25 02:48:51 -04:00
Richard Hansen
dafde8becb Fix erroneous backupmx recap check for dyndns1, dyndns2 2024-06-25 01:38:43 -04:00
Richard Hansen
7ac6eda7cc Fix missing local use* override in --query 2024-06-25 01:37:47 -04:00
Richard Hansen
c7c8c5f097 Fix usev4, usev6 output for --query 2024-06-25 01:32:27 -04:00
Richard Hansen
27b50a3b93 Fix --usev4=cisco, --usev4=cisco-asa warning messages 2024-06-25 01:29:29 -04:00
Richard Hansen
e1e8d5711a Fix get_ip argument in --query when testing --fw 2024-06-25 01:20:30 -04:00
Richard Hansen
b363fb48a5 Fix string equality check
The `$proto` interpolation wasn't quoted with `\Q` and `\E`, so
metacharacters in `$proto` could break the matching.  Switch from a
regex to an expression to fix the equality check and improve
readability.
2024-06-25 00:50:22 -04:00
Richard Hansen
61539105bd
Merge pull request #689 from rhansen/readability
Readability improvements
2024-06-22 17:32:27 -04:00
Richard Hansen
1be8438c70 Rename updateable to force_update for readability 2024-06-22 03:07:49 -04:00
Richard Hansen
b426b370fd Rename %cache to %recap for readability 2024-06-22 02:48:03 -04:00
Richard Hansen
49bd1b7347 Rename %services to %protocols for consistency 2024-06-22 02:42:51 -04:00
Richard Hansen
1718ceab70 Add comments documenting the cached variables 2024-06-22 02:35:01 -04:00
Richard Hansen
3d73e7c231 Add TODO comments for confusing bits of code 2024-06-22 02:30:01 -04:00
Richard Hansen
9a5500a667 Improve readability via minor logic tweaks
Change some code that is unnecessarily complicated or otherwise not
the right tool for the job to improve readability.
2024-06-22 02:30:01 -04:00
Richard Hansen
ab60675660 Improve readability of cache var update logic 2024-06-22 02:30:01 -04:00
Richard Hansen
0d712f7bbc Improve readability of wantip, wantipv4, wantipv6 fallback 2024-06-22 02:30:01 -04:00
Richard Hansen
5c38af2ed5 Improve readability by moving code out of unnecessary blocks
Invert conditions and move out unnecessary blocks to reduce
indentation and make it easier to see control flow.
2024-06-22 02:28:12 -04:00
Richard Hansen
160344514f Improve readability by simplifying if conditions 2024-06-22 02:27:44 -04:00
Richard Hansen
288a30ab1e Whitespace fixes 2024-06-22 01:38:28 -04:00
Richard Hansen
afa6db8129
Merge pull request #687 from rhansen/ci
ci: Switch from RedHat UBI to AlmaLinux
2024-06-06 20:22:47 -04:00
Richard Hansen
0c42478ea7 ci: Switch from RedHat UBI to AlmaLinux 2024-06-06 20:16:07 -04:00
Richard Hansen
1ee64537df
Merge pull request #686 from rhansen/header_ok
Minor improvements to `header_ok` utility function
2024-06-06 19:40:44 -04:00
Richard Hansen
2d4a93d5e7 header_ok: Fix typo(?) in HTTP response regular expression 2024-06-06 19:34:06 -04:00
Richard Hansen
211d59fccc header_ok: Log all non-2xx HTTP status codes 2024-06-06 19:34:06 -04:00
Richard Hansen
7fe7fd0e18 header_ok: Refactor for readability 2024-06-06 19:34:06 -04:00
Richard Hansen
adbac91be7 header_ok: Only keep first line of argument
This allows callers to pass the entire response without generating
overly long error messages.
2024-06-06 19:34:06 -04:00
Richard Hansen
b58a10b3e3 header_ok: Add unit tests 2024-06-06 19:34:06 -04:00
Richard Hansen
a486d4f976
Merge pull request #685 from rhansen/module-load
Improve loading of optional SHA1 and JSON modules
2024-06-06 19:10:21 -04:00
Richard Hansen
bb658d763a Simplify loading of JSON::PP 2024-06-06 19:08:15 -04:00
Richard Hansen
1401ff4aea Only attempt to load Digest::SHA
`Digest::SHA` has been a core module for a long time, and
`Digest::SHA1` has not been updated in a long time.
2024-06-06 19:07:25 -04:00
Richard Hansen
1e1e100d7f Prefer Digest::SHA over Digest::SHA1
`Digest::SHA` is a core module; `Digest::SHA1` is not.
2024-06-04 18:44:25 -04:00
Richard Hansen
a0240345bf Use Module->import(...) instead of import(Module, ...)
This matches the documentation of the `use` statement.
2024-06-04 18:44:25 -04:00
Richard Hansen
11be757d54
Merge pull request #683 from rhansen/curl
curl execution improvements
2024-06-03 03:27:15 -04:00
Richard Hansen
1c1642acfd configure.ac: Allow users to specify path to curl 2024-06-03 03:13:05 -04:00
Richard Hansen
31dbd8e4ed geturl: Set raw (binary) mode when reading from curl 2024-06-03 03:13:05 -04:00
Richard Hansen
8e901c3db6 geturl: Avoid the shell when invoking curl 2024-06-02 17:00:05 -04:00
Richard Hansen
09d8d0426e geturl: Don't suppress curl's STDERR
This makes it easier for users to troubleshoot problems.
2024-06-02 17:00:05 -04:00
Richard Hansen
09ce262c82
Merge pull request #674 from jortkoopmans/bugfix/673_Fix_DnsExit_subdomain
Fix DNSExit provider when provided with a zone and a non-identical hostname
2024-06-02 16:58:43 -04:00
jortkoopmans
73a67b728d dnsexit2: Move body of for loop to a separate function
For improved readability.
2024-06-02 16:58:00 -04:00
Richard Hansen
11d0c84639 dnsexit2: Don't skip remaining hosts on connect error or non-2xx
A non-2xx status code might be host-specific, so ddclient should
continue with the next host.  We could skip the remaining hosts if
there is a connection failure, but it doesn't hurt to retry.
2024-06-02 16:58:00 -04:00
jortkoopmans
216741c9ce dnsexit2: Fix when provided with a zone and a non-identical hostname
Trim the zone from the hostname in the request to fix issue.
2024-06-02 16:58:00 -04:00
jortkoopmans
ec2d5f7f69 dnsexit2: Add tests
Needs LWP::UserAgent.
2024-06-02 16:58:00 -04:00
Richard Hansen
282bb01e17 Bump version to v3.12.0~alpha
Enough has changed to warrant a minor revision bump.
2024-06-01 03:49:16 -04:00
Richard Hansen
a0e119c2f2
Merge pull request #681 from rhansen/group_hosts_by
group_hosts_by: Add IPv6 and undef/unset support
2024-06-01 03:09:18 -04:00
Richard Hansen
e60e6e804b group_hosts_by: Use Data::Dumper to make the group signature
This is a bit more robust than manually making the group signature
because it gracefully handles corner cases such as `undef`.
2024-06-01 03:06:06 -04:00
Richard Hansen
f4802fc534 Fix group_hosts_by call for IPv6-enabled services 2024-06-01 03:05:36 -04:00
Richard Hansen
343fcff625 group_hosts_by: Add support for wantipv4, wantipv6 2024-06-01 03:05:36 -04:00
Richard Hansen
ce0a362fd0 group_hosts_by: Add tests 2024-06-01 03:05:26 -04:00
Richard Hansen
ddb04075be
Merge pull request #680 from rhansen/dnsexit2
dnsexit2: Fix parsing of JSON response
2024-05-31 03:27:34 -04:00
Richard Hansen
f976b771d4 dnsexit2: Fix logging of erroneous response body 2024-05-30 18:29:38 -04:00
Richard Hansen
f7f4856b93 dnsexit2: Combine related log messages 2024-05-30 18:28:57 -04:00
Richard Hansen
24a22092ca dnsexit2: Don't croak if JSON decoding fails 2024-05-30 18:22:59 -04:00
Richard Hansen
d28c8ea7ad dnsexit2: Delete unnecessary debug messages 2024-05-30 17:56:51 -04:00
Richard Hansen
7b95b379aa dnsexit2: Fix extraction and processing of JSON response body 2024-05-30 17:52:12 -04:00
Richard Hansen
86ec02a9b6
Merge pull request #679 from rhansen/dnsexit2
dnsexit2: Minor fixes and improvements
2024-05-30 17:22:52 -04:00
Richard Hansen
2a47b17541 dnsexit2: Include the unexpected status in the error message 2024-05-30 16:26:44 -04:00
Richard Hansen
d8a1449a19 dnsexit2: Fix error message format string
This fixes a bug introduced in commit
2bf6d348b0.
2024-05-30 16:25:25 -04:00
Richard Hansen
6e5e2ab63f dnsexit2: Remove https:// from update service URL
This allows the `ssl` setting to control TLS vs. plain HTTP, and makes
it possible to create a compatible service that doesn't use TLS (e.g.,
for testing).
2024-05-30 16:21:25 -04:00
Richard Hansen
eebb1b8a47 dnsexit2: Delete redundant status-ipv* assignments 2024-05-30 16:19:41 -04:00
Richard Hansen
b3951e407a
Merge pull request #678 from rhansen/dnsexit2
dnsexit2: Code health improvements
2024-05-30 05:02:11 -04:00
Richard Hansen
3c84f7a1b5 dnsexit2: Delete unnecessary debug messages 2024-05-30 04:49:46 -04:00
Richard Hansen
5b7400ae7d dnsexit2: Normalize the zone up front 2024-05-30 04:48:44 -04:00
Richard Hansen
46bca54393 dnsexit2: Fix string interpolation 2024-05-30 04:04:19 -04:00
Richard Hansen
da9f39917f dnsexit2: Inline some unnecessary variables 2024-05-29 18:29:09 -04:00
Richard Hansen
6c89eaf4ac dnsexit2: Build updates array directly, not hash to array
to improve readability, and to make it easier to use
`group_hosts_by()` in the future to update multiple hosts at the same
time.
2024-05-29 18:25:24 -04:00
Richard Hansen
2bf6d348b0 dnsexit2: Reuse the $url variable 2024-05-29 18:25:24 -04:00
Richard Hansen
4804e15c12 dnsexit2: Add final comma after last list item
for consistency, and to avoid bugs if additional items are added or
the items are reordered.
2024-05-29 18:25:24 -04:00
Richard Hansen
7c4fe28bab dnsexit2: Simplify IP version loop 2024-05-29 17:57:20 -04:00
Richard Hansen
40d1bc8e51 dnsexit2: Clarify comments 2024-05-29 17:51:54 -04:00
Richard Hansen
18007dda8a dnsexit2: Delete unnecessary comments
Comments should only be used if the code is doing something
subtle/tricky/non-obvious/unusual, otherwise they're distracting and
might get out of sync with the code (in which case it becomes
difficult to tell if it's the comment or the code that's wrong).  If
the code is difficult to understand without comments but is doing
something ordinary, then the code needs to be modified to improve
readability.
2024-05-29 17:51:54 -04:00
Richard Hansen
61d34a9157 dnsexit2: Move code meanings closer to where it is used 2024-05-29 17:42:35 -04:00
Richard Hansen
df81075e49 dnsexit2: Rename variable to avoid confusion 2024-05-29 17:41:34 -04:00
Richard Hansen
ed7f4a68a4 dnsexit2: Rewrite circuitous variable assignments 2024-05-29 17:34:51 -04:00
Richard Hansen
3e91fd02bf dnsexit2: Invert conditions to improve readability
Instead of:

    if ($success1) {
        if ($success2) {
            if ($success3) {
                # yay
            } else {
                # fail
            }
        } else {
            # fail
        }
    } else {
        # fail
    }

do:

    if (!$success1) {
        # fail
    }
    if (!$success2) {
        # fail
    }
    if (!$success3) {
        # fail
    }
    # yay
2024-05-29 17:21:39 -04:00
Richard Hansen
9b1a785c6d dnsexit2: Don't repeat the same success message 2024-05-29 17:15:24 -04:00
Richard Hansen
3a5e86b4d2 dnsexit2: Convert string interpolation to sprintf format specifier
Rationale:
  * For consistency.
  * It's generally not a good idea to mix interpolation with `sprintf`
    because the interpolated string itself might coincidentally (or
    maliciously) contain format specifiers.
2024-05-29 17:10:06 -04:00
Richard Hansen
6cdf5da9f4 dnsexit2: Rename variable for brevity 2024-05-29 17:05:54 -04:00
Richard Hansen
63989d96fb dnsexit2: Move variable declaration to loop scope 2024-05-29 17:02:46 -04:00
Richard Hansen
0040fc9608 dnsexit2: Whitespace fixes 2024-05-29 17:02:46 -04:00
Richard Hansen
a91ca7a199 s/foreach/for/g for consistency 2024-05-29 16:48:00 -04:00
Richard Hansen
d1068bede1
Merge pull request #654 from TV4Fun/emailonly
Add 'emailonly' client to send status emails without needing a DDNS service
2024-05-25 15:13:36 -04:00
Joel Croteau
61b979c49e New 'emailonly' protocol that simply sends an email on IP change
This adds a protocol to email IP address changes without needing a
dynamic DNS service.  This is useful if you don't use a DDNS service
but want to be notified when the IP of a machine changes.
2024-05-25 00:38:10 -04:00
Richard Hansen
d8a9d9d089 Add support for infinite duration 2024-05-25 00:38:10 -04:00
Richard Hansen
65fb4db6cd
Merge pull request #676 from rhansen/logging
Various minor logging improvements
2024-05-23 02:07:40 -04:00
Richard Hansen
9c6e5fdda4 Output a | character in log message continuation lines
This makes it easier to tell where multi-line log messages begin and
end.
2024-05-23 02:04:29 -04:00
Richard Hansen
ff39ce3874 Don't use sprintf if there is only one argument
This avoids problems when logging a string that might have
metacharacters.
2024-05-23 02:04:19 -04:00
Richard Hansen
bcd57b486b Always log to STDERR, even for debug, info, etc.
Rationale:
  * Logging to STDERR enables separation of processable output (e.g.,
    `--version` or `--help`) and ephemeral status/error messages.
  * A single file descriptor for all log messages makes it easier for
    users to capture all log messages.
  * Consistency: it's what most utilities do.
2024-05-23 02:04:19 -04:00
Richard Hansen
d6693e0175 Use the de facto standard signature separator instead of "regards" 2024-05-23 01:57:12 -04:00
Richard Hansen
065b227711 logmsg: New low-level logging interface 2024-05-23 01:57:12 -04:00
Richard Hansen
f9dafa35a1 Rename $msgs to $emailbody to improve readability 2024-05-23 01:54:09 -04:00
Richard Hansen
66ec57a902
Merge pull request #670 from rhansen/status
Fix handling of legacy `status` with IPv6-aware protocols
2024-05-23 01:53:46 -04:00
Richard Hansen
8ef7b13cb0 Don't set legacy status in protocols if IPv6-aware
ddclient infrastructure will update the legacy `status` variable if
necessary.
2024-05-20 01:35:21 -04:00
Richard Hansen
ba18535c51 Fix broken legacy status handling
`$config{$h}{'status'}` was always initialized to a non-`undef` value,
so the `//` fallbacks never did anything.  Instead, any protocol that
does not explicitly update the legacy `status` variable (such as
`godaddy`) would always appear to have failed even if it had
succeeded.

Change the `status*` variables to `undef` by default, and only set
them when an attempt is made so that the legacy `//` fallback works as
expected.
2024-05-20 01:33:15 -04:00
Richard Hansen
f212613526 godaddy: Fix status field name
This shouldn't matter in practice because the `status-ipv$ipversion`
field is initialized to a non-`good` value so failing to set it to
`bad` doesn't turn it `good`, but it improves readability.
2024-05-20 01:30:33 -04:00
Richard Hansen
c60aa225a1 godaddy: Rename $status to $code 2024-05-20 01:30:33 -04:00
Richard Hansen
dc92f16eb2 dnsexit2: Update new status-ipv* vars, not legacy status
The `dnsexit2` protocol reads the IP addresses from the new `ipv4` and
`ipv6` variables, so it should update the `status-ipv4` and
`status-ipv6` variables.
2024-05-20 01:30:33 -04:00
Richard Hansen
baec50d134 1984: Update cached status and IP on success 2024-05-20 01:30:33 -04:00
Richard Hansen
8b0c038d63 1984: Fix missing next on failure 2024-05-20 01:30:33 -04:00
Richard Hansen
9573051e3e njalla: Update cached status and IP on success 2024-05-20 01:30:33 -04:00
Richard Hansen
8269021d7b
Merge pull request #672 from rhansen/changelog
Update changelog
2024-05-20 01:29:25 -04:00
Richard Hansen
0d85dfd044 Update changelog 2024-05-20 01:21:21 -04:00
Richard Hansen
6320e6c395 Don't require login and password to be set
Not all services use them.

This change should have been included with commit
27b5c535bc.
2024-05-20 00:13:37 -04:00
Richard Hansen
7b18e4bce4
Merge pull request #675 from rhansen/ci
CI improvements
2024-05-19 20:31:34 -04:00
Richard Hansen
86031edd2d ci: Disable fail-fast 2024-05-19 20:19:23 -04:00
Richard Hansen
6d2dba3aee ci: Upload distribution tarball as artifact
This makes it easier for users to try a fix.
2024-05-19 20:19:23 -04:00
Richard Hansen
f2c9158da4 ci: Test all supported versions of RedHat UBI 2024-05-19 20:19:23 -04:00
Richard Hansen
dd7a8aeb10 ci: Bump actions/checkout to v4 2024-05-19 20:19:23 -04:00
Richard Hansen
08c914c660 ci: Combine RedHat UBI with Fedora 2024-05-19 20:19:23 -04:00
Richard Hansen
c0ba4b7d91 ci: Test all supported Fedora versions and rawhide 2024-05-19 19:50:31 -04:00
Richard Hansen
b32619892f ci: Delete commented-out centos 2024-05-19 18:18:47 -04:00
Richard Hansen
545d5e10d8
Merge pull request #671 from rhansen/vars
Clean up service variable definitions
2024-05-19 02:45:17 -04:00
Richard Hansen
23b368f5ff Add missing final comma 2024-05-19 02:18:55 -04:00
Richard Hansen
27b5c535bc Use undef to disable required variables 2024-05-19 02:18:55 -04:00
Richard Hansen
4d1b3439ea Use service-common-defaults variables
This avoids a lot of duplication and improves readability by making it
easier to see service-specific variables.
2024-05-19 01:51:06 -04:00
Richard Hansen
6da30367d0 Inline unnecessary *-common-defaults variable definitions 2024-05-19 01:49:48 -04:00
Richard Hansen
5e3e10d32e Replace unnecessary merge function with hash initializers 2024-05-19 01:49:48 -04:00
Richard Hansen
52864f2bb1 Delete redundant variable definitions 2024-05-19 01:49:45 -04:00
Richard Hansen
58152b03de
Merge pull request #667 from rhansen/scalar
Fix "Scalar value better written as" warning
2024-05-18 17:22:44 -04:00
Richard Hansen
03ad24829c Fix "Scalar value better written as" warning
Also some readability improvements.
2024-05-18 17:21:20 -04:00
Richard Hansen
af50f7f69d
Merge pull request #664 from rhansen/cisco
Move `--use=cisco` and `--use=cisco-asa` to `%builtinfw`
2024-05-18 17:20:48 -04:00
Richard Hansen
6b7bf29e56 Move --use=cisco and --use=cisco-asa to %builtinfw
This simplifies the code and will make it easier to remove support for
these devices in the future.
2024-05-14 22:18:59 -04:00
Richard Hansen
d02a9cf6db Add infrastructure for custom logic in a %builtinfw entry 2024-05-14 22:18:59 -04:00
Richard Hansen
ee5bb2de90 Check, don't assume, that --use* names a firewall 2024-05-14 22:18:59 -04:00
Richard Hansen
474cc76587 Enable --usev4=cisco and --usev4=cisco-asa
These were implemented, but accidentally(?) left out of
`%ipv4_strategies` which prevented their use.
2024-05-14 22:18:59 -04:00
Richard Hansen
e2919873ba
Merge pull request #669 from rhansen/systemd
systemd.service unit file improvements
2024-05-14 22:16:48 -04:00
Richard Hansen
21de3cbc96 systemd: Make it easier to override the daemon interval 2024-05-14 22:12:36 -04:00
Richard Hansen
509ea8745a systemd: Set Restart=on-failure 2024-05-14 22:12:36 -04:00
Richard Hansen
c0a1431f78 systemd: Use Type=exec instead of fork
When forking, ddclient redirects STDERR and STDOUT to `/dev/null`,
which prevents useful information from appearing in the systemd
journal (`journalctl`).
2024-05-14 22:12:36 -04:00
Richard Hansen
48daf8a5d7
Merge pull request #668 from rhansen/logging
Log message improvements
2024-05-14 22:11:59 -04:00
Richard Hansen
5cad38a047 Don't attempt to read file if open fails 2024-05-14 22:00:12 -04:00
Richard Hansen
2eacc71acc Logging improvements
* Consistently use logging functions instead of `print`
  * Wording/formatting fixes
  * Use `info(...)` instead of `verbose('VERBOSE:', ...)`
2024-05-14 22:00:12 -04:00
Richard Hansen
50b7e3d94b
Merge pull request #666 from rhansen/retry
`--retry` improvements
2024-05-14 21:55:54 -04:00
Richard Hansen
066b19af8f Error out if --daemon and --retry are both specified 2024-05-14 21:55:12 -04:00
Richard Hansen
2764cd8a10 Clarify what --retry does 2024-05-14 21:55:12 -04:00
Richard Hansen
498df75790 Fix "no hosts to update" warning condition 2024-05-14 21:55:03 -04:00
Richard Hansen
542bb28a13 Consistently use --arg instead of -arg 2024-05-14 18:00:14 -04:00
Richard Hansen
8ac575125b
Merge pull request #665 from rhansen/usage
Enable `--use=disabled`; more `--help` usage improvements
2024-05-13 19:24:50 -04:00
Richard Hansen
12222ff912 Clarify interaction between --use, --usev4, and --usev6 2024-05-13 18:53:19 -04:00
Richard Hansen
e35be25010 Reorder --help for --usev4 and --usev6 for readability
and for consistency with `--use`.
2024-05-13 18:53:19 -04:00
Richard Hansen
05304622ea Add context to --use deprecation notices in --help 2024-05-13 18:52:22 -04:00
Richard Hansen
a911f2bc0e Include --use=disabled and --use=no in --help usage 2024-05-13 18:40:05 -04:00
Richard Hansen
16fd4d948d Enable --use=disabled
It's unclear why this entry did not exist before now.
2024-05-13 18:37:33 -04:00
Richard Hansen
07c4e4ad4c
Merge pull request #639 from rhansen/version
User-friendly pre-release version strings
2024-05-12 16:51:49 -04:00
Richard Hansen
dfb2196499 Translate Perl version string to user-friendly version string
Perl version strings are flawed in a few ways.  Convert them to
user-friendly strings when printed so that Git tags and tarball names
are easier for downstream distributions to work with.
2024-05-12 16:43:43 -04:00
Richard Hansen
0806363b57 Tell Autoconf to get the version from ddclient.in
This avoids the need to maintain the same version string in two
different places.
2024-05-12 16:43:43 -04:00
Richard Hansen
c9cec591f0 Add short option to --version argument
Passing `--version=short` simply prints the version and exits.  This
will make it possible for a future commit to change `configure.ac` to
extract the version string from `ddclient.in` to avoid maintaining the
same version string in two places.
2024-05-12 16:43:43 -04:00
Richard Hansen
5eb6a6d755
Merge pull request #662 from rhansen/skip
Distinguish unset `--*-skip` settings from set to the empty string
2024-05-12 16:03:28 -04:00
Richard Hansen
58d7be4e83 Distinguish unset --*-skip settings from set to the empty string
This prevents the `%builtinweb` or `%builtinfw` skip defaults from
overriding a user's explicitly empty `--web-skip=` or `--fw-skip=`
setting.

This is technically a backwards-incompatible change: Any config that
explicitly sets `--web-skip` or `--fw-skip` to the empty string but
depends on the built-in skip behavior will fail.  This is unlikely to
affect many (if any) users; compatibility concerns are believed to be
far less significant than the potential need to turn off the built-in
skip.
2024-05-12 15:55:28 -04:00
Richard Hansen
fe06a19742
Merge pull request #661 from rhansen/ssl-validate
Fix misspelled `*-ssl-validate` option names
2024-05-12 03:37:13 -04:00
Richard Hansen
281b7307a8 Fix misspelled *-ssl-validate option names
There is no `ssl-validate` option, and there never has been.
2024-05-10 16:54:40 -04:00
Richard Hansen
fedf0cbf40 Update ddclient::Test::Fake::HTTPD 2024-05-09 22:32:28 -04:00
Richard Hansen
f6f19c962e
Merge pull request #660 from rhansen/logs
Improve log messages
2024-05-07 23:29:30 -04:00
Richard Hansen
d525e28c20 Show original user input in debug message
Also add comments explaining the purpose of the lines, because it's
not immediately clear.
2024-05-07 23:04:20 -04:00
Richard Hansen
b7dd590300 Fix misleading, unclear, redundant, and unnecessary warnings 2024-05-07 23:04:20 -04:00
Richard Hansen
57f15bcb97 Don't modify $usev6 to avoid misleading log messages 2024-05-07 23:04:20 -04:00
Richard Hansen
01d1d5e142 Change t/geturl_connectivity.pl to handwritten
Commit a9c1e545fb removed the
`configure.ac` substitution, so the test no longer needs to be
generated.
2024-05-07 22:39:17 -04:00
Richard Hansen
97397db294
Merge pull request #659 from rhansen/usage
Improvements to `--help` usage output
2024-05-06 23:58:01 -04:00
Richard Hansen
908b728503 Refine --help usage for --use* strategies 2024-05-06 00:21:13 -04:00
Richard Hansen
09b42a78bd Use --arg instead of -arg or arg in --help usage
`--arg` is preferred over `-arg` because the broader convention is to
use double hyphens for long option names.  Perl accepts either.

`--arg` is preferred over `arg` to avoid confusion between `--use=ip`
and `--ip` and similar option pairs.
2024-05-06 00:21:13 -04:00
Richard Hansen
6ac1ee45b0 Consistently use -arg=val in --help usage 2024-05-06 00:21:13 -04:00
Richard Hansen
fc4daae0cd Consistently use | in placeholders for --help usage 2024-05-06 00:21:12 -04:00
Richard Hansen
77c9cb5512 Consistently use < and > for placeholders in --help usage 2024-05-06 00:21:12 -04:00
Richard Hansen
dac72a344c Remove unimplemented --usev* strategies from --help usage
The `ciscov4`, `ciscov6`, `cisco-asav4`, and `cisco-asav6` strategies
were never implemented, and it doesn't make sense to implement them
because the `v4` and `v6` variants don't follow the pattern
established by the `%builtinfw` strategies.

The `%builtinfw` strategies were never implemented for `--usev6`.
2024-05-06 00:21:12 -04:00
Richard Hansen
640a6f08d7 Fix indentation in --help output 2024-05-06 00:21:12 -04:00
Lenard Hess
9885d55a37
Merge pull request #646 from toniwiki/fix-dondominio-response-treatment
Fix DonDominio service response treatment
2024-03-28 23:25:29 +01:00
Toni Wiki
e6e0072e8d dondominio: Fix service response treatment 2024-03-28 12:56:09 +01:00
Lenard Hess
981dd5f333 Fixed _env suffixed config variables causing errors in check_value() 2024-03-19 22:03:20 +01:00
Lenard Hess
09ee38f694
Merge pull request #638 from rhansen/testdep
Tell make that the tests depend on `ddclient`
2024-03-19 22:03:06 +01:00
Lenard Hess
b803b308fa
Merge pull request #636 from ddclient/feature_gandi_pat_support
Gandi: Personal access token support
2024-03-19 21:58:31 +01:00
Lenard Hess
12e9a7c47b gandi: Added support for personal access tokens 2024-03-19 21:48:30 +01:00
Lenard Hess
9b7714c39c Revert "gandi: Changed authorization to personal access token"
This reverts commit a57cb3b9ff.

See https://github.com/ddclient/ddclient/issues/602 for more info.
2024-03-19 21:48:30 +01:00
Richard Hansen
5aa6530c84 Tell make that the tests depend on ddclient
This ensures that `ddclient` is rebuilt before running tests if
`ddclient.in` changes.
2024-03-06 23:32:11 -08:00
Lenard Hess
9c3fc230ba
Merge pull request #634 from domdomegg/patch-1
docs: Remove fork notice in README
2024-02-28 08:31:34 +01:00
Adam Jones
9ba82e5472
docs: Remove fork notice in README
This no longer makes sense, given this fork then became the upstream repo.
2024-02-28 00:11:20 +00:00
Lenard Hess
0be0cc6953
Merge pull request #627 from etkal/Fix-porkbun-root-domain-update
porkbun code not handling root domain
2024-02-25 16:19:06 +01:00
Lenard Hess
28bb7d076a
Merge pull request #628 from ikruglov/fix-googledomains-warning
fix warning "Argument "googledomains" isnt numeric in numeric eq (==)
2024-02-25 16:10:15 +01:00
Lenard Hess
eb7e9c5e2e
Merge pull request #629 from code-chicken/patch-1
Fix for getting url for keysystems
2024-02-25 16:07:58 +01:00
Rüdiger Hahn
8246c65ba8
Fix for getting url for keysystems 2024-02-14 22:36:48 +01:00
Ivan Kruglov
e47e63d91e fix warning "Argument "googledomains" isnt numeric in numeric eq (==) at /usr/sbin/ddclient line 2736. 2024-02-13 18:16:38 +01:00
Lenard Hess
a57cb3b9ff gandi: Changed authorization to personal access token
The previous API key mechanism has been deprecated.
See https://github.com/ddclient/ddclient/issues/602 for more.
2024-02-10 12:30:46 +01:00
Erik Tkal
4e33dd754f porkbun code not handling root domain 2024-02-05 18:21:58 -05:00
Lenard Hess
5b104ad116 Switch the defaults for webv4 and webv6 to dyndns
The googledomains option (https://domains.google.com/checkip) is soon to be
deprecated by Google (see https://github.com/ddclient/ddclient/issues/622).
2024-02-04 11:26:51 +01:00
Lenard Hess
34cc8fc70c
Merge pull request #624 from ddclient/feature_porkbun_subdomains
Feature porkbun subdomains
2024-02-04 10:34:51 +01:00
Lenard Hess
330ddc6bd2 porkbun: Moved subdomain processing out of IPv4/6 loop
The domain/subdomain processing is the same for IPv4 and IPv6, no need to repeat it
2024-02-03 16:18:55 +01:00
Lenard Hess
ae7f92772b porkbun: Updated documentation and config example 2024-02-03 16:13:13 +01:00
Lenard Hess
5e7609ea2a porkbun: Added 'root-domain' config option
Porkbun API requires separation of the root domain and subdomains.
Previously ddclient only supported one layer of subdomain or the root domain
by selecting between the two with the boolean 'on-root-domain'.

This change now allows to specify the root domain via the 'root-domain' parameter
ddclient will then split the host domain into root and subdomain
2024-02-03 13:57:09 +01:00
Lenard Hess
f1c77a06fb Added missing exit to -version argument 2024-02-03 13:50:34 +01:00
Lenard Hess
bab66330ca Added -version argument 2024-02-03 13:31:26 +01:00
Awalon
f5a1a906d1 Pull request #560: Updated GoDaddy to new IPv4/IPv6 logic
Changes by Lenard Hess based on Awalon's pull request:
- Rebased to master
- Removed use=disabled addition from this commit
2024-01-28 16:40:18 +01:00
Lenard Hess
fc4f87b33e
Merge pull request #616 from retep/retep-patch-1-1
Update Mythic Beasts mythicdyn module in ddclient.in
2024-01-14 14:09:47 +01:00
Lenard Hess
95ac201b4b
Merge pull request #603 from indrajitr/noip-v4-v6
noip: Adjust script to support simultaneous IPv4 and IPv6 updates
2024-01-14 13:59:10 +01:00
Marco Emilio "sphakka" Poleggi
dc84a74c7e fix(curl, doc): enable HTTP 30x redirections in curl requests. Fixes Issue #589
- curl: enable a configurable number of redirections (-redirects=<max>) to
  follow when making HTTP(S) requests.
- docs: update Infomaniak example to prefer 'dyndns2' instead of obsolete
  protocol.

Signed-off-by: Marco Emilio "sphakka" Poleggi <7766137+sphakka@users.noreply.github.com>
2024-01-13 15:53:56 +01:00
Lenard Hess
203fe47aa1
Merge pull request #604 from indrajitr/nsupdate-v4-v6
nsupdate: Adjust script to support simultaneous IPv4 and IPv6 updates
2024-01-13 15:04:47 +01:00
PeterF
6994b05ab6
Update ddclient.in
The mythicdyn module is modified so that it will update either or both V4 and/or V6 addresses depending upon which specific address parameters have been defined in the config file. The module examines the wantipv4 and wantipv6 parameters.
If required, both addresses will be updated in a single invocation.
2024-01-11 16:01:11 +00:00
Lenard Hess
ad854ab716 Fixed legacy providers not supporting usev6 2024-01-06 18:03:26 +01:00
Lenard Hess
05c18fce67 README: Reformatted the known issues a bit 2024-01-06 17:03:14 +01:00
Lenard Hess
256cd89bb1 README: Added some known issues 2024-01-06 16:57:10 +01:00
Lenard Hess
3c522a7aa2 Config parsing: Allow trailing comments after a backslash in the config
The cloudflare documentation example had lines with a comment after a
backslash. This actually did not work in the parser until now.

The lines in question:
	#protocol=cloudflare,        \
	#zone=domain.tld,            \
	#ttl=1,                      \
	#login=your-login-email,     \ # Only needed if you are using your global API key. If you are using an API token, set it to "token" (without double quotes).
	#password=APIKey             \ # This is either your global API key, or an API token. If you are using an API token, it must have the permissions "Zone - DNS - Edit" and "Zone - Zone - Read". The Zone resources must be "Include - All zones".
	#domain.tld,my.domain.tld
2024-01-04 18:21:48 +01:00
Matthew Ogilvie
d195bcc4b8 If present, give URL protocol precedence over other SSL settings 2024-01-04 16:25:27 +01:00
Indrajit Raychaudhuri
bfe20e75f8 nsupdate: Adjust script to support simultaneous IPv4 and IPv6 updates
Adjust `nic_nsupdate_update` to use `wantipv4` and `wantipv6` and
support simultaneous IPv4 and IPv6 updates.

Also, set proper `status-ipv4` and `status-ipv6` values after successful
update.
2023-12-02 15:38:33 -06:00
Indrajit Raychaudhuri
8c8a193a70 noip: Adjust script to support simultaneous IPv4 and IPv6 updates
Adjust `nic_noip_update` to use `wantipv4` and `wantipv6` and support
simultaneous IPv4 and IPv6 updates.

Note: Unlike `nic_dyndns2_update`, `$returnedips` actually contains
valid IPv4 and IPv6 addresses, so we can use the response to update the
status.
2023-12-02 15:35:14 -06:00
Lenard Hess
e0611ab192 Merge pull request #558 from TinfoilSubmarine/fix/gandi 2023-11-25 13:55:09 +01:00
Stewart Whitman
2ceb4a9526 Resolves #585 - inheritance for noip service 2023-11-25 13:24:44 +01:00
Lenard Hess
eec72794fd Merge pull request #593 from TinfoilSubmarine/fix/ipversion
Note: This branch has been locally rebased before merging!
2023-11-25 13:18:17 +01:00
Joel Beckmeyer
c382af56a5 don't print erroneous IP version 2023-11-25 13:07:08 +01:00
Joel Beckmeyer
846ab59e68 gandi: improve documentation 2023-11-24 15:56:37 -05:00
Joel Beckmeyer
5ec8bfe141 gandi: update logic
- allow updating IPv6/AAAA
- allow updating A and AAAA records simultaneously
- skip updating if record already has same IP
2023-11-24 15:56:37 -05:00
Lenard Hess
baa7e440ed Updated version number for v3.11.3_0 development 2023-11-23 13:08:07 +01:00
Lenard Hess
4a1b06630b Updated version number for v3.11.2 release 2023-11-23 13:06:21 +01:00
Lenard Hess
58c5e4dc3a Merge pull request #595 from ddclient/fix_legacy_caching 2023-11-23 13:00:58 +01:00
Lenard Hess
30f68e4098 docs: Added initial description on provider implementation rules 2023-11-23 13:00:06 +01:00
Lenard Hess
5d022b0520 Fixed caching for new providers with legacy 'use' parameter
When the configuration used the legacy 'use' parameter, we already
populated the new internal 'wantipv*' field alongside the legacy
'wantip' field. This allows both old and new providers to work.

The legacy providers set 'status'/'ip'.
The new providers then set 'status-ipv*'/'ipv*'.

The caching logic would look for 'status' and 'ip' when encountering a
'use' parameter in the config. We previously already changed ddclient to
set 'status' when 'status-ipv*' was set. Now we also set 'ip' from
'ipv*'. This ensures caching correctly works.
2023-11-23 13:00:06 +01:00
Lenard Hess
9145dc1bfd Merge pull request #588 from indrajitr/duckdns-update
duckdns: Adjust script to support simultaneous IPv4 and IPv6 updates
2023-11-19 20:12:26 +01:00
Indrajit Raychaudhuri
3a224b66a4 duckdns: Adjust script to support simultaneous IPv4 and IPv6 updates 2023-11-02 19:34:45 -05:00
Birger J. Nordølum
afa1275253 docs: fix typo of domeneshop 2023-10-29 13:52:54 +01:00
Lenard Hess
23bfa31ea5 Updated version number for v3.11.2_0 development 2023-10-25 21:25:43 +02:00
Lenard Hess
66af014aad Updated version number for v3.11.1 release 2023-10-25 21:22:47 +02:00
Lenard Hess
456fe79c2d Removed @PACKAGE_VERSION@ placeholder from ddclient for now.
This reverts the changes from 36744e5. This will be reimplemented once
the build process is better documented and properly implemented
by any downstream not yet using it (as of now linuxserver.io).

See https://github.com/linuxserver/docker-ddclient/issues/77
2023-10-25 21:19:18 +02:00
Lenard Hess
ea8216fae4 Updated changelog with porkbun provider fix 2023-10-25 21:17:39 +02:00
LenardHess
e2ce23ed33
Merge pull request #557 from TinfoilSubmarine/fix/porkbun
porkbun: rework logic to allow for simultaneous update of IPv4 and IPv6
2023-10-25 20:29:55 +02:00
Joel Beckmeyer
2d7610b7de porkbun: rework logic to allow for simultaneous update of IPv4 and IPv6 2023-10-21 17:52:35 -04:00
jortkoopmans
9913e0ec29 DNSExit update for ipv6.
- Support wantipv4 and wantipv6 configs automatically
- Remove manual record type setting
- Add support for hosts on your zone (subdomain)
- Update config examples
- Code/logic improvements
2023-10-21 20:36:48 +01:00
Lenard Hess
8ed2963b79 Updated version number for v3.11.1_0 development 2023-10-21 19:54:12 +02:00
Lenard Hess
17828eedf5 Updated version number for v3.11.0 release 2023-10-21 19:28:33 +02:00
Lenard Hess
39bdce9bb6 Bumped version numbers for next (pre)release 2023-10-15 16:15:54 +02:00
Lenard Hess
d4f9816a6a Finished v3.11.0_1 release 2023-10-15 13:23:22 +02:00
LenardHess
33a5c1b07d
Merge pull request #567 from tchebb/digitalocean-readme
Add DigitalOcean to README
2023-10-15 12:42:22 +02:00
Thomas Hebb
15f9472ac9 Add DigitalOcean to README
I forgot to document the new service in commit c436a34ede ("Add
support for Digital Ocean"). The changelog has since been updated to
mention it, but it's still missing from the README.
2023-09-03 21:08:28 -04:00
Reuben Thomas
ef496d108f Revert URLs to canonical repo 2023-07-19 22:27:44 +03:00
Lenard Hess
1715bd3a17 Fixed hosts trying to update if IP acquisition failed 2023-07-19 17:11:45 +03:00
Lenard Hess
d4db5cbc90 Updated changelog for v3.11.0_rc1
Note: I dropped the "DynDNS2 now uses the newer ipv4/ipv6 syntaxes", as
its not visible to users.
2023-07-19 17:11:45 +03:00
Lenard Hess
7869acb266 easydns, porkbun: Set status-ipv4 and status-ipv6 instead of status
This fixes caching issues when using the 'usev4' or 'usev6' parameters.
Without this, the "min-interval" and "warned-min-interval" limits will
not work.

For the legacy 'use' parameter, the wrapping code takes care of
translating 'status-ipv*' to 'status'.
2023-07-19 17:11:45 +03:00
Lenard Hess
17fd6ec083 Added preliminary explanation for provider functions 2023-07-19 17:11:45 +03:00
Lenard Hess
6c1f9632fa Fixed caching behaviour for new providers with legacy 'use' logic 2023-07-19 17:11:45 +03:00
Reuben Thomas
541e7f350c Update error message to reflect that curl is always used 2023-07-19 17:11:45 +03:00
Reuben Thomas
5af1550e62 README.md: update URLs to point to my fork 2023-07-19 17:11:45 +03:00
Reuben Thomas
e37cf19350 configure.ac: no longer require IO::Socket::IP or IO::Socket::SSL 2023-07-19 17:11:45 +03:00
Lenard Hess
379b1832de ddclient.in: Update Maintainers 2023-07-19 17:11:45 +03:00
Reuben Thomas
3678befe76 README.md: update and prettify list of dyn DNS providers 2023-07-19 17:11:45 +03:00
Reuben Thomas
b8bed7112f Remove defunct dnsexit protocol 2023-07-19 17:11:45 +03:00
Reuben Thomas
fbc64243f3 Note that we've added support for DNSExit API v2 2023-07-19 17:11:45 +03:00
Reuben Thomas
a9c1e545fb Require curl
Use command-line curl, and remove alternative Perl and Curl-via-Perl
implementations of network code.
2023-07-19 17:11:45 +03:00
Reuben Thomas
211404b5d1 ddclient.in: update maintainer details 2023-07-19 17:11:45 +03:00
Lenard Hess
52b5eea6f4 Implemented _env suffix for configuration
With this change, any config value may be set through an environment
variable by appending '_env' to the keyword (i.e. 'password_env' instead
of 'password') and setting the value to the name of the environment
variable that contains the actual configuration value.

This allows keeping sensitive info (i.e. login and password)
out of the configuration file.

Example configuration snippet:
	protocol=namecheap,                       \
	server=dynamicdns.park-your-domain.com,   \
	login_env=DD_LOGIN,                       \
	password_env=DD_PASSWORD                  \
	@
With this configuration snippet, ddclient will use the contents of
DD_LOGIN as the login value and the contents of DD_PASSWORD as the
password value.
These can in turn be supplied via the command line, .env files or any
other mechanism to safeguard sensitive information.
2023-07-19 17:11:45 +03:00
Lenard Hess
2af841acdb Changed password config regex
The password regex searches for password assignments, extracts the
password and replaces it with a dummy value to prevent it being logged.

This change adjusts the password regex to no longer accept trailing
characters behind the password string
2023-07-19 17:11:45 +03:00
Reuben Thomas
ae905b3baf README.md: update to show this project is live 2023-07-19 17:11:45 +03:00
jortkoopmans
ec4d83bc3f Add support for new DNSExit API (adding protocol dnsexit2). 2023-07-19 17:11:45 +03:00
Sandro Jäckel
a4eab34ab4
Add unmaintained notice 2023-07-04 21:28:53 +02:00
Sandro
2536a5e37a
Merge pull request #480 from michal-josef-spacek/fix_inet6
Rewrite deprecated use of IO::Socket::INET6 to new solution with IO::Socket::IP
2023-06-28 22:54:26 +02:00
Sandro
3136871720
Merge pull request #543 from zlaski/zoneedit-fixes
Fix script failures on ZoneEdit
2023-06-05 00:26:48 +02:00
Ziemowit Łąski
d3d7bda8ca Extend ZoneEdit polling interval to 10min 2023-06-03 00:42:28 -07:00
Ziemowit Łąski
218e1a9974 Squelch 'postscript' warning 2023-06-03 00:42:28 -07:00
Ziemowit Łąski
bbed067864 Fix script failures on ZoneEdit 2023-06-03 00:35:51 -07:00
Timothée Andres
82af20f8d4
Add infomaniak protocol (#537) 2023-06-01 13:47:53 +02:00
Franco Fichtner
1c91a5aa84
dyndns2: fix multiline parsing and multiple host handling (#542) 2023-06-01 10:46:04 +02:00
Sandro
841ffcbdaa
Merge pull request #536 from rolltack/rolltack-bug501
Fix bug #501: (Keysystems) removed wrong parameter
2023-04-18 18:01:29 +02:00
rolltack
aedf6f866b
Fix bug #501: (Keysystems) removed wrong parameter
Looks like there is a bug in line 542 in ddclient.in. The syntax of how the server URL is being set is different to all the other dynamic DNS services. To be precise there is one additional parameter. Instead of handing over the URL, the server variable receives the second "1" in the code below.
2023-04-15 23:53:06 +01:00
Sourabh Shirhatti
038ac6643c
Typo: s/wihtout/without (#531) 2023-04-11 21:46:18 +02:00
Sandro
92604ab78d
Merge pull request #533 from nl6720/systemd-unit-network-online-and-nss-lookup 2023-04-10 20:05:28 +02:00
nl6720
6312030c57
sample-etc_systemd.service: order after nss-lookup.target
This improves the chances that the local DNS resolver (e.g. dnsmasq,
systemd-resolved, Unbound) is up before the service runs and avoids
DNS related failures.

Pull in network-online.target via Wants= to comply with its description
in the systemd.special(7) man page and remove the redundant
"After=network.target" since network-online.target already orders itself
after network.target.
2023-04-10 19:51:27 +03:00
Sandro
a1e68a5b21
Merge pull request #532 from hexadecagram/master
Allow postscript to take args
2023-04-05 11:19:12 +02:00
{16/7}
e92c54f6f9 Allow postscript to take args
$globals{postscript} can now contain a full command string including
arguments. In order to facilitate this, the file executability check
(-x) has been modified such that the first substring up to the first
space (if it exists) is what is checked, rather than the whole string.
2023-04-04 14:58:39 -07:00
Sandro
419716fd22
Merge pull request #520 from tchebb/add-digitalocean 2023-03-20 01:35:30 +01:00
Thomas Hebb
c436a34ede Add support for Digital Ocean 2023-03-14 11:49:10 -04:00
Sandro
2ef926c577
Merge pull request #521 from LenardHess/feature_FritzBoxHostname
Add environment variable to override FRITZ!Box hostname
2023-03-14 14:35:58 +01:00
Sandro
b49bd9eda9
Merge pull request #519 from tchebb/fix-whitespace
Fix a few whitespace issues and a typo
2023-03-14 14:35:23 +01:00
Sandro
407f0c6350
Merge pull request #515 from tduboys/merge_config
Merge configs for the same hosts instead of using the last one
2023-03-14 14:34:53 +01:00
Lenard Hess
4458cceb1b Add environment variable to override FRITZ!Box hostname
For setups with a different DNS server than the FRITZ!Box, the fritz.box
DNS entry may be missing.
2023-02-26 11:46:22 +01:00
Thomas Hebb
07fbbeb5bb Fix a few whitespace issues and a typo 2023-02-25 23:28:45 -05:00
Thomas du Boÿs
b225d37528
Remove README.ssl from makefile as it's deleted on master 2023-02-21 21:10:28 +01:00
Thomas du Boÿs
36de4e0b88
updating changelog 2023-02-21 21:00:41 +01:00
Thomas du Boÿs
611b41e7a6
Merge configs for the same hosts instead of using the last one 2023-02-21 21:00:23 +01:00
Sandro Jäckel
d3a353990b
Update the changelog, bump next version to 3.11.0 because of breaking changes 2023-02-08 14:02:33 +01:00
Sandro Jäckel
8f7ddce2ec
Remove all init systems that use some variations of /etc/init.d 2023-02-08 14:02:02 +01:00
Jontron123
c5a956e386
Add support for Enom (#508)
* Add support for Enom

* Add support for Enom

* Add support for Enom
2023-02-08 13:59:52 +01:00
Naoya Niwa
65a1bcc7d9
Add support for Porkbun (#490)
* Add support for Porkbun

* Add IPv6 support for porkbun
2023-02-08 13:56:08 +01:00
Sandro
9fccfde9e5
Merge pull request #505 from tduboys/usev4_local_config 2023-01-31 20:43:44 +01:00
Sandro
76e441c542
Merge pull request #504 from tduboys/usev4_disable_use 2023-01-29 17:43:35 +01:00
Sandro
8bbafa5988
Merge pull request #506 from drinn/devel 2023-01-29 17:41:53 +01:00
Sandro
999dab7f53
Merge pull request #502 from tduboys/dyndns2_dual_stack 2023-01-29 17:39:08 +01:00
Thomas du Boÿs
5596ee83d1
set use to disabled if usev4 or usev6 is set 2023-01-28 18:49:59 +01:00
drinn
dbc40557d2 removed empty space 2023-01-28 09:59:58 -06:00
drinn
d35d62f3e7 updated nic_duckdns_update to account for extra lines in duckdns reply 2023-01-28 09:48:51 -06:00
Thomas du Boÿs
11a5bd5e7e
define usev4, usev6 and dependancies as per-host config 2023-01-28 11:34:41 +01:00
Thomas du Boÿs
cca4291360
fix ipv4 address on message log when address already set 2023-01-28 10:46:43 +01:00
Thomas du Boÿs
fa6c95f511
Update dyndns2 client to use new IPv4/IPv6 logic
Signed-off-by: Thomas du Boÿs <thomas@duboys.info>
2023-01-27 18:24:39 +01:00
Reuben Thomas
e910204b3d
Add support for Mythic Beasts Dynamic DNS (#312)
Co-authored-by: Sandro <sandro.jaeckel@gmail.com>
2023-01-14 02:24:03 +01:00
Luca Schöneberg
8d3a383587
Revert "fix hetzner zone problem", add zone_id to filter (Hetzner) (#491) 2023-01-13 22:30:06 +01:00
Sandro
5fcf4b37f2
Merge pull request #494 from mjbrowns/master 2023-01-13 18:51:27 +01:00
Sandro
63a78a7f46
Merge pull request #488 from ThinkChaos/fix/ovh-multiline-response 2023-01-13 18:51:16 +01:00
Sandro
086093839d
Merge pull request #487 from pekkanikander/master 2023-01-13 18:51:05 +01:00
Mitch Brown
ff48a0ccb9 add IPV6 support to duckdns protocol 2023-01-04 22:27:21 -05:00
bernhardfrenking
3149171aa7
Add DDNS API domeneshop.no (#478)
Co-authored-by: Sandro <sandro.jaeckel@gmail.com>
2022-12-30 03:23:30 +01:00
ThinkChaos
fcd3ef8b5a
fix: nic_ovh_update not ignoring extra data
Example bodies I've seen:

```
0013
good 127.0.0.1

0
```

```
0013
nochg 127.0.0.1
0
```

```
007
nohost

0
```

Seems like the trailing zero was not there before as the code relied
on `pop`. Instead, we find the first line that matches `good`/`nochg`.
2022-12-28 17:32:14 -05:00
Pekka Nikander
10041d225c Add IPv6 support for EasyDNS 2022-12-28 20:29:01 +02:00
Michal Josef Špaček
c4ff6c12bd Remove setting of MultiHomed, which is default in IO::Socket::IP
From doc in IO::Socket::IP in "IO::Socket::INET" INCOMPATIBILITES
section:
-----
The behaviour enabled by "MultiHomed" is in fact implemented by
"IO::Socket::IP" as it is required to correctly support searching for a
useable address from the results of the getaddrinfo(3) call. The
constructor will ignore the value of this argument, except if it is
defined but false. An exception is thrown in this case, because that
would request it disable the getaddrinfo(3) search behaviour in the
first place.
-----
2022-12-08 14:04:33 +01:00
Michal Josef Špaček
c747f2737a Rewrite deprecated use of IO::Socket::INET6 to new solution
Module IO::Socket::INET6 is deprecated.
There is common IO::Socket::IP module, which is working with ipv4 and
ipv6 in same way. There is backward compatibility with IO::Socket::INET6
2022-12-08 13:58:21 +01:00
Sandro
1a6e4431ab
Merge pull request #477 from lucaschoeneberg/master 2022-11-21 19:54:18 +01:00
Luca Schöneberg
89e30d0aa8 fix hetzner zone problem 2022-11-21 16:17:08 +01:00
gertfriend
f01110aedb
Add regfish (#471) 2022-11-18 08:43:47 +01:00
Sandro Jäckel
3dffe5372a
Format 2022-10-31 00:07:05 +01:00
Sandro Jäckel
e8cc636474
Use https in more places 2022-10-31 00:06:56 +01:00
Sandro Jäckel
d13469fde5
Bump version number in preparation for next release 2022-10-25 15:46:45 +02:00
Sandro Jäckel
36744e5b20
set version number via autoconf 2022-10-25 15:46:33 +02:00
Sandro Jäckel
ce5dfe3501
README.md: don't use version number 2022-10-25 15:46:07 +02:00
Sandro Jäckel
3e2cb0a0dc
Cut 3.10.0 release 2022-10-20 20:06:35 +02:00
satrapes
c9754a125c
Add support for njal.la (#459)
Co-authored-by: Dimitris Paraskevopoulos <dpparaskevopoulos@gmail.com>
2022-09-30 14:49:57 +02:00
Sandro
ca3be487f9
Merge pull request #462 from tchebb/cloudflare-cleanup 2022-09-25 22:13:33 +02:00
Thomas Hebb
8a6b9d0862 cloudflare: Remove unused $hostname variable
This is no longer used since commit 6c951a0395 ("Add files via
upload"), which updated to the Cloudflare API v4. The new API does not
require any preprocessing of the domain name.
2022-09-25 10:22:38 -07:00
pesenise
36b8db950f
Add support for domaindiscount24.com (#436)
* Update ddclient.in

add Row 526 - 529
add Row 869 - 877
add Row 6992 - 7066

* Update ChangeLog.md

* Update ChangeLog.md

* Update ddclient.in

Co-authored-by: Sandro <sandro.jaeckel@gmail.com>

* Update ChangeLog.md

Co-authored-by: Sandro <sandro.jaeckel@gmail.com>

* Update ChangeLog.md

Co-authored-by: Sandro <sandro.jaeckel@gmail.com>

* Update ddclient.in

Co-authored-by: Sandro <sandro.jaeckel@gmail.com>

* Update ddclient.in

Co-authored-by: Sandro <sandro.jaeckel@gmail.com>

* Update ddclient.in

Co-authored-by: Sandro <sandro.jaeckel@gmail.com>

* Update ddclient.in

Co-authored-by: Sandro <sandro.jaeckel@gmail.com>

* Update ddclient.in

Co-authored-by: Sandro <sandro.jaeckel@gmail.com>

Co-authored-by: Sandro <sandro.jaeckel@gmail.com>
2022-07-30 17:07:10 +02:00
Sandro
5382a982cb
Fix typo 2022-06-01 16:04:13 +02:00
Sandro Jäckel
0b8d391b26
Update changelog 2022-05-16 02:12:34 +02:00
Sandro Jäckel
4201bf3b03
Fix version parsing for real, cut 3.10.0_2 2022-05-16 02:07:49 +02:00
Sandro Jäckel
ca4ce91497
Use numeric only version to fix tests 2022-05-15 23:08:03 +02:00
Sandro Jäckel
6be775dc10
Bump version to 3.10.0rc1 2022-05-15 22:44:51 +02:00
Sandro Jäckel
3a7beb27bd
Prepare changelog for release 2022-05-15 22:30:16 +02:00
Richard Hansen
251b167d41
New -list-devices option
This will make it possible for the Debian package to fetch the list of
supported firewall/router devices and prompt the user to choose one
upon installation.
2022-05-15 22:28:38 +02:00
Richard Hansen
0ea681645b
New -list-protocols option
This will make it possible for the Debian package to fetch the list of
supported protocols and prompt the user to choose one upon
installation.
2022-05-15 22:28:33 +02:00
Richard Hansen
f5932d8be3
New -list-web-services option
This will make it possible for the Debian package to fetch the list of
supported built-in web-based IP discovery services and prompt the user
to choose one upon installation.
2022-05-15 22:28:26 +02:00
Sandro Jäckel
69996e9396
Fix CI 2022-05-15 22:20:16 +02:00
Sandro
833828334e
Merge pull request #413 from oddlama/develop
Improve warnings about ddclient.conf permissions. (fixes #348)
2022-05-15 22:10:17 +02:00
Sandro
e9bb850e40
Merge pull request #406 from schreibubi/hetzner_dyndns
Add support for hetzner dns console
2022-05-15 21:58:04 +02:00
Sandro Jäckel
d4a49991a8
Remove unused files 2022-05-15 21:28:08 +02:00
oddlama
327d999ca2
Improve warnings about ddclient.conf permissions. (fixes #348)
The new code will always warn if ddclient.conf is accessible by others,
warn if it is owned by ddclient and accessible by the group,
and otherwise warn if it is writable but not owned by ddclient.

This primarily allows two permission modes for ddclient.conf:
First, the classic `ddclient:ddclient mode 0600` as well as the
more restrictive `root:ddclient mode 0640` which previously
warned unnecessarily.
2022-05-12 20:34:06 +02:00
Joerg Werner
4a01678030 Add support for hetzner dns console 2022-04-23 17:46:10 +02:00
Awalon
beb7147a39
Added support for GoDaddy DNS zone updates. (#398) 2022-04-17 02:35:07 +02:00
Sandro
120d95ed59
Fix CI with newer git, remove git version check (#409) 2022-04-17 02:34:51 +02:00
Sandro
263cd80c7b
Merge pull request #405 from gmelodie/patch-1 2022-04-08 16:42:33 +02:00
Gabriel Cruz
98462633bd
Update pid file path from /run/var/ to /run 2022-04-03 17:00:59 -03:00
Sandro Jäckel
c29919bb0f
Try to clarify that use should always be first in the config 2022-01-25 20:12:31 +01:00
Sandro
ea46ea3c26
Merge pull request #376 from qs5779/my_two_cents 2022-01-24 00:03:59 +01:00
Sandro
215d4679e4
Merge pull request #374 from so-lar-is/add-support-for-1984-is 2022-01-24 00:02:33 +01:00
Sandro Jäckel
4f5f0e0efc
Update all http endpoints which support https to that 2022-01-23 23:59:16 +01:00
Sandro Jäckel
7342f27d09
Ignore nix development files 2022-01-22 18:59:50 +01:00
Sandro Jäckel
8666542c90
Trigger GitHub Actions on every branch and pull request 2022-01-22 18:53:01 +01:00
Sandro
9add1adf0b
Try to fix GitHub Actions 2022-01-22 18:47:32 +01:00
Sandro Jäckel
c226710628
Add minimal shell.nix to use with nix package manager and direnv file
which can be activated just with direnv or lorri
2022-01-20 01:14:54 +01:00
Sandro Jäckel
eaa3263dc0
Update namecheap example to be less confusing
Closes #382
2022-01-20 01:04:37 +01:00
me@so.lar.is
30778c5451 Add support for 1984.is 2022-01-19 01:48:54 +01:00
Quien Sabe
c09ea35052 Updated example service file to use network-online.target 2022-01-16 09:08:46 -07:00
Sandro
17160fb016
Merge pull request #343 from zraexy/patch-1 2022-01-13 17:11:34 +01:00
Sandro
cc50dca49c
Merge pull request #356 from inspector71/patch-2 2022-01-13 15:54:11 +01:00
Sandro
35917bc7f2
Merge pull request #353 from a93h/develop 2022-01-13 15:41:27 +01:00
Sandro
c56ce41824
Merge pull request #357 from pgalbraith/patch-1
fix typo: "socker" -> "socket"
2021-09-05 02:58:56 +02:00
Paul Galbraith
9c98e027df
fix typo: "socker" -> "socket" 2021-09-04 19:08:14 -04:00
inspector71
c2c32b51d8
Some formatting improvements 2021-08-28 15:49:43 +00:00
Austin H
3e952e6892 Cloudflare Fix
Cloudflare was returning values not being matched properly by the regex expression.
Numbers that were not Headers.
This fix or patch should resolve that issue, by only collecting one match to JSON relevant data.
2021-08-17 11:44:37 -04:00
Sandro
c44f446d34
Merge pull request #344 from zraexy/patch-2
Update easyDNS endpoint URL
2021-07-05 23:46:33 +02:00
David Mell
9631575ab4
Update easyDNS endpoint URL
Fixes #340
2021-06-29 12:49:12 -08:00
David Mell
ed128a0b99
Fix CloudFlare zone ID endpoint URL
Fixes #339
2021-06-29 12:44:59 -08:00
Sandro
5ca20a8d2f
Merge pull request #342 from rugk/patch-1
Fix typo in code comment
2021-06-19 23:04:59 +02:00
rugk
130bf46cfd
Fix typo in code comment 2021-06-19 19:24:45 +02:00
Reuben Thomas
f0270e4940
Add dnsexit support (based on #52) (#311)
* Patch in dnsexit support

Based on patch from here https://sourceforge.net/p/ddclient/discussion/399428/thread/04e23ee6/ hacked back in.

* dnsexit: check for valid responses that mean 'failure' (from @truesalo)

Co-authored-by: sreknob <sreknob@hotmail.com>
2021-05-12 14:45:28 -05:00
David Kerr
b84f2334e4
Redact login and password when printing out internal hash values (#274)
* Redact login and password when printing out internal hash values

* Remove from debug message in geturl()  parameters sent as part of a URL

* Update comment with password redaction

Making it clearer that all parameters are redacted, not just password related ones.

Co-authored-by: DaveSophoServices <dave@sophoservices.com>
2021-05-11 20:26:02 -05:00
James Davidson
7fea824ec1
Fix sample duckdns.org config (#301)
The included configuration for duckdns.org is incorrect and does not
match the protocol sample in the wiki[1].

[1] https://sourceforge.net/p/ddclient/wiki/protocols/#duckdns
2021-05-11 20:19:37 -05:00
David Kerr
24ba945949
IPv6 framework + Cloudflare + FreeDNS (#291)
* Add basic framework to support IPv6

* Update cloudflare to use new IPv6 framework

* Update FreeDNS to use new IPv6 framework
2021-05-11 20:16:19 -05:00
Mike Chester
9fb2aee4d0
Fix geturl function call for Gandi (#314)
* Fix geturl function call

The function should be called without the brackets

* Update ci.yml

Removed Cento6 & 8

Co-authored-by: DaveSophoServices <dave@sophoservices.com>
2021-05-11 10:48:44 -05:00
DaveSophoServices
f776018d82
Update ci.yml
Removed centos - tests are not running right.
2021-05-11 10:15:20 -05:00
DaveSophoServices
29cfc55581
Merge pull request #324 from krerkkiat/doc-cloudflare-token
modify Cloudflare documentation
2021-05-11 10:01:36 -05:00
DaveSophoServices
74cb987805
Merge pull request #333 from ddclient/332-http11
Use HTTP/1.0, fix #332
2021-05-11 10:00:03 -05:00
Sandro Jäckel
9a44eeb826
Use HTTP/1.0, fix #332 2021-05-11 11:47:10 +02:00
Krerkkiat Chusap
db8b6baca9 modify Cloudflare documentation
It seems that ddclient check if the login field is equal to "token" to
use the correct header for the API token.
2021-04-05 12:36:45 -04:00
Sandro
11a583b003
Merge pull request #266 from dkerr64/get-if-ip 2020-09-22 20:29:44 +02:00
David Kerr
4c76274ba6 Add missing comment block 2020-09-21 15:16:48 -04:00
David Kerr
1b2f45cc59 Add get_default_interface 2020-09-21 15:16:48 -04:00
David Kerr
213cf6ad09 Add get_ip_from_interface function 2020-09-21 15:16:11 -04:00
Sandro
bafe142692
Merge pull request #233 from dkerr64/curl
🎉
2020-09-21 19:57:26 +02:00
David Kerr
d1d7548e09 So the bug was actually in the escape_curl_param function, not that the data should not be escaped 2020-08-22 21:32:27 -04:00
David Kerr
6ae64e6cfb bug fix... segfault when using WWW::Curl::Easy->pushopt() replace with setopt() 2020-08-21 17:28:57 -04:00
David Kerr
4c79c6b607 must not escape the 'data' field sent to servers. 2020-08-21 17:01:13 -04:00
David Kerr
3a73e5e6b4 header_ok() function must accept HTTP versions other than just '1' 2020-08-21 16:59:07 -04:00
David Kerr
cde60432dd Remove from debug message in geturl() parameters sent as part of a URL 2020-08-12 12:53:59 -04:00
David Kerr
8106b3025f Add support to use WWW::Curl::Easy if it exists 2020-08-07 11:17:44 -04:00
David Kerr
d24b75960d Add support for curl and option to not validate SSL certificates for getip from web or firewall
Check exists not just length
2020-08-07 11:17:44 -04:00
Richard Hansen
3730ff54be
Merge pull request #265 from rhansen/builtinweb
Add additional builtinweb entries
2020-08-05 18:52:29 -04:00
Richard Hansen
2de6a02f14 New %builtinweb entries for nsupdate.info 2020-08-04 13:58:51 -04:00
Richard Hansen
c9b6c8b3bf New %builtinweb entries for whatismyv6.com 2020-08-04 13:57:07 -04:00
Richard Hansen
ae89dbdfa3 New %builtinweb entry for Hurricane Electric 2020-08-04 13:54:49 -04:00
Richard Hansen
fb42a50318 New %builtinweb entry for ZoneEdit 2020-08-04 13:51:26 -04:00
Richard Hansen
460cf2f465 New %builtinweb entry for FreeDNS 2020-08-04 13:51:26 -04:00
Richard Hansen
1a8bfafb3d New %builtinweb entry for Google Domains 2020-08-04 13:51:26 -04:00
Richard Hansen
ad81aa43d2 New %builtinweb entries for noip.com 2020-08-04 13:51:26 -04:00
Richard Hansen
295ba387aa Rename ipifyipv{4,6} to ipify-ipv{4,6}
The added dash makes it easier to read.
2020-08-04 13:51:26 -04:00
Richard Hansen
52abb27604 Mention new %builtinweb services in ChangeLog.md 2020-08-04 13:51:20 -04:00
Richard Hansen
f3a92fbe63 Delete trailing commas 2020-08-04 13:46:21 -04:00
Richard Hansen
deab8970a1 Whitespace fixes 2020-08-04 13:46:21 -04:00
Richard Hansen
bc849ed157
Merge pull request #269 from rhansen/if-skip
Turn `if-skip` into a no-op and mark it as deprecated
2020-08-04 13:45:59 -04:00
Richard Hansen
601460c0b3 Turn if-skip into a no-op and mark it as deprecated
There is no way the user can meaningfully set `if-skip` because the
user doesn't have control over how ddclient reads an interface's
settings (ddclient could theoretically run `ip addr show`, run
`ifconfig`, read a file in `/dev`, make a system call, use a Perl
library, etc.).
2020-08-03 12:55:38 -04:00
Sandro
985f591aec
Merge pull request #267 from rhansen/help-text 2020-08-03 12:05:03 +02:00
Richard Hansen
686bf5a8c8 Improve -help text 2020-08-02 23:38:46 -04:00
Richard Hansen
4bf9d59722 Whitespace fixes 2020-08-02 21:52:11 -04:00
Richard Hansen
59f363ffe2
Merge pull request #197 from dkerr64/Add-extract_ipv6_gua-function
Add extract_ipv6_global function
2020-08-02 16:03:28 -04:00
David Kerr
1ad4d6737a Add is_ipv6_global and extract_ipv6_global functions 2020-08-01 19:11:28 -04:00
Richard Hansen
147ee33754 Update changelog to note change to dslreports1 default server
This should have been done in 25a636879f
but I forgot.
2020-08-01 18:05:27 -04:00
Sandro
50ca9b6627
Merge pull request #264 from rhansen/dslreports
Change the default server for `dslreports1` to `www.dslreports.com`
2020-08-01 22:38:51 +02:00
Richard Hansen
25a636879f Change the default server for dslreports1 to www.dslreports.com
Before, it defaulted to `members.dyndns.org` which didn't make much
sense.
2020-08-01 16:22:38 -04:00
Sandro
35f1be83f6
Merge pull request #263 from rhansen/routers
Add new device built-ins (`fw=<device>`)
2020-07-27 19:40:50 +02:00
Richard Hansen
f8185182e9 Add new device built-ins (fw=<device>)
Thanks goes to Geoff Simmons, who provided the definitions in
https://bugs.debian.org/589980.
2020-07-27 12:23:35 -04:00
Richard Hansen
31173b3736 Use triple backticks to denote the code block
This keeps the line under 80 columns long, and avoids extra vertical
space between entries in the rendered output.
2020-07-27 12:20:17 -04:00
Sandro
3eef38def6
Merge pull request #261 from rhansen/connectivity-tests 2020-07-25 20:10:00 +02:00
Richard Hansen
310810c291 Group tests by IO::Socket class
Also delete some redundant SSL tests.
2020-07-24 15:23:54 -04:00
Richard Hansen
b46d064f55 Don't show -noipv6 when ipv6_opt is false 2020-07-24 15:18:42 -04:00
Richard Hansen
92a7590846 Whitespace fixes 2020-07-24 15:13:03 -04:00
Sandro
532589219f
Merge pull request #253 from rhansen/compat
Clarify compatibility goal and core module support
2020-07-22 10:56:55 +02:00
Sandro
2e1bb5165a
Merge pull request #254 from rhansen/geturl
Eliminate unnecessary hashref
2020-07-22 10:56:17 +02:00
Richard Hansen
8253c6705f
Merge pull request #257 from spack971/gandi-livedns
Add support for Gandi LiveDNS
2020-07-18 15:09:58 -04:00
Richard Hansen
ae7919fcc4 Mark gandi protocol's ttl var as optional
Gandi doesn't require a TTL in the update request. The protocol
implementation already does the right thing if the `ttl` var is
`undef`.
2020-07-18 15:05:53 -04:00
Jimmy Thrasibule
7f719dc305 Add support for Gandi LiveDNS
Allow update of a DNS record hosted by the Gandi LiveDNS service.

Signed-off-by: Jimmy Thrasibule <jimmy.thrasibule@orange.com>
Reviewed-by: Richard Hansen <rhansen@rhansen.org>
2020-07-18 15:01:52 -04:00
Jimmy Thrasibule
b6a7c44d39 Ensure header_ok accept any 2xx return code
Adapt `header_ok` to return success for any HTTP 2xx code.

Signed-off-by: Jimmy Thrasibule <jimmy.thrasibule@orange.com>
Reviewed-by: Richard Hansen <rhansen@rhansen.org>
2020-07-18 15:01:52 -04:00
Richard Hansen
da23769b68
Merge pull request #258 from rhansen/fix-daemon
Fix `-daemon` command-line argument parsing
2020-07-14 23:26:52 -04:00
Richard Hansen
286fe02478 Fix -daemon command-line argument parsing
It turns out the logic removed in
d10601de11 had a purpose after all.
2020-07-14 23:17:19 -04:00
Richard Hansen
cfcf5c1c04
Merge pull request #256 from rhansen/io-socket-inet
Import IO::Socket::INET
2020-07-14 17:35:24 -04:00
Richard Hansen
7d58f2d749 Import IO::Socket::INET
We've always required IO::Socket::INET but never explicitly included
it. For some reason that hasn't been a problem until now.

Fixes #255
2020-07-12 18:58:31 -04:00
Richard Hansen
5f1dacc3bd Eliminate unnecessary hashref
Pass the key-value pairs directly instead of via a hashref.
2020-07-11 21:39:48 -04:00
Richard Hansen
17069e3668 Clarify compatibility goal and core module support 2020-07-11 11:17:10 -04:00
Richard Hansen
7a21c1646c Sort the list of tests 2020-07-11 11:16:52 -04:00
Richard Hansen
c50ecfa9ee Merge pull request #198 from dkerr64/New-extract_ipv6-algorithm
New extract_ipv6 algorithm
2020-07-11 11:08:44 -04:00
David Kerr
29202f5bc1 New is_ipv6 and extract_ipv6 algorithms
Also add unit tests.
2020-07-11 11:04:47 -04:00
David Kerr
92c1294af9 Accept leading zeros in IPv4 addresses
Also add unit tests.
2020-07-11 11:04:33 -04:00
Sandro
f414493a06
Merge pull request #252 from rhansen/inet6
Skip IPv6 tests if IO::Socket::INET6 isn't available
2020-07-11 11:35:23 +02:00
Richard Hansen
a86f40ae9b Skip IPv6 tests if IO::Socket::INET6 isn't available
Fixes #251
2020-07-10 23:10:56 -04:00
Richard Hansen
ac7d8c7b6e
Merge pull request #249 from rhansen/mockmodule
Fix `write_cache` tests
2020-07-10 12:10:30 -04:00
Richard Hansen
d309732480 Add missing test dependency on Test::MockModule
This should have been done in 6ae5fe62d7
but I forgot.
2020-07-10 12:06:45 -04:00
Richard Hansen
bba1ecfe27 Switch from redefine to mock 2020-07-10 12:06:45 -04:00
Richard Hansen
173865bd75 Don't test writing to a read-only directory
root can always write to a read-only directory so the test was failing
on the CI runners (which run as root).
2020-07-10 12:06:45 -04:00
Richard Hansen
192a00ad64 Don't match against locale-dependent $! 2020-07-10 12:06:45 -04:00
Richard Hansen
4e1607c8f6 Enable autoflush on STDOUT and STDERR for tests
This prevents STDOUT lines from appearing out of order relative to
STDERR lines in the test log, which makes it much easier to understand
what's happening.

Devel::Autoflush is from https://metacpan.org/pod/Devel::Autoflush and
is licensed under the terms of the Apache 2.0 license.
2020-07-10 12:06:45 -04:00
Richard Hansen
4cee1e4c7d
Merge pull request #250 from Steve8291/patch-1
Adjust path to ddclient
2020-07-10 12:05:56 -04:00
Steve8291
6b7800380c Adjust path to ddclient
Installing with `make install` automatically places the ddclient
executable in `/usr/bin/ddclient`. This service file has the wrong
path and that causes systemd to be unable to start ddclient.
2020-07-10 12:04:21 -04:00
Richard Hansen
d0fe90ea2c
Merge pull request #229 from ddclient/repology-badge
Add repology.org to readme
2020-07-10 11:55:41 -04:00
Sandro
0b1cc726de Add repology.org to readme 2020-07-10 11:54:34 -04:00
Sandro
64ae58d49b
Merge pull request #240 from rhansen/geturl-unit-tests
Add `geturl` SSL tests
2020-07-08 20:38:06 +02:00
Richard Hansen
dd8e376784 Add geturl SSL tests
These don't test validation, only that IO::Socket::SSL is used.
2020-07-08 13:40:31 -04:00
Sandro
593206ad7d
Merge pull request #248 from rhansen/imports 2020-07-08 12:11:11 +02:00
Richard Hansen
6ff0362450 Get the AF_INET and friends constants from Socket
Apparently it is enough to simply import Socket or IO::Socket to use
AF_INET and friends, but all examples in official documentation show
them in the import list. Because I do not fully understand the
intricacies of Perl import logic, I do the same thing here, fully
aware that I might have joined a cargo cult. Regardless of its
correctness or necessity, listing the constants in the import list has
the advantage of making it clear why the `use` statement exists.

I chose to import the constants from Socket instead of IO::Socket
because that module's documentation explicitly documents the
constants.
2020-07-07 20:55:32 -04:00
Richard Hansen
3b931fb0a6 Add autoconf checks for all used core modules 2020-07-07 16:28:22 -04:00
Sandro
ca1b519444
Merge pull request #238 from rhansen/parse_assignments-subtest
Use `subtest` to group related tests
2020-07-07 20:28:57 +02:00
Richard Hansen
199e9125a4 Use subtest to group related tests
This reduces the output of `make check`, making it easier to zero in
on results of interest.
2020-07-07 13:01:15 -04:00
Richard Hansen
94aaff67cd Add Test::Simple v1.302175 to t/lib
The version of Test::More available in CentOS/RHEL 6 doesn't include
`subtest`, which we want to use. We can revert this commit once we
drop support for CentOS/RHEL 6.

The code is licensed under the same terms as Perl 5 itself:
https://github.com/Test-More/test-more/blob/v1.302175/LICENSE
2020-07-07 13:01:13 -04:00
Sandro
ee4191f865
Merge pull request #225 from reetp/master
Add DinaHosting
2020-07-07 10:15:32 +02:00
Sandro
f0c583890a
Merge pull request #246 from rhansen/unwrap
Unwrap unnecessarily wrapped lines
2020-07-07 10:11:37 +02:00
Sandro
b0b04aa278
Merge pull request #247 from rhansen/parse_assignments
Simplify `parse_assignments`
2020-07-07 10:11:21 +02:00
Sandro
eac5d25e47
Merge pull request #245 from rhansen/continue-on-failure
Don't skip updates to remaining hosts if one host fails
2020-07-07 10:10:42 +02:00
Sandro
9d7af91bf4
Merge pull request #242 from rhansen/mkdir-var-cache 2020-07-07 10:09:47 +02:00
Sandro
666fc293fb
Merge pull request #243 from rhansen/delete-fw-debug
Delete out-of-place debug messages
2020-07-07 10:08:49 +02:00
Sandro
44c92d9992
Merge pull request #244 from rhansen/truthiness
Test for definedness or emptiness, not truthiness
2020-07-07 10:05:59 +02:00
Richard Hansen
71acd749a1 Simplify parse_assignments 2020-07-07 00:10:33 -04:00
Richard Hansen
c3de24bb49 Unwrap unnecessarily wrapped lines 2020-07-07 00:09:44 -04:00
Richard Hansen
bdf8835904 Don't skip updates to remaining hosts if one host fails 2020-07-07 00:08:56 -04:00
Richard Hansen
ee8e1e8844 Don't abort if unable to write the cache file 2020-07-07 00:04:33 -04:00
Richard Hansen
6ae5fe62d7 Create /var/cache/ddclient if it doesn't exist
Fixes #76
2020-07-07 00:04:33 -04:00
Richard Hansen
df3c777e11 Delete out-of-place debug messages
Neither `opt('fw')` nor `$globals{'fw'}` are used in `geturl` so
delete the debug messages showing their values.
2020-07-07 00:03:56 -04:00
John Crisp
e2c3f9dd04 Add support for dinahosting
Fixes #203
2020-07-07 00:00:45 -04:00
Richard Hansen
231306395a Test for definedness or emptiness, not truthiness
Use `//` or `eq ''` for tests to avoid treating the string `'0'` as
false.
2020-07-06 23:58:51 -04:00
Richard Hansen
4670955cb6
Merge pull request #241 from rhansen/get_ip-ssl
Fix detection of `get_ip` caller
2020-07-06 23:56:47 -04:00
Richard Hansen
03dffae74e Honor the ssl option for the web URL 2020-07-06 20:20:01 -04:00
Richard Hansen
7921c53605 Explicitly tell geturl to ignore the global ssl option
Changing behavior based on the identity of the caller is fragile and
makes the code difficult to understand.
2020-07-06 20:19:27 -04:00
Richard Hansen
2e5db5af44 Fix detection of get_ip caller
This was broken in f6f920eb39.
2020-07-06 17:14:08 -04:00
Richard Hansen
4eae0d39a9
Merge pull request #239 from rhansen/perl-core
CentOS/RHEL/Fedora CI improvements
2020-07-06 16:44:28 -04:00
Richard Hansen
f11fef5c50 Install modules for testing on CentOS/RHEL/Fedora 2020-07-06 16:33:26 -04:00
Richard Hansen
1b63ae50c9 Colorize test results 2020-07-06 15:59:30 -04:00
Richard Hansen
5aa4fe71da Pass --refresh to dnf
Hopefully this will stop the "Downloading successful, but checksum
doesn't match" errors we occasionally see for Fedora.
2020-07-06 15:42:41 -04:00
Richard Hansen
34e5cbd97f Rename test-redhat to test-redhat-ubi7 2020-07-06 15:40:42 -04:00
Richard Hansen
ad95fd46c2 Install all core modules on CentOS/RHEL/Fedora
CentOS and RHEL have a `perl-core` metapackage that depends on all
packages providing core modules.

Fedora's `perl` package is equivalent to the CentOS/RHEL `perl-core`
package, and its `perl-interpreter` package is equivalent to the
CentOS/RHEL `perl` package.
2020-07-06 15:24:40 -04:00
Richard Hansen
e621afe375
Merge pull request #231 from ddclient/dead-provider
Remove dead provider
2020-07-06 12:47:55 -04:00
Sandro Jäckel
c8e2adf81a
Add changelog 2020-07-06 15:59:56 +02:00
Sandro Jäckel
b7e7d27a24
Remove dtdns 2020-07-06 15:59:55 +02:00
Sandro Jäckel
12a4a10c9c
Remove hammernode1 2020-07-06 15:57:52 +02:00
Sandro
0600f31d55
Merge pull request #235 from rhansen/geturl-unit-tests
Add `geturl` connectivity unit tests
2020-07-06 00:44:45 +02:00
Richard Hansen
323208e9cc Add geturl connectivity unit tests
Addresses #232
2020-07-05 18:36:46 -04:00
Sandro
b6770a4d9f
Merge pull request #234 from rhansen/url-parsing
Fix URL parsing for IPv6 URLs and pathless URLs
2020-07-06 00:33:22 +02:00
Sandro
cf34c21135
Merge pull request #236 from rhansen/caller-undef-warning
Silence warning when calling `geturl` from an anonymous sub
2020-07-06 00:25:18 +02:00
Richard Hansen
06503a483b Fix URL parsing for IPv6 URLs and pathless URLs
Now the following valid URLs are parsed correctly:
  * http://[::1]:123/foo
  * http://localhost?foo=bar

There are still problems with the URL parsing logic but this is enough
to write some unit tests.
2020-07-05 18:21:35 -04:00
Richard Hansen
49c8717420 Silence warning when calling geturl from an anonymous sub 2020-07-05 18:16:08 -04:00
Sandro
91803cbb41
Merge pull request #237 from rhansen/stringify-ports
Stringify default port numbers
2020-07-05 23:42:26 +02:00
Richard Hansen
a15cec7cd9 Stringify default port numbers
The IO::Socket classes expect strings for the port number because you
can pass service names from `/etc/services`. Numbers work too, but
using strings everywhere makes it easier to write unit tests.
2020-07-05 16:32:41 -04:00
Sandro
d79519f59c
Merge pull request #230 from rhansen/autoconf-test-find
Require `find` to be installed
2020-07-03 23:46:49 +02:00
Richard Hansen
9b1fc13d40 Require find to be installed 2020-07-03 17:35:11 -04:00
Richard Hansen
f527b7487c
Merge pull request #228 from dkerr64/cleanup
Add missing semicolons and fix incorrect debug message
2020-07-03 17:34:30 -04:00
David Kerr
52fdb0bdeb add missing semicolons and fix incorrect debug message 2020-07-03 17:32:27 -04:00
Sandro
d844039e6c
Merge pull request #175 from rhansen/config-file-parse
Improve parsing of config file assignments
2020-07-03 23:24:55 +02:00
Sandro
55b3754838
Merge pull request #227 from rhansen/ca-certs
New options to specify CA certificate location
2020-07-03 23:20:35 +02:00
Richard Hansen
f7ff1f8259 New options to specify CA certificate location
This is a prerequisite to adding `geturl()` unit tests (we will need
to run a dummy https server).
2020-07-03 16:59:18 -04:00
Richard Hansen
6d7d248f79 Improve parsing of config file assignments
* Ignore empty `key=value` strings in variable assignments. Now the
    following lines are supported with the expected meaning:
      * `a=1 , b=2`
      * `a=1,,b=2`
  * Improve the warning message when there is an unterminated quote.
  * Add a warning if the line ends with a backslash.

Also add unit tests.
2020-07-03 16:56:01 -04:00
Sandro
391a513d5c
Merge pull request #223 from rhansen/dist-tarball 2020-07-03 20:51:09 +02:00
Richard Hansen
b9b594fcea Test that the distribution tarball is complete 2020-07-03 14:27:18 -04:00
Sandro
f0eb0850da
Merge pull request #224 from rhansen/fedora-find
Install findutils on Fedora
2020-07-03 08:35:08 +02:00
Sandro
8cff1a6da2
Merge pull request #222 from rhansen/ci-debian
Also run tests on Debian testing, stable, oldstable
2020-07-03 08:33:40 +02:00
Richard Hansen
451bdd1086 Also run tests on Debian testing, stable, oldstable 2020-07-02 14:05:18 -04:00
Richard Hansen
a00d2cc18e Install findutils on Fedora 2020-07-02 09:58:58 -04:00
Sandro
9c6c7a2b39
Merge pull request #219 from rhansen/editor-variables
Update Vim modeline and Emacs file-local variables
2020-07-02 09:46:09 +02:00
Richard Hansen
283f609b28 Update Vim modeline and Emacs file-local variables
Both:
  * Force the file type to Perl
  * Set the tab width to 8 so that people cringe in horror at the
    sight of a tab
  * Set the line with to 99

Emacs:
  * Disable indent-tabs-mode
  * Set the indentation level to 4

Vim:
  * Highlight column 100

Addresses #206
2020-07-01 22:52:29 -04:00
Richard Hansen
5507b76d83
Merge pull request #218 from ddclient/redhat
Add redhat to ci
2020-07-01 21:50:51 -04:00
Sandro Jäckel
a23b8d558b Add redhat to ci 2020-07-01 21:48:03 -04:00
Richard Hansen
1614e62f2d
Merge pull request #221 from thorsteneb/master
Add FreeBSD; change README to use json-pp for Ubuntu
2020-07-01 12:34:41 -04:00
Thorsten Behrens
2afdf5043c Add FreeBSD; change README to use json-pp for Ubuntu 2020-07-01 12:33:21 -04:00
Richard Hansen
22e9da2d79
Merge pull request #220 from rhansen/dco
Document that contributions are subject to the DCO
2020-07-01 11:47:43 -04:00
Richard Hansen
290077dc5e Document that contributions are subject to the DCO 2020-07-01 11:46:32 -04:00
Richard Hansen
23e372d283
Merge pull request #216 from ddclient/perl-version
Explicit require version
2020-07-01 11:44:23 -04:00
Sandro Jäckel
c4f2670d8b Explicit require version
because centos does not include it at all times
2020-07-01 11:43:47 -04:00
Sandro
19813a7247
Merge pull request #195 from rhansen/config
Move per-service variables to the service definitions
2020-07-01 10:07:46 +02:00
Richard Hansen
8ed93cb576 Move per-service variables to the service definitions
Most of the entries in `%variables` are only used once. Move them down
to their respective service definitions.

Also:
  * Use idiomatic hash merging instead of `merge()`.
  * Sort the variables by name.
2020-06-30 22:14:15 -04:00
Sandro
ef566064d5
Merge pull request #215 from rhansen/verbose-tests
Recommend `VERBOSE=1` when running tests
2020-07-01 01:42:51 +02:00
Richard Hansen
c198e21c16 Recommend VERBOSE=1 when running tests
This causes Automake to output a failed test's log so that you don't
have to look at the `.log` file yourself.
2020-06-30 19:37:01 -04:00
Richard Hansen
296576d57f
Merge pull request #209 from ddclient/ci-centos
Add test for centos, use matrix for ubuntu
2020-06-30 18:57:39 -04:00
Sandro Jäckel
af718224b3 Add fedora to ci 2020-06-30 18:54:19 -04:00
Sandro Jäckel
ea840db62d Add centos 6 to ci 2020-06-30 18:51:41 -04:00
Sandro Jäckel
c4fae81053 Add centos 8 to ci 2020-06-30 18:51:41 -04:00
Richard Hansen
38d71b2efa Set VERBOSE=1 to show logs on failure 2020-06-30 18:47:22 -04:00
Sandro Jäckel
0ca6e62b67 Use matrix for ubuntu 2020-06-30 18:47:22 -04:00
Sandro
504e326274
Merge pull request #214 from rhansen/woima
Fix woima protocol implementation `for` loop
2020-07-01 00:45:31 +02:00
Richard Hansen
7a2d065a2d Fix woima protocol implementation for loop 2020-06-30 18:41:40 -04:00
Sandro
43c0581334
Merge pull request #213 from rhansen/regex-flag-compat
Remove the `/a` regex flag
2020-07-01 00:37:13 +02:00
Richard Hansen
ccc876c160 Remove the /a regex flag
This flag was added in Perl 5.14 so we can't use it.
2020-06-30 18:34:41 -04:00
Sandro
05e5759aa1
Merge pull request #212 from rhansen/automake-parallel-tests
Enable Automake's parallel-tests feature
2020-07-01 00:27:17 +02:00
Richard Hansen
65bc4cd986 Enable Automake's parallel-tests feature
Apparently it's off by default in Automake 1.11.
2020-06-30 18:22:22 -04:00
Richard Hansen
034e6501ed
Merge pull request #196 from dkerr64/Cleanup-extract_ipv4-and-is_ipv6-and-usage
Cleanup extract ipv4 and is ipv6 and usage
2020-06-30 15:54:25 -04:00
David Kerr
36d8b511b3 Move un_zero_pad into extract_ipv4, extract_ipv6
This also causes `is_ipv4` to reject IPv4 addresses with leading
zeros.
2020-06-30 15:44:24 -04:00
David Kerr
0a999577c7 Simplify the IPv4 regular expression 2020-06-30 15:43:07 -04:00
David Kerr
5da22a8a69 Implement is_ipv6 in terms of extract_ivp6 2020-06-30 15:26:40 -04:00
David Kerr
ab0a4597ce Validate the ip setting 2020-06-30 15:22:13 -04:00
David Kerr
fe513f733d Use is_ipv6, not extract_ipv6, to validate IPv6 address 2020-06-30 15:19:38 -04:00
David Kerr
af1332264f Delete unnecessary address check
`get_ip` is guaranteed to return a valid IP address or `undef`.
2020-06-30 15:16:55 -04:00
Sandro
7e0f696c87
Merge pull request #210 from rhansen/tap-driver.sh
Tell Git to ignore changes to build-aux/tap-driver.sh
2020-06-30 21:00:36 +02:00
Sandro
7c81627c92
Merge pull request #211 from rhansen/rename-template
Rename `*.template` to `*.in`
2020-06-30 20:51:32 +02:00
Richard Hansen
44eaf653f1 Rename *.template to *.in
Apparently the `.template` extension is commonly used in macOS for a
word processor template file.

See issue #206.
2020-06-30 13:27:08 -04:00
Richard Hansen
38e44ef1fb Tell Git to ignore changes to build-aux/tap-driver.sh 2020-06-30 12:27:11 -04:00
Richard Hansen
5e7683df85 Merge pull request #208 from ddclient/fix-shebang
Fix shebang
2020-06-30 11:59:27 -04:00
Sandro Jäckel
86a3294b0f Fix shebang
cause perl needs a regular shebang even when evoking the script
directly with perl
2020-06-30 11:55:11 -04:00
Sandro
06851b770e
Merge pull request #207 from rhansen/test-improvements 2020-06-30 09:08:50 +02:00
Richard Hansen
a8212a397e Add a test for unexpected warnings 2020-06-30 00:40:26 -04:00
Richard Hansen
0cc83cd5ec Simplify runtime imports in test code
Also use `BAIL_OUT` instead of `die` if `require 'ddclient'` fails.
2020-06-29 17:26:46 -04:00
Richard Hansen
858fe53072
Merge pull request #163 from rhansen/ipv6-design-doc
Design doc for IPv6 support
2020-06-29 17:24:32 -04:00
Richard Hansen
d31d9f8bde Design doc for IPv6 support
Add a document describing a design for comprehensive IPv6 support. The
ddclient maintainers agreed to this design, and it should be used to
guide the implementation of full IPv6 support.
2020-06-29 17:23:51 -04:00
Richard Hansen
58c6570dde
Merge pull request #184 from rhansen/freedns
Redo freedns.afraid.org protocol to fix several bugs
2020-06-29 17:22:56 -04:00
Richard Hansen
566c3c3d5e Redo freedns.afraid.org protocol to fix several bugs
* Support IPv6 addresses.
  * Support updating addresses that aren't the client's own addresses.
  * Set status to 'failed' if the update fails for any reason.
  * Don't skip hosts if a previous update failed.
  * Check for a non-OK code from the update server.
  * Strip headers before processing responses.

This still uses API v1 because API v2 currently has some limitations;
see #180 for details.

Fixes #180
2020-06-29 17:22:09 -04:00
Richard Hansen
d593892c6a Set up GitHub CI
Teach GitHub to run tests for changes to `master` and for pull
requests targeting `master`.
2020-06-29 17:14:21 -04:00
Richard Hansen
c72d128a9e Disable accidental interpolation in regular expression
Without this change, Perl prints the following warning:

> Possible unintended interpolation of `@$` in string at ddclient line 43.
2020-06-29 17:13:06 -04:00
Richard Hansen
dde91fd028 Typo fix (you -> your) 2020-06-29 17:12:01 -04:00
Richard Hansen
f360860378
Merge pull request #161 from rhansen/test-framework
Build system and unit test infrastructure
2020-06-29 11:09:12 -04:00
Richard Hansen
c390e75769 Add unit test infrastructure.
Now all that is needed to add a new unit test is to create a `t/*.pl`
file and list it in the `handwritten_tests` variable.

To run the test suite, run:

    ./autogen && ./configure && make check

Fixes #147
2020-06-29 11:08:32 -04:00
Richard Hansen
f6f920eb39 Use the "modulino" pattern to facilitate unit tests
Now the `ddclient` file can be used as a script or as a module. For
details, see: https://www.drdobbs.com/scripts-as-modules/184416165

Addresses #147
2020-06-29 11:08:28 -04:00
Richard Hansen
8cbcecba99 Add Autotools-based build infrastructure
This makes it easier to package ddclient, especially as enhancements
are made such as unit tests or a man page.

I chose GNU Autoconf and Automake mostly because I'm familiar with
them, but also because I know they are well supported. Unfortunately
they can be difficult to understand/maintain (especially Autoconf), so
we may want to convert to something else later.

Addresses #146, #147
2020-06-29 11:06:34 -04:00
Sandro
bfdf9454f0
Merge pull request #201 from rhansen/group_hosts_by
`group_hosts_by` improvements
2020-06-29 09:40:11 +02:00
Sandro
4f08d77cae
Merge pull request #202 from rhansen/cloudns
Add ClouDNS support
2020-06-29 09:36:44 +02:00
Richard Hansen
0792f9b272 Add ClouDNS support
Fixes #190
2020-06-29 01:15:42 -04:00
Richard Hansen
8fcc9b0e2f group_hosts_by improvements
* Don't modify `$config{$h}{$v}` if variable `$v` for host `$h` is
    `undef`.
  * Tolerate the user passing `wantip` or duplicate keys.
2020-06-29 01:15:28 -04:00
Richard Hansen
b1da99c361 Merge pull request #200 from rhansen/undo-revert
Add is_ipv4() and ipv4_match() functions
2020-06-29 01:13:43 -04:00
David Kerr
00ce8bdeb3 Add is_ipv4() and extract_ipv4() functions 2020-06-29 00:19:32 -04:00
Richard Hansen
8b2ede16c0 Revert "Add is_ipv4() and ipv4_match() functions"
Broke `ip=<IPv4 address>`.

This reverts commit 0caed7ca2a.
2020-06-28 23:57:58 -04:00
Richard Hansen
1766313397 Sort %builtinfw entries by key 2020-06-28 19:55:57 -04:00
Richard Hansen
3199f791d8 Sort %services entries by key 2020-06-28 19:55:57 -04:00
Sandro
b85d86795e
Merge pull request #193 from rhansen/config
Delete unused `config` entry
2020-06-29 01:37:29 +02:00
Richard Hansen
959c7154ad
Merge pull request #194 from rhansen/ip-extract
Rename `ipv4_match`, `ipv6_match` to `ipv4_extract`, `ipv6_extract`
2020-06-28 17:14:17 -04:00
Richard Hansen
8a63c5b74f Rename ipv4_match, ipv6_match to extract_ipv4, extract_ipv6
"Match" only implies a boolean return value. While these functions can
be used in boolean context, "extract" more closely matches their
intended purpose.
2020-06-28 17:09:36 -04:00
Richard Hansen
dc47afea38 Delete unused config entry 2020-06-26 21:04:01 -04:00
Richard Hansen
7556aaa5e1
Merge pull request #191 from rhansen/deprecate-banlocal
Turn `fw-banlocal` into a no-op and mark it as deprecated
2020-06-26 21:01:40 -04:00
Richard Hansen
4edecf3dc1 Turn fw-banlocal into a no-op and mark it as deprecated
`fw-banlocal` is problematic:
  * There's not much point to it. Regardless of whether it is enabled,
    the end result is a DNS record that is not being updated to a
    useful value. It does cause a warning to be logged, but because it
    is not enabled by default it doesn't help the poor user who is
    trying to figure out why they can't reach their machine. By the
    time they realize that enabling this option would have saved them
    hours of troubleshooting, they no longer need to enable it because
    they already know what the problem is.
  * It's a misnomer: `fw-banlocal` doesn't just filter out local IP
    addresses from `use=fw`, it also filters them out of all other
    address sources except `use=ip`.
  * It doesn't filter out local IPv6 addresses.
  * The resulting warning ("unable to determine IP address") is
    misleading.

We might want to add a warning whenever a non-global address is
discovered (along with an option to silence the warning), but that
should be done in a future commit if at all.
2020-06-25 23:32:58 -04:00
Sandro
08c7e71352
Merge pull request #187 from rhansen/defined-or-op
Use the `//` operator to simplify code
2020-06-24 20:01:19 +02:00
Richard Hansen
a84015015f Use the // operator to simplify code 2020-06-24 13:34:31 -04:00
Sandro
271f277126
Merge pull request #169 from rhansen/geturl-force-ip-version 2020-06-24 15:15:12 +02:00
Richard Hansen
39bd6fce9e New geturl param to force IPv4 or IPv6
This will be used by the upcoming `webv4` and `webv6` options to
ensure that the checkip service returns the desired type of IP
address.

Addresses #172
2020-06-23 11:55:46 -04:00
Richard Hansen
323a873b22 Change geturl to take a hash of parameters
This makes the call sites more readable, and it will be easier to
extend in the future (to add an option to force IPv4 or IPv6, for
example).
2020-06-23 11:55:46 -04:00
Richard Hansen
7fafb8df7e
Merge pull request #186 from dkerr64/is_ipv4-function
Add is_ipv4() and ipv4_match() functions
2020-06-23 11:54:12 -04:00
David Kerr
0caed7ca2a Add is_ipv4() and ipv4_match() functions 2020-06-23 11:52:27 -04:00
Richard Hansen
aeba95aef4
Merge pull request #182 from rhansen/fix-use-ip
Fix `use=ip` when `ip` is set to an IPv4 address
2020-06-17 12:16:35 -04:00
Richard Hansen
99a60995c4 Fix use=ip when ip is set to an IPv4 address
Before, with `use=ip,ip=1.2.3.4`, `get_ip` would return `undef` and
print a warning:

  WARNING:  found neither ipv4 nor ipv6 address
2020-06-17 12:16:05 -04:00
Sandro
2f26ed5969
Merge pull request #183 from rhansen/bool-parsing
Fix parsing of "true" as a boolean value
2020-06-17 09:43:35 +02:00
Richard Hansen
40f355d05e Fix parsing of "true" as a boolean value
Before, "t" and "ttrue" were accepted as true, but not "true".

Also simplify the true and false regular expressions.
2020-06-16 23:23:02 -04:00
Richard Hansen
7cc36539e7 Move Data::Validate::IP removal note to dependency changes section 2020-06-16 14:23:02 -04:00
Richard Hansen
5b251f3802
Merge pull request #178 from dkerr64/RemoveValidateIP
Remove dependency on Data::Validate::IP
2020-06-15 23:19:03 -04:00
David Kerr
d4c55dd0f5 Remove dependency on Data::Validate::IP
This module is not available by default on many systems, and not
available at all on lightweight embedded systems.
2020-06-15 23:17:12 -04:00
Sandro
35eac827e3
Merge pull request #173 from rhansen/request-body-crlf
Don't replace LF with CRLF in body of HTTP request
2020-06-14 15:59:18 +02:00
Sandro
0b60ce3f94
Merge pull request #174 from rhansen/host-opt
Fix global fallback when host-specific setting is undefined
2020-06-14 02:02:33 +02:00
Richard Hansen
ffb908ab49 Don't replace LF with CRLF in body of HTTP request
Now the Content-Length header matches the actual length of the body.

Also, don't replace an LF with CRLF if it is already preceeded by CR.
2020-06-13 14:41:30 -04:00
Richard Hansen
f6d5ce3383 Fix global fallback when host-specific setting is undefined
This commit only changes behavior if the hostname is a falsy string
(`''` or `'0'`) and there is a variable that:
  * was not set globally before the host definition,
  * was not set in the host definition,
  * was set globally after the host definition, and
  * is relevant to the host.
2020-06-13 13:38:33 -04:00
Richard Hansen
b3f2f7029d Whitespace fixes 2020-06-13 11:43:33 -04:00
Sandro
38bec6d135
Merge pull request #171 from rhansen/iproute2
Prefer `ip` command from iproute2 over `ifconfig`
2020-06-13 11:23:49 +02:00
Richard Hansen
e3a6cbf1b6 Prefer ip command from iproute2 over ifconfig
On Linux systems, `ifconfig` is long deprecated in favor of the `ip`
command from iproute2. Some systems don't have iproute2 (BSDs in
particular), so ddclient will still attempt `ifconfig` if `ip` is
missing.

Also: Don't hide STDERR because error messages are important for
troubleshooting problems. To avoid STDERR noise on systems without the
`ip` command, the command's existence is checked before it is run.

Notes:
  * The fetched addresses could be limited to IPv4 or IPv6 depending
    on `opt('ipv6')`, and non-global addresses could be filtered out,
    but any filtering risks breaking a nontrivial number of existing
    configurations.
  * This change runs the risk of breaking existing configs that set
    `if-skip`. Due to the deprecation of `ifconfig`, and the belief
    that only a negligible number of users set `if-skip`, the benefits
    of this change are believed to outweigh the config migration
    burden imposed on users.

Fixes #93.
2020-06-12 22:54:49 -04:00
Sandro
20429c1199
Merge pull request #165 from rhansen/multiline-log-space
Remove extra space at beginning of multiline log messages
2020-06-13 00:09:27 +02:00
Richard Hansen
d60a310599 Remove extra space at beginning of multiline log messages 2020-06-12 15:37:30 -04:00
Sandro
eb4b226af0
Merge pull request #153 from rhansen/infer-use 2020-06-12 21:30:16 +02:00
Richard Hansen
e696d57ff2 Prefer ip over if over web when inferring use
If the user passed `-ip` they almost certainly want to use it, even if
they also passed `-if` and `-web`.

Similarly, if the user passed `-if` they almost certainly want to use
it even if they also passed `-web`.
2020-06-12 11:02:48 -04:00
Richard Hansen
1c13c24981 Fix misuse of define() 2020-06-12 11:02:48 -04:00
Sandro
7fa1beb11e
Merge pull request #166 from rhansen/perl-5.10 2020-06-12 12:07:34 +02:00
Richard Hansen
9cd418f79c Bump minimum required Perl to v5.10.1
This allows us to use the `//` and `//=` operators.

v5.10.1 was chosen because that is the oldest version of Perl among
all currently supported releases of Ubuntu, CentOS, RHEL, Fedora, and
Debian.
2020-06-11 23:18:11 -04:00
Richard Hansen
9e672a8c7d
Merge pull request #144 from rhansen/contributing
Start a contributor guide
2020-06-11 23:11:21 -04:00
Richard Hansen
e74797f557 Start a contributor guide
Addreses #122, #129
2020-06-11 23:10:39 -04:00
Richard Hansen
6e8d7e9744
Merge pull request #158 from rhansen/news
Convert RELEASENOTE to a history of notable changes
2020-06-11 23:05:00 -04:00
Richard Hansen
33dc46d8f4 Update ChangeLog.md with recent changes affecting compatibility 2020-06-11 15:33:27 -04:00
Richard Hansen
17707b0cba Note when Data::Validate::IP dependency was added 2020-06-11 15:33:27 -04:00
Richard Hansen
a3c8d581fa Combine RELEASENOTE, ChangeLog, Changelog.old into ChangeLog.md
Create a document whose main purpose is to describe notable changes
between released versions. Populate it with the contents of
RELEASENOTE over time and the entries from ChangeLog and
Changelog.old.

For recent releases, the full announcement text can still be found at
https://github.com/ddclient/ddclient/releases
2020-06-11 15:33:27 -04:00
Richard Hansen
593ed1b7a0 Delete unnecessary double quotes
Also minor style cleanups.
2020-06-11 13:04:09 -04:00
Richard Hansen
e6d1d73a4a Whitespace fixes 2020-06-11 13:02:22 -04:00
Richard Hansen
1d78f5fbe3
Merge pull request #155 from rhansen/content-type-header
Fix regex searching for Content-Type header
2020-06-09 15:01:34 -04:00
Richard Hansen
fe3893e26a Fix regex searching for Content-Type header
* Add the `m` modifier because the `$headers` variable can contain
    multiple headers. If `$headers` contains a Content-Type header but
    it is the second or later header then the regex won't match
    without `m`.
  * Add the `i` modifier because RFC 7230 says that header field names
    are case-insensitive.
  * Don't require a space after the colon because RFC 7230 says that
    the space is optional.
2020-06-09 15:00:01 -04:00
Sandro
7d094c0976
Merge pull request #154 from rhansen/geturl-request-newline
Remove extra newline in HTTP request
2020-06-09 14:41:19 +02:00
Richard Hansen
a12004cc4c Remove extra newline in HTTP request
Before, if there were no custom request headers, the request would end
with three newlines instead of two.
2020-06-09 00:22:05 -04:00
Richard Hansen
c995698b7e Revert "Merge pull request #156 from rhansen/news"
This reverts commit 9ab23a8e8c, reversing
changes made to 31902ac1b1.
2020-06-08 21:17:28 -04:00
Sandro
9ab23a8e8c
Merge pull request #156 from rhansen/news
Start a NEWS document for notable changes
2020-06-08 05:54:09 +02:00
Richard Hansen
1d4a154a21 Update NEWS.md with recent changes affecting compatibility 2020-06-07 17:54:42 -04:00
Richard Hansen
80a19539a1 Note when Data::Validate::IP dependency was added 2020-06-07 17:42:15 -04:00
Richard Hansen
1b5b156097 Create NEWS.md, seeded with RELEASENOTE's history
Create a document that describes notable changes between released
versions. Populate it with the contents of RELEASENOTE over time, and
delete RELEASENOTE as it is now redundant. (The full announcements can
still be found at https://github.com/ddclient/ddclient/releases.)

The name NEWS.md was chosen because it is the convention, and because
Debian policy says documents of this nature must be installed at
/usr/share/doc/ddclient/NEWS.gz. For details, see:
https://www.debian.org/doc/debian-policy/ch-docs.html#changelog-files-and-release-notes
2020-06-07 17:13:17 -04:00
Sandro
31902ac1b1
Merge pull request #152 from rhansen/printf-fixes 2020-06-04 22:47:46 +02:00
Richard Hansen
fb033448b2 Fix usage of printf-like functions
* Remove interpolations from the format specifier (in case the
    variable contains a `%` character).
  * Match the number of arguments to the number of `%` substitutions
    in the format specifier.
2020-06-04 15:47:57 -04:00
Richard Hansen
059f8ecbf0 Whitespace fixes 2020-06-04 15:44:24 -04:00
Sandro
9590a85d83
Merge pull request #150 from rhansen/longer-daemon-default
Use a longer default interval if run as ddclientd
2020-06-03 07:09:48 +02:00
Richard Hansen
0444399c0d Use a longer default interval if run as ddclientd
One minute is too short for a default value.

Addresses #149
2020-06-02 22:23:53 -04:00
Sandro
5cd21f7c7e
Merge pull request #145 from rhansen/cleanups
Delete unnecessary semicolons
2020-06-02 02:05:30 +02:00
Sandro
918e9a97b7
Merge pull request #143 from rhansen/delete-concont
Remove `concont` protocol.
2020-06-02 00:12:08 +02:00
Sandro
2ab9afbc79
Merge pull request #92 from xlammertink/ovhsupport
Added OVH DynHost support
2020-06-02 00:08:25 +02:00
Richard Hansen
fd50a9b44c Delete unnecessary semicolons 2020-06-01 15:18:27 -04:00
Richard Hansen
7de450fd58 Remove concont protocol
It is unclear that this protocol is in use anywhere.  See
https://sourceforge.net/p/ddclient/mailman/message/432027/ for some
discussion.

If it turns out that users are still using `concont` we can revert
this change.
2020-05-31 22:52:22 -04:00
xlammertink
5070bd4296 Added OVH DynHost support 2020-05-31 11:29:30 -04:00
Sandro
f4e6e90c38
Merge pull request #142 from rhansen/config-line-format
Expand comment documenting config line format
2020-05-31 07:29:51 +02:00
Richard Hansen
30180edbc4 Expand comment documenting config line format
Eventually we should move this to README.md or something.
2020-05-30 23:49:56 -04:00
Richard Hansen
01a746c773
Merge pull request #138 from rhansen/dyndns-za-net
Replace dydns.za.net with dyndns.za.net
2020-05-30 23:47:54 -04:00
Richard Hansen
08c2b6c5c3 Replace dydns.za.net with dyndns.za.net
dydns.za.net doesn't appear to exist.
2020-05-30 23:45:21 -04:00
Richard Hansen
d65805b84a
Merge pull request #140 from ddclient/fix-interpolation
Fix here doc interpolation
2020-05-30 22:30:04 -04:00
Sandro Jäckel
babbef1544 Fix here doc interpolation 2020-05-30 22:29:17 -04:00
Richard Hansen
6ae69a1ce6
Merge pull request #141 from ddclient/show-debug-ssl
Show debug ssl
2020-05-30 22:23:57 -04:00
Sandro Jäckel
096288ed18 Expand tabs to spaces in vim 2020-05-30 22:19:43 -04:00
Sandro Jäckel
0206262850 Show debug connection settings after evaluating use-ssl
Before this change we often showed http:// in debug log
even when we later connect via https. This is confusing.

Closes #139
2020-05-30 22:19:43 -04:00
hgducharme
cf2693a656
Added NoIP example to sample-etc_ddclient.conf
Closes #51
2020-05-30 05:11:08 +02:00
Sandro
afba2f375e
Merge pull request #127 from rhansen/delete-unused-varargs
Delete unused varargs from _read_config and parse_assignment(s)
2020-05-29 10:55:31 +02:00
Sandro
104c3245ce
Merge pull request #133 from rhansen/pid-only-if-daemonized
Only write the PID file if daemonized
2020-05-29 10:51:56 +02:00
Sandro
85286de11d
Merge pull request #137 from ddclient/remove-web_strategies
Remove unused variable web_strategies
2020-05-29 10:44:51 +02:00
Sandro
96516edf4c
Merge pull request #125 from ddclient/ipify
Add ipify ipv4 and ipv6 as ip getter
2020-05-29 10:41:45 +02:00
Sandro Jäckel
3f8ff1f7dd
Add ipify ipv4 and ipv6 as ip getter 2020-05-29 10:41:10 +02:00
Sandro
e0f3dfaa43
Merge pull request #124 from ddclient/myonlineportal
Add myonlineportal as ip getter
2020-05-29 10:39:14 +02:00
Richard Hansen
6757c2ec0e Delete unused varargs from _read_config and parse_assignment(s) 2020-05-28 22:26:14 -04:00
Richard Hansen
b094c1bff5 Only write the PID file if daemonized
There's not much point in writing a PID file if the user does not want
to fork. (The process executing ddclient already knows the PID, so it
can save it to a file if desired.)

This change is a prerequisite to using Proc::Daemon to fix the buggy
daemonization logic.
2020-05-28 22:26:14 -04:00
Sandro
dc37e00d9d
Merge pull request #119 from rhansen/force-daemon
Do not prevent daemonization when force is set
2020-05-29 04:15:22 +02:00
Sandro
eef57851f9
Merge pull request #118 from rhansen/url 2020-05-29 04:14:57 +02:00
Sandro
4e8ec26c5b
Change link to github page 2020-05-29 04:14:39 +02:00
Richard Hansen
55d7a16985 Update ddclient home page URL 2020-05-28 22:08:09 -04:00
Richard Hansen
b88d4aa679 Do not prevent daemonization when force is set
The force option should only be about ignoring the cache and existing
value, not about controlling when updates are triggered or whether the
program runs in the foreground.
2020-05-28 22:04:26 -04:00
Sandro
c314164d66
Merge pull request #134 from rhansen/syslog-when-daemon
Delete do-nothing `$opt{'syslog'} = 1;` when daemonized
2020-05-29 04:00:51 +02:00
Sandro
6a48fbca42
Merge pull request #131 from rhansen/redundant-daemon-opt-processing
Delete redundant `$opt{'daemon'}` processing
2020-05-29 03:53:27 +02:00
Sandro Jäckel
2adedb611b
Remove unused variable web_strategies 2020-05-29 03:48:04 +02:00
Sandro Jäckel
17a12ec192
Add myonlineportal as ip getter 2020-05-29 03:46:56 +02:00
Sandro
489f5aefd5
Merge pull request #135 from rhansen/fix-usage 2020-05-29 03:35:16 +02:00
Sandro
d5c4895115
Merge pull request #136 from rhansen/init-script-cleanup 2020-05-29 03:23:57 +02:00
Richard Hansen
e7c43e9eef Improve robustness of daemon interval extraction
Without this change the init script incorrectly handles config file
lines like these:

    foo=bar # daemon=123
    foodaemon=123
    daemonfoo=123
    daemon=0
    DAEMON=123
2020-05-28 14:53:37 -04:00
Richard Hansen
cecbaba3e0 Whitespace and minor style fixes 2020-05-28 14:53:37 -04:00
Richard Hansen
7be4d58b90 Convert invocations of usage() to fatal()
The usage text is extremely long which causes the error message to
scroll off the top of the screen. Switch to fatal() to avoid this
problem.
2020-05-28 14:46:13 -04:00
Richard Hansen
ca7f0927fc Fix usage()
* The first argument to usage() was supposed to be the exit status,
    but that is not how usage() is invoked (except in the `-help`
    case). Change usage() to work with the existing invocations rather
    than fix the invocations.
  * Don't attempt to send an email when passed `-help`.
  * Include the usage error message in the emailed log.
2020-05-28 14:46:13 -04:00
Richard Hansen
3a6a2ac036 Log errors to STDERR 2020-05-28 14:46:13 -04:00
Richard Hansen
d70c3bf784 Delete do-nothing $opt{'syslog'} = 1; when daemonized
That line has no effect because of the `%opt = %saved_opt;` line a few
lines later.
2020-05-28 11:19:13 -04:00
Richard Hansen
d10601de11 Delete redundant $opt{'daemon'} processing
The stuff done in this deleted block is already done in `check_value`.
2020-05-28 11:19:13 -04:00
Sandro
f425cea2d1
Merge pull request #128 from rhansen/ddclientd
Improve default daemonization when run as ddclientd
2020-05-28 05:00:33 +02:00
Sandro
dc81105781
Merge pull request #126 from rhansen/quote-here-doc 2020-05-28 04:52:08 +02:00
Sandro
31993eeb3b
Merge pull request #132 from rhansen/delete-commented-code 2020-05-28 02:22:59 +02:00
Richard Hansen
fcdaf7c3da Delete commented-out code
If it still had value it wouldn't be commented out.
2020-05-27 12:59:50 -04:00
Richard Hansen
e27d6af755 Quote the here-doc delimiter
The quoting might not be required for Perl, but without it Emacs's
syntax highlighting gets very confused.
2020-05-26 22:04:02 -04:00
Richard Hansen
b78144f7d5 Improve default daemonization when run as ddclientd
The output of -help now shows that daemonization is enabled by default
when the command is named something that ends with 'd' (such as
ddclientd).
2020-05-26 21:43:50 -04:00
Sandro Jäckel
4f0226ef05
Fix formatting especially with code examples, apply linter suggestions 2020-05-27 03:27:03 +02:00
Sandro Jäckel
42c21391f3
Update install instructions
Closes #144
2020-05-27 03:18:18 +02:00
Sandro
b6b9878315
Merge pull request #120 from rhansen/whitespace-fixes 2020-05-27 02:32:58 +02:00
Sandro
ee3c90c85f
Merge branch 'master' into whitespace-fixes 2020-05-27 02:32:32 +02:00
Sandro
bc23fd809c
Merge pull request #104 from psiegl/duckdns 2020-05-27 02:29:55 +02:00
Sandro
448e5c22c9
Change password 2020-05-27 02:29:26 +02:00
Richard Hansen
280818b384 Whitespace fixes
* Convert tabs to spaces
  * Use consistent indentation
  * Use consistent vertical alignment
2020-05-26 15:16:51 -04:00
wimpunk
233f1919dd
Removing dnspark (#105)
Removing dnspark as the service doesn't exist anymore.
2020-05-26 20:53:37 +02:00
Sandro Jäckel
3d1ed60812
Merge remote-tracking branch 'rhansen/process_args' (#121) 2020-05-26 20:52:29 +02:00
Sandro Jäckel
ac45f98bcd
Merge remote-tracking branch 'rhansen/sig' (#117) 2020-05-26 20:52:08 +02:00
Sandro Jäckel
ba488414f1
Merge remote-tracking branch 'rhansen/shebang' (#116) 2020-05-26 20:50:43 +02:00
Richard Hansen
b1cc82f2fa Replace Perl -w flag with use warnings;
Also delete the useless 2nd shebang line and bump the required Perl
version.

Now the shebang line conforms with Debian policy 4.1.2 to 4.2.0. See:
https://www.debian.org/doc/debian-policy/upgrading-checklist.html#version-4-1-2

Perl v5.8.0 (released in 2002) was chosen because:
  * `use warnings` was added in Perl v5.6.0 (released 2000)
  * The `require` function itself changed in v5.8.0 to support the
    more readable non-numeric version literal syntax.
2020-05-26 12:10:14 -04:00
Richard Hansen
5211cb55c8 Clean up process_args
* Delete unused variable `%opts`
  * Ensure that `%opt` exists before it is referenced in `process_args`
  * Don't bother returning a copy of `%opt`
2020-05-25 22:43:55 -04:00
Richard Hansen
f47ea295d5 Gracefully exit if interrupted by SIGINT 2020-05-24 21:56:07 -04:00
Richard Hansen
fb67669902 Don't attempt to catch the uncatchable SIGKILL signal 2020-05-24 21:51:26 -04:00
jameskupke
7a9991966b
Updated Namecheap example (#115) 2020-05-10 23:13:08 +02:00
Greg Best
18cc3a99e9
Added support for cloudflare API tokens. (#102)
* Added support for cloudflare API tokens. Do not provide a login if using one. The token must have permissions for All zones - Zone:Read, DNS:Edit.

* Fixed the grammar in the comments.

Co-authored-by: Greg Best <greg@NinjaCatServer>
2020-04-06 20:46:50 +02:00
samwell61
45ae9913f9
Fixed cloudflare cache not updating properly (#98)
Don't use the key for the cache but use the domain.

Co-authored-by: Samuel Bailey <samuel@bingbong.tech>
2020-04-06 20:44:33 +02:00
Patrick Siegl
56d819f4c4 DuckDNS uses https over http 2020-03-04 17:37:33 +01:00
wimpunk
89c2230ada Preparing the release of v3.9.1 2020-01-08 10:56:03 +01:00
wim vinckier
557f822749 README: removed a few sf.net links
We're starting to migrate the website to ddclient.net and the project is
now mostly managed on github so there's no need to mention the old
links.
2019-10-17 21:33:01 +02:00
Dave Smith
e19e1df555
Set $name before trying to adjust it 2019-10-05 20:52:33 -05:00
Dave Smith
321ca60d04
Merge branch 'nfsn-wip' of github.com:Frogging101/ddclient into merge_Frogging101 2019-09-26 20:27:54 -05:00
Dave Smith
9179655803
Fix 74 Use JSON:PP in Yandex 2019-09-21 20:59:27 -05:00
Dave Smith
9d2cdb9fb2
Merge branch 'master' of github.com:ddclient/ddclient 2019-09-12 10:25:59 -05:00
Dave Smith
01cf5bdd2d
Merge branch 'master' of github.com:okeeblow/ddclient 2019-09-12 09:55:51 -05:00
DaveSophoServices
0871aa0360
Merge pull request #65 from SuperSandro2000/SuperSandro2000-patch-1
Add perl modules to install instructions
2019-09-12 09:44:06 -05:00
DaveSophoServices
3b37d3c78d
Merge branch 'master' into SuperSandro2000-patch-1 2019-09-12 09:43:51 -05:00
DaveSophoServices
b41c0d0a16
Merge pull request #66 from kbumsik/master
Add systemd sample and instruction
2019-09-12 09:38:48 -05:00
Dave Smith
c473b904bd
Merge branch 'master' of github.com:madmalkav/ddclient
plus formatting
2019-09-03 20:38:07 -05:00
Dave Smith
b998b3b663 Merge branch 'patch-1' of github.com:SuperSandro2000/ddclient 2019-09-03 20:11:17 -05:00
DaveSophoServices
6c59584352
Merge pull request #69 from AlJohri/update-readme
update readme, document Data::Validate::IP
2019-09-03 19:59:43 -05:00
Dave Smith
8a4c93f592 Stop putting a Content-Type into the request, if one is already present 2019-08-29 09:38:10 -05:00
Dave Smith
0ca0d462ac
Merge branch 'master' of github.com:Akimkin/ddclient 2019-08-22 15:26:41 -05:00
fabianskibr
27b42691b0
add nsupdate.info config samples 2019-08-03 14:57:27 -03:00
Al
4467c63527 update readme, document Data::Validate::IP 2019-06-25 14:16:37 -04:00
Ian Colwell
e910af8bac Restore ability to update multiple namecheap domains (#64)
* Revert to previous functionality
* Revert example config
* Remove redundant commas
* Update example conf
* Revert whitespace formatting
2019-06-06 13:37:51 +02:00
root
30dce80ad0 Add support for dondominio.com 2019-04-06 17:27:22 +02:00
Sandro Jäckel
d90d6799d3
Fix fritz box example for newer routers 2019-04-06 13:14:47 +02:00
Bumsik Kim
3feaf02ebb Add systemd sample and instruction 2019-03-20 12:29:47 +00:00
Sandro Jäckel
1910fb361c
Add perl modules to install instructions 2019-03-19 00:21:53 +01:00
okeeblow
c771d3f81f
Fix errant tabs in nic_dnsmadeeasy_update 2018-10-18 05:07:26 -07:00
Allison Reid
2f7e8ee236 Add support for DNS Made Easy (https://dnsmadeeasy.com)
UPDATE:   Updating 77282436
  DEBUG:    proxy  =
  DEBUG:    url    = https://cp.dnsmadeeasy.com/servlet/updateip?username=xxx@xxx.org&password=xxxxxx&ip=192.168.43.239&id=77282436
  DEBUG:    server = cp.dnsmadeeasy.com
  CONNECT:  cp.dnsmadeeasy.com
  CONNECTED:  using SSL
  SENDING:  GET /servlet/updateip?username=xxx@xxx.org&password=xxxxxxx&ip=192.168.43.239&id=77282436 HTTP/1.0
  SENDING:   Host: cp.dnsmadeeasy.com
  SENDING:   User-Agent: ddclient/3.9.0
  SENDING:   Connection: close
  SENDING:
  SENDING:
  RECEIVE:  HTTP/1.1 200 OK
  RECEIVE:  Server: Apache-Coyote/1.1
  RECEIVE:  Pragma: No-cache
  RECEIVE:  Cache-Control: no-cache
  RECEIVE:  Expires: Thu, 01 Jan 1970 00:00:00 UTC
  RECEIVE:  x-dnsme-requestId: 496b9516-44da-48fc-b750-256f191848f5
  RECEIVE:  Set-Cookie: JSESSIONID=17103D9DF72BB33118DD2177BD8813A0; Path=/; Secure; HttpOnly
  RECEIVE:  Content-Type: text/plain
  RECEIVE:  Date: Thu, 18 Oct 2018 11:41:45 GMT
  RECEIVE:  Connection: close
  RECEIVE:
  RECEIVE:  success
  SUCCESS:  Updating 77282436: good: IP address set to 192.168.43.239
2018-10-18 04:53:21 -07:00
John Brooks
f61b7df439 Document NearlyFreeSpeech.NET support
Add example, update README and sample .conf file
2018-08-12 14:58:32 -04:00
John Brooks
8b83e8f196 Add NearlyFreeSpeech.NET Support 2018-08-12 13:23:58 -04:00
wimpunk
02c983a991 Preparing the release of v3.9.0 2018-08-09 17:58:16 +02:00
Kevin P. Fleming
118cad0f11 Specify port number properly to 'nsupdate' (#58)
If a port number is included in the 'server' configuration item,
ddclient allows a port number to be specified by appending a colon
and the port number to the server's name or IPv4 address. However,
nsupdate does not support this syntax, it requires the port number
to be separated from the server name/address by whitespace.

Signed-off-by: Kevin P. Fleming <kevin@km6g.us>
2018-07-25 11:08:49 +02:00
Denton Liu
ab706ccae0 Fix sample Cloudflare config (#57)
The extra comma bleeds into the API request sent to Cloudflare and, as a
result, causes it to fail. Reordering the options and removing the comma
at the password fliield, fixes this problem.
2018-06-25 16:28:00 +02:00
wimpunk
ec2acfb1f3
Support IPv6 for CloudFlare
This makes the Cloudflare support IPv6-aware.

Ideally, A and AAAA records would be updated in one shot, as CloudFlare has a 5 minute throttling limit for API calls that change records.

Merge pull request #56 from d235j/cloudflare-ipv6
2018-05-23 12:25:05 +02:00
wimpunk
c176457e12
name cheap support https now
Merge pull request #55 from wjzhou/wzhou/namecheap-https
2018-05-23 12:21:24 +02:00
David Ryskalczyk
7e850b7560 Support IPv6 for CloudFlare 2018-05-20 19:24:12 -04:00
Wujun Zhou
1da21d82e1 name cheap support https now
From name cheap it seems http is supported now.
https://www.namecheap.com/support/knowledgebase/article.aspx/29/11/how-to-use-the-browser-to-dynamically-update-hosts-ip

Since the password was send on plaintext, https should be used
2018-05-17 02:37:54 -04:00
wimpunk
3dd2054124
Align ddclient behavior and documentation with namecheap's
Follow expected behavior.  Applying patch #54 from @jmdevince
2018-05-14 18:41:34 +02:00
jmdevince
4394c1914f
Follow expected behavior
Align ddclient behavior and documentation with namecheap's - https://www.namecheap.com/support/knowledgebase/article.aspx/583/11/how-do-i-configure-ddclient
2018-05-04 10:44:59 -05:00
wimpunk
94dc35984f Update version in README
Corrected version number as suggested by @abelbeck.
2017-02-15 21:49:25 +01:00
wimpunk
e33aa2fa96 Adding sample-get-ip-from-fritzbox
Example config showing how to retrieve IP from fritzbox via UPnP
using ddclients cmd option.  The script has been provided by @Rusk85
in pull request #45
2017-02-15 21:31:09 +01:00
Rusk85
40409911b3 script to retrieve IP from fritzbox via UPnP
Original author of this one-liner can be found here:
http://scytale.name/blog/2010/01/fritzbox-wan-ip
2017-02-15 21:26:57 +01:00
wimpunk
fbd62b7cce Use JSON::PP instead of the (deprecated) JSON::Any
As suggeseted in pull request #48 by @abelbeck, this commit replaces
the deprecated JSON::Any by JSON::PP.  This only influences cloudflare
users.
2017-02-15 21:06:56 +01:00
Lonnie Abelbeck
7321959383 cosmetic, remove stray space indent 2017-02-15 21:01:42 +01:00
Lonnie Abelbeck
fca9b2149b Use JSON::PP instead of the (deprecated) JSON::Any 2017-02-15 21:01:42 +01:00
wimpunk
47df8f45b4 Adding support for freemyip.com
Support provided by @Cadence-GitHub in by pull request #47
2017-02-13 21:21:13 +01:00
Tomasz Grabowski
d6359cb7e0 Adding required documentation and examples 2017-01-16 18:12:29 -05:00
Tomasz Grabowski
b3a234a70f Adding support for free dns service at freemyip.com 2017-01-16 18:03:26 -05:00
wimpunk
a9240d00f5 Merge pull request #46 from fcolista/master
sample-etc_rc.d_init.d_ddclient.alpine: openrc uses openrc-run now

Runscript is now absolute.  Pull request #46
2016-11-15 17:55:41 +01:00
Francesco Colista
a785948800 sample-etc_rc.d_init.d_ddclient.alpine: openrc uses openrc-run now, runscript is obsolete 2016-11-14 18:36:19 +00:00
wimpunk
a9ab60e7a1 Merge pull request #44 from esetnik/cloudflare_config
Cloudflare Config fix from #44.

Specifying the `server` directive caused the Cloudflare protocol to use the wrong url when communicating with Cloudflare API v4. It works if the directive is removed.
2016-09-08 15:38:40 +02:00
Ethan Setnik
abb6674d60
update sample config with functional cloudflare settings 2016-09-08 01:08:34 -04:00
wimpunk
df883fd091 Merge pull request #42 from Harry-Xue/master
Update CloudFlare from API v1 to API v4.

Patch provided by @Harry-Xue by pull-request #42
2016-05-25 08:47:27 +02:00
Harry-Xue
f52195700b Add files via upload
Catch up to changes in wimpunk/master.
2016-05-24 21:50:39 -07:00
Harry-Xue
6c951a0395 Add files via upload
Updated CloudFlare API from v1 to v4.
2016-05-24 21:18:08 -07:00
Harry-Xue
1d848de60c Merge pull request #1 from wimpunk/master
Catch up to wimpunk/ddclient
2016-05-24 21:07:01 -07:00
wimpunk
7cad3a497f Merge pull request #38 from MichaelHarder/fix-nsupdate-ipv6-record-type
fix nsupdate using wrong type for ipv6 addresses

nsupdate was failing because it was trying to set an A record with an ipv6 address. This will check for an ipv6 address and use the appropriate record type.
2016-02-11 21:07:06 +01:00
Michael Harder
62c6460784 fix nsupdate using wrong type for ipv6 addresses 2016-02-04 01:06:17 -08:00
wimpunk
747620cf66 Merge branch 'github' 2016-01-26 19:46:24 +01:00
wimpunk
68b9e346d1 Merge branch 'github' 2016-01-26 19:45:46 +01:00
wimpunk
1ec1b291ba Merge pull request #37 from beamerblvd/add-nsupdate-tcp-support
Add support for telling `nsupdate` to use TCP instead of UDP
By default, `nsupdate` uses UDP unless the update size is too large to fit in a UDP datagram, in which case it automatically switches to TCP. This change adds a `tcp` configuration option to the `nsupdate` protocol so that the user can force `nsupdate` to use TCP.
2016-01-26 19:34:44 +01:00
Nick Williams
375d075a3c Add support for telling nsupdate to use TCP instead of UDP
By default, `nsupdate` uses UDP unless the update size is too large to fit in a UDP datagram, in which case it automatically switches to TCP. This change adds a `tcp` configuration option to the `nsupdate` protocol so that the user can force `nsupdate` to use TCP.
2016-01-26 10:42:22 -06:00
wimpunk
35eefc3411 Merge pull request #36 from geraldhansen/master
Add ipv6 support by @geraldhansen
2016-01-25 21:46:51 +01:00
wimpunk
6b7942a139 README: fixing duckdns identation 2016-01-25 21:40:18 +01:00
Gerald Hansen
9ba67ab9f8 fix description for missing package 2016-01-19 10:37:08 +01:00
Gerald Hansen
3c2ef3e24c add ipv6 sample config for myonlineportal.net 2016-01-18 22:43:26 +01:00
Gerald Hansen
dc01f09224 add ipv6 support 2016-01-18 22:31:12 +01:00
Gerald Hansen
027fa03895 add ipv6 support for web option 2016-01-18 12:30:07 +01:00
wimpunk
eafb707437 Revert "Merge branch 'github'"
This reverts commit 38f9762e2c, reversing
changes made to 5bea1a58f7.
2015-12-04 11:54:18 +01:00
wimpunk
38f9762e2c Merge branch 'github'
Conflicts:
	README.md
	ddclient
2015-12-04 11:54:15 +01:00
wimpunk
bec4521ecd Merge branch 'hank-freedns-fix' into github
Fixed the last part of pull request #31 from @hank.
Cleaned up the code on FreeDNS.
2015-12-03 21:39:29 +01:00
wimpunk
5abb9fe1fe Fixing warnings on FreeDNS update NOP
Fix based on pull request #31 on github commited by @hank.
_original comments_
When FreeDNS was updating, I was noticing that it would send back an HTTP 200
with the text "Address [IP] has not changed", but ddclient was issuing a
failed status for this and logging a ton of text to syslog. I changed the
function a tiny bit to allow this to be a success status. I also reformatted
the code to all spaces instead of mixed spaces and tabs, but you can take that
or leave it - I don't really care, it was just a total whitespace disaster
before.
2015-12-03 21:27:41 +01:00
wimpunk
4f7fb1b3aa README: update version number.
This change was suggested in pull request #31 on github by @hank.
2015-12-03 21:18:13 +01:00
Erik Gregg
a2815d5081 Minor change to cache ip on freedns no-change 2015-11-29 14:13:20 -05:00
Erik Gregg
b478bf1a85 Don't issue warnings when freedns IP didn't change
Before this update, freedns warnings would appear in the log even though
FreeDNS sent back a code 200 with a message indicating the IP address was
already correct.  A simple regex change was all that was needed to make this a
success instead.  Now, it looks like this:

DEBUG:    server = freedns.afraid.org
SUCCESS:  updating xxx.xxx.xxx good: IP address has not changed

Conflicts:
	ddclient
2015-11-29 14:09:25 -05:00
wimpunk
5bea1a58f7 Merge pull request #25 from dancapper/master
Adding configurable TTL to Cloudflare

This change adds configurable TTL to cloudflare instead of just using hardcoded value of 1 which sets "automatic" TTL any time ddclient updates the IP address.

git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@195 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-10-13 20:26:00 +00:00
wimpunk
017f04b500 Merge pull request #24 from gkranis/master
Adding duckdns example

Duckdns example added to sample-etc_ddclient.conf

git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@194 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-10-13 20:25:53 +00:00
wimpunk
80046c5a23 Prevent service to start multiple times.
Added messages if trying to start/stop already started/stopped service.
Added daemon install instructions for ubuntu.

git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@193 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-10-13 20:25:45 +00:00
wimpunk
3d996f0878 odd-fw-patch-squashed
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@192 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-10-13 20:12:21 +00:00
wimpunk
19d517284c Added support for woima.fi dyndns service
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@191 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-10-13 20:10:15 +00:00
wimpunk
a2ea922aa3 Merge pull request #11 from Tatsuya-Nonogaki/master
This is the squashed commits of former odd-fw-patch and its addition, which will add functions to;

* un-zeropad IP address returned by some odd routers,
* make $ip UNDEF if get_ip('fw') returned a local IP address.
2015-09-30 21:55:24 +02:00
wimpunk
d197e10556 Merge pull request #24 from gkranis/master
Adding duckdns example

Duckdns example added to sample-etc_ddclient.conf
2015-09-30 21:47:47 +02:00
wimpunk
59147f662b Merge pull request #25 from dancapper/master
Adding configurable TTL to Cloudflare

This change adds configurable TTL to cloudflare instead of just using hardcoded value of 1 which sets "automatic" TTL any time ddclient updates the IP address.
2015-09-30 21:45:22 +02:00
wimpunk
c36b2a0dd7 Merge pull request #26 from jabaz/master
Added support for woima.fi dyndns service
2015-09-30 17:41:33 +02:00
wimpunk
32e6b9bc19 Merge pull request #27 from jabaz/master-ubuntu
Prevent service to start multiple times

Added messages if trying to start/stop already started/stopped service.
Added daemon install instructions for ubuntu.
2015-09-30 17:37:54 +02:00
Janne Hannila
14e8539eaf Prevent service to start multiple times.
Added messages if trying to start/stop already started/stopped service.
Added daemon install instructions for ubuntu.
2015-09-30 14:59:58 +03:00
Janne Hannila
35e6c1a163 Added support for woima.fi dyndns service 2015-09-30 14:54:02 +03:00
wimpunk
e7290d827b Cleanup: removing revision info.
Removing revision info even when it's just in the comments.

git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@190 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-09-28 21:42:02 +02:00
wimpunk
6b6b837b9a Cleanup: removing revision info.
Removing revision info even when it's just in the comments.

git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@190 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-09-28 19:41:09 +00:00
Wim Vinckier
6fc2f511b6 Cleanup: removing revision info from ddclient
Preparing the complete merge with sf.
2015-09-28 21:38:28 +02:00
wimpunk
db5d87ed60 Adding ChangeLog
Since we are not going to fetch the changes from svn anymore,
we add the old ChangeLog again.

git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@189 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-09-28 19:36:18 +00:00
wimpunk
e21442184b Cleanup: removing old ignore files
Switching to git so we don't need .cvsignore anymore

git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@188 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-09-28 19:32:39 +00:00
wimpunk
6b6042bdc3 FSF address
Address for FSF was wrong, corrected

git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@187 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-09-28 19:21:17 +00:00
wimpunk
88c2eb46e6 Cleanup: removing Id tags from the files
Preparing a complete move to git.  The Id tag isn't useful so removing from
the files seemed to be the best solotion

git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@186 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-09-28 21:17:51 +02:00
wimpunk
60fe051b7a Cleanup: removing Id tags from the files
Preparing a complete move to git.  The Id tag isn't useful so removing from
the files seemed to be the best solotion

git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@186 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-09-28 19:13:03 +00:00
dancapper
17d31e4373 typo fix 2015-07-14 22:19:02 +12:00
dancapper
a4ceba9c2b Merge pull request #1 from dancapper/dancapper-patch-1
cloudflare - add ttl to config
2015-07-14 22:13:56 +12:00
dancapper
a7fce1a9bd add ttl for cloudflare 2015-07-14 22:13:22 +12:00
dancapper
331a5491af cloudflare - add ttl to config
Configurable ttl for cloudflare instead of hardcoded 1 (auto)
2015-07-14 22:11:41 +12:00
George Kranis
4a640ed4c0 duckdns example 2015-06-01 22:02:37 +03:00
wimpunk
3cbb0f42f9 Merge pull request #23 from MedicMomcilo/patch-1
Corrected FSF address.

Merging pull request #23 from @MedicMomcilo
2015-05-31 11:27:36 +02:00
MedicMomcilo
c497ed04c7 FSF address
Address for FSF was wrong, corrected
2015-05-31 01:55:41 +02:00
wimpunk
83a5f70e4c Preparing for v3.8.3
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@184 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-05-28 19:59:34 +00:00
wimpunk
3b1b6fa8f8 Removing unneeded release directory
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@183 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-05-28 19:36:06 +00:00
wimpunk
ee9ecc75d6 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.


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@182 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-03-23 19:03:15 +00:00
wimpunk
ba6ec1cb70 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.



git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@181 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-03-23 18:53:56 +00:00
wimpunk
79fe974a94 ddclient: reindenting cloudflare
Indenting cloudflare according to the vim tags


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@180 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-03-23 18:52:33 +00:00
wimpunk
4456c4863a ddclient: correction after duckdns merge
Correcting duckdns configuration after commit r178


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@179 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-03-23 18:51:07 +00:00
wimpunk
ddf25d3ab1 Added simple support for Duckdns www.duckdns.org
Patch provided by gkranis on github.
Merge branch 'gkranis'



git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@178 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-03-23 18:46:16 +00:00
wimpunk
3ec5dd56c6 Added duckDNS to the README.md
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@177 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-03-21 11:58:29 +00:00
wimpunk
6dee46c0aa update ubuntu init.d script
Merge pull request #9 from gottaloveit/master


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@176 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-03-21 11:51:03 +00:00
wimpunk
7272ed73ba Renamed Changelog to Changelog.old
Avoiding conflicts on case insensitive filesystems


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@175 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-03-21 10:48:19 +00:00
wimpunk
9037a9b762 Add missing config line for CloudFlare
Merge pull request #19 from shikasta-net/fixes



git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@174 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-03-21 10:43:29 +00:00
wimpunk
8e2dc5d3b8 Merge pull request #22 from reddyr/patch-1
loopia.se changed the "Current Address:" output string to "Current IP
Address:"



git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@173 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-03-21 10:39:35 +00:00
wimpunk
ebe8a28c65 fixed missing ) for cloudflare service hash
Merge pull request #16 from adepretis/master


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@172 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-03-21 10:34:18 +00:00
Denis Akimkin
9c5b933bef Add support for Yandex.Mail for Domain DNS service (domain.yandex.com)
Yandex's DNS management API reference is located at:
https://api.yandex.com/domain/doc/about.xml
2015-03-09 00:52:36 +02:00
wimpunk
c12ee9123c Adding support for google domain
Patch gently provided through github on
https://github.com/wimpunk/ddclient/pull/13


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@171 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2015-01-20 11:57:13 +00:00
Tatsuya-Nonogaki
441f58fdb1 odd-fw-patch-squashed 2014-12-30 01:58:57 +09:00
wimpunk
e384564d12 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.


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@170 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2014-10-08 13:28:29 +00:00
wimpunk
a52ddf7492 Bugfix: allowing long username-password combinations
Patch provided by dirdi through github.


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@169 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2014-09-09 07:00:39 +00:00
wimpunk
4721e3c5b1 Fixing bug #72: Account info revealed during noip update
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@166 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2014-08-20 06:11:16 +00:00
wimpunk
5495a18d19 Interfaces can be named almost anything on modern systems.
Patch provided by Stephen Couchman through github


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@165 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2014-08-20 06:08:41 +00:00
wimpunk
9912a765dd 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


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@164 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2014-06-30 19:20:35 +00:00
wimpunk
0a245f8c9b Adding support for nsupdate.
Patch provided by Daniel Roethlisberger <daniel@roe.ch> through github.


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@163 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2014-06-02 19:51:10 +00:00
wimpunk
bed1b56671 Removed revision information
Revision information isn't very usable when switching to git.



git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@162 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2014-04-29 17:51:59 +00:00
wimpunk
db57ab1c97 Added Alpine Linux init script
Patch send by Tal on github.


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@161 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2014-03-20 20:02:14 +00:00
wimpunk
7a132fc676 Corrected release note
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@160 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2014-03-20 19:56:58 +00:00
wimpunk
de6b2ee8a4 Commiting updated release information
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@159 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2013-12-26 09:42:35 +00:00
wimpunk
ffc7eade7f Committing release notes and readme information to trunk
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@158 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2013-12-26 09:42:01 +00:00
wimpunk
aed1e51328 Moving patching to the root of the repository.
The patches are mostly there for historical reasons.  They've been moved
away to make cleaning easier.  I think the applied patches should even be
removed.


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@156 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2013-11-05 21:04:30 +00:00
wimpunk
b0e6b06188 Fallback to iproute if ifconfig doesn't work.
This fix applies the patch provided by Maccied Grela in [bugs:#26]


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@155 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2013-10-28 22:38:56 +00:00
wimpunk
9fa0e5872b preventing deep sleep - see [bugs:#46]
Fixing [bugs:#46] by applying the provided patch.


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@154 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2013-10-28 21:37:16 +00:00
wimpunk
65c6f32f57 Applying patch from [fb1ad014] fixing bug [#14]
More info can be found on [fb1ad014] and has been discussed in the mailinglist:
http://article.gmane.org/gmane.network.dns.ddclient.user/71.  The patch was
send by Rodrigo Araujo.


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@153 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2013-07-08 13:20:35 +00:00
wimpunk
b8aa76214e Adding sha1-patch provided by pirast in [9742ac09]
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@152 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2013-05-14 19:10:05 +00:00
wimpunk
efc62a3d41 Adding support for ChangeIP based on the patch from Michele Giorato
http://sourceforge.net/p/ddclient/discussion/399428/thread/e85661ad/


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@150 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2013-04-28 14:55:34 +00:00
wimpunk
415fb15634 Updated README file
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@148 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2013-04-28 14:28:00 +00:00
wimpunk
face3058aa Applying markdown synstax to README
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@147 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2013-04-28 14:16:02 +00:00
wimpunk
1b406ca4c6 Updates after releasing 3.8.1
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@131 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2011-07-11 22:21:49 +00:00
wimpunk
80b0c44e70 Corrected release/readme.txt
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@129 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2011-07-11 20:53:57 +00:00
wimpunk
326c026b1d Applied ip-up_run-parts.diff from ubuntu
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@128 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2011-07-11 20:24:43 +00:00
wimpunk
fa6d1714c4 Applied smc-barricade-fw-alt.diff from ubuntu
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@127 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2011-07-11 20:21:28 +00:00
wimpunk
790c3f8966 Fixing #28: FreeDNS.afraid.org changed api slightly
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@126 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2011-07-03 10:03:39 +00:00
wimpunk
1b4c31b82e Added patch for dtdns-support (#39)
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@125 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2011-05-19 20:31:20 +00:00
wimpunk
e0a1283b10 Patching with nic_updateable-warning patch provided by antespi in ticket #2
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@124 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2011-03-09 07:39:18 +00:00
wimpunk
4a21e0ac53 Patching with zoneedit patch provided by killer-jk in ticket #15
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@123 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2011-03-08 21:21:08 +00:00
wimpunk
6ff4d054b7 Added longer password support, sended by Ingo Schwarze (#3130634)
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@122 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2010-12-07 07:25:08 +00:00
wimpunk
e406318257 Fixing bug #13: multiple fetch-ip but introducing a multiple ip bug
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@121 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2010-10-13 20:29:16 +00:00
wimpunk
4edbb7a3e9 patch for #10: invalid value for keyword ip
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@120 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2010-09-14 11:19:47 +00:00
wimpunk
a7d8c50e06 Applied patch from ticket #8, patch for cache content leaks to global
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@119 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2010-09-13 06:31:58 +00:00
wimpunk
c3a888bc6a Applied patch from ticket #7, provided by Chris Carr
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@118 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2010-09-13 06:28:14 +00:00
wimpunk
290190cdfd Fixed #6: Add Red Hat package name to Perl module IO::Socket::SSL error message
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@117 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2010-07-01 08:08:57 +00:00
wimpunk
e688f232cf Subversion revision added
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@116 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2010-02-24 23:05:22 +00:00
wimpunk
d5b70d1665 Added cisco-asa patch (2891001) submitted by Philip Gladstone
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@115 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2009-11-09 20:46:17 +00:00
wimpunk
8fff829fa2 Added prevent-hang patch (2880462) submitted by Panos
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@114 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2009-11-09 20:25:58 +00:00
wimpunk
7f7c7ac15b Added foreground patch (1893144) submitted by John Palkovic
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@113 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2009-10-19 08:24:25 +00:00
wimpunk
ea34d551cb #1609799 Support for LoopiaDNS (submitted by scilence)
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@112 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2009-09-10 10:21:19 +00:00
wimpunk
beab2f1052 applied freedns patch (patch 2832129)
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@111 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2009-08-05 21:13:15 +00:00
wimpunk
a5d0064af9 Bug 2792436: fixed abuse message of dyndns
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@110 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2009-05-16 10:07:26 +00:00
wimpunk
a62b850e27 Added warning about the update interval (#2619505)
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@109 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2009-02-27 07:30:46 +00:00
wimpunk
428ff2e223 Modified during the release of ddclient-3.8.0
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@108 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2009-01-27 20:17:52 +00:00
wimpunk
7a437f9fdb help about postscript added
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@106 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-12-04 18:05:23 +00:00
wimpunk
8b2d89d707 Added better password handling sended by Ingo Schwarze
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@105 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-11-19 21:09:07 +00:00
wimpunk
f5721bd42f Added ddclient wrapper script
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@104 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-11-19 21:04:16 +00:00
wimpunk
bd74f3ff0f Extra fix for multiple IP's
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@103 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-11-19 20:56:18 +00:00
wimpunk
6e3ef3a2a9 Added some remarks concerning the postscript. See
https://sourceforge.net/forum/message.php?msg_id=5550545


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@102 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-11-01 11:23:03 +00:00
wimpunk
c92e2d1c61 Added support for multiple IP adresses. See
http://permalink.gmane.org/gmane.network.dns.ddclient.user/17


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@101 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-09-30 20:49:07 +00:00
wimpunk
eb93d66237 extra comments added to namecheap patch
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@100 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-09-30 20:41:53 +00:00
wimpunk
d0f9a33f19 namecheap patch added to patches section
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@99 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-07-04 17:04:42 +00:00
wimpunk
61cbbb806e New trunk created based on the old trunk/svn
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@98 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-06-13 20:26:56 +00:00
wimpunk
34828d3d47 Moved old trunk/svn to ddclient and it will be the new trunk
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@96 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-06-13 20:24:24 +00:00
wimpunk
6fa269d37d Moved old trunk/svn to ddclient and it will be the new trunk
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/ddclient@96 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-06-13 20:24:24 +00:00
wimpunk
9346074251 Ignoring test configuration
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@95 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-06-13 20:21:02 +00:00
wimpunk
3eb6a3af25 Ignoring test configuration
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@95 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-06-13 20:21:02 +00:00
wimpunk
561fb5bbd8 Added some release related files
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@94 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-06-13 20:11:07 +00:00
wimpunk
7d03b7a6a0 Added some release related files
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@94 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-06-13 20:11:07 +00:00
wimpunk
365a1b3598 Added not used no-host patch to patches section
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@93 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-06-13 20:08:38 +00:00
wimpunk
2c3faf69c7 Added not used no-host patch to patches section
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@93 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-06-13 20:08:38 +00:00
wimpunk
1e5829363f Removed xml directory from trunk
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@92 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-06-13 19:56:44 +00:00
wimpunk
f453209e82 Moved old html directory to new location
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@91 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-06-13 19:54:45 +00:00
wimpunk
28aae6ba08 Added more info about the daemon interval
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@90 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-06-05 19:33:41 +00:00
wimpunk
5b02058fb8 Added more info about the daemon interval
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@90 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-06-05 19:33:41 +00:00
wimpunk
2c82f89c54 Preventing error while reading cache when ip wasn't set correctly before
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@89 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-06-05 19:10:53 +00:00
wimpunk
5fc7106be7 Preventing error while reading cache when ip wasn't set correctly before
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@89 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-06-05 19:10:53 +00:00
wimpunk
e4856a0add Preventing an error when trying to send a message on mail-failure
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@88 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-06-05 07:04:20 +00:00
wimpunk
20bfbfbbef Preventing an error when trying to send a message on mail-failure
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@88 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-06-05 07:04:20 +00:00
wimpunk
f2bdafd2a0 Modified documentation about zoneedit based on the comments from Oren Held
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@87 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-06-02 21:10:25 +00:00
wimpunk
ded79ea64e Modified documentation about zoneedit based on the comments from Oren Held
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@87 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-06-02 21:10:25 +00:00
wimpunk
08d827bb5c Added patch which was applied to rev 27 (posted by James deBoer)
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@86 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-03-04 08:33:41 +00:00
wimpunk
a899e41127 Added patch which was applied to rev 27 (posted by James deBoer)
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@86 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-03-04 08:33:41 +00:00
wimpunk
751664bb66 Patch modified to apply on ddclient 3.7.3
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@85 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-02-19 15:01:04 +00:00
wimpunk
cb4b18e620 Patch modified to apply on ddclient 3.7.3
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@85 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-02-19 15:01:04 +00:00
wimpunk
54a61d76a6 Added mail-on-kill patch to patches section
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@84 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-02-08 10:08:24 +00:00
wimpunk
03838725fc Added mail-on-kill patch to patches section
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@84 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-02-08 10:08:24 +00:00
wimpunk
8c5ba3a09c Sending mail when killed, not after TERM-signal
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@83 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-02-05 08:31:06 +00:00
wimpunk
a97eed732f Sending mail when killed, not after TERM-signal
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@83 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-02-05 08:31:06 +00:00
wimpunk
67f751b154 Added creation of cache dir
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@82 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-02-05 08:16:11 +00:00
wimpunk
53ccfe931d Added creation of cache dir
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@82 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2008-02-05 08:16:11 +00:00
wimpunk
6fb184641d Added and applied default timeout patch from
https://bugs.launchpad.net/ubuntu/+source/ddclient/+bug/116066


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@81 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-10-29 21:02:20 +00:00
wimpunk
0665e32378 Added and applied default timeout patch from
https://bugs.launchpad.net/ubuntu/+source/ddclient/+bug/116066


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@81 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-10-29 21:02:20 +00:00
wimpunk
5a30d09f60 Added ddclient-noip.patch send by Kurt Bussche.
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@80 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-08-29 09:04:33 +00:00
wimpunk
cf90b72d7b Added ddclient-noip.patch send by Kurt Bussche.
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@80 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-08-29 09:04:33 +00:00
wimpunk
fdfde09d7b Updated version number to 3.7.3
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@78 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-08-07 06:35:55 +00:00
wimpunk
84646fdbde Updated version number to 3.7.3
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@78 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-08-07 06:35:55 +00:00
wimpunk
07e20debfe Applied typo_dnspark.patch send by Marco
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@77 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-08-01 07:31:43 +00:00
wimpunk
5574607cec Applied typo_dnspark.patch send by Marco
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@77 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-08-01 07:31:43 +00:00
wimpunk
8850e7d327 Renamed dyndns.org to dyndns.com
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@76 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-31 07:06:48 +00:00
wimpunk
847e1d6965 Renamed dyndns.org to dyndns.com
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@76 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-31 07:06:48 +00:00
wimpunk
f4996ca163 Removed ^M at line 37
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@75 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-31 07:05:20 +00:00
wimpunk
dcfb7d4281 Removed ^M at line 37
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@75 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-31 07:05:20 +00:00
wimpunk
dd1128260f Removed line 183, comments on Vigor 2200 USB
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@74 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-31 07:00:11 +00:00
wimpunk
2509245170 Removed line 183, comments on Vigor 2200 USB
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@74 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-31 07:00:11 +00:00
wimpunk
9d68dba7aa Ignoring ChangeLog since autogenerated
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@73 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-30 20:12:56 +00:00
wimpunk
969c590c03 Ignoring ChangeLog since autogenerated
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@73 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-30 20:12:56 +00:00
wimpunk
ebc443f9a2 Notification about changed ChangeLog configuration
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@72 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-30 20:04:30 +00:00
wimpunk
5f10c9fbbc Notification about changed ChangeLog configuration
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@72 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-30 20:04:30 +00:00
wimpunk
b3c386329e Removed patch since it's invalid
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@71 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-30 10:14:30 +00:00
wimpunk
2b9db93c05 Removed patch since it's invalid
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@71 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-30 10:14:30 +00:00
wimpunk
0857501e11 Added not applied opendns.patch, see tracker #1758564
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@70 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-30 07:13:33 +00:00
wimpunk
b605c97186 Added not applied opendns.patch, see tracker #1758564
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@70 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-30 07:13:33 +00:00
wimpunk
b507eec71a Added debian and ubuntu patches
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@69 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-30 07:11:22 +00:00
wimpunk
2863dd459d Added debian and ubuntu patches
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@69 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-30 07:11:22 +00:00
wimpunk
d58f40b5c3 Added url to feature request dyndns
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@68 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-29 19:07:49 +00:00
wimpunk
ad4578a3e0 Added url to feature request dyndns
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@68 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-29 19:07:49 +00:00
wimpunk
f6a7831c59 Run dos2unix on readme and it's patch which Marco Rodrigues submitted.
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@67 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-12 20:19:51 +00:00
wimpunk
962dc85e1b Run dos2unix on readme and it's patch which Marco Rodrigues submitted.
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@67 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-12 20:19:51 +00:00
wimpunk
47692944c8 Partial applied readme.patch. See tracker #1752931
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@66 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-12 20:12:37 +00:00
wimpunk
55cf02920b Partial applied readme.patch. See tracker #1752931
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@66 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-12 20:12:37 +00:00
wimpunk
9029bdb00d signature modified
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@65 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-10 21:04:00 +00:00
wimpunk
217d1ca825 signature modified
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@65 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-10 21:04:00 +00:00
wimpunk
5c8edddbd6 Added website to ddclient comments
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@64 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-10 20:04:28 +00:00
wimpunk
e913a475a5 Added website to ddclient comments
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@64 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-10 20:04:28 +00:00
wimpunk
cf0fa41393 Added extra comments to the patch.
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@63 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-10 19:56:19 +00:00
wimpunk
85c4821628 Added extra comments to the patch.
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@63 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-10 19:56:19 +00:00
wimpunk
6a8ad8f878 Added patches and applied regex_vlan.patch. See bug #1747337
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@62 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-10 19:36:37 +00:00
wimpunk
0cb7275311 Added patches and applied regex_vlan.patch. See bug #1747337
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@62 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-10 19:36:37 +00:00
wimpunk
3828b022d1 Applied typo_namecheap_patch.diff send by Marco Rodrigues
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@61 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-10 07:26:28 +00:00
wimpunk
728694e795 Applied typo_namecheap_patch.diff send by Marco Rodrigues
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@61 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-10 07:26:28 +00:00
wimpunk
8927454256 Reverted the patch from torsten. See [ 1749470 ] Bug in Script sample-etc_ppp_ip-up.local
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@60 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-07 12:37:42 +00:00
wimpunk
2597d38632 Reverted the patch from torsten. See [ 1749470 ] Bug in Script sample-etc_ppp_ip-up.local
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@60 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-07 12:37:42 +00:00
wimpunk
5276d3a801 Adding some release documentation
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@59 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-04 08:02:33 +00:00
wimpunk
24dee446e1 Adding some release documentation
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@59 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-07-04 08:02:33 +00:00
wimpunk
ff087571a8 Changed version number
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@57 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-06-14 06:36:34 +00:00
wimpunk
ee766fccc2 Changed version number
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@57 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-06-14 06:36:34 +00:00
wimpunk
d2800e7d50 Patches directory added
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@55 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-06-14 06:31:37 +00:00
wimpunk
027bd8df29 Patches directory added
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@55 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-06-14 06:31:37 +00:00
wimpunk
7d39485a75 3com-oc-remote812 patch by The_Beast via IRC: see patches/3com-oc-remote812.patch
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@54 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-06-12 07:10:24 +00:00
wimpunk
68ab0f5d25 3com-oc-remote812 patch by The_Beast via IRC: see patches/3com-oc-remote812.patch
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@54 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-06-12 07:10:24 +00:00
wimpunk
e8ef4acf5e Applied easydns.patch, patch 117054
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@53 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-06-05 21:34:45 +00:00
wimpunk
b1f3e574e6 Applied easydns.patch, patch 117054
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@53 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-06-05 21:34:45 +00:00
wimpunk
fa31265d6b Changed nic_namecheap_update following the suggestion of edmdude on the forum (https://sourceforge.net/forum/message.php?msg_id=4316938)
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@52 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-05-28 17:02:31 +00:00
wimpunk
183df2a7eb Changed nic_namecheap_update following the suggestion of edmdude on the forum (https://sourceforge.net/forum/message.php?msg_id=4316938)
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@52 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-05-28 17:02:31 +00:00
wimpunk
31e4f9c103 Updated the link to the ubuntu forum
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@51 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-05-21 15:38:42 +00:00
wimpunk
8d0642e4d8 Mentioning the wiki pages
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@50 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-05-19 13:54:03 +00:00
wimpunk
ecf806ef1a Added some ubuntu specific stuff.
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@49 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-05-19 12:07:49 +00:00
wimpunk
43131c64d1 Cosmetic change about checkip
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@48 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-05-19 11:40:57 +00:00
wimpunk
904588184a Cosmetic change about checkip
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@48 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-05-19 11:40:57 +00:00
wimpunk
85bb9aaee2 Applied checked_ssl_load.diff from ubuntu
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@47 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-05-19 11:22:59 +00:00
wimpunk
d18857e39d Applied checked_ssl_load.diff from ubuntu
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@47 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-05-19 11:22:59 +00:00
wimpunk
71b8022af1 Removed the two empty lines at the end of ddclient
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@46 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-05-19 11:20:35 +00:00
wimpunk
4fa1a884ef Removed the two empty lines at the end of ddclient
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@46 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-05-19 11:20:35 +00:00
wimpunk
d5a1bb85c1 Added a faq
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@45 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-02-26 21:21:26 +00:00
wimpunk
1362a87793 added a TODO list
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@44 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-02-26 07:43:59 +00:00
wimpunk
7d4520d12a added a TODO list
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@44 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-02-26 07:43:59 +00:00
wimpunk
6ff9e58e14 Preventing unitialized values, check https://sourceforge.net/forum/message.php?msg_id=4167772
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@43 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-02-21 16:54:08 +00:00
wimpunk
76bd12a948 Preventing unitialized values, check https://sourceforge.net/forum/message.php?msg_id=4167772
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@43 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-02-21 16:54:08 +00:00
wimpunk
1b974b3280 Added extra p tag
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@41 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-01-25 15:24:44 +00:00
wimpunk
154a0f11c0 Changed max-interval to 25days. See https://www.dyndns.com/services/dns/dyndns/faq.html
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@40 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-01-24 23:41:16 +00:00
wimpunk
7247771d63 Changed max-interval to 25days. See https://www.dyndns.com/services/dns/dyndns/faq.html
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@40 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2007-01-24 23:41:16 +00:00
wimpunk
57b59643ae Applied maxinterval.diff: Increase max interval for updates.
See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=129370
http://www.dyndns.com/support/services/dyndns/faq.html#q15



git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@39 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-12-03 10:43:16 +00:00
wimpunk
87a001faac Applied maxinterval.diff: Increase max interval for updates.
See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=129370
http://www.dyndns.com/support/services/dyndns/faq.html#q15



git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@39 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-12-03 10:43:16 +00:00
wimpunk
c30044a79f Applied cisco_fw.diff: Use configured hostname for firewall access with
-use=cisco (closes: #345712). Thanks to Per Carlson for the patch!
See http://bugs.debian.org/345712. 


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@38 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-12-03 10:38:29 +00:00
wimpunk
d978f06204 Applied cisco_fw.diff: Use configured hostname for firewall access with
-use=cisco (closes: #345712). Thanks to Per Carlson for the patch!
See http://bugs.debian.org/345712. 


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@38 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-12-03 10:38:29 +00:00
wimpunk
97438a3575 Applied smc-barricade-7401bra.patch: Support for SMC Barricade 7401BRA FW
firewall (submitted by Torsten)
Changelog modified for all previous patches from Torsten


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@37 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-12-02 15:00:48 +00:00
wimpunk
33dad60c7a Applied smc-barricade-7401bra.patch: Support for SMC Barricade 7401BRA FW
firewall (submitted by Torsten)
Changelog modified for all previous patches from Torsten


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@37 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-12-02 15:00:48 +00:00
wimpunk
38147d7e09 Applied update-new-config.patch: Force update if config has changed
(submitted by Torsten)


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@36 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-12-02 14:53:59 +00:00
wimpunk
344c36c607 Applied update-new-config.patch: Force update if config has changed
(submitted by Torsten)


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@36 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-12-02 14:53:59 +00:00
wimpunk
be05257113 Applied ip-up_run-parts.diff: Fix parameter in ip-up script.
(submitted by Torsten)


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@35 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-12-02 14:46:01 +00:00
wimpunk
c3b2771c8b Applied ip-up_run-parts.diff: Fix parameter in ip-up script.
(submitted by Torsten)


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@35 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-12-02 14:46:01 +00:00
wimpunk
f1ef8ac065 Applied help_nonroot.diff: Allow calling the help function as non-root.
(submitted by Torsten)


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@34 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-12-02 14:40:37 +00:00
wimpunk
33b438c5f9 Applied help_nonroot.diff: Allow calling the help function as non-root.
(submitted by Torsten)


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@34 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-12-02 14:40:37 +00:00
wimpunk
d61684e22f Applied cachedir.diff: Original ddclient stores a cache file in /etc which
would belong in /var/cache in my opinion and according to the FHS.  Patch
changes that. (submitted by Torsten)


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@33 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-12-02 14:16:42 +00:00
wimpunk
9383adf9d9 Applied cachedir.diff: Original ddclient stores a cache file in /etc which
would belong in /var/cache in my opinion and according to the FHS.  Patch
changes that. (submitted by Torsten)


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@33 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-12-02 14:16:42 +00:00
wimpunk
a8f27939eb Applied abuse_msg.diff: ddclient still reports the email to contact dyndns.org
but they prefer a web form today (IIRC). This patch adjusts the abuse warning
printed by ddclient. (submitted by Torsten)


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@32 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-12-02 14:11:48 +00:00
wimpunk
e9cdb27f95 Applied abuse_msg.diff: ddclient still reports the email to contact dyndns.org
but they prefer a web form today (IIRC). This patch adjusts the abuse warning
printed by ddclient. (submitted by Torsten)


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@32 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-12-02 14:11:48 +00:00
wimpunk
799570d381 Changed Changelog syntax
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@31 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-12-02 14:09:38 +00:00
wimpunk
f299ce5ccb Changed Changelog syntax
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@31 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-12-02 14:09:38 +00:00
wimpunk
5cd586e38d Don't send any mail when in not running daemon mode (patch submitted by Daniel Thaler)
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@30 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-11-27 07:47:33 +00:00
wimpunk
af4b8d2df8 Don't send any mail when in not running daemon mode (patch submitted by Daniel Thaler)
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@30 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-11-27 07:47:33 +00:00
wimpunk
2740a57766 Added a little irc comment
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@29 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-11-14 07:45:20 +00:00
wimpunk
39a4848787 Added patch "Patch: Treat --daemon values as intervals"
(submitted by James deBoer)


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@28 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-11-03 08:01:41 +00:00
wimpunk
15fa2c995f Added patch "Patch: Treat --daemon values as intervals"
(submitted by James deBoer)


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@28 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-11-03 08:01:41 +00:00
wimpunk
a596670250 Modified todo.txt
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@27 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-10-01 11:38:16 +00:00
wimpunk
a5a3211944 Made website more Valid XHTML
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@26 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-10-01 11:29:58 +00:00
wimpunk
fae4976112 Added subversion to download section
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@25 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-10-01 10:02:31 +00:00
wimpunk
def5573d5a forgot to close a div tag
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@24 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-10-01 09:50:20 +00:00
wimpunk
7c28ea4c35 Added some svn keywords
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@23 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-10-01 09:47:57 +00:00
wimpunk
7054e7736e Added initscript for Ubuntu (posted by Paolo Martinelli)
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@22 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-09-30 13:15:58 +00:00
wimpunk
b0c449fd3f Added initscript for Ubuntu (posted by Paolo Martinelli)
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@22 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-09-30 13:15:58 +00:00
wimpunk
39f833279a URL of zoneedit has changed (see bug #1558483)
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@21 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-09-14 14:24:46 +00:00
wimpunk
2bd881d433 URL of zoneedit has changed (see bug #1558483)
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@21 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-09-14 14:24:46 +00:00
wimpunk
bddbb84cc0 Changed indentation
Using constants for pages


git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@20 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-09-13 06:49:40 +00:00
wimpunk
280f7dd971 Changed todo a little
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@19 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-09-12 07:04:46 +00:00
wimpunk
de8c7553b3 postscript added
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@18 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-09-11 06:38:27 +00:00
wimpunk
81aec1d061 Added step by step
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@17 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-09-07 19:44:27 +00:00
wimpunk
ccab4ab8d1 Added a todo list for the website
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@16 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-09-07 15:49:06 +00:00
wimpunk
c18902e3ad Initial xml.php file
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@15 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-06-20 17:09:06 +00:00
wimpunk
e28475fbc5 Splitted index.php in different files
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@14 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-06-19 10:47:23 +00:00
wimpunk
d29bee992f Added xml.php for debugging
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@13 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-06-19 10:28:43 +00:00
wimpunk
5cdb05bfef Debuginformation added.
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@12 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-06-19 10:23:50 +00:00
wimpunk
3e3f3efa61 Changed version number
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@11 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-06-14 20:53:35 +00:00
wimpunk
0bf9df0a65 Changed version number
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@11 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-06-14 20:53:35 +00:00
wimpunk
cbd2c978b4 Created trunk and tags, moved directories to it
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk/svn@8 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-06-14 19:51:39 +00:00
wimpunk
787b76f4a3 Created trunk and tags, moved directories to it
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/trunk@8 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-06-14 19:51:39 +00:00
wimpunk
3db9527a8d Changed the order of perl and update of README.ssl
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/svn@6 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-06-14 19:28:49 +00:00
ddfisher
94c30b3434 see Changelog
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/svn@5 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-06-11 08:30:49 +00:00
ddfisher
179303adc9 updated changelog
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/svn@4 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-06-10 01:55:14 +00:00
ddfisher
a487e35755 See Changelog
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/svn@3 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-06-10 01:47:41 +00:00
wimpunk
74f33b719d Reorganise
git-svn-id: svn+ssh://svn.code.sf.net/p/ddclient/code/svn@2 3873ddee-7413-0410-b6c4-c2c57c1ab35a
2006-05-22 19:37:19 +00:00
143 changed files with 37140 additions and 5769 deletions

6
.autom4te.cfg Normal file
View file

@ -0,0 +1,6 @@
# Disable autom4te cache to ensure that any change to ddclient.in triggers a
# rebuild of the configure script (which gets the version of ddclient from
# ddclient.in). See <https://lists.gnu.org/r/automake/2019-10/msg00002.html>.
begin-language: "Autoconf-without-aclocal-m4"
args: --no-cache
end-language: "Autoconf-without-aclocal-m4"

5
.envrc Normal file
View file

@ -0,0 +1,5 @@
if has lorri; then
eval "$(lorri direnv)"
else
use nix
fi

111
.github/workflows/ci.yml vendored Normal file
View file

@ -0,0 +1,111 @@
name: CI
on:
push:
pull_request:
jobs:
test-debian-like:
strategy:
fail-fast: false
matrix:
image:
- ubuntu:latest
- ubuntu:20.04
- debian:testing
- debian:stable
- debian:oldstable
runs-on: ubuntu-latest
container:
image: ${{ matrix.image }}
steps:
- name: install dependencies
run: |
apt-get update &&
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
automake \
ca-certificates \
git \
curl \
libhttp-daemon-perl \
libhttp-daemon-ssl-perl \
libplack-perl \
libtest-mockmodule-perl \
libtest-tcp-perl \
libtest-warnings-perl \
liburi-perl \
libwww-perl \
net-tools \
make \
;
- uses: actions/checkout@v4
- name: autogen
run: ./autogen
- name: configure
run: ./configure
- name: check
run: make VERBOSE=1 AM_COLOR_TESTS=always check
- name: distcheck
run: make VERBOSE=1 AM_COLOR_TESTS=always distcheck
- name: distribution tarball is complete
run: ./.github/workflows/scripts/dist-tarball-check
- if: ${{ matrix.image == 'debian:testing' }}
uses: actions/upload-artifact@v4
with:
name: distribution-tarball
path: ddclient-*.tar.gz
test-fedora-like:
strategy:
fail-fast: false
matrix:
image:
- fedora:39
- fedora:latest
- fedora:rawhide
- almalinux:8
- almalinux:latest
runs-on: ubuntu-latest
container:
image: ${{ matrix.image }}
steps:
- uses: actions/checkout@v4
- name: enable repositories (AlmaLinux 8)
if: ${{ matrix.image == 'almalinux:8' }}
run: |
dnf --refresh install -y 'dnf-command(config-manager)' epel-release &&
dnf config-manager --set-enabled powertools
- name: enable repositories (AlmaLinux latest)
if: ${{ matrix.image == 'almalinux:latest' }}
run: |
dnf --refresh install -y 'dnf-command(config-manager)' epel-release &&
dnf config-manager --set-enabled crb
- name: install dependencies
# The --skip-broken argument works around missing packages. (They're
# only used for testing, so it's OK to not install them.)
run: |
dnf --refresh install --skip-broken -y \
automake \
findutils \
iproute \
make \
curl \
perl \
perl-HTTP-Daemon \
perl-HTTP-Daemon-SSL \
perl-IO-Socket-INET6 \
perl-Plack \
perl-Test-MockModule \
perl-Test-TCP \
perl-Test-Warnings \
perl-core \
perl-libwww-perl \
net-tools \
;
- name: autogen
run: ./autogen
- name: configure
run: ./configure
- name: check
run: make VERBOSE=1 AM_COLOR_TESTS=always check
- name: distcheck
run: make VERBOSE=1 AM_COLOR_TESTS=always distcheck

49
.github/workflows/pr.yml vendored Normal file
View file

@ -0,0 +1,49 @@
name: Pull Request
on:
pull_request:
types:
- labeled
- opened
- reopened
- synchronize
- unlabeled
jobs:
linear-history:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'pr-permit-nonlinear') }}
name: Linear History
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: No new merge commits
run: |
log() { printf %s\\n "$*" >&2; }
error() { log "ERROR: $@"; }
fatal() { error "$@"; exit 1; }
try() { log "Running command $@"; "$@" || fatal "'$@' failed"; }
out=$(try git rev-list -n 1 --merges '${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}') || exit 1
[ -z "${out}" ] || {
error "pull request includes a merge commit and does not have the 'pr-permit-nonlinear' label"
git show "${out}" >&2
exit 1
}
no-autosquash:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'pr-permit-autosquash') }}
name: No --autosquash commits
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: 'No commits with messages starting with "fixup!", "squash!", or "amend!"'
run: |
log() { printf %s\\n "$*" >&2; }
error() { log "ERROR: $@"; }
fatal() { error "$@"; exit 1; }
try() { log "Running command $@"; "$@" || fatal "'$@' failed"; }
out=$(try git log --oneline '${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}') || exit 1
! grep -E '^[^ ]* (fixup|squash|amend)!' <<EOF || fatal "--autosquash commits not allowed without the 'pr-permit-autosquash' label"
${out}
EOF

72
.github/workflows/scripts/dist-tarball-check vendored Executable file
View file

@ -0,0 +1,72 @@
#!/bin/sh
pecho() { printf %s\\n "$*"; }
log() { pecho "$@"; }
warning() { log "::warning::$@"; }
error() { log "::error::$@"; }
fatal() { error "$@"; exit 1; }
try() { "$@" || fatal "'$@' failed"; }
# actions/checkout@v2 only makes a clone if Git is v2.18 or later, and this
# test requires a clone.
git_ver=$(try dpkg-query -f '${Version}' -W git) || exit 1
dpkg --compare-versions "${git_ver}" ge '1:2.18~' || {
warning "This test requires Git v2.18 or later"
exit 0
}
dist_tarball=$(ls ddclient-*.tar.gz) \
|| fatal "'make dist' must be run before this test"
tmpdir=$(try mktemp -d) || exit 1
# newer git versions are particular about file ownership which can be ignored here
git config --global --add safe.directory /__w/ddclient/ddclient || true
log "Copying contents of Git repository..."
try git archive --format=tar --prefix=git-repo/ HEAD \
| try tar -C "${tmpdir}" -xv || exit 1
(
try cd "${tmpdir}"/git-repo
# Delete files checked into Git that shouldn't be in the distribution
# tarball.
try rm -rf \
.envrc \
.github \
.gitignore \
docs/ipv6-design-doc.md \
docs/ProviderGuidelines.md \
shell.nix \
;
# TODO: Delete this next line once support for Automake 1.11 is dropped and
# tap-driver.sh is removed from the Git repository. It is deleted here to
# avoid a spurious diff.
try rm -f build-aux/tap-driver.sh
) || exit 1
log "Extracting distribution tarball..."
try tar -C "${tmpdir}" -xvzf "${dist_tarball}"
try mv "${tmpdir}/${dist_tarball%.tar.gz}" "${tmpdir}"/dist-tarball
(
try cd "${tmpdir}"/dist-tarball
# Delete generated files
try rm -rf \
Makefile.in \
aclocal.m4 \
build-aux/install-sh \
build-aux/missing \
build-aux/tap-driver.sh \
configure \
;
) || exit 1
log "Comparing Git repository with distribution tarball..."
cd "${tmpdir}"
diff -qNr git-repo dist-tarball >/dev/null || {
error "Unexpected diff between the repo and the distribution tarball."
error "You may need to add a file to EXTRA_DIST in Makefile.am."
error "Diff output:"
diff -uNr git-repo dist-tarball \
| while IFS= read -r line; do error "${line}"; done
exit 1
}
log "No difference"

20
.gitignore vendored
View file

@ -3,3 +3,23 @@ release
.svn
.cvsignore
*~
/Makefile
/Makefile.in
/aclocal.m4
/autom4te.cache/
/build-aux/config.guess
/build-aux/config.sub
/build-aux/install-sh
/build-aux/missing
/build-aux/tap-driver.sh
/config.log
/config.status
/configure
/ddclient
/ddclient-*.tar.gz
/ddclient.conf
/t/*.log
/t/*.trs
/t/geturl_connectivity.pl
/t/version.pl
/test-suite.log

294
CONTRIBUTING.md Normal file
View file

@ -0,0 +1,294 @@
# How to Contribute
Thank you for your interest in making ddclient better! This document
provides guidelines to make the contribution process as smooth as
possible.
To contribute changes, please open a pull request against the
[ddclient GitHub project](https://github.com/ddclient/ddclient/pulls).
## Developer Certificate of Origin
All contributions are subject to the [Developer Certificate of Origin
v1.1](https://developercertificate.org/), copied below. A
`Signed-off-by` line in each commit message is **not** required.
```
Developer Certificate of Origin
Version 1.1
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
1 Letterman Drive
Suite D4700
San Francisco, CA, 94129
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
```
## Style
* Above all else, try to match the existing style surrounding your
edits.
* No trailing whitespace.
* Use spaces, not tabs.
* Indentation level is 4 spaces.
* Use parentheses for Perl function invocations: `print($fh "foo")`
not `print $fh "foo"`
* When reasonable, break lines longer than 99 characters. Rationale:
- Imposing a limit makes it practical to open many side-by-side
files or terminals without worrying about horizontal scrolling.
- 99 is used instead of 100 so that the +/- column added by
unified diff does not cause wrapping in 100 column wide
terminals.
* Add spaces to vertically align adjacent lines of code when doing
so improves readability.
The following [perltidy](https://metacpan.org/pod/perltidy) command is
not perfect but it can get you close to our preferred style:
```shell
perltidy -l=99 -conv -ci=4 -ola -ce -nbbc -kis -pt=2 -b ddclient
```
## Git Hygiene
* Please keep your pull request commits rebased on top of `main`.
* Please use `git rebase -i` to make your commits easy to review:
- Put unrelated changes in separate commits
- Squash your fixup commits
* Write your commit message in imperative mood, and explain *why*
the change is made (unless obvious) in addition to *what* is
changed.
If you are not very comfortable with Git, we encourage you to read
[Pro Git](https://git-scm.com/book) by Scott Chacon and Ben Straub
(freely available online).
## Unit tests
Always add tests for your changes when feasible.
To run the ddclient test suite:
1. Install GNU Autoconf and Automake
2. Run: `./autogen && ./configure && make VERBOSE=1 check`
To add a new test script:
1. Create a new `t/*.pl` file with contents like this:
```perl
use Test::More;
# Your test dependencies go here.
SKIP: { eval { require Test::Warnings; } or skip($@, 1); }
eval { require 'ddclient'; } or BAIL_OUT($@);
# Your tests go here.
done_testing();
```
See the documentation for
[Test::More](https://perldoc.perl.org/Test/More.html) for
details.
2. Add your script to the `handwritten_tests` variable in
`Makefile.am`.
3. If your test script requires 3rd party modules, add the modules
to the list of test modules in `configure.ac` and re-run
`./autogen && ./configure`. Be sure to skip the tests if the
module is not available. For example:
```perl
eval { require Foo::Bar; } or plan(skip_all => $@);
```
## Compatibility
We strive to find the right balance between features, code
maintainability, and broad platform support. To that end, please limit
yourself to Perl language features and modules available on the
following platforms:
* Debian oldstable and newer
* Ubuntu, [all maintained
releases](https://ubuntu.com/about/release-cycle)
* Fedora, [all maintained
releases](https://fedoraproject.org/wiki/Fedora_Release_Life_Cycle)
* CentOS, [all maintained
releases](https://wiki.centos.org/About/Product)
* Red Hat Enterprise Linux, [all maintained
releases](https://access.redhat.com/support/policy/updates/errata/)
See https://pkgs.org for available modules and versions.
Exceptions:
* You may depend on modern language features or modules for new
functionality when no feasible alternative exists, as long as the
new dependency does not break existing functionality on old
plaforms.
* Test scripts may depend on arbitrary modules as long as the tests
are skipped if the modules are not available. Effort should be
taken to only use modules that are broadly available.
You may use any core Perl module as long as it is available in all
versions of Perl we support. (Though please make sure it is listed in
the appropriate `configure.ac` check.) Stated another way: We are not
interested in supporting platforms that lack some core Perl modules,
unless doing so is trivial.
All shell scripts should conform with [POSIX Issue 7 (2018
edition)](https://pubs.opengroup.org/onlinepubs/9699919799/) or later.
## Prefer Revert and Redo, Not Fix
Suppose a recent change broke something or otherwise needs
refinement. It is tempting to simply push a fix, but it is usually
better to revert the original change then redo it:
* There is less subjectivity with a revert, so you are more likely
to get a quick approval and merge. You can quickly "stop the
bleeding" while you and the project maintainers debate about the
best way to fix the problem with the original commit.
* It is easier and less mistake-prone to cherry-pick a single commit
(the redo commit) than two commits (the original commit plus the
required fix).
* Someone using blame to review the history will see the redo
commit, not the buggy original commit.
## For ddclient Project Maintainers
### Merging Pull Requests
To facilitate reviews and code archaeology, `main` should have a
semi-linear commit history like this:
```
* f4e6e90 sandro.jaeckel@gmail.com 2020-05-31 07:29:51 +0200 (main)
|\ Merge pull request #142 from rhansen/config-line-format
| * 30180ed rhansen@rhansen.org 2020-05-30 13:09:38 -0400
|/ Expand comment documenting config line format
* 01a746c rhansen@rhansen.org 2020-05-30 23:47:54 -0400
|\ Merge pull request #138 from rhansen/dyndns-za-net
| * 08c2b6c rhansen@rhansen.org 2020-05-29 14:44:57 -0400
|/ Replace dydns.za.net with dyndns.za.net
* d65805b rhansen@rhansen.org 2020-05-30 22:30:04 -0400
|\ Merge pull request #140 from ddclient/fix-interpolation
| * babbef1 sandro.jaeckel@gmail.com 2020-05-30 04:03:44 +0200
|/ Fix here doc interpolation
* 6ae69a1 rhansen@rhansen.org 2020-05-30 22:23:57 -0400
|\ Merge pull request #141 from ddclient/show-debug-ssl
| * 096288e sandro.jaeckel@gmail.com 2020-05-30 04:42:27 +0200
| | Expand tabs to spaces in vim
| * 0206262 sandro.jaeckel@gmail.com 2020-05-30 04:40:58 +0200
|/ Show debug connection settings after evaluating use-ssl
...
```
See https://stackoverflow.com/a/15721436 for an explanation of the
benefits.
This semi-linear style is mostly useful for multi-commit pull
requests. For single-commit pull requests, GitHub's "Squash and merge"
and "Rebase and merge" options are fine, though this approach still
has value:
* The merge commit's commit message can link to the pull request
or contain other contextual information.
* It's easier to see who merged the PR (just look at the merge
commit author.)
* You can easily see both the original author timestamp (when the
change was made) and the merge timestamp (when it went live).
To achieve a history like the above, the pull request must be rebased
onto `main` before merging. Unfortunately, GitHub does not have a
one-click way to do this (the "Rebase and merge" option does a
fast-forward merge, which is not what we want). See
[isaacs/github#1143](https://github.com/isaacs/github/issues/1143) and
[isaacs/github#1017](https://github.com/isaacs/github/issues/1017). Until
GitHub adds that feature, it has to be done manually:
```shell
# Set this to the name of the GitHub user or project that owns the
# fork used for the pull request:
PR_USER=
# Set this to the name of the branch in the fork used for the pull
# request:
PR_BRANCH=
# The commands below assume that `origin` refers to the
# ddclient/ddclient repository
git remote set-url origin git@github.com:ddclient/ddclient.git
# Add a remote for the fork used in the PR
git remote add "${PR_USER:?}" git@github.com:"${PR_USER:?}"/ddclient
# Fetch the latest commits for the PR and ddclient main
git remote update -p
# Switch to the pull request branch
git checkout -b "${PR_USER:?}-${PR_BRANCH:?}" "${PR_USER:?}/${PR_BRANCH:?}"
# Rebase the commits (optionally using -i to clean up history) onto
# the current ddclient main branch
git rebase origin/main
# Force update the contributor's fork. This will only work if the
# contributor has checked the "Allow edits by maintainers" box in the
# PR. If not, you will have to manually merge the rebased commits.
git push -f
# If the force push was successful, you can now go into the GitHub UI
# and merge using the "Create a merge request" option.
#
# If the force push failed because the contributor did not check
# "Allow edits by maintainers", or if you prefer to merge manually,
# continue with the next steps.
# Switch to the local main branch
git checkout main
# Make sure the local main branch is up to date
git merge --ff-only origin/main
# Merge in the rebased pull request branch **WITHOUT DOING A
# FAST-FORWARD MERGE**
git merge --no-ff "${PR_USER:?}-${PR_BRANCH:?}"
# Review the commits before pushing
git log --graph --oneline --decorate origin/main..
# Push to ddclient main
git push origin main
```

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.

560
ChangeLog
View file

@ -1,560 +0,0 @@
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.
The patches are mostly there for historical reasons. They've been
moved away to make cleaning easier. I think the applied patches should
even be removed.
2013-10-28 wimpunk
* [r155] ddclient: Fallback to iproute if ifconfig doesn't work.
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.
2013-07-08 wimpunk
* [r153] ddclient: Applying patch from [fb1ad014] fixing bug [#14]
More info can be found on [fb1ad014] and has been discussed in
the mailinglist:
http://article.gmane.org/gmane.network.dns.ddclient.user/71. The
patch was send by Rodrigo Araujo.
2013-05-14 wimpunk
* [r152] ddclient: Adding sha1-patch provided by pirast in
[9742ac09]
2013-04-28 wimpunk
* [r150] README.md, ddclient, sample-etc_ddclient.conf: Adding
support for ChangeIP based on the patch from Michele Giorato
http://sourceforge.net/p/ddclient/discussion/399428/thread/e85661ad/
* [r148] README.md: Updated README file
* [r147] ., README, README.md: Applying markdown syntax to README
2011-07-11 wimpunk
* [r131] release/readme.txt: Updates after releasing 3.8.1
* [r129] release/readme.txt: Corrected release/readme.txt
* [r128] sample-etc_ppp_ip-up.local: Applied ip-up_run-parts.diff
from ubuntu
* [r127] ddclient: Applied smc-barricade-fw-alt.diff from ubuntu
2011-07-03 wimpunk
* [r126] ddclient: Fixing #28: FreeDNS.afraid.org changed api
slightly
2011-05-19 wimpunk
* [r125] ddclient, sample-etc_ddclient.conf: Added patch for
dtdns-support (#39)
2011-03-09 wimpunk
* [r124] ddclient: Patching with nic_updateable-warning patch
provided by antespi in ticket #2
2011-03-08 wimpunk
* [r123] ddclient: Patching with zoneedit patch provided by
killer-jk in ticket #15
2010-12-07 wimpunk
* [r122] ddclient: Added longer password support, sended by Ingo
Schwarze (#3130634)
2010-10-13 wimpunk
* [r121] ddclient: Fixing bug #13: multiple fetch-ip but
introducing a multiple ip bug
2010-09-14 wimpunk
* [r120] ddclient: patch for #10: invalid value for keyword ip
2010-09-13 wimpunk
* [r119] ddclient: Applied patch from ticket #8, patch for cache
content leaks to global
* [r118] ddclient: Applied patch from ticket #7, provided by Chris
Carr
2010-07-01 wimpunk
* [r117] ddclient: Fixed #6: Add Red Hat package name to Perl
module IO::Socket::SSL error message
2010-02-24 wimpunk
* [r116] ddclient: Subversion revision added
2009-11-09 wimpunk
* [r115] ddclient, patches/cisco-asa.patch: Added cisco-asa patch
(2891001) submitted by Philip Gladstone
* [r114] ddclient, patches/prevent-hang.patch: Added prevent-hang
patch (2880462) submitted by Panos
2009-10-19 wimpunk
* [r113] ddclient, patches/foreground.patch: Added foreground patch
(1893144) submitted by John Palkovic
2009-09-10 wimpunk
* [r112] README, ddclient, patches/loopia.patch,
sample-etc_ddclient.conf: #1609799 Support for LoopiaDNS
(submitted by scilence)
2009-08-05 wimpunk
* [r111] ddclient, patches/freedns-patch: applied freedns patch
(patch 2832129)
2009-05-16 wimpunk
* [r110] ddclient: Bug 2792436: fixed abuse message of dyndns
2009-02-27 wimpunk
* [r109] sample-etc_ddclient.conf: Added warning about the update
interval (#2619505)
2009-01-27 wimpunk
* [r108] .cvsignore, RELEASENOTE, ddclient, release,
release/readme.txt: Modified during the release of ddclient-3.8.0
2008-12-04 wimpunk
* [r106] ddclient: help about postscript added
2008-11-19 wimpunk
* [r105] ddclient, patches/password.patch: Added better password
handling sended by Ingo Schwarze
* [r104] TODO, sample-ddclient-wrapper.sh: Added ddclient wrapper
script
* [r103] ddclient: Extra fix for multiple IP's
2008-11-01 wimpunk
* [r102] sample-etc_ddclient.conf: Added some remarks concerning
the postscript. See
https://sourceforge.net/forum/message.php?msg_id=5550545
2008-09-30 wimpunk
* [r101] ddclient, patches/multiple-ip.patch: Added support for
multiple IP adresses. See
http://permalink.gmane.org/gmane.network.dns.ddclient.user/17
* [r100] patches/namecheap.patch: extra comments added to namecheap
patch
2008-07-04 wimpunk
* [r99] patches/namecheap.patch: namecheap patch added to patches
section
2008-06-13 wimpunk
* [r98] .: New trunk created based on the old trunk/svn
* [r96] svn: Moved old trunk/svn to ddclient and it will be the new
trunk
* [r95] svn: Ignoring test configuration
* [r94] svn/.cvsignore, svn/RELEASENOTE, svn/UPGRADE: Added some
release related files
* [r93] svn/patches/no-host.patch: Added not used no-host patch to
patches section
2008-06-05 wimpunk
* [r90] svn/ddclient: Added more info about the daemon interval
* [r89] svn/ddclient: Preventing error while reading cache when ip
wasn't set correctly before
* [r88] svn/ddclient: Preventing an error when trying to send a
message on mail-failure
2008-06-02 wimpunk
* [r87] svn/ddclient, svn/sample-etc_ddclient.conf: Modified
documentation about zoneedit based on the comments from Oren Held
2008-03-04 wimpunk
* [r86] svn/patches/ddclient.daemon-timeout.patch: Added patch
which was applied to rev 27 (posted by James deBoer)
2008-02-19 wimpunk
* [r85] svn/patches/eurodns.patch: Patch modified to apply on
ddclient 3.7.3
2008-02-08 wimpunk
* [r84] svn/patches/mail-on-kill.patch: Added mail-on-kill patch to
patches section
2008-02-05 wimpunk
* [r83] svn/ddclient: Sending mail when killed, not after
TERM-signal
* [r82] svn/README: Added creation of cache dir
2007-10-29 wimpunk
* [r81] svn/ddclient, svn/patches/ubuntu/default-timeout.patch:
Added and applied default timeout patch from
https://bugs.launchpad.net/ubuntu/+source/ddclient/+bug/116066
2007-08-29 wimpunk
* [r80] svn/ddclient, svn/patches/ddclient-noip.patch: Added
ddclient-noip.patch send by Kurt Bussche.
2007-08-07 wimpunk
* [r78] svn/ddclient: Updated version number to 3.7.3
2007-08-01 wimpunk
* [r77] svn/ddclient, svn/patches/typo_dnspark.patch: Applied
typo_dnspark.patch send by Marco
2007-07-31 wimpunk
* [r76] svn/README.ssl: Renamed dyndns.org to dyndns.com
* [r75] svn/README: Removed ^M at line 37
* [r74] svn/ddclient: Removed line 183, comments on Vigor 2200 USB
2007-07-30 wimpunk
* [r73] svn: Ignoring ChangeLog since autogenerated
* [r72] svn/Changelog: Notification about changed ChangeLog
configuration
* [r71] svn/patches/ubuntu/dyndns_com.diff: Removed patch since
it's invalid
* [r70] svn/patches/opendns.patch: Added not applied opendns.patch,
see tracker #1758564
* [r69] svn/patches/debianpatches,
svn/patches/debianpatches/abuse_msg.diff,
svn/patches/debianpatches/cachedir.diff,
svn/patches/debianpatches/cisco_fw.diff,
svn/patches/debianpatches/config_path.diff,
svn/patches/debianpatches/daemon_check.diff,
svn/patches/debianpatches/daemon_interval.diff,
svn/patches/debianpatches/help_nonroot(2).diff,
svn/patches/debianpatches/help_nonroot.diff,
svn/patches/debianpatches/ip-up_run-parts.diff,
svn/patches/debianpatches/maxinterval.diff,
svn/patches/debianpatches/readme.txt,
svn/patches/debianpatches/sample_path.diff,
svn/patches/debianpatches/smc-barricade-7401bra.patch,
svn/patches/debianpatches/smc-barricade-fw-alt.diff,
svn/patches/debianpatches/update-new-config.patch,
svn/patches/ubuntu, svn/patches/ubuntu/checked_ssl_load.diff,
svn/patches/ubuntu/config_path.diff,
svn/patches/ubuntu/daemon_interval.diff,
svn/patches/ubuntu/dyndns_com.diff,
svn/patches/ubuntu/sample_ubuntu.diff, svn/patches/ubuntu/series,
svn/patches/ubuntu/smc-barricade-fw-alt.diff: Added debian and
ubuntu patches
2007-07-29 wimpunk
* [r68] svn/TODO: Added url to feature request dyndns
2007-07-12 wimpunk
* [r67] svn/README, svn/patches/readme.patch: Run dos2unix on
readme and it's patch which Marco Rodrigues submitted.
* [r66] svn/README, svn/patches/readme.patch: Partial applied
readme.patch. See tracker #1752931
2007-07-10 wimpunk
* [r65] svn/ddclient: signature modified
* [r64] svn/ddclient: Added website to ddclient comments
* [r63] svn/patches/regex_vlan.patch: Added extra comments to the
patch.
* [r62] svn/ddclient, svn/patches/create_patch.sh,
svn/patches/regex_vlan.patch,
svn/patches/typo_namecheap_patch.diff.new: Added patches and
applied regex_vlan.patch. See bug #1747337
* [r61] svn/ddclient: Applied typo_namecheap_patch.diff send by
Marco Rodrigues
2007-07-07 wimpunk
* [r60] svn/sample-etc_ppp_ip-up.local: Reverted the patch from
torsten. See [ 1749470 ] Bug in Script sample-etc_ppp_ip-up.local
2007-07-04 wimpunk
* [r59] svn/release, svn/release/readme.txt: Adding some release
documentation
2007-06-14 wimpunk
* [r57] svn/Changelog, svn/ddclient: Changed version number
* [r55] svn/patches, svn/patches/3com-oc-remote812.patch,
svn/patches/easydns.patch, svn/patches/eurodns.patch: Patches
directory added
2007-06-12 wimpunk
* [r54] svn/ddclient: 3com-oc-remote812 patch by The_Beast via IRC:
see patches/3com-oc-remote812.patch
2007-06-05 wimpunk
* [r53] svn/ddclient: Applied easydns.patch, patch 117054
2007-05-28 wimpunk
* [r52] svn/ddclient: Changed nic_namecheap_update following the
suggestion of edmdude on the forum
(https://sourceforge.net/forum/message.php?msg_id=4316938)
2007-05-19 wimpunk
* [r48] svn/ddclient: Cosmetic change about checkip
* [r47] svn/ddclient: Applied checked_ssl_load.diff from ubuntu
* [r46] svn/ddclient: Removed the two empty lines at the end of
ddclient
2007-02-26 wimpunk
* [r44] svn/TODO: added a TODO list
2007-02-21 wimpunk
* [r43] svn/Changelog, svn/ddclient: Preventing unitialized values,
check https://sourceforge.net/forum/message.php?msg_id=4167772
2007-01-24 wimpunk
* [r40] svn/Changelog, svn/ddclient: Changed max-interval to
25days. See https://www.dyndns.com/services/dns/dyndns/faq.html
2006-12-03 wimpunk
* [r39] svn/Changelog, svn/ddclient: Applied maxinterval.diff:
Increase max interval for updates.
See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=129370
http://www.dyndns.com/support/services/dyndns/faq.html#q15
* [r38] svn/ddclient: Applied cisco_fw.diff: Use configured
hostname for firewall access with
-use=cisco (closes: #345712). Thanks to Per Carlson for the
patch!
See http://bugs.debian.org/345712.
2006-12-02 wimpunk
* [r37] svn/Changelog, svn/ddclient: Applied
smc-barricade-7401bra.patch: Support for SMC Barricade 7401BRA FW
firewall (submitted by Torsten)
Changelog modified for all previous patches from Torsten
* [r36] svn/ddclient: Applied update-new-config.patch: Force update
if config has changed
(submitted by Torsten)
* [r35] svn/sample-etc_ppp_ip-up.local: Applied
ip-up_run-parts.diff: Fix parameter in ip-up script.
(submitted by Torsten)
* [r34] svn/ddclient: Applied help_nonroot.diff: Allow calling the
help function as non-root.
(submitted by Torsten)
* [r33] svn/ddclient: Applied cachedir.diff: Original ddclient
stores a cache file in /etc which
would belong in /var/cache in my opinion and according to the
FHS. Patch
changes that. (submitted by Torsten)
* [r32] svn/ddclient: Applied abuse_msg.diff: ddclient still
reports the email to contact dyndns.org
but they prefer a web form today (IIRC). This patch adjusts the
abuse warning
printed by ddclient. (submitted by Torsten)
* [r31] svn/Changelog: Changed Changelog syntax
2006-11-27 wimpunk
* [r30] svn/Changelog, svn/ddclient: Don't send any mail when in
not running daemon mode (patch submitted by Daniel Thaler)
2006-11-03 wimpunk
* [r28] svn/Changelog, svn/ddclient: Added patch "Patch: Treat
--daemon values as intervals"
(submitted by James deBoer)
2006-09-30 wimpunk
* [r22] svn/Changelog, svn/sample-etc_rc.d_init.d_ddclient.ubuntu:
Added initscript for Ubuntu (posted by Paolo Martinelli)
2006-09-14 wimpunk
* [r21] svn/Changelog, svn/ddclient: URL of zoneedit has changed
(see bug #1558483)
2006-06-14 wimpunk
* [r11] svn/Changelog, svn/ddclient: Changed version number
* [r8] ., html, svn, xml: Created trunk and tags, moved directories
to it
* [r6] Changed the order of perl and update of README.ssl
2006-06-11 ddfisher
* [r5] see Changelog
2006-06-10 ddfisher
* [r4] updated changelog
* [r3] See Changelog
2006-05-22 wimpunk
* [r2] Reorganise

1165
ChangeLog.md Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,304 +0,0 @@
Changelog
3.7.3
* Changelog moved to more correct ChangeLog
generated by svn2cl --group-by-day -i
See http://tinyurl.com/2fzhc6
3.7.2
* Preventing unitialized values, check
https://sourceforge.net/forum/message.php?msg_id=4167772
* added a TODO list
* Removed the two empty lines at the end of ddclient
* Applied checked_ssl_load.diff from Ubuntu
* Cosmetic change about checkip
* Changed nic_namecheap_update following the suggestion of edmdude
on the forum (https://sourceforge.net/forum/message.php?msg_id=4316938)
* Applied easydns.patch
* 3com-oc-remote812 patch by The_Beast via IRC.
* Applied eurodns.patch
3.7.1
* URL of zoneedit has changed (see bug #1558483)
* Added initscript for Ubuntu (posted by Paolo Martinelli)
* Added patch "Patch: Treat --daemon values as intervals"
(submitted by James deBoer)
* Don't send any mail when in not running daemon mode
(patch submitted by Daniel Thaler)
* Changed Changelog syntax
* Applied patches submitted by Torsten:
abuse_msg.diff: ddclient still reports the email to contact dyndns.org
but they prefer a web form today (IIRC). This patch adjusts the abuse
warning printed by ddclient.
cachedir.diff: Original ddclient stores a cache file in /etc which
would belong in /var/cache in my opinion and according to the FHS.
help_nonroot.diff: Allow calling the help function as non-root.
update-new-config.patch: Force update if config has changed
smc-barricade-7401bra.patch: Support for SMC Barricade 7401BRA FW
firewall
cisco_fw.diff: Use configured hostname for firewall access
with -use=cisco (closes: #345712). Thanks to Per Carlson for the
patch! See http://bugs.debian.org/345712.
maxinterval.diff: Increase max interval for updates.
See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=129370
http://www.dyndns.com/support/services/dyndns/faq.html#q15
* Changed max-interval to 25days. See
https://www.dyndns.com/services/dns/dyndns/faq.html
3.7.0
- Added vi tag
- Added support for 2Wire 1701HG Gateway (see
https://sourceforge.net/forum/message.php?msg_id=3496041 submitted by hemo)
- added ssl-support by perlhaq
- updated cvs version to 3.7.0-pre
- added support for Linksys RV042, see feature requests #1501093, #1500877
- added support for netgear-rp614, see feature request #1237039
- added support for watchguard-edge-x, patch #1468981
- added support for dlink-524, see patch #1314272
- added support for rtp300
- added support for netgear-wpn824
- added support for linksys-wcg200, see patch #1280713
- added support for netgear-dg834g, see patch #1176425
- added support for netgear-wgt624, see patch #1165209
- added support for sveasoft, see patch #1102432
- added support for smc-barricade-7004vbr, see patch #1087989
- added support for sitecom-dc202, see patch #1060119
- fixed the error of stripping out '#' in the middle of password, bug #1465932
- fixed a couple bugs in sample-etc_rc.d_init.d_ddclient and added some extra auto distro detection
- added the validation of values when reading the configuration value.
- this fixes a bug when trying to use periods/intervals in the daemon check times, bug #1209743
- added timeout option to the IO::Socket call for timing out the initial connection, bug: #1085110
3.6.7
- modified sample-etc_rc.d_init.d_ddclient.lsb (bug #1231930)
- support for ConCont Protocol (patch #1265128) submitted by seather_misery
- problem with sending mail should be solved
- corrected a few writing mistakes
- support for 'NetComm NB3' adsl modem (submitted by crazyprog)
- Added Sitelutions DynDNS, fixed minor Namecheap bug (patch #1346867)
3.6.6
- support for olitec-SX200
- added sample-etc_rc.d_init.d_ddclient.lsb as a sample script for lsb-compliant systems.
- support for linksys wrt854g (thanks to Nick Triantos)
- support for linksys ver 3
- support for Thomson (Alcatel) SpeedTouch 510 (thanks to Aldoir)
- Cosmetic fixes submitted by John Owens
3.6.5
- there was a bug in the linksys-ver2
- support for postscript (thanks to Larry Hendrickson)
- Changelog out of README
- modified all documentation to use /etc/ddclient/ddclient.conf (notified by nicolasmartin in bug [1070646])
3.6.4
- added support for NameCheap service (thanks to Dan Boardman)
- added support for linksys ver2 (thanks to Dan Perik)
3.6.3
- renamed sample-etc_dhclient-enter-hooks to sample-etc_dhclient-exit-hooks
- add support for the Allnet 1298 Router
- add -a to ifconfig to query all interfaces (for Solaris and OpenBSD)
- update the process status to reflect what is happening.
- add a To: line when sending e-mail
- add mail-failure to send mail on failures only
- try all addresses for multihomed hosts (like check.dyndns.org)
- add support for dnspark
- add sample for OrgDNS.org
3.6.2
- add support for Xsense Aero
- add support for Alcatel Speedtouch Pro
- do authentication when either the login or password are defined.
- fix parsing of web status pages
- 3.6
- add support for EasyDNS (see easydns.com)
- add warning for possible incorrect continuation lines in the .conf file.
- add if-skip with the default as was used before.
- add cmd-skip.
- 3.5.4
- added !active result code for DynDNS.org
- 3.5.2
- avoid undefined variable in get_ip
- 3.5.1
- fix parsing of quoted strings in .conf file
- add filename and line number to any warnings regarding files.
- 3.5
- allow any url to be specified for -fw {address|url}
use -fw-skip {pattern} to specify a string preceding the IP address at the URL's page
- allow any url to be specified for -web {address|url}
use -web-skip {pattern} to specify a string preceding the IP address at the URL's page
- modify -test to display any IP addresses that could be obtained from
any interfaces, builtin fw definitions, or web status pages.
- 3.4.6 (not released)
- fix errors in -help
- allow non-FQDNs as hosts; dslreports requires this.
- handle german ifconfig output
- try to get english messages from ifconfig so other languages are handled too.
- added support for com 3c886a 56k Lan Modem
- 3.4.5
- handle french ifconfig output
- 3.4.4
- added support for obtaining the IP address from a Cisco DHCP interface.
(Thanks, Tim)
- 3.4.2
- update last modified time when nochg is returned from dyndns
- add example regarding fw-login and fw-password's required by some
home routers
- 3.4.1
- add option (-pid) to record process id in a file. This option should be
defined in the .conf file as it is done in the sample.
- add detection of SIGHUP. When this signal is received, ddclient will
wake up immediately, reload it's configuration file, and update
the IP addresses if necessary.
- 3.4
- ALL PEOPLE USING THIS CLIENT ARE URGED TO UPGRADE TO 3.4 or better.
- fixed several timer related bugs.
- reformatted some messages.
- 3.3.8
- added support for the ISDN channels on ELSA LANCOM DSL/10 router
- 3.3.7
- suppress repeated identical e-mail messages.
- 3.3.6
- added support for the ELSA LANCOM DSL/10 router
- ignore 0.0.0.0 when obtained from any FW/router.
- 3.3.5
- fixed sample ddclient.conf. fw-ip= should be fw=
- fixed problem getting status pages for some routers
- 3.3.4
- added support for the MaxGate's UGATE-3x00 routers
- 3.3.3
- sample* correct checks for private addresses
- add redhat specific sample-etc_rc.d_init.d_ddclient.redhat
- make daemon-mode be the default when named ddclientd
- added support for the Linksys BEF* Internet Routers
- 3.3.2
- (sample-etc_rc.d_init.d_ddclient) set COLUMNS to a large number so that
'ps -aef' will not prematurely truncate the CMD.
- 3.3
- added rpm (thanks to Bo Forslund)
- added support for the Netgear RT3xx Internet Routers
- modified sample-etc_rc.d_init.d_ddclient to work with other Unix beside RedHat.
- avoid rewritting the ddclient.cache file unnecessarily
- fixed other minor bugs
- 3.2.0
- add support for DynDNS's custom domain service.
- change suggested directory to /usr/sbin
- 3.1.0
- clean up; fix minor bugs.
- removed -refresh
- add min-interval to avoid too frequent update attempts.
- add min-error-interval to avoid too frequent update attempts when the
service is unavailable.
- 3.0.1
- make all values case sensitive (ie. passwords)
- 3.0
- new release!
- new ddclient.conf format
- rewritten to support DynDNS's NIC2 and other dynamic DNS services
- added Hammernode (hn.org)
- added ZoneEdit (zoneedit.com)
- added DSLreports (dslreports.com) host monitoring
- added support for obtaining IP addresses from
- interfaces,
- commands,
- web,
- external commands,
- Watchguard's SOHO router
- Netopia's R910 router
- and SMC's Barracade
- added daemon mode
- added logging msgs to syslog and e-mail
- 2.3.7
- add -refresh to the sample scripts so default arguments are obtained from the cache
- added local-ip script for obtaining the address of an interface
- added public-ip script for obtaining the ip address as seen from a public web page
- 2.3.6
- fixed bug the broke enabling retrying when members.dyndns.org was down.
- 2.3.5
- prevent warnings from earlier versions of Perl.
- 2.3.4
- added sample-etc_dhclient-enter-hooks for those using the ISC DHCP client (dhclient)
- 2.3.3
- make sure that ddclient.conf is only readable by the owner so that no one
- else can see the password (courtesy of Steve Greenland).
-- NOTE: you will need to change the permissions on ddclient.conf to prevent
-- others from obtaining viewing your password.
-- ie. chmod go-rwx /etc/ddclient.conf
- 2.3.2
- make sure 'quiet' messages are printed when -verbose or -debug is enabled
- fix error messages for those people using proxies.
- 2.3
- fixed a problem reading in cached entries
- 2.2.1
- sample-etc_ppp_ip-up.local - local ip address is $4 or $PPP_LOCAL (for debian)
- use <CR><LF> as the line terminator (some proxies are strict about this)
- 2.2
- added support (-static) for updating static DNS (thanks Marc Sira)
- changed ddclient.cache format (old style is still read)
- sample-etc_ppp_ip-up.local - detect improper calling sequences
- sample-etc_ppp_ip-up.local - local ip address is $3 or $PPP_LOCAL (for debian)
- 2.1.2
- updated README
- 2.1.1
- make sure result code reflects any failures
- optionally (-quiet) omit messages for unnecessary updates
- update sample-etc_cron.d_ddclient to use -quiet
- 2.1
- avoid unnecessary updates by recording the last hosts updated in a
cache file (default /etc/ddclient.cache)
- optionally (-force) force an update, even if it may be unnecessary.
This can be used to prevent dyndns.org from deleting a host that has not
required an update for a long period of time.
- optionally (-refresh), reissue all host updates.
This can be used together with cron to periodically update DynDNS.
See sample-etc-cron.d-ddclient for details.
- optionally (-retry) save failed updates for future processing.
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 $
------------------------------------------------------------------------

165
Makefile.am Normal file
View file

@ -0,0 +1,165 @@
ACLOCAL_AMFLAGS = -I build-aux/m4
EXTRA_DIST = \
CONTRIBUTING.md \
COPYING \
COPYRIGHT \
ChangeLog.md \
README.cisco \
README.md \
autogen \
sample-ddclient-wrapper.sh \
sample-etc_cron.d_ddclient \
sample-etc_dhclient-exit-hooks \
sample-etc_dhcpc_dhcpcd-eth0.exe \
sample-etc_ppp_ip-up.local \
sample-etc_systemd.service \
sample-get-ip-from-fritzbox
CLEANFILES =
subst_files = ddclient ddclient.conf
EXTRA_DIST += $(subst_files:=.in)
CLEANFILES += $(subst_files)
$(subst_files): Makefile
rm -f '$@' '$@'.tmp
in='$@'.in; \
test -f "$${in}" || in='$(srcdir)/'$${in}; \
sed \
-e 's|@PACKAGE_VERSION[@]|$(PACKAGE_VERSION)|g' \
-e '1 s|^#\!.*perl$$|#\!$(PERL)|g' \
-e 's|@localstatedir[@]|$(localstatedir)|g' \
-e 's|@confdir[@]|$(confdir)|g' \
-e 's|@runstatedir[@]|$(runstatedir)|g' \
-e 's|@CURL[@]|$(CURL)|g' \
"$${in}" >'$@'.tmp && \
{ ! test -x "$${in}" || chmod +x '$@'.tmp; }
mv '$@'.tmp '$@'
ddclient: $(srcdir)/ddclient.in
ddclient.conf: $(srcdir)/ddclient.conf.in
bin_SCRIPTS = ddclient
conf_DATA = ddclient.conf
install-data-local:
$(MKDIR_P) '$(DESTDIR)$(localstatedir)'/cache/ddclient
AM_TESTS_ENVIRONMENT = \
abs_top_srcdir='$(abs_top_srcdir)'; export abs_top_srcdir;
LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \
$(top_srcdir)/build-aux/tap-driver.sh
TEST_EXTENSIONS = .pl
PL_LOG_DRIVER = $(LOG_DRIVER)
PL_LOG_COMPILER = $(PERL)
AM_PL_LOG_FLAGS = -Mstrict -w \
-I'$(abs_top_builddir)' \
-I'$(abs_top_srcdir)'/t/lib \
-MDevel::Autoflush
handwritten_tests = \
t/builtinfw_query.pl \
t/check_value.pl \
t/get_ip_from_if.pl \
t/geturl_connectivity.pl \
t/geturl_response.pl \
t/group_hosts_by.pl \
t/header_ok.pl \
t/interval_expired.pl \
t/is-and-extract-ipv4.pl \
t/is-and-extract-ipv6.pl \
t/is-and-extract-ipv6-global.pl \
t/logmsg.pl \
t/parse_assignments.pl \
t/protocol_directnic.pl \
t/protocol_dnsexit2.pl \
t/protocol_dyndns2.pl \
t/read_recap.pl \
t/skip.pl \
t/ssl-validate.pl \
t/update_nics.pl \
t/use_cmd.pl \
t/use_web.pl \
t/variable_defaults.pl \
t/write_recap.pl
generated_tests = \
t/version.pl
TESTS = $(handwritten_tests) $(generated_tests)
$(TESTS): ddclient
EXTRA_DIST += $(handwritten_tests) \
.autom4te.cfg \
t/lib/Devel/Autoflush.pm \
t/lib/Test/Builder.pm \
t/lib/Test/Builder/Formatter.pm \
t/lib/Test/Builder/IO/Scalar.pm \
t/lib/Test/Builder/Module.pm \
t/lib/Test/Builder/Tester.pm \
t/lib/Test/Builder/Tester/Color.pm \
t/lib/Test/Builder/TodoDiag.pm \
t/lib/Test/More.pm \
t/lib/Test/Simple.pm \
t/lib/Test/Tester.pm \
t/lib/Test/Tester/Capture.pm \
t/lib/Test/Tester/CaptureRunner.pm \
t/lib/Test/Tester/Delegate.pm \
t/lib/Test/use/ok.pm \
t/lib/Test2.pm \
t/lib/Test2/API.pm \
t/lib/Test2/API/Breakage.pm \
t/lib/Test2/API/Context.pm \
t/lib/Test2/API/Instance.pm \
t/lib/Test2/API/Stack.pm \
t/lib/Test2/Event.pm \
t/lib/Test2/Event/Bail.pm \
t/lib/Test2/Event/Diag.pm \
t/lib/Test2/Event/Encoding.pm \
t/lib/Test2/Event/Exception.pm \
t/lib/Test2/Event/Fail.pm \
t/lib/Test2/Event/Generic.pm \
t/lib/Test2/Event/Note.pm \
t/lib/Test2/Event/Ok.pm \
t/lib/Test2/Event/Pass.pm \
t/lib/Test2/Event/Plan.pm \
t/lib/Test2/Event/Skip.pm \
t/lib/Test2/Event/Subtest.pm \
t/lib/Test2/Event/TAP/Version.pm \
t/lib/Test2/Event/V2.pm \
t/lib/Test2/Event/Waiting.pm \
t/lib/Test2/EventFacet.pm \
t/lib/Test2/EventFacet/About.pm \
t/lib/Test2/EventFacet/Amnesty.pm \
t/lib/Test2/EventFacet/Assert.pm \
t/lib/Test2/EventFacet/Control.pm \
t/lib/Test2/EventFacet/Error.pm \
t/lib/Test2/EventFacet/Hub.pm \
t/lib/Test2/EventFacet/Info.pm \
t/lib/Test2/EventFacet/Info/Table.pm \
t/lib/Test2/EventFacet/Meta.pm \
t/lib/Test2/EventFacet/Parent.pm \
t/lib/Test2/EventFacet/Plan.pm \
t/lib/Test2/EventFacet/Render.pm \
t/lib/Test2/EventFacet/Trace.pm \
t/lib/Test2/Formatter.pm \
t/lib/Test2/Formatter/TAP.pm \
t/lib/Test2/Hub.pm \
t/lib/Test2/Hub/Interceptor.pm \
t/lib/Test2/Hub/Interceptor/Terminator.pm \
t/lib/Test2/Hub/Subtest.pm \
t/lib/Test2/IPC.pm \
t/lib/Test2/IPC/Driver.pm \
t/lib/Test2/IPC/Driver/Files.pm \
t/lib/Test2/Tools/Tiny.pm \
t/lib/Test2/Util.pm \
t/lib/Test2/Util/ExternalMeta.pm \
t/lib/Test2/Util/Facets2Legacy.pm \
t/lib/Test2/Util/HashBase.pm \
t/lib/Test2/Util/Trace.pm \
t/lib/ddclient/Test/Fake/HTTPD.pm \
t/lib/ddclient/Test/Fake/HTTPD/dummy-ca-cert.pem \
t/lib/ddclient/Test/Fake/HTTPD/dummy-server-cert.pem \
t/lib/ddclient/Test/Fake/HTTPD/dummy-server-key.pem \
t/lib/ddclient/Test/Fake/HTTPD/other-ca-cert.pem \
t/lib/ddclient/t.pm \
t/lib/ddclient/t/HTTPD.pm \
t/lib/ddclient/t/Logger.pm \
t/lib/ddclient/t/ip.pm \
t/lib/ok.pm

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

359
README.md
View file

@ -1,128 +1,254 @@
===============================================================================
# DDCLIENT v3.8.2
# DDCLIENT
ddclient is a Perl client used to update dynamic DNS entries for accounts
on many dynamic DNS services.
`ddclient` is a Perl client used to update dynamic DNS entries for accounts
on many dynamic DNS services. It uses `curl` for internet access.
===============================================================================
on docker compose
```docker-compose
services:
ddclient:
image: lscr.io/linuxserver/ddclient:latest
container_name: ddclient
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Rome
volumes:
- /home/orangepi/dockerfiles/ddclient/config:/config
restart: unless-stopped
```
file ddclient.conf per servizio DDNS di dynu.com da mettere nel folder config
```file
daemon=60 # check every 300 seconds
syslog=yes # log update msgs to syslog
mail=root # mail all msgs to root#mail-failure=root # mail failed update msgs to root
pid=/var/run/ddclient/ddclient.pid # record PID in file.
use=web, web=checkip.dynu.com/, web-skip='IP Address'
protocol=dyndns2 # default protocol
server=api.dynu.com
# default login
login=FabioMich66 # your default user
password=Master66! # your default password
wildcard=yes
patachina.casacam.net
```
## Alternatives
You might also want to consider using one of the following, if they support
your dynamic DNS provider(s): <https://github.com/troglobit/inadyn> or
<https://github.com/lopsided98/dnsupdate>.
## Supported services
Dynamic DNS services currently supported include:
DynDNS.com - See http://www.dyndns.com for details on obtaining a free account.
Hammernode - See http://www.hn.org for details on obtaining a free account.
Zoneedit - See http://www.zoneedit.com for details.
EasyDNS - See http://www.easydns.com for details.
NameCheap - See http://www.namecheap.com for details
ConCont - See http://www.dydns.za.net for details
DnsPark - See http://www.dnspark.com for details
DslReports - See http://www.dslreports.com for details
Sitelutions - See http://www.sitelutions.com for details
Loopia - See http://www.loopia.se for details
Noip - See http://www.noip.com/ for details
Freedns - See http://freedns.afraid.org/ for details
ChangeIP - See http://www.changeip.com/ for details
dtdns - See http://www.dtdns.com/ for details
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
* [1984.is](https://www.1984.is/product/freedns)
* [ChangeIP](https://www.changeip.com)
* [CloudFlare](https://www.cloudflare.com)
* [ClouDNS](https://www.cloudns.net)
* [DDNS.fm](https://www.ddns.fm/)
* [DigitalOcean](https://www.digitalocean.com/)
* [dinahosting](https://dinahosting.com)
* [Directnic](https://directnic.com)
* [DonDominio](https://www.dondominio.com)
* [DNS Made Easy](https://dnsmadeeasy.com)
* [DNSExit](https://dnsexit.com/dns/dns-api)
* [dnsHome.de](https://www.dnshome.de)
* [Domeneshop](https://api.domeneshop.no/docs/#tag/ddns/paths/~1dyndns~1update/get)
* [DslReports](https://www.dslreports.com)
* [Duck DNS](https://duckdns.org)
* [DynDNS.com](https://account.dyn.com)
* [EasyDNS](https://www.easydns.com )
* [Enom](https://www.enom.com)
* [Freedns](https://freedns.afraid.org)
* [Freemyip](https://freemyip.com)
* [Gandi](https://gandi.net)
* [GoDaddy](https://www.godaddy.com)
* [Hurricane Electric](https://dns.he.net)
* [Infomaniak](https://faq.infomaniak.com/2376)
* [INWX](https://www.inwx.com/)
* [Loopia](https://www.loopia.se)
* [Mythic Beasts](https://www.mythic-beasts.com/support/api/dnsv2/dynamic-dns)
* [NameCheap](https://www.namecheap.com)
* [NearlyFreeSpeech.net](https://www.nearlyfreespeech.net/services/dns)
* [Njalla](https://njal.la/docs/ddns)
* [Noip](https://www.noip.com)
* nsupdate - see nsupdate(1) and ddns-confgen(8)
* [OVH](https://www.ovhcloud.com)
* [Porkbun](https://porkbun.com)
* [regfish.de](https://www.regfish.de/domains/dyndns)
* [Sitelutions](https://www.sitelutions.com)
* [Yandex](https://dns.yandex.com)
* [Zoneedit](https://www.zoneedit.com)
DDclient now supports many of cable/dsl broadband routers.
`ddclient` supports finding your IP address from many cable and DSL
broadband routers.
Comments, suggestions and requests: use the forums on
http://sourceforge.net/projects/ddclient/
Comments, suggestions and requests: please file an issue at
https://github.com/ddclient/ddclient/issues/new
The code was originally written by Paul Burry and is now hosted and maintained
through sourceforge.net. Please check out http://ddclient.sf.net
The code was originally written by Paul Burry and is now hosted and
maintained through github.com. Please check out https://ddclient.net
-------------------------------------------------------------------------------
REQUIREMENTS:
## REQUIREMENTS
- one or more accounts from one of the dynamic DNS services
* An account from a supported dynamic DNS service provider
* Perl v5.10.1 or later
* `JSON::PP` perl library for JSON support
* Linux, macOS, or any other Unix-ish system
* An implementation of `make` (such as [GNU
Make](https://www.gnu.org/software/make/))
* If you are installing from a clone of the Git repository, you will
also need [GNU Autoconf](https://www.gnu.org/software/autoconf/)
and [GNU Automake](https://www.gnu.org/software/automake/).
- Perl 5.014 or later
(you need the IO::Socket::SSL perl library for ssl-support
and JSON::Any perl library for JSON support)
## DOWNLOAD
- Linux or probably any common Unix system
See https://github.com/ddclient/ddclient/releases
-------------------------------------------------------------------------------
INSTALLATION:
## INSTALLATION
cp ddclient /usr/sbin/
mkdir /etc/ddclient
mkdir /var/cache/ddclient
cp sample-etc_ddclient.conf /etc/ddclient/ddclient.conf
vi /etc/ddclient/ddclient.conf
-- and change hostnames, logins, and passwords appropriately
### Distribution Package
## For those using Redhat style rc files and using daemon-mode:
cp sample-etc_rc.d_init.d_ddclient /etc/rc.d/init.d/ddclient
## enable automatic startup when booting
## check your distribution
/sbin/chkconfig --add ddclient
## start the first time by hand
/etc/rc.d/init.d/ddclient start
<a href="https://repology.org/project/ddclient/versions">
<img src="https://repology.org/badge/vertical-allrepos/ddclient.svg" alt="Packaging status" align="right">
</a>
The easiest way to install ddclient is to install a package offered by your
operating system. See the image to the right for a list of distributions with a ddclient package.
## For those using Alpine style rc files and using daemon-mode:
cp sample-etc_rc.d_init.d_ddclient.alpine /etc/init.d/ddclient
## enable automatic startup when booting
rc-update add ddclient
## make sure you have perl installed
apk add perl
## start the first time by hand
rc-service ddclient start
### Manual Installation
## If you are not using daemon-mode, configure cron and dhcp or ppp
## as described below.
1. Extract the distribution tarball (`.tar.gz` file) and `cd` into
the directory:
-------------------------------------------------------------------------------
TROUBLESHOOTING:
```shell
tar xvfa ddclient-3.XX.X.tar.gz
cd ddclient-3.XX.X
```
1. enable debugging and verbose messages.
``$ ddclient -daemon=0 -debug -verbose -noquiet``
(If you are installing from a clone of the Git repository, you
must run `./autogen` before continuing to the next step.)
2. Do you need to specify a proxy?
If so, just add a
``proxy=your.isp.proxy``
to the ddclient.conf file.
2. Run the following commands to build and install:
3. Define the IP address of your router with ``fw=xxx.xxx.xxx.xxx`` in
``/etc/ddclient/ddclient.conf`` and then try
``$ ddclient -daemon=0 -query``
to see if the router status web page can be understood.
```shell
./configure \
--prefix=/usr \
--sysconfdir=/etc \
--localstatedir=/var
make
make VERBOSE=1 check
sudo make install
```
4. Need support for another router/firewall?
Define the router status page yourself with:
``fw=url-to-your-router``'s-status-page
``fw-skip=any-string-preceding-your-IP-address``
3. Edit `/etc/ddclient/ddclient.conf`.
ddclient does something like this to provide builtin support for
common routers.
For example, the Linksys routers could have been added with:
fw=192.168.1.1/Status.htm
fw-skip=WAN.*?IP Address
#### systemd
OR
Send me the output from:
$ ddclient -geturl {fw-ip-status-url} [-login login [-password password]]
and I'll add it to the next release!
cp sample-etc_systemd.service /etc/systemd/system/ddclient.service
ie. for my fw/router I used:
$ ddclient -geturl 192.168.1.254/status.htm
enable automatic startup when booting
5. Some broadband routers require the use of a password when ddclient
accesses its status page to determine the router's WAN IP address.
If this is the case for your router, add
fw-login=your-router-login
fw-password=your-router-password
to the beginning of your ddclient.conf file.
Note that some routers use either 'root' or 'admin' as their login
while some others accept anything.
systemctl enable ddclient.service
-------------------------------------------------------------------------------
USING DDCLIENT WITH ppp
start the first time by hand
systemctl start ddclient.service
## Known issues
This is a list for quick referencing of known issues. For further details check out the linked issues and the changelog.
Note that any issues prior to version v3.9.1 will not be listed here.
If a fix is committed but not yet part of any tagged release, the notes here will reference the not-yet-released version number.
### v3.11.2 - v3.9.1: SSL parameter breaks HTTP-only IP acquisition
The `ssl` parameter forces all connections to use HTTPS. While technically
working as expected, this behavior keeps coming up as a pain point when using
HTTP-only IP querying sites such as http://checkip.dyndns.org. Starting with
v4.0.0, the behavior is changed to respect `http://` in a URL. A separate
parameter to disallow all HTTP connections or warn about them may be added
later.
**Fix**: v4.0.0 uses HTTP to connect to URLs starting with `http://`. See
[here](https://github.com/ddclient/ddclient/pull/608) for more info.
**Workaround**: Disable the SSL parameter
### v3.10.0: Chunked encoding not corretly supported in IO::Socket HTTP code
Using the IO::Socket HTTP code will break in various ways whenever the server responds using HTTP 1.1 chunked encoding. Refer to [this issue](https://github.com/ddclient/ddclient/issues/548) for more info.
**Fix**: v3.11.0 - IO::Socket has been deprecated there and curl has been made the standard.
**Workaround**: Use curl for transfers by either setting `-curl` in the command line or by adding `curl=yes` in the config
### v3.10.0: Spammed updates to some providers
This issue arises when using the `use` parameter in the config and using one of these providers:
- Cloudflare
- Hetzner
- Digitalocean
- Infomaniak
**Fix**: v3.11.2
**Workaround**: Use the `usev4`/`usev6` parameters instead of `use`.
## TROUBLESHOOTING
* Enable debugging and verbose messages: `ddclient --daemon=0 --debug --verbose`
* Do you need to specify a proxy?
If so, just add a `proxy=your.isp.proxy` to the `ddclient.conf` file.
* Define the IP address of your router with `fwv4=xxx.xxx.xxx.xxx` in
`/etc/ddclient/ddclient.conf` and then try `$ ddclient --daemon=0 --query`
to see if the router status web page can be understood.
* Need support for another router/firewall?
Define the router yourself with:
```
usev4=fwv4
fwv4=url-to-your-router-status-page
fwv4-skip="regular expression matching any string preceding your IP address, if necessary"
```
ddclient does something like this to provide builtin support for common
routers.
For example, the Linksys routers could have been added with:
```
usev4=fwv4
fwv4=192.168.1.1/Status.htm
fwv4-skip=WAN.*?IP Address
```
OR [create a new issue](https://github.com/ddclient/ddclient/issues/new)
containing the output from:
```
curl --include --location http://url.of.your.firewall/ip-status-page
```
so that we can add a new firewall definition to a future release of
ddclient.
* Some broadband routers require the use of a password when ddclient accesses
its status page to determine the router's WAN IP address.
If this is the case for your router, add
```
fw-login=your-router-login
fw-password=your-router-password
```
to the beginning of your ddclient.conf file.
Note that some routers use either 'root' or 'admin' as their login while
some others accept anything.
## USING DDCLIENT WITH `ppp`
If you are using a ppp connection, you can easily update your DynDNS
entry with each connection, with:
@ -133,8 +259,7 @@ entry with each connection, with:
Alternatively, you may just configure ddclient to operate as a daemon
and monitor your ppp interface.
-------------------------------------------------------------------------------
USING DDCLIENT WITH cron
## USING DDCLIENT WITH `cron`
If you have not configured ddclient to use daemon-mode, you'll need to
configure cron to force an update once a month so that the dns entry will
@ -144,43 +269,41 @@ not become stale.
cp sample-etc_cron.d_ddclient /etc/cron.d/ddclient
vi /etc/cron.d/ddclient
-------------------------------------------------------------------------------
USING DDCLIENT WITH dhcpcd-1.3.17
## USING DDCLIENT WITH `dhcpcd`
If you are using dhcpcd-1.3.17 or thereabouts, you can easily update
your DynDNS entry automatically every time your lease is obtained
or renewed by creating an executable file named:
/etc/dhcpc/dhcpcd-{your-interface}.exe
``/etc/dhcpc/dhcpcd-{your-interface}.exe``
ie.:
cp sample-etc_dhcpc_dhcpcd-eth0.exe /etc/dhcpc/dhcpcd-{your-interface}.exe
``cp sample-etc_dhcpc_dhcpcd-eth0.exe /etc/dhcpc/dhcpcd-{your-interface}.exe``
In my case, it is named dhcpcd-eth0.exe and contains the lines:
#!/bin/sh
PATH=/usr/sbin:/root/bin:${PATH}
logger -t dhcpcd IP address changed to $1
ddclient -proxy fasthttp.sympatico.ca -wildcard -ip $1 | logger -t ddclient
exit 0
```shell
#!/bin/sh
PATH=/usr/bin:/root/bin:${PATH}
logger -t dhcpcd IP address changed to $1
ddclient --proxy fasthttp.sympatico.ca --wildcard --ip $1 | logger -t ddclient
exit 0
```
Other DHCP clients may have another method of calling out to programs
for updating DNS entries.
for updating DNS entries.
Alternatively, you may just configure ddclient to operate as a daemon
and monitor your ethernet interface.
-------------------------------------------------------------------------------
USING DDCLIENT WITH dhclient
## USING DDCLIENT WITH `dhclient`
If you are using the ISC DHCP client (dhclient), you can update
If you are using the ISC DHCP client (dhclient), you can update
your DynDNS entry automatically every time your lease is obtained
or renewed by creating an executable file named:
/etc/dhclient-exit-hooks
``/etc/dhclient-exit-hooks``
ie.:
cp sample-etc_dhclient-exit-hooks /etc/dhclient-exit-hooks
``cp sample-etc_dhclient-exit-hooks /etc/dhclient-exit-hooks``
Edit /etc/dhclient-exit-hooks to change any options required.
Edit ``/etc/dhclient-exit-hooks`` to change any options required.
Alternatively, you may just configure ddclient to operate as a daemon
and monitor your ethernet interface.
-------------------------------------------------------------------------------

View file

@ -1,10 +0,0 @@
Since 3.7.0, ddclient support ssl-updates
To use ssl, put "ssl=yes" in your configuration and make sure
you have IO::Socket::SSL.
On debian, you need libio-socket-ssl-perl to have IO::Socket::SSL
On alpine, you need perl-io-socket-ssl to have IO::Socket::SSL
ssl support is tested on folowing dynamic dns providers:
- dyndns.com

View file

@ -1,12 +0,0 @@
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:
* 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.

14
TODO
View file

@ -1,14 +0,0 @@
* ssl:
- check if the library can be used
- ssl on routers
- ssl on other providers
* notice about irc: there's almost always someone there but we're sometimes idle
or at work...
* adding router: halted, only in patches section.
* add doc postscript
* FAQ: bad hostname (checkip)
* note about init-scripts.
* request from dyndns: http://tinyurl.com/2l3twf
* check bugs

View file

22
autogen Executable file
View file

@ -0,0 +1,22 @@
#!/bin/sh
pecho() { printf %s\\n "$*"; }
log() { pecho "$@"; }
error() { log "ERROR: $@" >&2; }
fatal() { error "$@"; exit 1; }
try() { "$@" || fatal "'$@' failed"; }
try cd "${0%/*}"
# aclocal complains if a directory passed to AC_CONFIG_MACRO_DIR doesn't exist.
try mkdir -p build-aux/m4
# autoreconf's '--force' option doesn't affect any of the files installed by the '--install' option.
# Remove the files to truly force them to be updated.
try rm -f \
aclocal.m4 \
build-aux/config.guess \
build-aux/config.sub \
build-aux/install-sh \
build-aux/missing \
build-aux/tap-driver.sh \
;
try autoreconf -fviW all

View file

@ -0,0 +1,177 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_compare_version.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
#
# DESCRIPTION
#
# This macro compares two version strings. Due to the various number of
# minor-version numbers that can exist, and the fact that string
# comparisons are not compatible with numeric comparisons, this is not
# necessarily trivial to do in a autoconf script. This macro makes doing
# these comparisons easy.
#
# The six basic comparisons are available, as well as checking equality
# limited to a certain number of minor-version levels.
#
# The operator OP determines what type of comparison to do, and can be one
# of:
#
# eq - equal (test A == B)
# ne - not equal (test A != B)
# le - less than or equal (test A <= B)
# ge - greater than or equal (test A >= B)
# lt - less than (test A < B)
# gt - greater than (test A > B)
#
# Additionally, the eq and ne operator can have a number after it to limit
# the test to that number of minor versions.
#
# eq0 - equal up to the length of the shorter version
# ne0 - not equal up to the length of the shorter version
# eqN - equal up to N sub-version levels
# neN - not equal up to N sub-version levels
#
# When the condition is true, shell commands ACTION-IF-TRUE are run,
# otherwise shell commands ACTION-IF-FALSE are run. The environment
# variable 'ax_compare_version' is always set to either 'true' or 'false'
# as well.
#
# Examples:
#
# AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8])
# AX_COMPARE_VERSION([3.15],[lt],[3.15.8])
#
# would both be true.
#
# AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8])
# AX_COMPARE_VERSION([3.15],[gt],[3.15.8])
#
# would both be false.
#
# AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8])
#
# would be true because it is only comparing two minor versions.
#
# AX_COMPARE_VERSION([3.15.7],[eq0],[3.15])
#
# would be true because it is only comparing the lesser number of minor
# versions of the two values.
#
# Note: The characters that separate the version numbers do not matter. An
# empty string is the same as version 0. OP is evaluated by autoconf, not
# configure, so must be a string, not a variable.
#
# The author would like to acknowledge Guido Draheim whose advice about
# the m4_case and m4_ifvaln functions make this macro only include the
# portions necessary to perform the specific comparison specified by the
# OP argument in the final configure script.
#
# LICENSE
#
# Copyright (c) 2008 Tim Toolan <toolan@ele.uri.edu>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 13
dnl #########################################################################
AC_DEFUN([AX_COMPARE_VERSION], [
AC_REQUIRE([AC_PROG_AWK])
# Used to indicate true or false condition
ax_compare_version=false
# Convert the two version strings to be compared into a format that
# allows a simple string comparison. The end result is that a version
# string of the form 1.12.5-r617 will be converted to the form
# 0001001200050617. In other words, each number is zero padded to four
# digits, and non digits are removed.
AS_VAR_PUSHDEF([A],[ax_compare_version_A])
A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
-e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
-e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
-e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
-e 's/[[^0-9]]//g'`
AS_VAR_PUSHDEF([B],[ax_compare_version_B])
B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
-e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
-e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
-e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
-e 's/[[^0-9]]//g'`
dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary
dnl # then the first line is used to determine if the condition is true.
dnl # The sed right after the echo is to remove any indented white space.
m4_case(m4_tolower($2),
[lt],[
ax_compare_version=`echo "x$A
x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"`
],
[gt],[
ax_compare_version=`echo "x$A
x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"`
],
[le],[
ax_compare_version=`echo "x$A
x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"`
],
[ge],[
ax_compare_version=`echo "x$A
x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"`
],[
dnl Split the operator from the subversion count if present.
m4_bmatch(m4_substr($2,2),
[0],[
# A count of zero means use the length of the shorter version.
# Determine the number of characters in A and B.
ax_compare_version_len_A=`echo "$A" | $AWK '{print(length)}'`
ax_compare_version_len_B=`echo "$B" | $AWK '{print(length)}'`
# Set A to no more than B's length and B to no more than A's length.
A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"`
B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"`
],
[[0-9]+],[
# A count greater than zero means use only that many subversions
A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
],
[.+],[
AC_WARNING(
[invalid OP numeric parameter: $2])
],[])
# Pad zeros at end of numbers to make same length.
ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`"
B="$B`echo $A | sed 's/./0/g'`"
A="$ax_compare_version_tmp_A"
# Check for equality or inequality as necessary.
m4_case(m4_tolower(m4_substr($2,0,2)),
[eq],[
test "x$A" = "x$B" && ax_compare_version=true
],
[ne],[
test "x$A" != "x$B" && ax_compare_version=true
],[
AC_WARNING([invalid OP parameter: $2])
])
])
AS_VAR_POPDEF([A])dnl
AS_VAR_POPDEF([B])dnl
dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE.
if test "$ax_compare_version" = "true" ; then
m4_ifvaln([$4],[$4],[:])dnl
m4_ifvaln([$5],[else $5])dnl
fi
]) dnl AX_COMPARE_VERSION

View file

@ -0,0 +1,77 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_prog_perl_modules.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_PROG_PERL_MODULES([MODULES], [ACTION-IF-TRUE], [ACTION-IF-FALSE])
#
# DESCRIPTION
#
# Checks to see if the given perl modules are available. If true the shell
# commands in ACTION-IF-TRUE are executed. If not the shell commands in
# ACTION-IF-FALSE are run. Note if $PERL is not set (for example by
# calling AC_CHECK_PROG, or AC_PATH_PROG), AC_CHECK_PROG(PERL, perl, perl)
# will be run.
#
# MODULES is a space separated list of module names. To check for a
# minimum version of a module, append the version number to the module
# name, separated by an equals sign.
#
# Example:
#
# AX_PROG_PERL_MODULES( Text::Wrap Net::LDAP=1.0.3, ,
# AC_MSG_WARN(Need some Perl modules)
#
# LICENSE
#
# Copyright (c) 2009 Dean Povey <povey@wedgetail.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 8
AU_ALIAS([AC_PROG_PERL_MODULES], [AX_PROG_PERL_MODULES])
AC_DEFUN([AX_PROG_PERL_MODULES],[dnl
m4_define([ax_perl_modules])
m4_foreach([ax_perl_module], m4_split(m4_normalize([$1])),
[
m4_append([ax_perl_modules],
[']m4_bpatsubst(ax_perl_module,=,[ ])[' ])
])
# Make sure we have perl
if test -z "$PERL"; then
AC_CHECK_PROG(PERL,perl,perl)
fi
if test "x$PERL" != x; then
ax_perl_modules_failed=0
for ax_perl_module in ax_perl_modules; do
AC_MSG_CHECKING(for perl module $ax_perl_module)
# Would be nice to log result here, but can't rely on autoconf internals
$PERL -e "use $ax_perl_module; exit" > /dev/null 2>&1
if test $? -ne 0; then
AC_MSG_RESULT(no);
ax_perl_modules_failed=1
else
AC_MSG_RESULT(ok);
fi
done
# Run optional shell commands
if test "$ax_perl_modules_failed" = 0; then
:
$2
else
:
$3
fi
else
AC_MSG_WARN(could not find perl)
fi])dnl

View file

@ -0,0 +1,70 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_prog_perl_version.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_PROG_PERL_VERSION([VERSION],[ACTION-IF-TRUE],[ACTION-IF-FALSE])
#
# DESCRIPTION
#
# Makes sure that perl supports the version indicated. If true the shell
# commands in ACTION-IF-TRUE are executed. If not the shell commands in
# ACTION-IF-FALSE are run. Note if $PERL is not set (for example by
# running AC_CHECK_PROG or AC_PATH_PROG) the macro will fail.
#
# Example:
#
# AC_PATH_PROG([PERL],[perl])
# AX_PROG_PERL_VERSION([5.8.0],[ ... ],[ ... ])
#
# This will check to make sure that the perl you have supports at least
# version 5.8.0.
#
# NOTE: This macro uses the $PERL variable to perform the check.
# AX_WITH_PERL can be used to set that variable prior to running this
# macro. The $PERL_VERSION variable will be valorized with the detected
# version.
#
# LICENSE
#
# Copyright (c) 2009 Francesco Salvestrini <salvestrini@users.sourceforge.net>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 13
AC_DEFUN([AX_PROG_PERL_VERSION],[
AC_REQUIRE([AC_PROG_SED])
AC_REQUIRE([AC_PROG_GREP])
AS_IF([test -n "$PERL"],[
ax_perl_version="$1"
AC_MSG_CHECKING([for perl version])
changequote(<<,>>)
perl_version=`$PERL --version 2>&1 \
| $SED -n -e '/This is perl/b inspect
b
: inspect
s/.* (\{0,1\}v\([0-9]*\.[0-9]*\.[0-9]*\))\{0,1\} .*/\1/;p'`
changequote([,])
AC_MSG_RESULT($perl_version)
AC_SUBST([PERL_VERSION],[$perl_version])
AX_COMPARE_VERSION([$ax_perl_version],[le],[$perl_version],[
:
$2
],[
:
$3
])
],[
AC_MSG_WARN([could not find the perl interpreter])
$3
])
])

View file

@ -0,0 +1,70 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_with_prog.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_WITH_PROG([VARIABLE],[program],[VALUE-IF-NOT-FOUND],[PATH])
#
# DESCRIPTION
#
# Locates an installed program binary, placing the result in the precious
# variable VARIABLE. Accepts a present VARIABLE, then --with-program, and
# failing that searches for program in the given path (which defaults to
# the system path). If program is found, VARIABLE is set to the full path
# of the binary; if it is not found VARIABLE is set to VALUE-IF-NOT-FOUND
# if provided, unchanged otherwise.
#
# A typical example could be the following one:
#
# AX_WITH_PROG(PERL,perl)
#
# NOTE: This macro is based upon the original AX_WITH_PYTHON macro from
# Dustin J. Mitchell <dustin@cs.uchicago.edu>.
#
# LICENSE
#
# Copyright (c) 2008 Francesco Salvestrini <salvestrini@users.sourceforge.net>
# Copyright (c) 2008 Dustin J. Mitchell <dustin@cs.uchicago.edu>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 17
AC_DEFUN([AX_WITH_PROG],[
AC_PREREQ([2.61])
pushdef([VARIABLE],$1)
pushdef([EXECUTABLE],$2)
pushdef([VALUE_IF_NOT_FOUND],$3)
pushdef([PATH_PROG],$4)
AC_ARG_VAR(VARIABLE,Absolute path to EXECUTABLE executable)
AS_IF(test -z "$VARIABLE",[
AC_MSG_CHECKING(whether EXECUTABLE executable path has been provided)
AC_ARG_WITH(EXECUTABLE,AS_HELP_STRING([--with-EXECUTABLE=[[[PATH]]]],absolute path to EXECUTABLE executable), [
AS_IF([test "$withval" != yes && test "$withval" != no],[
VARIABLE="$withval"
AC_MSG_RESULT($VARIABLE)
],[
VARIABLE=""
AC_MSG_RESULT([no])
AS_IF([test "$withval" != no], [
AC_PATH_PROG([]VARIABLE[],[]EXECUTABLE[],[]VALUE_IF_NOT_FOUND[],[]PATH_PROG[])
])
])
],[
AC_MSG_RESULT([no])
AC_PATH_PROG([]VARIABLE[],[]EXECUTABLE[],[]VALUE_IF_NOT_FOUND[],[]PATH_PROG[])
])
])
popdef([PATH_PROG])
popdef([VALUE_IF_NOT_FOUND])
popdef([EXECUTABLE])
popdef([VARIABLE])
])

123
configure.ac Normal file
View file

@ -0,0 +1,123 @@
AC_PREREQ([2.63])
# Get the version from ddclient.in so that the same version string
# doesn't have to be maintained in two places. The m4_dquote macro is
# used instead of quote characters to ensure that the command is only
# run once. The command outputs quote characters to prevent
# incidental expansion (the m4_esyscmd macro does not quote the
# command output itself, so the command output is subject to
# expansion).
AC_INIT([ddclient], m4_dquote(m4_esyscmd([printf '[%s]' "$(./ddclient.in --version=short)"])))
# Needed because of the above invocation of ddclient.in.
AC_SUBST([CONFIGURE_DEPENDENCIES], ['$(top_srcdir)/ddclient.in'])
AC_CONFIG_SRCDIR([ddclient.in])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([build-aux/m4])
AC_REQUIRE_AUX_FILE([tap-driver.sh])
# If the automake dependency is bumped to v1.12 or newer, remove
# build-aux/tap-driver.sh from the repository. Automake 1.12+ comes
# with tap-driver.sh, and autoreconf will copy in the version
# distributed with automake. (Automake 1.11 and older don't come with
# tap-driver.sh, so build-aux/tap-driver.sh is checked in to keep the
# above AC_REQUIRE_AUX_FILE line from causing configure to complain
# about a mising file if the user has Automake 1.11.)
AM_INIT_AUTOMAKE([1.11 -Wall -Werror foreign subdir-objects parallel-tests])
AM_SILENT_RULES
m4_define([CONFDIR_DEFAULT], [${sysconfdir}/AC_PACKAGE_NAME])
AC_ARG_WITH(
[confdir],
[AS_HELP_STRING(
[--with-confdir=DIR],
m4_expand([[look for ddclient.conf in DIR @<:@default: ]CONFDIR_DEFAULT[@:>@]]))],
[],
# The single quotes are intentional; see:
# https://www.gnu.org/software/automake/manual/html_node/Uniform.html
[with_confdir='CONFDIR_DEFAULT'])
AC_SUBST([confdir], [${with_confdir}])
AC_PROG_MKDIR_P
# The Fedora Docker image doesn't come with the 'findutils' package.
# 'find' is required for 'make distcheck', which the user might not
# run. We could log a warning instead of erroring out, but:
# * a warning is unlikely to be seen,
# * 'make distcheck' doesn't yield a non-0 exit code if 'find' is
# not available,
# * 'find' is a core utility that should always be available, and
# * we might use 'find' for other purposes in the future.
AC_PATH_PROG([FIND], [find])
AS_IF([test -z "${FIND}"], [AC_MSG_ERROR(['find' utility not found])])
AC_ARG_WITH([curl],
[AS_HELP_STRING([[--with-curl[=CURL]]], [use CURL as absolute path to curl executable])],
[],
[with_curl=yes])
AS_CASE([${with_curl}],
[[yes]], [AC_PATH_PROG([CURL], [curl])],
[[no]], [CURL=],
[
AC_MSG_CHECKING([for curl])
CURL=${with_curl}
AC_MSG_RESULT([${CURL}])
]);
AS_IF([test -z "${CURL}"], [AC_MSG_ERROR([curl not found])])
AX_WITH_PROG([PERL], perl)
AX_PROG_PERL_VERSION([5.10.1], [],
[AC_MSG_ERROR([Perl 5.10.1 or newer not found])])
AC_SUBST([PERL])
# Perl modules required to run ddclient. Note: CentOS, RHEL, and
# Fedora put some core modules in separate packages, and the perl
# package doesn't depend on all of them, so their availability can't
# be assumed.
m4_foreach_w([_m], [
Data::Dumper
File::Basename
File::Path
File::Temp
Getopt::Long
Socket
Sys::Hostname
version=0.77
], [AX_PROG_PERL_MODULES([_m], [],
[AC_MSG_ERROR([missing required Perl module _m])])])
# Perl modules required for tests. If these modules are not installed
# then some tests will fail. Only prints a warning if not installed.
m4_foreach_w([_m], [
B
Exporter
File::Spec::Functions
File::Temp
List::Util
Scalar::Util
re
], [AX_PROG_PERL_MODULES([_m], [],
[AC_MSG_WARN([some tests will fail due to missing module _m])])])
# Optional Perl modules for tests. If these modules are not installed
# then some tests will be skipped, but no tests should fail. Only
# prints a warning if not installed.
m4_foreach_w([_m], [
Carp
HTTP::Daemon=6.12
HTTP::Daemon::SSL
HTTP::Message::PSGI
HTTP::Request
HTTP::Response
JSON::PP
Test::MockModule
Test::TCP
Test::Warnings
Time::HiRes
URI
parent
], [AX_PROG_PERL_MODULES([_m], [],
[AC_MSG_WARN([some tests may be skipped due to missing module _m])])])
AC_CONFIG_FILES([
Makefile
t/version.pl
])
AC_OUTPUT

4231
ddclient

File diff suppressed because it is too large Load diff

421
ddclient.conf.in Normal file
View file

@ -0,0 +1,421 @@
######################################################################
##
## Define default global variables with lines like:
## var=value [, var=value]*
## These values will be used for each following host unless overridden
## with a local variable definition.
##
## Define local variables for one or more hosts with:
## var=value [, var=value]* host.and.domain[,host2.and.domain...]
##
## Lines can be continued on the following line by ending the line
## with a \
##
##
## Warning: not all supported routers or dynamic DNS services
## are mentioned here.
##
######################################################################
## Use encryption (TLS) when the scheme (either "http://" or "https://") is
## missing from a URL. Defaults to "yes".
#ssl=yes
daemon=300 # check every 300 seconds
syslog=yes # log update msgs to syslog
mail=root # mail all msgs to root
mail-failure=root # mail failed update msgs to root
# mail-from=root # set the email "From:" header to "root". If
# unset (the default) or empty, the from address
# depends on your system's default behavior.
pid=@runstatedir@/ddclient.pid # record PID in file.
# postscript=script # run script after updating. The new IP is
# added as argument.
#
#use=watchguard-soho, fw=192.168.111.1:80 # via Watchguard's SOHO FW
#use=netopia-r910, fw=192.168.111.1:80 # via Netopia R910 FW
#use=smc-barricade, fw=192.168.123.254:80 # via SMC's Barricade FW
#use=netgear-rt3xx, fw=192.168.0.1:80 # via Netgear's internet FW
#use=linksys, fw=192.168.1.1:80 # via Linksys's internet FW
#use=maxgate-ugate3x00, fw=192.168.0.1:80 # via MaxGate's UGATE-3x00 FW
#use=elsa-lancom-dsl10, fw=10.0.0.254:80 # via ELSA LanCom DSL/10 DSL Router
#use=elsa-lancom-dsl10-ch01, fw=10.0.0.254:80 # via ELSA LanCom DSL/10 DSL Router
#use=elsa-lancom-dsl10-ch02, fw=10.0.0.254:80 # via ELSA LanCom DSL/10 DSL Router
#use=alcatel-stp, fw=10.0.0.138:80 # via Alcatel Speed Touch Pro
#use=xsense-aero, fw=192.168.1.1:80 # via Xsense Aero Router
#use=allnet-1298, fw=192.168.1.1:80 # via AllNet 1298 DSL Router
#use=3com-oc-remote812, fw=192.168.0.254:80 # via 3com OfficeConnect Remote 812
#use=e-tech, fw=192.168.1.1:80 # via E-tech Router
#use=cayman-3220h, fw=192.168.0.1:1080 # via Cayman 3220-H DSL Router
#
#fw-login=admin, fw-password=XXXXXX # FW login and password
#
## To obtain an IP address from FW status page (using fw-login, fw-password)
#use=fw, fw=192.168.1.254/status.htm, fw-skip='IP Address' # found after IP Address
#
## To obtain an IP address via UPnP from router
## Requires miniupnpc to be installed on the system.
#use=cmd, cmd=external-ip
#
## To obtain an IP address from Web status page (using the proxy if defined)
## by default, checkip.dyndns.org is used if you use the dyndns protocol.
## Using use=web is enough to get it working.
## WARNING: set deamon at least to 600 seconds if you use checkip or you could
## get banned from their service.
#use=web, web=checkip.dyndns.org/, web-skip='IP Address' # found after IP Address
#
#use=ip, ip=127.0.0.1 # via static IP's
#use=if, if=eth0 # via interfaces
#use=web # via web
#
#protocol=dyndns2 # default protocol
#proxy=fasthttp.sympatico.ca:80 # default proxy
#server=members.dyndns.org # default server
#server=members.dyndns.org:8245 # default server (bypassing proxies)
#login=your-login # default login
#password=test # default password
#mx=mx.for.your.host # default MX
#backupmx=yes|no # host is primary MX?
#wildcard=yes|no # add wildcard CNAME?
##
## dyndns.org dynamic addresses
##
## (supports variables: wildcard,mx,backupmx)
##
# server=members.dyndns.org, \
# protocol=dyndns2 \
# your-dynamic-host.dyndns.org
##
## ZoneEdit (zoneedit.com)
##
# server=dynamic.zoneedit.com, \
# protocol=zoneedit1, \
# login=your-zoneedit-login, \
# password=your-zoneedit-password \
# your.any.domain,your-2nd.any.dom
##
## EasyDNS (easydns.com)
##
# server=members.easydns.com, \
# protocol=easydns, \
# login=your-easydns-login, \
# password=your-easydns-password \
# your.any.domain,your-2nd.any.domain
##
## dslreports.com dynamic-host monitoring
##
# server=members.dslreports.com \
# protocol=dslreports1, \
# login=dslreports-login, \
# password=dslreports-password \
# dslreports-unique-id
##
## OrgDNS.org account-configuration
##
# use=web, web=members.orgdns.org/nic/ip
# protocol=dyndns2
# server=www.orgdns.org \
# login=yourLoginName \
# password=yourPassword \
# yourSubdomain.orgdns.org
##
## NameCheap (namecheap.com)
##
# protocol=namecheap, \
# server=dynamicdns.park-your-domain.com, \
# login=example.com, \
# password=example.com-password \
# subdomain.example.com
##
## NearlyFreeSpeech.NET (nearlyfreespeech.net)
##
# protocol=nfsn, \
# zone=example.com, \
# login=member-login, \
# password=api-key \
# example.com,subdomain.example.com
##
## Loopia (loopia.se)
##
# use=web, web=loopia
# protocol=dyndns2
# server=dns.loopia.se
# script=/XDynDNSServer/XDynDNS.php
# login=my-loopia.se-login
# password=my-loopia.se-password
# my.domain.tld,other.domain.tld
##
## NoIP (noip.com)
##
# protocol=noip, \
# ssl=yes, \
# server=dynupdate.no-ip.com, \
# login=your-noip-login, \
# password=your-noip-password \
# your-host.domain.com, your-2nd-host.domain.com
##
## ChangeIP (changeip.com)
##
## single host update
# protocol=changeip, \
# login=my-my-changeip.com-login, \
# password=my-changeip.com-password \
# myhost.changeip.org
##
## CloudFlare (www.cloudflare.com)
##
# protocol=cloudflare, \
# zone=domain.tld, \
# ttl=1, \
# login=your-login-email, \ # Only needed if you are using your global API key. If you are using an API token, set it to "token" (without double quotes).
# password=APIKey \ # This is either your global API key, or an API token. If you are using an API token, it must have the permissions "Zone - DNS - Edit" and "Zone - Zone - Read". The Zone resources must be "Include - All zones".
# domain.tld,my.domain.tld
##
## Gandi (gandi.net)
##
## Single host update
# protocol=gandi
# zone=example.com
# password=my-gandi-access-token
# use-personal-access-token=yes
# ttl=10800 # optional
# myhost.example.com
##
## GoDaddy (godaddy.com)
##
# protocol=godaddy, \
# password=my-godaddy-api-key, \
# password=my-godaddy-secret, \
# ttl=600 \
# zone=example.com, \
# myhost.example.com,nexthost.example.com
##
## Hurricane Electric (dns.he.net)
##
# protocol=he.net, \
# password=my-genereated-password \
# myhost.example.com
##
## Duckdns (http://www.duckdns.org/)
##
#
# protocol=duckdns, \
# password=my-auto-generated-password \
# hostwithoutduckdnsorg
##
## Freemyip (http://freemyip.com/)
##
#
# protocol=freemyip,
# password=my-token
# myhost
##
## DDNS.FM (https://ddns.fm/)
##
#
# protocol=ddns.fm,
# password=my-token
# myhost.example.com
##
## MyOnlinePortal (http://myonlineportal.net)
##
# # 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
# protocol=dyndns2
# ssl=yes
# login=your-myonlineportal-username
# password=your-myonlineportal-password
# domain.myonlineportal.net
##
## nsupdate.info IPV4(https://www.nsupdate.info)
##
# use=web, web=http://ipv4.nsupdate.info/myip
# protocol=dyndns2
# server=ipv4.nsupdate.info
# login=domain.nsupdate.info
# password='123'
# domain.nsupdate.info
##
## nsupdate.info IPV6 (https://www.nsupdate.info)
## ddclient releases <= 3.8.1 do not support IPv6
##
# usev6=if, if=eth0
# protocol=dyndns2
# server=ipv6.nsupdate.info
# login=domain.nsupdate.info
# password='123'
# domain.nsupdate.info
##
## Yandex.Mail for Domain (domain.yandex.com)
##
# protocol=yandex, \
# login=domain.tld, \
# password=yandex-pdd-token \
# my.domain.tld,other.domain.tld \
##
## DNS Made Easy (https://dnsmadeeasy.com)
##
# protocol=dnsmadeeasy,
# login=your-account-email-address
# password=your-generated-password
# your-numeric-record-id-1,your-numeric-record-id-2,...
##
## OVH DynHost (https://ovh.com)
##
# protocol=ovh,
# login=example.com-dynhostuser,
# password=your_password
# test.example.com
##
## Porkbun (https://porkbun.com/)
##
# protocol=porkbun
# apikey=APIKey
# secretapikey=SecretAPIKey
# root-domain=example.com
# host.example.com,host2.sub.example.com
# example.com,sub.example.com
##
## ClouDNS (https://www.cloudns.net)
##
# protocol=cloudns, \
# dynurl=https://ipv4.cloudns.net/api/dynamicURL/?q=Njc1OTE2OjY3Njk0NDM6YTk2, \
# myhost.example.com
##
## dinahosting (https://dinahosting.com)
##
# protocol=dinahosting, \
# login=myusername, \
# password=mypassword \
# myhost.mydomain.com
##
## dnsexit (www.dnsexit.com)
##
# protocol=dnsexit, \
# login=myusername, \
# password=mypassword, \
# subdomain-1.domain.com,subdomain-2.domain.com
##
## dnsexit2 (API method www.dnsexit.com)
##
# protocol=dnsexit2
# password=MyAPIKey
# subdomain-1.domain.com,subdomain-2.domain.com
##
## domeneshop (www.domeneshop.no)
##
# protocol=domeneshop
# login=<token>
# password=<secret>
# subdomain-1.domain.com,subdomain-2.domain.com
##
## Njal.la (http://njal.la/)
##
# protocol=njalla,
# password=mypassword
# quietreply=no|yes
# my-domain.com
##
## regfish.de (www.regfish.de/)
##
# protocol=regfishde,
# password=mypassword
# my-domain.com
##
## Enom (www.enom.com)
##
# protocol=enom,
# login=domain.name,
# password=domain-password
# my-domain.com
##
## DigitalOcean (www.digitalocean.com)
##
# protocol=digitalocean, \
# zone=example.com, \
# password=api-token \
# example.com,sub.example.com
##
## Directnic (directnic.com)
##
# protocol=directnic,
# urlv4=https://directnic.com/dns/gateway/ipv4_token/
# urlv6=https://directnic.com/dns/gateway/ipv6_token/
# my-domain.com
##
## Infomaniak (www.infomaniak.com)
##
# protocol=infomaniak,
# login=ddns_username,
# password=ddns_password
# example.com
#
# N.B. the infomaniak protocol is obsolete. Please use dyndns2 instead:
#
# protocol=dyndns2,
# use=web, web=infomaniak.com/ip.php/
# login=ddns_username,
# password=ddns_password
# redirect=2
# example.com
##
## Email Only
##
# protocol=emailonly
# host.example.com
##
## dnsHome.de
##
# protocol=dyndns2 \
# server=www.dnshome.de \
# login=subdomain.domain.tld \
# password=your_password \
# subdomain.domain.tld
##
## INWX
##
# protocol=inwx \
# login=my-inwx-DynDNS-account-username \
# password=my-inwx-DynDNS-account-password \
# myhost.example.org

7705
ddclient.in Executable file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,39 @@
# Provider implementations
Author: [@LenardHess](https://github.com/LenardHess/)\
Date: 2023-11-23
This document is meant to detail the mechanisms that provider implementation shall use. It differentiates between new and legacy provider implementations. The former are adhering to the IPv6 support updates being done to ddclient, the legacy ones are from before that update.
## New provider Implementation
1. Grab the IP(s) from $config{$host}{'wantipv4'} and/or $config{$host}{'wantipv6'}
2. Optional: Query the provider for the current IP record(s). If they are already good, skip updating IP record(s)
3. Update the IP record(s).
4. If successful (or if the records were already good):
- Set 'status-ipv4' and/or 'status-ipv6' to 'good'
- Set 'ipv4' and/or 'ipv6' to the IP that has been set
- Set 'mtime' to the current time
5. If not successful:
- Set 'status-ipv4' and/or 'status-ipv6' to an error message
- Set 'atime' to the current time
The new provider implementation should not set 'status' nor 'ip'. They're part of the legacy infrastructure and ddclient will take care of setting them correctly.
## Legacy provider implementations
1. Grab the IP from $config{$host}{'wantip'}
2. Optional: Query the provider for the current IP record. If it is already good, skip updating IP record
3. Update the IP record.
4. If successful (or if the record was already good):
- Set 'status' to 'good'
- Set 'ip' to the IP that has been set
- Set 'mtime' to the current time
5. If not successful:
- Set 'status' to an error message
- Set 'atime' to the current time
# ToDo
- Decide/Inquire whether services prefer querying the IP first. Then decide whether to make it mandatory.
- Write guidelines on checking existing records (i.e. check TTL as well?).
- Start a list of providers and their implementation state
- Add more details to this document
- Whether 'wantip*' ought to be deleted when read or not.

337
docs/ipv6-design-doc.md Normal file
View file

@ -0,0 +1,337 @@
# Design Doc: IPv6 Support
Author: [@rhansen](https://github.com/rhansen/)\
Date: 2020-06-09\
Signed off by:
[@SuperSandro2000](https://github.com/SuperSandro2000/)
## Objective
Add full IPv6 support to ddclient, including support for dual-stack
systems.
## Background
ddclient's current IPv6 support is limited:
* Users can update either an IPv6 record or an IPv4 record for a
host, not both.
* If SSL is used for an HTTP request, IPv6 will be used if the
remote host has a AAAA record, even if the user would rather use
IPv4. This breaks `use=web` for IPv4 if the `web` URL's host has a
AAAA record.
* The `use=if` method only works if the user sets `if-skip` to
something that skips over all IPv4 addresses in the output of
`ifconfig` (or `ip`). If the output contains an IPv4 address after
the IPv6 address then `use=if` cannot be used for IPv6.
* There is no support for falling back to IPv4 if an IPv6 connection
fails.
* `use=if` does not filter out locally scoped or temporary IPv6
addresses.
Some attempts have been made to add more robust IPv6 support:
* Debian's ddclient package applies a
[patch](https://salsa.debian.org/debian/ddclient/-/blob/67a138aa3d98d70f01766123f58ef40e98693fd4/debian/patches/usev6.diff)
that adds a new `usev6` option. The `usev6` option can be set to
`ip` or `if`, but not any of the other strategies currently
available for the `use` option (`web`, `cmd`, `fw`, `cisco`,
`cisco-asa`). When set to `ip` or `if`, only IPv6 addresses are
considered; IPv4 addresses are ignored. The patch does not change
the behavior of the `use` option, so `use=web` or `use=cmd` can be
used for IPv6 if pointed at something that only outputs an IPv6
address.
* [ddclient-curl](https://github.com/astlinux-project/ddclient-curl)
is a fork of ddclient that uses curl as the HTTP client (instead
of ddclient's own homemade client) for more robust IPv6 support.
* PR #40 is perhaps the most comprehensive attempt at adding full
IPv6 support, but it was never merged and has since
bit-rotted. There is renewed effort to rebase the changes and get
them merged in. PR #40 adds new options and changes some existing
options. The approach taken is to completely isolate IPv4 address
detection from IPv6 address detection and require the update
protocol callbacks to handle each type of address appropriately.
## Requirements
* The mechanism for determining the current IPv4 address (the `use`
option) must be independently configurable from the mechanism used
to determine the current IPv6 address.
* The user must be able to disable IPv4 address updates without
affecting IPv6 updates.
* The user must be able to disable IPv6 address updates without
affecting IPv4 updates.
* If HTTP polling is used for both IPv4 and IPv6 address discovery,
the URL used to determine the IPv4 address (the `web` option) must
be independently configurable from the URL used to determine the
IPv6 address.
* The use of IPv4 or IPv6 to update a record must be independent of
the type of record being updated (IPv4 or IPv6).
* The callback for the update protocol must be given both addresses,
even if only one of the two addresses has changed.
* The callback for the update protocol must be told which addresses
have changed.
* There must be IPv6 equivalents to `use=ip`, `use=if`, `use=web`,
and `use=cmd`. For the IPv6 equivalent to `use=if`, it is
acceptable to ignore non-global and temporary addresses (the user
can always use the IPv6 equivalent to `use=cmd` to get non-global
or temporary addresses).
* Existing support for updating IPv6 records must not be lost.
* Some dynamic DNS service providers use separate credentials for
the IPv4 and IPv6 records. These providers must be supported,
either by accepting both sets of credentials in a single host's
configuration or by allowing the user to specify the same host
twice, once for IPv4 and once for IPv6.
### Nice-to-Haves
* The user should be able to force the update protocol to use IPv4
or IPv6.
* Unless configured otherwise, ddclient should first attempt to
update via IPv6 and fall back to IPv4 if the IPv6 connection
fails. This behavior can be added later; for now it is acceptable
to keep the current behavior (use IPv6 without IPv4 fallback if
there is a AAAA record, use IPv4 if there is no AAAA record).
* Full backwards compatibility with existing config files and
flags. The trade-offs between migration burden, long-term
usability, and code maintenance should be carefully considered.
* IPv6 equivalents to `use=fw`, `use=cisco`, and `use=cisco-asa`.
* Add IPv6 support in protocol callbacks where IPv6 support is
currently missing. (This can be done later.)
## Proposal
### Configuration changes
* Add new `usev4` and `usev6` settings that are like the current
`use` setting except they only apply to IPv4 and IPv6,
respectively.
* `usev4` can be set to one of the following values: `disabled`,
`ipv4`, `webv4`, `fwv4`, `ifv4`, `cmdv4`, `ciscov4`,
`cisco-asav4`
* `usev6` can be set to one of the following values: `disabled`,
`ipv6`, `webv6`, `fwv6`, `ifv6`, `cmdv6`, `ciscov6`,
`cisco-asav6`
* Add a new `use` strategy: `disabled`.
* The `disabled` value for `use`, `usev4`, and `usev6` causes
ddclient to act as if it was never set. This is useful for
overriding the global value for a particular host.
* For compatibility with ddclient-curl, `no` is a deprecated alias
of `disabled`.
* Add new `ipv4`, `ipv6`, `webv4`, `webv4-skip`, `webv6`,
`webv6-skip`, `ifv4`, `ifv6`, `cmdv4`, `cmdv6`, etc. settings that
behave like their versionless counterparts except they only apply
to IPv4 or IPv6. Deprecate the versionless counterparts, and
change their behavior so that they also influence the default
value of the versioned options. (Example: Suppose
`usev4=ifv4`. If `ifv4` is not set then `if` is used.) Special
notes:
* The value of `ip` will only serve as the default for `ipv4`
(or `ipv6`) if it contains an IPv4 (or IPv6) address.
* There is currently an `ipv6` boolean setting. To preserve
backward compatibility with existing configs, `ipv6` set to a
boolean value is ignored (other than a warning).
* There is no `ifv4-skip` or `ifv6-skip` because it's ddclient's
responsibility to properly parse the output of whatever tool
it uses to read the interface's addresses.
* For now there is no `cmdv4-skip` or `cmdv6-skip`. Anyone who
already knows how to write a regular expression can probably
write a wrapper script. These may be added in the future if
users request them, especially if it facilitates migration
away from the deprecated `cmd-skip` setting.
* For `usev6=ifv6`, interfaces are likely to have several IPv6
addresses (unlike IPv4). Choosing the "right" IPv6 address is
not trivial. Fortunately, we don't have to solve this
perfectly right now; we can choose something that mostly
works and let user bug reports guide future refinements. For
the first iteration, we will try the following:
* Ignore addresses that are not global unicast.
(Unfortunately, the `ip` command from iproute2 does not
provide a way to filter out ULA addresses so we will have
to do this ourselves.)
* Ignore temporary addresses.
* If no addresses remain, log a warning and don't update the
IPv6 record.
* Otherwise, if one of the remaining addresses matches the
previously selected address, continue to use it.
* Otherwise, select one arbitrarily.
* Deprecate the `use` setting (print a loud warning) but keep its
existing semantics with an exception: If there is a conflict with
`usev4` or `usev6` then those take priority:
* If `use`, `usev4`, and `usev6` are all set then a warning is
logged and the `use` setting is ignored.
* If `use` and `usev4` are both set and the `use` strategy
discovers an IPv4 address that differs from the address
discovered by the `usev4` strategy, then the address from
`usev4` is used and a warning is logged.
* If `use` and `usev6` are both set and the `use` strategy
discovers an IPv6 address that differs from the address
discovered by the `usev6` strategy, then the address from
`usev6` is used and a warning is logged.
* If `usev4` (`usev6`) is not set:
* If `ipv4` (`usev6`) is set, ddclient acts as if `usev4`
(`usev6`) was set to `ipv4` (`ipv6`).
* Otherwise, if `ifv4` (`ifv6`) is set, ddclient acts as if
`usev4` (`usev6`) was set to `ifv4` (`ifv6`).
* Otherwise, if `cmdv4` (`cmdv6`) is set, ddclient acts as if
`usev4` (`usev6`) was set to `cmdv4` (`cmdv6`).
* Otherwise, if `fwv4` (`fwv6`) is set, ddclient acts as if
`usev4` (`usev6`) was set to `fwv4` (`fwv6`).
* Otherwise, `usev4` (`usev6`) remains unset.
* To support separate credentials for IPv4 vs. IPv6 updates, users
can specify the same host multiple times, each time with different
options.
### Internal API changes
* Add two new entries to the `$config{$host}` hash:
* `$config{$host}{'wantipv4'}` is set to:
* If `usev4` is enabled, the IPv4 address discovered by the
`usev4` strategy.
* Otherwise, if `use` is enabled and the `use` strategy
discovered an IPv4 address, the IPv4 address discovered by
the `use` strategy.
* Otherwise, `undef`.
* `$config{$host}{'wantipv6'}` is set to:
* If `usev6` is enabled, the IPv6 address discovered by the
`usev6` strategy.
* Otherwise, if `use` is enabled and the `use` strategy
discovered an IPv6 address, the IPv6 address discovered by
the `use` strategy.
* Otherwise, `undef`.
* Deprecate the existing `$config{$host}{'wantip'}` entry, to be
removed after all update protocol callbacks have been updated to
use the above new entries. In the meantime, this entry's value
depends on which of `use`, `usev4`, and `usev6` is enabled, and
what type of IP address is discovered by the `use` strategy (if
enabled), according to the following table:
| `use` | `usev4` | `usev6` | resulting value |
| :---: | :---: | :---: | :--- |
| ✔(IPv4) | ✖ | ✖ | the IPv4 address discovered by the `use` strategy |
| ✔(IPv6) | ✖ | ✖ | the IPv6 address discovered by the `use` strategy |
| ✖ | ✔ | ✖ | the IPv4 address discovered by the `usev4` strategy |
| ✖ | ✖ | ✔ | the IPv6 address discovered by the `usev6` strategy |
| ✔(IPv4) | ✔ | ✖ | the IPv4 address discovered by the `usev4` strategy (and log another warning if it doesn't match the IPv4 address found by the `use` strategy) |
| ✔(IPv6) | ✔ | ✖ | the IPv6 address discovered by the `use` strategy |
| ✔(IPv4) | ✖ | ✔ | the IPv4 address discovered by the `use` strategy |
| ✔(IPv6) | ✖ | ✔ | the IPv6 address discovered by the `usev6` strategy (and log another warning if it doesn't match the IPv6 address found by the `use` strategy) |
* To support separate credentials for IPv4 vs. IPv6 updates, convert
the `%config` hash of host configs into a list of host configs. A
second definition for the same host adds a second entry rather
than overwrites the existing entry.
## Alternatives Considered
### Repurpose the existing settings for v4
Rather than create new `usev4`, `ifv4`, `cmdv4`, etc. settings,
repurpose the existing `use`, `if`, `cmd`, etc. settings for IPv4.
Why this was rejected:
* There is a usability advantage to the symmetry with the `v6`
settings.
* It is easier to remain compatible with existing configurations.
### Let `use` set the default for `usev4`
Rather than three separate IP discovery mechanisms (`use`, `usev4`,
and `usev6`), have just two (`usev4` and `usev6`) and let the old
`use` setting control the default for `usev4`: If `usev4` is not set,
then `use=foo` is equivalent to `usev4=foov4`.
Why this was rejected: Backwards incompatibility. Specifically,
configurations that previously updated an IPv6 record would instead
(attempt to) update an IPv4 record.
### Let `use` set the default for `usev4` and `usev6`
Rather than three separate IP discovery mechanisms (`use`, `usev4`,
and `usev6`), have just two (`usev4` and `usev6`) and let the old
`use` setting control the default for `usev4` and `usev6`:
* If neither `usev4` nor `usev6` is set, then `use=foo` is
equivalent to `usev4=foov4,usev6=foov6`.
* If `usev4` is set but not `usev6`, then `use=foo` is equivalent to
`usev6=foov6`.
* If `usev6` is set but not `usev4`, then `use=foo` is equivalent to
`usev4=foov4`.
* If both `usev4` and `usev6` are set, then `use=foo` is ignored.
Why this was rejected: The new design would cause existing
configurations to trigger surprising, and possibly undesired (e.g.,
timeouts or update errors), new behavior:
* Configurations that previously updated only an IPv4 record would
also update an IPv6 record.
* Similarly, configurations that previously updated only an IPv6
record would also update an IPv4 record.
### Replace uses of `'wantip'` with `'wantipv4'`
Rather than support `'wantip'`, `'wantipv4'`, and `'wantipv6'`, just
replace all `'wantip'` references to `'wantipv4'`.
Why this was rejected: This would break compatibility for users that
are currently updating IPv6 addresses. (Compatibility would be
restored once the update protocol callbacks are updated to honor
`'wantipv6'`.)
### Single `if` setting for both `usev4=if` and `usev6=if`
The proposed design calls for separate `ifv4` and `ifv6` settings. If
the user sets `usev4=if,usev6=if`, then the user most likely wants to
use the same interface for both IPv4 and IPv6. Rather than create
separate `ifv4` and `ifv6` settings, have a single `if` setting used
for both `usev4` and `usev6`.
Why this was rejected:
* Separate `v4` and `v6` settings adds consistency to the
configuration.
* There are cases where a user will want to use a different
interface. In particular, an IPv6 over IPv4 tunnel (e.g.,
https://tunnelbroker.net) involves creating a separate interface
that is used only for IPv6.
### Separate IPv4 and IPv6 credentials
In order to support providers that use separate credentials for IPv4
and IPv6 updates, the proposed design allows the user to define the
same host twice. We could instead add additional options so that the
user can provide both sets of credentials in a single host definition.
Why this was rejected:
* The proposed design is easier to implement, as it does not require
any modifications to existing protocol implementations.
* The proposed design is less likely to cause problems for users
that rely on globals instead of host-specific options. For
example, a configuration file like the following might not do what
the user expects:
```
ssl=true, use=if, if=eth0
protocol=foo
login=username-for-ipv4
password=password-for-ipv4
loginv6=username-for-ipv6
passwordv6=password-for-ipv6
myhost.example.com
protocol=bar
login=username
password=password
# This host definition will use loginv6, passwordv6 from above
# because the user didn't end each setting with a line
# continuation:
my-other-host.example.com
```
* The proposed design provides some bonus functionality:
* Users can smoothly transition between different providers by
updating both providers simultaneously until the domain
registration switches to the new registrar.
* Users can take advantage of providers that support multiple A
or multiple AAAA records for the same hostname, assuming each
record has independent credentials.

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
@ -10,8 +9,4 @@
######################################################################
## force an update twice a month (only if you are not using daemon-mode)
##
## 30 23 1,15 * * root /usr/sbin/ddclient -daemon=0 -syslog -quiet -force
######################################################################
## retry failed updates every hour (only if you are not using daemon-mode)
##
## 0 * * * * root /usr/sbin/ddclient -daemon=0 -syslog -quiet retry
## 30 23 1,15 * * root /usr/bin/ddclient -daemon=0 -syslog -quiet -force

View file

@ -1,216 +0,0 @@
######################################################################
##
## $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
## with a local variable definition.
##
## Define local variables for one or more hosts with:
## var=value [, var=value]* host.and.domain[,host2.and.domain...]
##
## Lines can be continued on the following line by ending the line
## with a \
##
##
## Warning: not all supported routers or dynamic DNS services
## are mentioned here.
##
######################################################################
daemon=300 # check every 300 seconds
syslog=yes # log update msgs to syslog
mail=root # mail all msgs to root
mail-failure=root # mail failed update msgs to root
pid=/var/run/ddclient.pid # record PID in file.
ssl=yes # use ssl-support. Works with
# ssl-library
# postscript=script # run script after updating. The
# new IP is added as argument.
#
#use=watchguard-soho, fw=192.168.111.1:80 # via Watchguard's SOHO FW
#use=netopia-r910, fw=192.168.111.1:80 # via Netopia R910 FW
#use=smc-barricade, fw=192.168.123.254:80 # via SMC's Barricade FW
#use=netgear-rt3xx, fw=192.168.0.1:80 # via Netgear's internet FW
#use=linksys, fw=192.168.1.1:80 # via Linksys's internet FW
#use=maxgate-ugate3x00, fw=192.168.0.1:80 # via MaxGate's UGATE-3x00 FW
#use=elsa-lancom-dsl10, fw=10.0.0.254:80 # via ELSA LanCom DSL/10 DSL Router
#use=elsa-lancom-dsl10-ch01, fw=10.0.0.254:80 # via ELSA LanCom DSL/10 DSL Router
#use=elsa-lancom-dsl10-ch02, fw=10.0.0.254:80 # via ELSA LanCom DSL/10 DSL Router
#use=alcatel-stp, fw=10.0.0.138:80 # via Alcatel Speed Touch Pro
#use=xsense-aero, fw=192.168.1.1:80 # via Xsense Aero Router
#use=allnet-1298, fw=192.168.1.1:80 # via AllNet 1298 DSL Router
#use=3com-oc-remote812, fw=192.168.0.254:80 # via 3com OfficeConnect Remote 812
#use=e-tech, fw=192.168.1.1:80 # via E-tech Router
#use=cayman-3220h, fw=192.168.0.1:1080 # via Cayman 3220-H DSL Router
#
#fw-login=admin, fw-password=XXXXXX # FW login and password
#
## To obtain an IP address from FW status page (using fw-login, fw-password)
#use=fw, fw=192.168.1.254/status.htm, fw-skip='IP Address' # found after IP Address
#
## To obtain an IP address from Web status page (using the proxy if defined)
## by default, checkip.dyndns.org is used if you use the dyndns protocol.
## Using use=web is enough to get it working.
## WARNING: set deamon at least to 600 seconds if you use checkip or you could
## get banned from their service.
#use=web, web=checkip.dyndns.org/, web-skip='IP Address' # found after IP Address
#
#use=ip, ip=127.0.0.1 # via static IP's
#use=if, if=eth0 # via interfaces
#use=web # via web
#
#protocol=dyndns2 # default protocol
#proxy=fasthttp.sympatico.ca:80 # default proxy
#server=members.dyndns.org # default server
#server=members.dyndns.org:8245 # default server (bypassing proxies)
#login=your-login # default login
#password=test # default password
#mx=mx.for.your.host # default MX
#backupmx=yes|no # host is primary MX?
#wildcard=yes|no # add wildcard CNAME?
##
## dyndns.org dynamic addresses
##
## (supports variables: wildcard,mx,backupmx)
##
# server=members.dyndns.org, \
# protocol=dyndns2 \
# your-dynamic-host.dyndns.org
##
## dyndns.org static addresses
##
## (supports variables: wildcard,mx,backupmx)
##
# static=yes, \
# server=members.dyndns.org, \
# protocol=dyndns2 \
# your-static-host.dyndns.org
##
##
## dyndns.org custom addresses
##
## (supports variables: wildcard,mx,backupmx)
##
# custom=yes, \
# server=members.dyndns.org, \
# protocol=dyndns2 \
# your-domain.top-level,your-other-domain.top-level
##
## ZoneEdit (zoneedit.com)
##
# server=dynamic.zoneedit.com, \
# protocol=zoneedit1, \
# login=your-zoneedit-login, \
# password=your-zoneedit-password \
# your.any.domain,your-2nd.any.dom
##
## EasyDNS (easydns.com)
##
# server=members.easydns.com, \
# protocol=easydns, \
# login=your-easydns-login, \
# password=your-easydns-password \
# your.any.domain,your-2nd.any.domain
##
## Hammernode (hn.org) dynamic addresses
##
# server=dup.hn.org, \
# protocol=hammernode1, \
# login=your-hn-login, \
# password=your-hn-password \
# your-hn-host.hn.org,your-2nd-hn-host.hn.org
##
## dslreports.com dynamic-host monitoring
##
# server=members.dslreports.com \
# protocol=dslreports1, \
# login=dslreports-login, \
# password=dslreports-password \
# dslreports-unique-id
##
## OrgDNS.org account-configuration
##
# use=web, web=members.orgdns.org/nic/ip
# server=www.orgdns.org \
# protocol=dyndns2 \
# login=yourLoginName \
# password=yourPassword \
# yourSubdomain.orgdns.org
##
## dnspark.com
## (supports variables: mx, mxpri)
##
# use=web, web=ipdetect.dnspark.com, web-skip='Current Address:'
# protocol=dnspark, \
# server=www.dnspark.com, \
# your-host.dnspark.com
##
## NameCheap (namecheap.com)
##
# protocol=namecheap, \
# server=dynamicdns.park-your-domain.com, \
# login=my-namecheap.com-login, \
# password=my-namecheap.com-password \
# myhost.namecheap.com
##
##
## Loopia (loopia.se)
##
# use=web
# web=loopia
# protocol=dyndns2
# server=dns.loopia.se
# script=/XDynDNSServer/XDynDNS.php
# login=my-loopia.se-login
# password=my-loopia.se-password
# my.domain.tld,other.domain.tld
##
##
## ChangeIP (changeip.com)
##
## single host update
# protocol=changeip, \
# login=my-my-changeip.com-login, \
# password=my-changeip.com-password \
# myhost.changeip.org
##
## DtDNS (www.dtdns.com)
##
# protocol=dtdns,
# server=www.dtdns.com,
# client=ddclient,
# password=my-dtdns.com-password
# myhost.dtdns.net, otherhost.dtdns.net
##
## CloudFlare (www.cloudflare.com)
##
#protocol=cloudflare, \
#zone=domain.tld, \
#server=www.cloudflare.com, \
#login=your-login-email, \
#password=APIKey \
#domain.tld,my.domain.tld
##
## Google Domains (www.google.com/domains)
##
# protocol=googledomains,
# login=my-auto-generated-username,
# password=my-auto-generated-password
# my.domain.tld, otherhost.domain.tld

View file

@ -1,11 +1,9 @@
#!/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.
PATH=/usr/sbin:${PATH}
PATH=/usr/bin:${PATH}
case "$new_ip_address" in
10.*) ;;
172.1[6-9].* | 172.2[0-9].* | 172.3[0-1].*) ;;

View file

@ -1,8 +1,6 @@
#!/bin/sh
######################################################################
## $Id: sample-etc_dhcpc_dhcpcd-eth0.exe 96 2008-06-13 20:24:24Z wimpunk $
######################################################################
PATH=/usr/sbin:${PATH}
PATH=/usr/bin:${PATH}
## update the DNS server unless the IP address is a private address
## that may be used as an internal LAN address. This may be true if

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
@ -16,7 +14,7 @@
## in the environment as either PPP_LOCAL or IPLOCAL.
##
######################################################################
PATH=/usr/sbin:${PATH}
PATH=/usr/bin:${PATH}
IP=
IP=${IP:-$PPP_LOCAL}
IP=${IP:-$IPLOCAL}

View file

@ -1,91 +0,0 @@
#!/bin/bash
#
# ddclient This shell script takes care of starting and stopping
# ddclient.
#
# chkconfig: 2345 65 35
# description: ddclient provides support for updating dynamic DNS services.
CONF=/etc/ddclient/ddclient.conf
program=ddclient
[ -f $CONF ] || exit 0
system=unknown
if [ -f /etc/fedora-release ]; then
system=fedora
elif [ -f /etc/redhat-release ]; then
system=redhat
elif [ -f /etc/debian_version ]; then
system=debian
fi
PID=''
if [ "$system" = "fedora" ] || [ "$system" = "redhat" ]; then
. /etc/init.d/functions
PID=`pidofproc $program`
else
PID=`ps -aef | grep "$program - sleep" | grep -v grep | awk '{print $2}'`
fi
PATH=/usr/sbin:/usr/local/sbin:${PATH}
export PATH
# See how we were called.
case "$1" in
start)
# Start daemon.
DELAY=`grep -v '^\s*#' $CONF | grep -i -m 1 "daemon" | awk -F '=' '{print $2}'`
if [ -z "$DELAY" ] ; then
DELAY="-daemon 300"
else
DELAY=''
fi
echo -n "Starting ddclient: "
if [ "$system" = "fedora" ] || [ "$system" = "redhat" ]; then
daemon $program $DELAY
else
ddclient $DELAY
fi
echo
;;
stop)
# Stop daemon.
echo -n "Shutting down ddclient: "
if [ -n "$PID" ] ; then
if [ "$system" = "fedora" ] || [ "$system" = "redhat" ]; then
killproc $program
else
kill $PID
fi
else
echo "ddclient is not running"
fi
echo
;;
restart)
$0 stop
$0 start
;;
status)
if [ "$system" = "fedora" ] || [ "$system" = "redhat" ]; then
status $program
else
if test "$PID"
then
for p in $PID
do
echo "$program (pid $p) is running"
done
else
echo "$program is stopped"
fi
fi
;;
*)
echo "Usage: ddclient {start|stop|restart|status}"
exit 1
esac
exit 0

View file

@ -1,38 +0,0 @@
#!/sbin/runscript
description="ddclient Daemon for Alpine"
command="/usr/sbin/ddclient"
config_file="/etc/ddclient/ddclient.conf"
command_args=""
pidfile=$(grep -v '^\s*#' "${config_file}" | grep -i -m 1 pid= | awk -F '=' '{print $2}')
delay=$(grep -v '^\s*#' "${config_file}" | grep -i -m 1 "daemon" | awk -F '=' '{print $2}')
if [ -z "${delay}" ]
then
command_args="-daemon 300"
else
command_args=""
fi
depend() {
use logger
need net
after firewall
}
start() {
ebegin "Starting ddclient"
start-stop-daemon --start \
--exec "${command}" \
--pidfile "${pidfile}" \
-- \
${command_args}
eend $?
}
stop() {
ebegin "Stopping ddclient"
start-stop-daemon --stop --exec "${command}" \
--pidfile "${pidfile}"
eend $?
}

View file

@ -1,66 +0,0 @@
#!/bin/sh
#
# ddclient This shell script takes care of starting and stopping
# ddclient.
#
# chkconfig: 2345 65 35
# description: ddclient provides support for updating dynamic DNS services.
#
# Above is for RedHat and now the LSB part
### BEGIN INIT INFO
# Provides: ddclient
# Required-Start: $syslog $remote_fs
# Should-Start: $time ypbind sendmail
# Required-Stop: $syslog $remote_fs
# Should-Stop: $time ypbind sendmail
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Short-Description: ddclient provides support for updating dynamic DNS services
# Description: ddclient is a Perl client used to update dynamic DNS
# entries for accounts on many dynamic DNS services and
# 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
DDCLIENT_BIN=/usr/sbin/ddclient
#
# LSB Standard (SuSE,RedHat,...)
#
if [ -f /lib/lsb/init-functions ] ; then
. /lib/lsb/init-functions
fi
# See how we were called.
case "$1" in
start)
echo -n "Starting ddclient "
start_daemon $DDCLIENT_BIN -daemon 300
rc_status -v
;;
stop)
echo -n "Shutting down ddclient "
killproc -TERM `basename $DDCLIENT_BIN`
rc_status -v
;;
restart)
$0 stop
$0 start
rc_status
;;
status)
echo -n "Checking for service ddclient "
checkproc `basename $DDCLIENT_BIN`w
rc_status -v
;;
*)
echo "Usage: ddclient {start|stop|restart|status}"
exit 1
esac
exit 0

View file

@ -1,41 +0,0 @@
#!/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.
#
# chkconfig: 2345 65 35
# description: ddclient provides support for updating dynamic DNS services.
[ -f /etc/ddclient/ddclient.conf ] || exit 0
. /etc/rc.d/init.d/functions
# See how we were called.
case "$1" in
start)
# Start daemon.
echo -n "Starting ddclient: "
touch /var/lock/subsys/ddclient
daemon ddclient -daemon 300
echo
;;
stop)
# Stop daemon.
echo -n "Shutting down ddclient: "
killproc ddclient
echo
rm -f /var/lock/subsys/ddclient
;;
restart)
$0 stop
$0 start
;;
status)
status ddclient
;;
*)
echo "Usage: ddclient {start|stop|restart|status}"
exit 1
esac
exit 0

View file

@ -1,51 +0,0 @@
#!/bin/sh
### 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
PIDFILE=/var/run/ddclient.pid
test -x $DDCLIENT || exit 0
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
;;
esac
exit 0

View file

@ -0,0 +1,13 @@
[Unit]
Description=Dynamic DNS Update Client
Wants=network-online.target
After=network-online.target nss-lookup.target
[Service]
Type=exec
Environment=daemon_interval=5m
ExecStart=/usr/bin/ddclient --daemon ${daemon_interval} --foreground
Restart=on-failure
[Install]
WantedBy=multi-user.target

21
sample-get-ip-from-fritzbox Executable file
View file

@ -0,0 +1,21 @@
#!/bin/bash
#
# Script to fetch IP from fritzbox
#
# Contributed by @Rusk85 in request #45
# Script can be used in the configuration by adding
#
# use=cmd, cmd=/etc/ddclient/get-ip-from-fritzbox
#
# All credits for this one liner go to the author of this blog:
# http://scytale.name/blog/2010/01/fritzbox-wan-ip
# Disclaimer: It might be necessary to make the script executable
# Set default hostname to connect to the FritzBox
: ${FRITZ_BOX_HOSTNAME:=fritz.box}
curl -s -H 'Content-Type: text/xml; charset="utf-8"' \
-H 'SOAPAction: urn:schemas-upnp-org:service:WANIPConnection:1#GetExternalIPAddress' \
-d '<?xml version="1.0" encoding="utf-8"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <s:Body> <u:GetExternalIPAddress xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1" /></s:Body></s:Envelope>' \
"http://$FRITZ_BOX_HOSTNAME:49000/igdupnp/control/WANIPConn1" | \
grep -Eo '\<[[:digit:]]{1,3}(\.[[:digit:]]{1,3}){3}\>'

11
shell.nix Normal file
View file

@ -0,0 +1,11 @@
{ pkgs ? import <nixpkgs> { } }:
with pkgs;
mkShellNoCC {
buildInputs = [
autoconf
automake
gnumake
];
}

169
t/builtinfw_query.pl Normal file
View file

@ -0,0 +1,169 @@
use Test::More;
BEGIN { SKIP: { eval { require Test::Warnings; 1; } or skip($@, 1); } }
BEGIN { eval { require 'ddclient'; } or BAIL_OUT($@); }
sub setbuiltinfw {
my ($fw) = @_;
no warnings 'once';
$ddclient::builtinfw{$fw->{name}} = $fw;
%ddclient::ip_strategies = ddclient::builtinfw_strategy($fw->{name});
%ddclient::ipv4_strategies = ddclient::builtinfwv4_strategy($fw->{name});
%ddclient::ipv6_strategies = ddclient::builtinfwv6_strategy($fw->{name});
}
my @gotcalls;
my $skip_test_fw = 't/builtinfw_query.pl skip test';
setbuiltinfw({
name => $skip_test_fw,
query => sub { return '192.0.2.1 skip1 192.0.2.2 skip2 192.0.2.3'; },
queryv4 => sub { return '192.0.2.4 skip1 192.0.2.5 skip3 192.0.2.6'; },
queryv6 => sub { return '2001:db8::1 skip1 2001:db8::2 skip4 2001:db8::3'; },
});
my @skip_test_cases = (
{
desc => 'query',
getip => \&ddclient::get_ip,
useopt => 'use',
cfgxtra => {},
want => '192.0.2.2',
},
{
desc => 'queryv4',
getip => \&ddclient::get_ipv4,
useopt => 'usev4',
cfgxtra => {'fwv4-skip' => 'skip3'},
want => '192.0.2.6',
},
{
desc => 'queryv4 with fw-skip fallback',
getip => \&ddclient::get_ipv4,
useopt => 'usev4',
cfgxtra => {},
want => '192.0.2.5',
},
{
desc => 'queryv6',
getip => \&ddclient::get_ipv6,
useopt => 'usev6',
cfgxtra => {'fwv6-skip' => 'skip4'},
want => '2001:db8::3',
},
{
# Support for --usev6=<builtin> wasn't added until after --fwv6-skip was added, so fallback
# to the deprecated --fw-skip option was never needed.
desc => 'queryv6 ignores fw-skip',
getip => \&ddclient::get_ipv6,
useopt => 'usev6',
cfgxtra => {},
want => '2001:db8::1',
},
);
for my $tc (@skip_test_cases) {
my $h = "t/builtinfw_query.pl $tc->{desc}";
$ddclient::config{$h} = {
$tc->{useopt} => $skip_test_fw,
'fw-skip' => 'skip1',
%{$tc->{cfgxtra}},
};
my $got = $tc->{getip}(ddclient::strategy_inputs($tc->{useopt}, $h));
is($got, $tc->{want}, $tc->{desc});
}
my $default_inputs_fw = 't/builtinfw_query.pl default inputs';
setbuiltinfw({
name => $default_inputs_fw,
query => sub { my %p = @_; push(@gotcalls, \%p); return '192.0.2.1'; },
queryv4 => sub { my %p = @_; push(@gotcalls, \%p); return '192.0.2.2'; },
queryv6 => sub { my %p = @_; push(@gotcalls, \%p); return '2001:db8::1'; },
});
my @default_inputs_test_cases = (
{
desc => 'use with default inputs',
getip => \&ddclient::get_ip,
useopt => 'use',
want => {use => $default_inputs_fw, fw => 'server', 'fw-skip' => 'skip',
'fw-login' => 'login', 'fw-password' => 'password', 'fw-ssl-validate' => 1},
},
{
desc => 'usev4 with default inputs',
getip => \&ddclient::get_ipv4,
useopt => 'usev4',
want => {usev4 => $default_inputs_fw, fwv4 => 'serverv4', fw => 'server',
'fwv4-skip' => 'skipv4', 'fw-skip' => 'skip', 'fw-login' => 'login',
'fw-password' => 'password', 'fw-ssl-validate' => 1},
},
{
desc => 'usev6 with default inputs',
getip => \&ddclient::get_ipv6,
useopt => 'usev6',
want => {usev6 => $default_inputs_fw, fwv6 => 'serverv6', 'fwv6-skip' => 'skipv6'},
},
);
for my $tc (@default_inputs_test_cases) {
my $h = "t/builtinfw_query.pl $tc->{desc}";
$ddclient::config{$h} = {
$tc->{useopt} => $default_inputs_fw,
'fw' => 'server',
'fwv4' => 'serverv4',
'fwv6' => 'serverv6',
'fw-login' => 'login',
'fw-password' => 'password',
'fw-ssl-validate' => 1,
'fw-skip' => 'skip',
'fwv4-skip' => 'skipv4',
'fwv6-skip' => 'skipv6',
};
@gotcalls = ();
$tc->{getip}(ddclient::strategy_inputs($tc->{useopt}, $h));
is_deeply(\@gotcalls, [$tc->{want}], $tc->{desc});
}
my $custom_inputs_fw = 't/builtinfw_query.pl custom inputs';
setbuiltinfw({
name => $custom_inputs_fw,
query => sub { my %p = @_; push(@gotcalls, \%p); return '192.0.2.1'; },
inputs => ['if'],
queryv4 => sub { my %p = @_; push(@gotcalls, \%p); return '192.0.2.2'; },
inputsv4 => ['ifv4'],
queryv6 => sub { my %p = @_; push(@gotcalls, \%p); return '2001:db8::1'; },
inputsv6 => ['ifv6'],
});
my @custom_inputs_test_cases = (
{
desc => 'use with custom inputs',
getip => \&ddclient::get_ip,
useopt => 'use',
want => {use => $custom_inputs_fw, if => 'eth0'},
},
{
desc => 'usev4 with custom inputs',
getip => \&ddclient::get_ipv4,
useopt => 'usev4',
want => {usev4 => $custom_inputs_fw, ifv4 => 'eth4'},
},
{
desc => 'usev6 with custom inputs',
getip => \&ddclient::get_ipv6,
useopt => 'usev6',
want => {usev6 => $custom_inputs_fw, ifv6 => 'eth6'},
},
);
for my $tc (@custom_inputs_test_cases) {
my $h = "t/builtinfw_query.pl $tc->{desc}";
$ddclient::config{$h} = {
$tc->{useopt} => $custom_inputs_fw,
'if' => 'eth0',
'ifv4' => 'eth4',
'ifv6' => 'eth6',
};
@gotcalls = ();
$tc->{getip}(ddclient::strategy_inputs($tc->{useopt}, $h));
is_deeply(\@gotcalls, [$tc->{want}], $tc->{desc});
}
done_testing();

53
t/check_value.pl Normal file
View file

@ -0,0 +1,53 @@
use Test::More;
use strict;
SKIP: { eval { require Test::Warnings; } or skip($@, 1); }
eval { require 'ddclient'; } or BAIL_OUT($@);
my @test_cases = (
{
type => ddclient::T_FQDN(),
input => 'example.com',
want => 'example.com',
},
{
type => ddclient::T_FQDN(),
input => 'example',
want_invalid => 1,
},
{
type => ddclient::T_URL(),
input => 'https://www.example.com',
want => 'https://www.example.com',
},
{
type => ddclient::T_URL(),
input => 'https://directnic.com/dns/gateway/ad133/',
want => 'https://directnic.com/dns/gateway/ad133/',
},
{
type => ddclient::T_URL(),
input => 'HTTPS://MixedCase.com/',
want => 'HTTPS://MixedCase.com/',
},
{
type => ddclient::T_URL(),
input => 'ftp://bad.protocol/',
want_invalid => 1,
},
{
type => ddclient::T_URL(),
input => 'bad-url',
want_invalid => 1,
},
);
for my $tc (@test_cases) {
my $got;
my $got_invalid = !(eval {
$got = ddclient::check_value($tc->{input},
ddclient::setv($tc->{type}, 0, 0, undef, undef));
1;
});
is($got_invalid, !!$tc->{want_invalid}, "$tc->{type}: $tc->{input}: validity");
is($got, $tc->{want}, "$tc->{type}: $tc->{input}: normalization") if !$tc->{want_invalid};
}
done_testing();

65
t/get_ip_from_if.pl Normal file
View file

@ -0,0 +1,65 @@
use Test::More;
BEGIN { SKIP: { eval { require Test::Warnings; 1; } or skip($@, 1); } }
BEGIN { eval { require 'ddclient'; } or BAIL_OUT($@); }
use ddclient::t;
subtest "get_default_interface tests" => sub {
for my $sample (@ddclient::t::routing_samples) {
if (defined($sample->{want_ipv4_if})) {
my $interface = ddclient::get_default_interface(4, $sample->{text});
is($interface, $sample->{want_ipv4_if}, $sample->{name});
}
if (defined($sample->{want_ipv6_if})) {
my $interface = ddclient::get_default_interface(6, $sample->{text});
is($interface, $sample->{want_ipv6_if}, $sample->{name});
}
}
};
subtest "get_ip_from_interface tests" => sub {
for my $sample (@ddclient::t::interface_samples) {
# interface name is undef as we are passing in test data
if (defined($sample->{want_ipv4_from_if})) {
my $ip = ddclient::get_ip_from_interface(undef, 4, undef, $sample->{text}, $sample->{MacOS});
is($ip, $sample->{want_ipv4_from_if}, $sample->{name});
}
if (defined($sample->{want_ipv6gua_from_if})) {
my $ip = ddclient::get_ip_from_interface(undef, 6, 'gua', $sample->{text}, $sample->{MacOS});
is($ip, $sample->{want_ipv6gua_from_if}, $sample->{name});
}
if (defined($sample->{want_ipv6ula_from_if})) {
my $ip = ddclient::get_ip_from_interface(undef, 6, 'ula', $sample->{text}, $sample->{MacOS});
is($ip, $sample->{want_ipv6ula_from_if}, $sample->{name});
}
}
};
subtest "Get default interface and IP for test system (IPv4)" => sub {
my $interface = ddclient::get_default_interface(4);
plan(skip_all => 'no IPv4 interface') if !$interface;
isnt($interface, "lo", "Check for loopback 'lo'");
isnt($interface, "lo0", "Check for loopback 'lo0'");
my $ip1 = ddclient::get_ip_from_interface("default", 4);
my $ip2 = ddclient::get_ip_from_interface($interface, 4);
is($ip1, $ip2, "Check IPv4 from default interface");
SKIP: {
skip('default interface does not have an appropriate IPv4 addresses') if !$ip1;
ok(ddclient::is_ipv4($ip1), "Valid IPv4 from get_ip_from_interface($interface)");
}
};
subtest "Get default interface and IP for test system (IPv6)" => sub {
my $interface = ddclient::get_default_interface(6);
plan(skip_all => 'no IPv6 interface') if !$interface;
isnt($interface, "lo", "Check for loopback 'lo'");
isnt($interface, "lo0", "Check for loopback 'lo0'");
my $ip1 = ddclient::get_ip_from_interface("default", 6);
my $ip2 = ddclient::get_ip_from_interface($interface, 6);
is($ip1, $ip2, "Check IPv6 from default interface");
SKIP: {
skip('default interface does not have an appropriate IPv6 addresses') if !$ip1;
ok(ddclient::is_ipv6($ip1), "Valid IPv6 from get_ip_from_interface($interface)");
}
};
done_testing();

57
t/geturl_connectivity.pl Normal file
View file

@ -0,0 +1,57 @@
use Test::More;
BEGIN { SKIP: { eval { require Test::Warnings; 1; } or skip($@, 1); } }
BEGIN { eval { require 'ddclient'; } or BAIL_OUT($@); }
use ddclient::t::HTTPD;
use ddclient::t::ip;
httpd_required();
$ddclient::globals{'ssl_ca_file'} = $ca_file;
for my $ipv ('4', '6') {
for my $ssl (0, 1) {
my $httpd = httpd($ipv, $ssl) or next;
$httpd->run(sub {
return [200, ['Content-Type' => 'application/octet-stream'], [$_[0]->as_string()]];
});
}
}
my @test_cases = (
{ipv6_opt => 0, server_ipv => '4', client_ipv => ''},
{ipv6_opt => 0, server_ipv => '4', client_ipv => '4'},
# IPv* client to a non-SSL IPv6 server is not expected to work unless opt('ipv6') is true
{ipv6_opt => 0, server_ipv => '6', client_ipv => '6'},
# Fetch without ssl
{ server_ipv => '4', client_ipv => '' },
{ server_ipv => '4', client_ipv => '4' },
{ server_ipv => '6', client_ipv => '' },
{ server_ipv => '6', client_ipv => '6' },
# Fetch with ssl
{ ssl => 1, server_ipv => '4', client_ipv => '' },
{ ssl => 1, server_ipv => '4', client_ipv => '4' },
{ ssl => 1, server_ipv => '6', client_ipv => '' },
{ ssl => 1, server_ipv => '6', client_ipv => '6' },
);
for my $tc (@test_cases) {
$tc->{ipv6_opt} //= 0;
$tc->{ssl} //= 0;
SKIP: {
skip("IPv6 not supported on this system", 1)
if $tc->{server_ipv} eq '6' && !$ipv6_supported;
skip("HTTP::Daemon too old for IPv6 support", 1)
if $tc->{server_ipv} eq '6' && !$httpd_ipv6_supported;
skip("HTTP::Daemon::SSL not available", 1) if $tc->{ssl} && !$httpd_ssl_supported;
my $uri = httpd($tc->{server_ipv}, $tc->{ssl})->endpoint();
my $name = sprintf("IPv%s client to %s%s",
$tc->{client_ipv} || '*', $uri, $tc->{ipv6_opt} ? ' (-ipv6)' : '');
$ddclient::globals{'ipv6'} = $tc->{ipv6_opt};
my $got = ddclient::geturl(url => $uri, ipversion => $tc->{client_ipv});
isnt($got // '', '', $name);
}
}
done_testing();

27
t/geturl_response.pl Normal file
View file

@ -0,0 +1,27 @@
use Test::More;
SKIP: { eval { require Test::Warnings; } or skip($@, 1); }
eval { require 'ddclient'; } or BAIL_OUT($@);
# Fake curl. Use the printf utility, which can process escapes. This allows Perl to drive the fake
# curl with plain ASCII and get arbitrary bytes back, avoiding problems caused by any encoding that
# might be done by Perl (e.g., "use open ':encoding(UTF-8)';").
my @fakecurl = ('sh', '-c', 'printf %b "$1"', '--');
my @test_cases = (
{
desc => 'binary body',
# Body is UTF-8 encoded ✨ (U+2728 Sparkles) followed by a 0xff byte (invalid UTF-8).
printf => join('\r\n', ('HTTP/1.1 200 OK', '', '\0342\0234\0250\0377')),
# The raw bytes should come through as equally valued codepoints. They must not be decoded.
want => "HTTP/1.1 200 OK\n\n\xe2\x9c\xa8\xff",
},
);
for my $tc (@test_cases) {
@ddclient::curl = (@fakecurl, $tc->{printf});
$ddclient::curl if 0; # suppress spurious warning "Name used only once: possible typo"
my $got = ddclient::geturl(url => 'http://ignored');
is($got, $tc->{want}, $tc->{desc});
}
done_testing();

113
t/group_hosts_by.pl Normal file
View file

@ -0,0 +1,113 @@
use Test::More;
SKIP: { eval { require Test::Warnings; } or skip($@, 1); }
eval { require 'ddclient'; } or BAIL_OUT($@);
eval { require Data::Dumper; } or skip($@, 1);
Data::Dumper->import();
my $h1 = 'h1';
my $h2 = 'h2';
my $h3 = 'h3';
$ddclient::config{$h1} = {
common => 'common',
h1h2 => 'h1 and h2',
unique => 'h1',
falsy => 0,
maybeunset => 'unique',
};
$ddclient::config{$h2} = {
common => 'common',
h1h2 => 'h1 and h2',
unique => 'h2',
falsy => '',
maybeunset => undef, # should not be grouped with unset
};
$ddclient::config{$h3} = {
common => 'common',
h1h2 => 'unique',
unique => 'h3',
falsy => undef,
# maybeunset is intentionally not set
};
my @test_cases = (
{
desc => 'empty attribute set yields single group with all hosts',
groupby => [qw()],
want => [{cfg => {}, hosts => [$h1, $h2, $h3]}],
},
{
desc => 'common attribute yields single group with all hosts',
groupby => [qw(common)],
want => [{cfg => {common => 'common'}, hosts => [$h1, $h2, $h3]}],
},
{
desc => 'subset share a value',
groupby => [qw(h1h2)],
want => [
{cfg => {h1h2 => 'h1 and h2'}, hosts => [$h1, $h2]},
{cfg => {h1h2 => 'unique'}, hosts => [$h3]},
],
},
{
desc => 'all unique',
groupby => [qw(unique)],
want => [
{cfg => {unique => 'h1'}, hosts => [$h1]},
{cfg => {unique => 'h2'}, hosts => [$h2]},
{cfg => {unique => 'h3'}, hosts => [$h3]},
],
},
{
desc => 'combination',
groupby => [qw(common h1h2)],
want => [
{cfg => {common => 'common', h1h2 => 'h1 and h2'}, hosts => [$h1, $h2]},
{cfg => {common => 'common', h1h2 => 'unique'}, hosts => [$h3]},
],
},
{
desc => 'falsy values',
groupby => [qw(falsy)],
want => [
{cfg => {falsy => 0}, hosts => [$h1]},
{cfg => {falsy => ''}, hosts => [$h2]},
# undef intentionally becomes unset because undef always means "fall back to global or
# default".
{cfg => {}, hosts => [$h3]},
],
},
{
desc => 'set, unset, undef',
groupby => [qw(maybeunset)],
want => [
{cfg => {maybeunset => 'unique'}, hosts => [$h1]},
# undef intentionally becomes unset because undef always means "fall back to global or
# default".
{cfg => {}, hosts => [$h2, $h3]},
],
},
{
desc => 'missing attribute',
groupby => [qw(thisdoesnotexist)],
want => [{cfg => {}, hosts => [$h1, $h2, $h3]}],
},
);
for my $tc (@test_cases) {
my @got = ddclient::group_hosts_by([$h1, $h2, $h3], @{$tc->{groupby}});
# @got is used as a set of sets. Sort everything to make comparison easier.
$_->{hosts} = [sort(@{$_->{hosts}})] for @got;
@got = sort({
for (my $i = 0; $i < @{$a->{hosts}} && $i < @{$b->{hosts}}; ++$i) {
my $x = $a->{hosts}[$i] cmp $b->{hosts}[$i];
return $x if $x != 0;
}
return @{$a->{hosts}} <=> @{$b->{hosts}};
} @got);
is_deeply(\@got, $tc->{want}, $tc->{desc})
or diag(Data::Dumper->new([\@got, $tc->{want}],
[qw(got want)])->Sortkeys(1)->Useqq(1)->Dump());
}
done_testing();

74
t/header_ok.pl Normal file
View file

@ -0,0 +1,74 @@
use Test::More;
SKIP: { eval { require Test::Warnings; } or skip($@, 1); }
eval { require 'ddclient'; } or BAIL_OUT($@);
my $have_mock = eval { require Test::MockModule; };
my $failmsg;
my $module;
if ($have_mock) {
$module = Test::MockModule->new('ddclient');
# Note: 'mock' is used instead of 'redefine' because 'redefine' is not available in the versions
# of Test::MockModule distributed with old Debian and Ubuntu releases.
$module->mock('failed', sub { $failmsg //= ''; $failmsg .= sprintf(shift, @_) . "\n"; });
}
my @test_cases = (
{
desc => 'malformed not OK',
input => 'malformed',
want => 0,
wantmsg => qr/unexpected/,
},
{
desc => 'HTTP/1.1 200 OK',
input => 'HTTP/1.1 200 OK',
want => 1,
},
{
desc => 'HTTP/2 200 OK',
input => 'HTTP/2 200 OK',
want => 1,
},
{
desc => 'HTTP/3 200 OK',
input => 'HTTP/3 200 OK',
want => 1,
},
{
desc => '401 not OK, fallback message',
input => 'HTTP/1.1 401 ',
want => 0,
wantmsg => qr/authentication failed/,
},
{
desc => '403 not OK, fallback message',
input => 'HTTP/1.1 403 ',
want => 0,
wantmsg => qr/not authorized/,
},
{
desc => 'other 4xx not OK',
input => 'HTTP/1.1 456 bad',
want => 0,
wantmsg => qr/bad/,
},
{
desc => 'only first line is logged on error',
input => "HTTP/1.1 404 not found\n\nbody",
want => 0,
wantmsg => qr/(?!body)/,
},
);
for my $tc (@test_cases) {
subtest $tc->{desc} => sub {
$failmsg = '';
is(ddclient::header_ok($tc->{input}), $tc->{want}, 'return value matches');
SKIP: {
skip('Test::MockModule not available') if !$have_mock;
like($failmsg, $tc->{wantmsg} // qr/^$/, 'fail message matches');
}
};
}
done_testing();

51
t/interval_expired.pl Normal file
View file

@ -0,0 +1,51 @@
use Test::More;
SKIP: { eval { require Test::Warnings; } or skip($@, 1); }
eval { require 'ddclient'; } or BAIL_OUT($@);
my $h = 't/interval_expired.pl';
my $default_now = 1000000000;
my @test_cases = (
{
interval => 'inf',
want => 0,
},
{
now => 'inf',
interval => 'inf',
want => 0,
},
{
cache => '-inf',
interval => 'inf',
want => 0,
},
{
cache => undef, # Falsy cache value.
interval => 'inf',
want => 0,
},
{
now => 0,
cache => 0, # Different kind of falsy cache value.
interval => 'inf',
want => 0,
},
);
for my $tc (@test_cases) {
$tc->{now} //= $default_now;
# For convenience, $tc->{cache} is an offset from $tc->{now}, not an absolute time..
my $cachetime = $tc->{now} + $tc->{cache} if defined($tc->{cache});
$ddclient::config{$h} = {'interval' => $tc->{interval}};
%ddclient::config if 0; # suppress spurious warning "Name used only once: possible typo"
$ddclient::cache{$h} = {'cached-time' => $cachetime} if defined($cachetime);
%ddclient::cache if 0; # suppress spurious warning "Name used only once: possible typo"
$ddclient::now = $tc->{now};
$ddclient::now if 0; # suppress spurious warning "Name used only once: possible typo"
my $desc = "now=$tc->{now}, cache=${\($cachetime // 'undef')}, interval=$tc->{interval}";
is(ddclient::interval_expired($h, 'cached-time', 'interval'), $tc->{want}, $desc);
}
done_testing();

83
t/is-and-extract-ipv4.pl Normal file
View file

@ -0,0 +1,83 @@
use Test::More;
use B qw(perlstring);
SKIP: { eval { require Test::Warnings; } or skip($@, 1); }
eval { require 'ddclient'; } or BAIL_OUT($@);
my @valid_ipv4 = (
"192.168.1.1",
"0.0.0.0",
"000.000.000.000",
"255.255.255.255",
"10.0.0.0",
);
my @invalid_ipv4 = (
undef,
"",
"192.168.1",
"0.0.0",
"000.000",
"256.256.256.256",
".10.0.0.0",
);
subtest "is_ipv4() with valid addresses" => sub {
foreach my $ip (@valid_ipv4) {
ok(ddclient::is_ipv4($ip), "is_ipv4('$ip')");
}
};
subtest "is_ipv4() with invalid addresses" => sub {
foreach my $ip (@invalid_ipv4) {
ok(!ddclient::is_ipv4($ip), sprintf("!is_ipv4(%s)", defined($ip) ? "'$ip'" : 'undef'));
}
};
subtest "is_ipv4() with char adjacent to valid address" => sub {
foreach my $ch (split(//, '/.,:z @$#&%!^*()_-+'), "\n") {
subtest perlstring($ch) => sub {
foreach my $ip (@valid_ipv4) {
subtest $ip => sub {
my $test = $ch . $ip; # insert at front
ok(!ddclient::is_ipv4($test), "!is_ipv4('$test')");
$test = $ip . $ch; # add at end
ok(!ddclient::is_ipv4($test), "!is_ipv4('$test')");
$test = $ch . $ip . $ch; # wrap front and end
ok(!ddclient::is_ipv4($test), "!is_ipv4('$test')");
};
}
};
}
};
subtest "extract_ipv4()" => sub {
my @test_cases = (
{name => "undef", text => undef, want => undef},
{name => "empty", text => "", want => undef},
{name => "invalid", text => "1.2.3.256", want => undef},
{name => "two addrs", text => "1.1.1.1\n2.2.2.2", want => "1.1.1.1"},
{name => "host+port", text => "1.2.3.4:123", want => "1.2.3.4"},
{name => "zero pad", text => "001.002.003.004", want => "1.2.3.4"},
);
foreach my $tc (@test_cases) {
is(ddclient::extract_ipv4($tc->{text}), $tc->{want}, $tc->{name});
}
};
subtest "extract_ipv4() of valid addr with adjacent non-word char" => sub {
foreach my $wb (split(//, '/, @$#&%!^*()_-+:'), "\n") {
subtest perlstring($wb) => sub {
my $test = "";
foreach my $ip (@valid_ipv4) {
$test = "foo" . $wb . $ip . $wb . "bar"; # wrap front and end
$ip =~ s/\b0+\B//g; ## remove embedded leading zeros for testing
is(ddclient::extract_ipv4($test), $ip, perlstring($test));
}
};
}
};
done_testing();

View file

@ -0,0 +1,66 @@
use Test::More;
use ddclient::t;
SKIP: { eval { require Test::Warnings; } or skip($@, 1); }
eval { require 'ddclient'; } or BAIL_OUT($@);
subtest "is_ipv6_global() with valid but non-globally-routable addresses" => sub {
foreach my $ip (
# The entirety of ::/16 is assumed to never contain globally routable addresses
"::",
"::1",
"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
# fc00::/7 unique local addresses (ULA)
"fc00::",
"fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
# fe80::/10 link-local unicast addresses
"fe80::",
"febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
# ff00::/8 multicast addresses
"ff00::",
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
# Case insensitivity of the negative lookahead
"FF00::",
) {
ok(!ddclient::is_ipv6_global($ip), "!is_ipv6_global('$ip')");
}
};
subtest "is_ipv6_global() with valid, globally routable addresses" => sub {
foreach my $ip (
"1::", # just after ::/16 assumed non-global block
"fbff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", # just before fc00::/7 ULA block
"fe00::", # just after fc00::/7 ULA block
"fe7f:ffff:ffff:ffff:ffff:ffff:ffff:ffff", # just before fe80::/10 link-local block
"fec0::", # just after fe80::/10 link-local block
"feff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", # just before ff00::/8 multicast block
) {
ok(ddclient::is_ipv6_global($ip), "is_ipv6_global('$ip')");
}
};
subtest "extract_ipv6_global()" => sub {
my @test_cases = (
{name => "undef", text => undef, want => undef},
{name => "empty", text => "", want => undef},
{name => "only non-global", text => "foo fe80:: bar", want => undef},
{name => "single global", text => "foo 2000:: bar", want => "2000::"},
{name => "multiple globals", text => "2000:: 3000::", want => "2000::"},
{name => "global before non-global", text => "2000:: fe80::", want => "2000::"},
{name => "non-global before global", text => "fe80:: 2000::", want => "2000::"},
{name => "zero pad", text => "2001::0001", want => "2001::1"},
);
foreach my $tc (@test_cases) {
is(ddclient::extract_ipv6_global($tc->{text}), $tc->{want}, $tc->{name});
}
};
subtest "interface config samples" => sub {
for my $sample (@ddclient::t::interface_samples) {
if (defined($sample->{want_extract_ipv6_global})) {
my $got = ddclient::extract_ipv6_global($sample->{text});
is($got, $sample->{want_extract_ipv6_global}, $sample->{name});
}
}
};
done_testing();

441
t/is-and-extract-ipv6.pl Normal file
View file

@ -0,0 +1,441 @@
use Test::More;
use B qw(perlstring);
use ddclient::t;
SKIP: { eval { require Test::Warnings; } or skip($@, 1); }
eval { require 'ddclient'; } or BAIL_OUT($@);
my @valid_ipv6 = (
"::abcd:efAB:CDEF", # case sensitivity
"08:09:0a:0b:0c:0d:0e:0f", # leading zeros
# with thanks to http://home.deds.nl/~aeron/regex/valid_ipv6.txt
"1111:2222:3333:4444:5555:6666:7777:8888",
"1111:2222:3333:4444:5555:6666:7777::",
"1111:2222:3333:4444:5555:6666::",
"1111:2222:3333:4444:5555::",
"1111:2222:3333:4444::",
"1111:2222:3333::",
"1111:2222::",
"1111::",
"::",
"1111:2222:3333:4444:5555:6666::8888",
"1111:2222:3333:4444:5555::8888",
"1111:2222:3333:4444::8888",
"1111:2222:3333::8888",
"1111:2222::8888",
"1111::8888",
"::8888",
"1111:2222:3333:4444:5555::7777:8888",
"1111:2222:3333:4444::7777:8888",
"1111:2222:3333::7777:8888",
"1111:2222::7777:8888",
"1111::7777:8888",
"::7777:8888",
"1111:2222:3333:4444::6666:7777:8888",
"1111:2222:3333::6666:7777:8888",
"1111:2222::6666:7777:8888",
"1111::6666:7777:8888",
"::6666:7777:8888",
"1111:2222:3333::5555:6666:7777:8888",
"1111:2222::5555:6666:7777:8888",
"1111::5555:6666:7777:8888",
"::5555:6666:7777:8888",
"1111:2222::4444:5555:6666:7777:8888",
"1111::4444:5555:6666:7777:8888",
"::4444:5555:6666:7777:8888",
"1111::3333:4444:5555:6666:7777:8888",
"::3333:4444:5555:6666:7777:8888",
"::2222:3333:4444:5555:6666:7777:8888",
# IPv4-mapped IPv6 addresses
"1111:2222:3333:4444:5555:6666:0.0.0.0",
"1111:2222:3333:4444:5555:6666:00.00.00.00",
"1111:2222:3333:4444:5555:6666:000.000.000.000",
"1111:2222:3333:4444:5555:6666:123.123.123.123",
"1111:2222:3333:4444:5555::123.123.123.123",
"1111:2222:3333:4444::123.123.123.123",
"1111:2222:3333::123.123.123.123",
"1111:2222::123.123.123.123",
"1111::123.123.123.123",
"::123.123.123.123",
"1111:2222:3333:4444::6666:123.123.123.123",
"1111:2222:3333::6666:123.123.123.123",
"1111:2222::6666:123.123.123.123",
"1111::6666:123.123.123.123",
"::6666:123.123.123.123",
"1111:2222:3333::5555:6666:123.123.123.123",
"1111:2222::5555:6666:123.123.123.123",
"1111::5555:6666:123.123.123.123",
"::5555:6666:123.123.123.123",
"1111:2222::4444:5555:6666:123.123.123.123",
"1111::4444:5555:6666:123.123.123.123",
"::4444:5555:6666:123.123.123.123",
"1111::3333:4444:5555:6666:123.123.123.123",
"::3333:4444:5555:6666:123.123.123.123",
"::2222:3333:4444:5555:6666:123.123.123.123",
);
my @invalid_ipv6 = (
# Empty string and bogus text
undef,
"",
" ",
"foobar",
# Valid IPv6 with extra text before or after
"foo2001:DB8:4341:0781:1111:2222:3333:4444",
"foo 2001:DB8:4341:0781::4444",
"foo 2001:DB8:4341:0781:1111:: bar",
"foo2001:DB8:4341:0781::100bar",
"2001:DB8:4341:0781::1 bar",
"2001:DB8:4341:0781::0001bar",
"foo bar 3001:DB8:4341:0781:1111:2222:3333:4444 foo bar",
"__3001:DB8:4341:0781::4444",
"__3001:DB8:4341:0781:1111::__",
"--3001:DB8:4341:0781::100--",
"/3001:DB8:4341:0781::1/",
"3001:DB8:4341:0781::0001%",
"fdb6:1d86:d9bd:1::4444%eth0",
"fdb6:1d86:d9bd:1:1111::%ens192",
"fdb6:1d86:d9bd:1::100%en0",
"fdb6:1d86:d9bd:1::1%eth1.100",
# With thanks to http://home.deds.nl/~aeron/regex/invalid_ipv6.txt
# Invalid data
"XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX",
# Too many components
"1111:2222:3333:4444:5555:6666:7777:8888:9999",
"1111:2222:3333:4444:5555:6666:7777:8888::",
"::2222:3333:4444:5555:6666:7777:8888:9999",
# Too few components
"1111:2222:3333:4444:5555:6666:7777",
"1111:2222:3333:4444:5555:6666",
"1111:2222:3333:4444:5555",
"1111:2222:3333:4444",
"1111:2222:3333",
"1111:2222",
"1111",
# Missing :
"11112222:3333:4444:5555:6666:7777:8888",
"1111:22223333:4444:5555:6666:7777:8888",
"1111:2222:33334444:5555:6666:7777:8888",
"1111:2222:3333:44445555:6666:7777:8888",
"1111:2222:3333:4444:55556666:7777:8888",
"1111:2222:3333:4444:5555:66667777:8888",
"1111:2222:3333:4444:5555:6666:77778888",
# Missing : intended for ::
"1111:2222:3333:4444:5555:6666:7777:8888:",
"1111:2222:3333:4444:5555:6666:7777:",
"1111:2222:3333:4444:5555:6666:",
"1111:2222:3333:4444:5555:",
"1111:2222:3333:4444:",
"1111:2222:3333:",
"1111:2222:",
"1111:",
":",
":8888",
":7777:8888",
":6666:7777:8888",
":5555:6666:7777:8888",
":4444:5555:6666:7777:8888",
":3333:4444:5555:6666:7777:8888",
":2222:3333:4444:5555:6666:7777:8888",
":1111:2222:3333:4444:5555:6666:7777:8888",
# :::
":::2222:3333:4444:5555:6666:7777:8888",
"1111:::3333:4444:5555:6666:7777:8888",
"1111:2222:::4444:5555:6666:7777:8888",
"1111:2222:3333:::5555:6666:7777:8888",
"1111:2222:3333:4444:::6666:7777:8888",
"1111:2222:3333:4444:5555:::7777:8888",
"1111:2222:3333:4444:5555:6666:::8888",
"1111:2222:3333:4444:5555:6666:7777:::",
# Double ::
"::2222::4444:5555:6666:7777:8888",
"::2222:3333::5555:6666:7777:8888",
"::2222:3333:4444::6666:7777:8888",
"::2222:3333:4444:5555::7777:8888",
"::2222:3333:4444:5555:7777::8888",
"::2222:3333:4444:5555:7777:8888::",
"1111::3333::5555:6666:7777:8888",
"1111::3333:4444::6666:7777:8888",
"1111::3333:4444:5555::7777:8888",
"1111::3333:4444:5555:6666::8888",
"1111::3333:4444:5555:6666:7777::",
"1111:2222::4444::6666:7777:8888",
"1111:2222::4444:5555::7777:8888",
"1111:2222::4444:5555:6666::8888",
"1111:2222::4444:5555:6666:7777::",
"1111:2222:3333::5555::7777:8888",
"1111:2222:3333::5555:6666::8888",
"1111:2222:3333::5555:6666:7777::",
"1111:2222:3333:4444::6666::8888",
"1111:2222:3333:4444::6666:7777::",
"1111:2222:3333:4444:5555::7777::",
# Invalid data
"XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:1.2.3.4",
"1111:2222:3333:4444:5555:6666:256.256.256.256",
# Too many components
"1111:2222:3333:4444:5555:6666:7777:8888:1.2.3",
"1111:2222:3333:4444:5555:6666:7777:1.2.3.4",
"1111:2222:3333:4444:5555:6666::1.2.3.4",
"::2222:3333:4444:5555:6666:7777:1.2.3.4",
"1111:2222:3333:4444:5555:6666:1.2.3.4.5",
# Too few components
"1111:2222:3333:4444:5555:1.2.3.4",
"1111:2222:3333:4444:1.2.3.4",
"1111:2222:3333:1.2.3.4",
"1111:2222:1.2.3.4",
"1111:1.2.3.4",
"1.2.3.4",
# Missing :
"11112222:3333:4444:5555:6666:1.2.3.4",
"1111:22223333:4444:5555:6666:1.2.3.4",
"1111:2222:33334444:5555:6666:1.2.3.4",
"1111:2222:3333:44445555:6666:1.2.3.4",
"1111:2222:3333:4444:55556666:1.2.3.4",
"1111:2222:3333:4444:5555:66661.2.3.4",
# Missing .
"1111:2222:3333:4444:5555:6666:255255.255.255",
"1111:2222:3333:4444:5555:6666:255.255255.255",
"1111:2222:3333:4444:5555:6666:255.255.255255",
# Missing : intended for ::
":1.2.3.4",
":6666:1.2.3.4",
":5555:6666:1.2.3.4",
":4444:5555:6666:1.2.3.4",
":3333:4444:5555:6666:1.2.3.4",
":2222:3333:4444:5555:6666:1.2.3.4",
":1111:2222:3333:4444:5555:6666:1.2.3.4",
# :::
":::2222:3333:4444:5555:6666:1.2.3.4",
"1111:::3333:4444:5555:6666:1.2.3.4",
"1111:2222:::4444:5555:6666:1.2.3.4",
"1111:2222:3333:::5555:6666:1.2.3.4",
"1111:2222:3333:4444:::6666:1.2.3.4",
"1111:2222:3333:4444:5555:::1.2.3.4",
# Double ::
"::2222::4444:5555:6666:1.2.3.4",
"::2222:3333::5555:6666:1.2.3.4",
"::2222:3333:4444::6666:1.2.3.4",
"::2222:3333:4444:5555::1.2.3.4",
"1111::3333::5555:6666:1.2.3.4",
"1111::3333:4444::6666:1.2.3.4",
"1111::3333:4444:5555::1.2.3.4",
"1111:2222::4444::6666:1.2.3.4",
"1111:2222::4444:5555::1.2.3.4",
"1111:2222:3333::5555::1.2.3.4",
# Missing parts
"::.",
"::..",
"::...",
"::1...",
"::1.2..",
"::1.2.3.",
"::.2..",
"::.2.3.",
"::.2.3.4",
"::..3.",
"::..3.4",
"::...4",
# Extra : in front
":1111:2222:3333:4444:5555:6666:7777::",
":1111:2222:3333:4444:5555:6666::",
":1111:2222:3333:4444:5555::",
":1111:2222:3333:4444::",
":1111:2222:3333::",
":1111:2222::",
":1111::",
":::",
":1111:2222:3333:4444:5555:6666::8888",
":1111:2222:3333:4444:5555::8888",
":1111:2222:3333:4444::8888",
":1111:2222:3333::8888",
":1111:2222::8888",
":1111::8888",
":::8888",
":1111:2222:3333:4444:5555::7777:8888",
":1111:2222:3333:4444::7777:8888",
":1111:2222:3333::7777:8888",
":1111:2222::7777:8888",
":1111::7777:8888",
":::7777:8888",
":1111:2222:3333:4444::6666:7777:8888",
":1111:2222:3333::6666:7777:8888",
":1111:2222::6666:7777:8888",
":1111::6666:7777:8888",
":::6666:7777:8888",
":1111:2222:3333::5555:6666:7777:8888",
":1111:2222::5555:6666:7777:8888",
":1111::5555:6666:7777:8888",
":::5555:6666:7777:8888",
":1111:2222::4444:5555:6666:7777:8888",
":1111::4444:5555:6666:7777:8888",
":::4444:5555:6666:7777:8888",
":1111::3333:4444:5555:6666:7777:8888",
":::3333:4444:5555:6666:7777:8888",
":::2222:3333:4444:5555:6666:7777:8888",
":1111:2222:3333:4444:5555:6666:1.2.3.4",
":1111:2222:3333:4444:5555::1.2.3.4",
":1111:2222:3333:4444::1.2.3.4",
":1111:2222:3333::1.2.3.4",
":1111:2222::1.2.3.4",
":1111::1.2.3.4",
":::1.2.3.4",
":1111:2222:3333:4444::6666:1.2.3.4",
":1111:2222:3333::6666:1.2.3.4",
":1111:2222::6666:1.2.3.4",
":1111::6666:1.2.3.4",
":::6666:1.2.3.4",
":1111:2222:3333::5555:6666:1.2.3.4",
":1111:2222::5555:6666:1.2.3.4",
":1111::5555:6666:1.2.3.4",
":::5555:6666:1.2.3.4",
":1111:2222::4444:5555:6666:1.2.3.4",
":1111::4444:5555:6666:1.2.3.4",
":::4444:5555:6666:1.2.3.4",
":1111::3333:4444:5555:6666:1.2.3.4",
":::3333:4444:5555:6666:1.2.3.4",
":::2222:3333:4444:5555:6666:1.2.3.4",
# Extra : at end
"1111:2222:3333:4444:5555:6666:7777:::",
"1111:2222:3333:4444:5555:6666:::",
"1111:2222:3333:4444:5555:::",
"1111:2222:3333:4444:::",
"1111:2222:3333:::",
"1111:2222:::",
"1111:::",
":::",
"1111:2222:3333:4444:5555:6666::8888:",
"1111:2222:3333:4444:5555::8888:",
"1111:2222:3333:4444::8888:",
"1111:2222:3333::8888:",
"1111:2222::8888:",
"1111::8888:",
"::8888:",
"1111:2222:3333:4444:5555::7777:8888:",
"1111:2222:3333:4444::7777:8888:",
"1111:2222:3333::7777:8888:",
"1111:2222::7777:8888:",
"1111::7777:8888:",
"::7777:8888:",
"1111:2222:3333:4444::6666:7777:8888:",
"1111:2222:3333::6666:7777:8888:",
"1111:2222::6666:7777:8888:",
"1111::6666:7777:8888:",
"::6666:7777:8888:",
"1111:2222:3333::5555:6666:7777:8888:",
"1111:2222::5555:6666:7777:8888:",
"1111::5555:6666:7777:8888:",
"::5555:6666:7777:8888:",
"1111:2222::4444:5555:6666:7777:8888:",
"1111::4444:5555:6666:7777:8888:",
"::4444:5555:6666:7777:8888:",
"1111::3333:4444:5555:6666:7777:8888:",
"::3333:4444:5555:6666:7777:8888:",
"::2222:3333:4444:5555:6666:7777:8888:",
);
subtest "is_ipv6() with valid addresses" => sub {
foreach my $ip (@valid_ipv6) {
ok(ddclient::is_ipv6($ip), "is_ipv6('$ip')");
}
};
subtest "is_ipv6() with invalid addresses" => sub {
foreach my $ip (@invalid_ipv6) {
ok(!ddclient::is_ipv6($ip), sprintf("!is_ipv6(%s)", defined($ip) ? "'$ip'" : 'undef'));
}
};
subtest "is_ipv6() with char adjacent to valid address" => sub {
foreach my $ch (split(//, '/.,:z @$#&%!^*()_-+'), "\n") {
subtest perlstring($ch) => sub {
foreach my $ip (@valid_ipv6) {
subtest $ip => sub {
my $test = $ch . $ip; # insert at front
ok(!ddclient::is_ipv6($test), "!is_ipv6('$test')");
$test = $ip . $ch; # add at end
ok(!ddclient::is_ipv6($test), "!is_ipv6('$test')");
$test = $ch . $ip . $ch; # wrap front and end
ok(!ddclient::is_ipv6($test), "!is_ipv6('$test')");
};
}
};
}
};
subtest "extract_ipv6()" => sub {
my @test_cases = (
{name => "undef", text => undef, want => undef},
{name => "empty", text => "", want => undef},
{name => "invalid", text => "::12345", want => undef},
{name => "two addrs", text => "::1\n::2", want => "::1"},
{name => "zone index", text => "fe80::1%0", want => "fe80::1"},
{name => "url host+port", text => "[::1]:123", want => "::1"},
{name => "url host+zi+port", text => "[fe80::1%250]:123", want => "fe80::1"},
{name => "zero pad", text => "::0001", want => "::1"},
);
foreach my $tc (@test_cases) {
is(ddclient::extract_ipv6($tc->{text}), $tc->{want}, $tc->{name});
}
};
subtest "extract_ipv6() of valid addr with adjacent non-word char" => sub {
foreach my $wb (split(//, '/, @$#&%!^*()_-+'), "\n") {
subtest perlstring($wb) => sub {
my $test = "";
foreach my $ip (@valid_ipv6) {
$test = "foo" . $wb . $ip . $wb . "bar"; # wrap front and end
$ip =~ s/\b0+\B//g; ## remove embedded leading zeros for testing
is(ddclient::extract_ipv6($test), $ip, perlstring($test));
}
};
}
};
subtest "interface config samples" => sub {
for my $sample (@ddclient::t::interface_samples) {
if (defined($sample->{want_extract_ipv6_global})) {
subtest $sample->{name} => sub {
my $ip = ddclient::extract_ipv6($sample->{text});
ok(ddclient::is_ipv6($ip), "extract_ipv6() returns an IPv6 address");
};
foreach my $line (split(/\n/, $sample->{text})) {
my $ip = ddclient::extract_ipv6($line);
if ($ip) { ## Test cases may have lines that do not contain IPv6 address.
ok(ddclient::is_ipv6($ip),
sprintf("extract_ipv6(%s) returns an IPv6 address", perlstring($line)));
}
}
}
}
};
done_testing();

106
t/lib/Devel/Autoflush.pm Normal file
View file

@ -0,0 +1,106 @@
package Devel::Autoflush;
# ABSTRACT: Set autoflush from the command line
our $VERSION = '0.06'; # VERSION
my $kwalitee_nocritic = << 'END';
# can't use strict as older stricts load Carp and we can't allow side effects
use strict;
END
my $old = select STDOUT;
$|++;
select STDERR;
$|++;
select $old;
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Devel::Autoflush - Set autoflush from the command line
=head1 VERSION
version 0.06
=head1 SYNOPSIS
perl -MDevel::Autoflush Makefile.PL
=head1 DESCRIPTION
This module is a hack to set autoflush for STDOUT and STDERR from the command
line or from C<PERL5OPT> for code that needs it but doesn't have it.
This often happens when prompting:
# guess.pl
print "Guess a number: ";
my $n = <STDIN>;
As long as the output is going to a terminal, the prompt is flushed when STDIN
is read. However, if the output is being piped, the print statement will
not automatically be flushed, no prompt will be seen and the program will
silently appear to hang while waiting for input. This might happen with 'tee':
$ perl guess.pl | tee capture.out
Use Devel::Autoflush to work around this:
$ perl -MDevel::Autoflush guess.pl | tee capture.out
Or set it in C<PERL5OPT>:
$ export PERL5OPT=-MDevel::Autoflush
$ perl guess.pl | tee capture.out
= SEE ALSO
=over 4
=item *
L<CPANPLUS::Internals::Utils::Autoflush> -- same idea but STDOUT only and
only available as part of the full CPANPLUS distribution
=back
=for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan
=head1 SUPPORT
=head2 Bugs / Feature Requests
Please report any bugs or feature requests through the issue tracker
at L<https://github.com/dagolden/Devel-Autoflush/issues>.
You will be notified automatically of any progress on your issue.
=head2 Source Code
This is open source software. The code repository is available for
public review and contribution under the terms of the license.
L<https://github.com/dagolden/Devel-Autoflush>
git clone https://github.com/dagolden/Devel-Autoflush.git
=head1 AUTHOR
David Golden <dagolden@cpan.org>
=head1 COPYRIGHT AND LICENSE
This software is Copyright (c) 2014 by David Golden.
This is free software, licensed under:
The Apache License, Version 2.0, January 2004
=cut

2608
t/lib/Test/Builder.pm Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,107 @@
package Test::Builder::Formatter;
use strict;
use warnings;
our $VERSION = '1.302175';
BEGIN { require Test2::Formatter::TAP; our @ISA = qw(Test2::Formatter::TAP) }
use Test2::Util::HashBase qw/no_header no_diag/;
BEGIN {
*OUT_STD = Test2::Formatter::TAP->can('OUT_STD');
*OUT_ERR = Test2::Formatter::TAP->can('OUT_ERR');
my $todo = OUT_ERR() + 1;
*OUT_TODO = sub() { $todo };
}
sub init {
my $self = shift;
$self->SUPER::init(@_);
$self->{+HANDLES}->[OUT_TODO] = $self->{+HANDLES}->[OUT_STD];
}
sub plan_tap {
my ($self, $f) = @_;
return if $self->{+NO_HEADER};
return $self->SUPER::plan_tap($f);
}
sub debug_tap {
my ($self, $f, $num) = @_;
return if $self->{+NO_DIAG};
my @out = $self->SUPER::debug_tap($f, $num);
$self->redirect(\@out) if @out && ref $f->{about} && defined $f->{about}->{package}
&& $f->{about}->{package} eq 'Test::Builder::TodoDiag';
return @out;
}
sub info_tap {
my ($self, $f) = @_;
return if $self->{+NO_DIAG};
my @out = $self->SUPER::info_tap($f);
$self->redirect(\@out) if @out && ref $f->{about} && defined $f->{about}->{package}
&& $f->{about}->{package} eq 'Test::Builder::TodoDiag';
return @out;
}
sub redirect {
my ($self, $out) = @_;
$_->[0] = OUT_TODO for @$out;
}
sub no_subtest_space { 1 }
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test::Builder::Formatter - Test::Builder subclass of Test2::Formatter::TAP
=head1 DESCRIPTION
This is what takes events and turns them into TAP.
=head1 SYNOPSIS
use Test::Builder; # Loads Test::Builder::Formatter for you
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

View file

@ -0,0 +1,659 @@
package Test::Builder::IO::Scalar;
=head1 NAME
Test::Builder::IO::Scalar - A copy of IO::Scalar for Test::Builder
=head1 DESCRIPTION
This is a copy of L<IO::Scalar> which ships with L<Test::Builder> to
support scalar references as filehandles on Perl 5.6. Newer
versions of Perl simply use C<open()>'s built in support.
L<Test::Builder> can not have dependencies on other modules without
careful consideration, so its simply been copied into the distribution.
=head1 COPYRIGHT and LICENSE
This file came from the "IO-stringy" Perl5 toolkit.
Copyright (c) 1996 by Eryq. All rights reserved.
Copyright (c) 1999,2001 by ZeeGee Software Inc. All rights reserved.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
=cut
# This is copied code, I don't care.
##no critic
use Carp;
use strict;
use vars qw($VERSION @ISA);
use IO::Handle;
use 5.005;
### The package version, both in 1.23 style *and* usable by MakeMaker:
$VERSION = "2.114";
### Inheritance:
@ISA = qw(IO::Handle);
#==============================
=head2 Construction
=over 4
=cut
#------------------------------
=item new [ARGS...]
I<Class method.>
Return a new, unattached scalar handle.
If any arguments are given, they're sent to open().
=cut
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = bless \do { local *FH }, $class;
tie *$self, $class, $self;
$self->open(@_); ### open on anonymous by default
$self;
}
sub DESTROY {
shift->close;
}
#------------------------------
=item open [SCALARREF]
I<Instance method.>
Open the scalar handle on a new scalar, pointed to by SCALARREF.
If no SCALARREF is given, a "private" scalar is created to hold
the file data.
Returns the self object on success, undefined on error.
=cut
sub open {
my ($self, $sref) = @_;
### Sanity:
defined($sref) or do {my $s = ''; $sref = \$s};
(ref($sref) eq "SCALAR") or croak "open() needs a ref to a scalar";
### Setup:
*$self->{Pos} = 0; ### seek position
*$self->{SR} = $sref; ### scalar reference
$self;
}
#------------------------------
=item opened
I<Instance method.>
Is the scalar handle opened on something?
=cut
sub opened {
*{shift()}->{SR};
}
#------------------------------
=item close
I<Instance method.>
Disassociate the scalar handle from its underlying scalar.
Done automatically on destroy.
=cut
sub close {
my $self = shift;
%{*$self} = ();
1;
}
=back
=cut
#==============================
=head2 Input and output
=over 4
=cut
#------------------------------
=item flush
I<Instance method.>
No-op, provided for OO compatibility.
=cut
sub flush { "0 but true" }
#------------------------------
=item getc
I<Instance method.>
Return the next character, or undef if none remain.
=cut
sub getc {
my $self = shift;
### Return undef right away if at EOF; else, move pos forward:
return undef if $self->eof;
substr(${*$self->{SR}}, *$self->{Pos}++, 1);
}
#------------------------------
=item getline
I<Instance method.>
Return the next line, or undef on end of string.
Can safely be called in an array context.
Currently, lines are delimited by "\n".
=cut
sub getline {
my $self = shift;
### Return undef right away if at EOF:
return undef if $self->eof;
### Get next line:
my $sr = *$self->{SR};
my $i = *$self->{Pos}; ### Start matching at this point.
### Minimal impact implementation!
### We do the fast fast thing (no regexps) if using the
### classic input record separator.
### Case 1: $/ is undef: slurp all...
if (!defined($/)) {
*$self->{Pos} = length $$sr;
return substr($$sr, $i);
}
### Case 2: $/ is "\n": zoom zoom zoom...
elsif ($/ eq "\012") {
### Seek ahead for "\n"... yes, this really is faster than regexps.
my $len = length($$sr);
for (; $i < $len; ++$i) {
last if ord (substr ($$sr, $i, 1)) == 10;
}
### Extract the line:
my $line;
if ($i < $len) { ### We found a "\n":
$line = substr ($$sr, *$self->{Pos}, $i - *$self->{Pos} + 1);
*$self->{Pos} = $i+1; ### Remember where we finished up.
}
else { ### No "\n"; slurp the remainder:
$line = substr ($$sr, *$self->{Pos}, $i - *$self->{Pos});
*$self->{Pos} = $len;
}
return $line;
}
### Case 3: $/ is ref to int. Do fixed-size records.
### (Thanks to Dominique Quatravaux.)
elsif (ref($/)) {
my $len = length($$sr);
my $i = ${$/} + 0;
my $line = substr ($$sr, *$self->{Pos}, $i);
*$self->{Pos} += $i;
*$self->{Pos} = $len if (*$self->{Pos} > $len);
return $line;
}
### Case 4: $/ is either "" (paragraphs) or something weird...
### This is Graham's general-purpose stuff, which might be
### a tad slower than Case 2 for typical data, because
### of the regexps.
else {
pos($$sr) = $i;
### If in paragraph mode, skip leading lines (and update i!):
length($/) or
(($$sr =~ m/\G\n*/g) and ($i = pos($$sr)));
### If we see the separator in the buffer ahead...
if (length($/)
? $$sr =~ m,\Q$/\E,g ### (ordinary sep) TBD: precomp!
: $$sr =~ m,\n\n,g ### (a paragraph)
) {
*$self->{Pos} = pos $$sr;
return substr($$sr, $i, *$self->{Pos}-$i);
}
### Else if no separator remains, just slurp the rest:
else {
*$self->{Pos} = length $$sr;
return substr($$sr, $i);
}
}
}
#------------------------------
=item getlines
I<Instance method.>
Get all remaining lines.
It will croak() if accidentally called in a scalar context.
=cut
sub getlines {
my $self = shift;
wantarray or croak("can't call getlines in scalar context!");
my ($line, @lines);
push @lines, $line while (defined($line = $self->getline));
@lines;
}
#------------------------------
=item print ARGS...
I<Instance method.>
Print ARGS to the underlying scalar.
B<Warning:> this continues to always cause a seek to the end
of the string, but if you perform seek()s and tell()s, it is
still safer to explicitly seek-to-end before subsequent print()s.
=cut
sub print {
my $self = shift;
*$self->{Pos} = length(${*$self->{SR}} .= join('', @_) . (defined($\) ? $\ : ""));
1;
}
sub _unsafe_print {
my $self = shift;
my $append = join('', @_) . $\;
${*$self->{SR}} .= $append;
*$self->{Pos} += length($append);
1;
}
sub _old_print {
my $self = shift;
${*$self->{SR}} .= join('', @_) . $\;
*$self->{Pos} = length(${*$self->{SR}});
1;
}
#------------------------------
=item read BUF, NBYTES, [OFFSET]
I<Instance method.>
Read some bytes from the scalar.
Returns the number of bytes actually read, 0 on end-of-file, undef on error.
=cut
sub read {
my $self = $_[0];
my $n = $_[2];
my $off = $_[3] || 0;
my $read = substr(${*$self->{SR}}, *$self->{Pos}, $n);
$n = length($read);
*$self->{Pos} += $n;
($off ? substr($_[1], $off) : $_[1]) = $read;
return $n;
}
#------------------------------
=item write BUF, NBYTES, [OFFSET]
I<Instance method.>
Write some bytes to the scalar.
=cut
sub write {
my $self = $_[0];
my $n = $_[2];
my $off = $_[3] || 0;
my $data = substr($_[1], $off, $n);
$n = length($data);
$self->print($data);
return $n;
}
#------------------------------
=item sysread BUF, LEN, [OFFSET]
I<Instance method.>
Read some bytes from the scalar.
Returns the number of bytes actually read, 0 on end-of-file, undef on error.
=cut
sub sysread {
my $self = shift;
$self->read(@_);
}
#------------------------------
=item syswrite BUF, NBYTES, [OFFSET]
I<Instance method.>
Write some bytes to the scalar.
=cut
sub syswrite {
my $self = shift;
$self->write(@_);
}
=back
=cut
#==============================
=head2 Seeking/telling and other attributes
=over 4
=cut
#------------------------------
=item autoflush
I<Instance method.>
No-op, provided for OO compatibility.
=cut
sub autoflush {}
#------------------------------
=item binmode
I<Instance method.>
No-op, provided for OO compatibility.
=cut
sub binmode {}
#------------------------------
=item clearerr
I<Instance method.> Clear the error and EOF flags. A no-op.
=cut
sub clearerr { 1 }
#------------------------------
=item eof
I<Instance method.> Are we at end of file?
=cut
sub eof {
my $self = shift;
(*$self->{Pos} >= length(${*$self->{SR}}));
}
#------------------------------
=item seek OFFSET, WHENCE
I<Instance method.> Seek to a given position in the stream.
=cut
sub seek {
my ($self, $pos, $whence) = @_;
my $eofpos = length(${*$self->{SR}});
### Seek:
if ($whence == 0) { *$self->{Pos} = $pos } ### SEEK_SET
elsif ($whence == 1) { *$self->{Pos} += $pos } ### SEEK_CUR
elsif ($whence == 2) { *$self->{Pos} = $eofpos + $pos} ### SEEK_END
else { croak "bad seek whence ($whence)" }
### Fixup:
if (*$self->{Pos} < 0) { *$self->{Pos} = 0 }
if (*$self->{Pos} > $eofpos) { *$self->{Pos} = $eofpos }
return 1;
}
#------------------------------
=item sysseek OFFSET, WHENCE
I<Instance method.> Identical to C<seek OFFSET, WHENCE>, I<q.v.>
=cut
sub sysseek {
my $self = shift;
$self->seek (@_);
}
#------------------------------
=item tell
I<Instance method.>
Return the current position in the stream, as a numeric offset.
=cut
sub tell { *{shift()}->{Pos} }
#------------------------------
=item use_RS [YESNO]
I<Instance method.>
B<Deprecated and ignored.>
Obey the current setting of $/, like IO::Handle does?
Default is false in 1.x, but cold-welded true in 2.x and later.
=cut
sub use_RS {
my ($self, $yesno) = @_;
carp "use_RS is deprecated and ignored; \$/ is always consulted\n";
}
#------------------------------
=item setpos POS
I<Instance method.>
Set the current position, using the opaque value returned by C<getpos()>.
=cut
sub setpos { shift->seek($_[0],0) }
#------------------------------
=item getpos
I<Instance method.>
Return the current position in the string, as an opaque object.
=cut
*getpos = \&tell;
#------------------------------
=item sref
I<Instance method.>
Return a reference to the underlying scalar.
=cut
sub sref { *{shift()}->{SR} }
#------------------------------
# Tied handle methods...
#------------------------------
# Conventional tiehandle interface:
sub TIEHANDLE {
((defined($_[1]) && UNIVERSAL::isa($_[1], __PACKAGE__))
? $_[1]
: shift->new(@_));
}
sub GETC { shift->getc(@_) }
sub PRINT { shift->print(@_) }
sub PRINTF { shift->print(sprintf(shift, @_)) }
sub READ { shift->read(@_) }
sub READLINE { wantarray ? shift->getlines(@_) : shift->getline(@_) }
sub WRITE { shift->write(@_); }
sub CLOSE { shift->close(@_); }
sub SEEK { shift->seek(@_); }
sub TELL { shift->tell(@_); }
sub EOF { shift->eof(@_); }
sub FILENO { -1 }
#------------------------------------------------------------
1;
__END__
=back
=cut
=head1 WARNINGS
Perl's TIEHANDLE spec was incomplete prior to 5.005_57;
it was missing support for C<seek()>, C<tell()>, and C<eof()>.
Attempting to use these functions with an IO::Scalar will not work
prior to 5.005_57. IO::Scalar will not have the relevant methods
invoked; and even worse, this kind of bug can lie dormant for a while.
If you turn warnings on (via C<$^W> or C<perl -w>),
and you see something like this...
attempt to seek on unopened filehandle
...then you are probably trying to use one of these functions
on an IO::Scalar with an old Perl. The remedy is to simply
use the OO version; e.g.:
$SH->seek(0,0); ### GOOD: will work on any 5.005
seek($SH,0,0); ### WARNING: will only work on 5.005_57 and beyond
=head1 VERSION
$Id: Scalar.pm,v 1.6 2005/02/10 21:21:53 dfs Exp $
=head1 AUTHORS
=head2 Primary Maintainer
David F. Skoll (F<dfs@roaringpenguin.com>).
=head2 Principal author
Eryq (F<eryq@zeegee.com>).
President, ZeeGee Software Inc (F<http://www.zeegee.com>).
=head2 Other contributors
The full set of contributors always includes the folks mentioned
in L<IO::Stringy/"CHANGE LOG">. But just the same, special
thanks to the following individuals for their invaluable contributions
(if I've forgotten or misspelled your name, please email me!):
I<Andy Glew,>
for contributing C<getc()>.
I<Brandon Browning,>
for suggesting C<opened()>.
I<David Richter,>
for finding and fixing the bug in C<PRINTF()>.
I<Eric L. Brine,>
for his offset-using read() and write() implementations.
I<Richard Jones,>
for his patches to massively improve the performance of C<getline()>
and add C<sysread> and C<syswrite>.
I<B. K. Oxley (binkley),>
for stringification and inheritance improvements,
and sundry good ideas.
I<Doug Wilson,>
for the IO::Handle inheritance and automatic tie-ing.
=head1 SEE ALSO
L<IO::String>, which is quite similar but which was designed
more-recently and with an IO::Handle-like interface in mind,
so you could mix OO- and native-filehandle usage without using tied().
I<Note:> as of version 2.x, these classes all work like
their IO::Handle counterparts, so we have comparable
functionality to IO::String.
=cut

View file

@ -0,0 +1,182 @@
package Test::Builder::Module;
use strict;
use Test::Builder;
require Exporter;
our @ISA = qw(Exporter);
our $VERSION = '1.302175';
=head1 NAME
Test::Builder::Module - Base class for test modules
=head1 SYNOPSIS
# Emulates Test::Simple
package Your::Module;
my $CLASS = __PACKAGE__;
use parent 'Test::Builder::Module';
@EXPORT = qw(ok);
sub ok ($;$) {
my $tb = $CLASS->builder;
return $tb->ok(@_);
}
1;
=head1 DESCRIPTION
This is a superclass for L<Test::Builder>-based modules. It provides a
handful of common functionality and a method of getting at the underlying
L<Test::Builder> object.
=head2 Importing
Test::Builder::Module is a subclass of L<Exporter> which means your
module is also a subclass of Exporter. @EXPORT, @EXPORT_OK, etc...
all act normally.
A few methods are provided to do the C<< use Your::Module tests => 23 >> part
for you.
=head3 import
Test::Builder::Module provides an C<import()> method which acts in the
same basic way as L<Test::More>'s, setting the plan and controlling
exporting of functions and variables. This allows your module to set
the plan independent of L<Test::More>.
All arguments passed to C<import()> are passed onto
C<< Your::Module->builder->plan() >> with the exception of
C<< import =>[qw(things to import)] >>.
use Your::Module import => [qw(this that)], tests => 23;
says to import the functions C<this()> and C<that()> as well as set the plan
to be 23 tests.
C<import()> also sets the C<exported_to()> attribute of your builder to be
the caller of the C<import()> function.
Additional behaviors can be added to your C<import()> method by overriding
C<import_extra()>.
=cut
sub import {
my($class) = shift;
Test2::API::test2_load() unless Test2::API::test2_in_preload();
# Don't run all this when loading ourself.
return 1 if $class eq 'Test::Builder::Module';
my $test = $class->builder;
my $caller = caller;
$test->exported_to($caller);
$class->import_extra( \@_ );
my(@imports) = $class->_strip_imports( \@_ );
$test->plan(@_);
local $Exporter::ExportLevel = $Exporter::ExportLevel + 1;
$class->Exporter::import(@imports);
}
sub _strip_imports {
my $class = shift;
my $list = shift;
my @imports = ();
my @other = ();
my $idx = 0;
while( $idx <= $#{$list} ) {
my $item = $list->[$idx];
if( defined $item and $item eq 'import' ) {
push @imports, @{ $list->[ $idx + 1 ] };
$idx++;
}
else {
push @other, $item;
}
$idx++;
}
@$list = @other;
return @imports;
}
=head3 import_extra
Your::Module->import_extra(\@import_args);
C<import_extra()> is called by C<import()>. It provides an opportunity for you
to add behaviors to your module based on its import list.
Any extra arguments which shouldn't be passed on to C<plan()> should be
stripped off by this method.
See L<Test::More> for an example of its use.
B<NOTE> This mechanism is I<VERY ALPHA AND LIKELY TO CHANGE> as it
feels like a bit of an ugly hack in its current form.
=cut
sub import_extra { }
=head2 Builder
Test::Builder::Module provides some methods of getting at the underlying
Test::Builder object.
=head3 builder
my $builder = Your::Class->builder;
This method returns the L<Test::Builder> object associated with Your::Class.
It is not a constructor so you can call it as often as you like.
This is the preferred way to get the L<Test::Builder> object. You should
I<not> get it via C<< Test::Builder->new >> as was previously
recommended.
The object returned by C<builder()> may change at runtime so you should
call C<builder()> inside each function rather than store it in a global.
sub ok {
my $builder = Your::Class->builder;
return $builder->ok(@_);
}
=cut
sub builder {
return Test::Builder->new;
}
=head1 SEE ALSO
L<< Test2::Manual::Tooling::TestBuilder >> describes the improved
options for writing testing modules provided by L<< Test2 >>.
=cut
1;

View file

@ -0,0 +1,675 @@
package Test::Builder::Tester;
use strict;
our $VERSION = '1.302175';
use Test::Builder;
use Symbol;
use Carp;
=head1 NAME
Test::Builder::Tester - test testsuites that have been built with
Test::Builder
=head1 SYNOPSIS
use Test::Builder::Tester tests => 1;
use Test::More;
test_out("not ok 1 - foo");
test_fail(+1);
fail("foo");
test_test("fail works");
=head1 DESCRIPTION
A module that helps you test testing modules that are built with
L<Test::Builder>.
The testing system is designed to be used by performing a three step
process for each test you wish to test. This process starts with using
C<test_out> and C<test_err> in advance to declare what the testsuite you
are testing will output with L<Test::Builder> to stdout and stderr.
You then can run the test(s) from your test suite that call
L<Test::Builder>. At this point the output of L<Test::Builder> is
safely captured by L<Test::Builder::Tester> rather than being
interpreted as real test output.
The final stage is to call C<test_test> that will simply compare what you
predeclared to what L<Test::Builder> actually outputted, and report the
results back with a "ok" or "not ok" (with debugging) to the normal
output.
=cut
####
# set up testing
####
my $t = Test::Builder->new;
###
# make us an exporter
###
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(test_out test_err test_fail test_diag test_test line_num);
sub import {
my $class = shift;
my(@plan) = @_;
my $caller = caller;
$t->exported_to($caller);
$t->plan(@plan);
my @imports = ();
foreach my $idx ( 0 .. $#plan ) {
if( $plan[$idx] eq 'import' ) {
@imports = @{ $plan[ $idx + 1 ] };
last;
}
}
__PACKAGE__->export_to_level( 1, __PACKAGE__, @imports );
}
###
# set up file handles
###
# create some private file handles
my $output_handle = gensym;
my $error_handle = gensym;
# and tie them to this package
my $out = tie *$output_handle, "Test::Builder::Tester::Tie", "STDOUT";
my $err = tie *$error_handle, "Test::Builder::Tester::Tie", "STDERR";
####
# exported functions
####
# for remembering that we're testing and where we're testing at
my $testing = 0;
my $testing_num;
my $original_is_passing;
# remembering where the file handles were originally connected
my $original_output_handle;
my $original_failure_handle;
my $original_todo_handle;
my $original_formatter;
my $original_harness_env;
# function that starts testing and redirects the filehandles for now
sub _start_testing {
# Hack for things that conditioned on Test-Stream being loaded
$INC{'Test/Stream.pm'} ||= 'fake' if $INC{'Test/Moose/More.pm'};
# even if we're running under Test::Harness pretend we're not
# for now. This needed so Test::Builder doesn't add extra spaces
$original_harness_env = $ENV{HARNESS_ACTIVE} || 0;
$ENV{HARNESS_ACTIVE} = 0;
my $hub = $t->{Hub} || ($t->{Stack} ? $t->{Stack}->top : Test2::API::test2_stack->top);
$original_formatter = $hub->format;
unless ($original_formatter && $original_formatter->isa('Test::Builder::Formatter')) {
my $fmt = Test::Builder::Formatter->new;
$hub->format($fmt);
}
# remember what the handles were set to
$original_output_handle = $t->output();
$original_failure_handle = $t->failure_output();
$original_todo_handle = $t->todo_output();
# switch out to our own handles
$t->output($output_handle);
$t->failure_output($error_handle);
$t->todo_output($output_handle);
# clear the expected list
$out->reset();
$err->reset();
# remember that we're testing
$testing = 1;
$testing_num = $t->current_test;
$t->current_test(0);
$original_is_passing = $t->is_passing;
$t->is_passing(1);
# look, we shouldn't do the ending stuff
$t->no_ending(1);
}
=head2 Functions
These are the six methods that are exported as default.
=over 4
=item test_out
=item test_err
Procedures for predeclaring the output that your test suite is
expected to produce until C<test_test> is called. These procedures
automatically assume that each line terminates with "\n". So
test_out("ok 1","ok 2");
is the same as
test_out("ok 1\nok 2");
which is even the same as
test_out("ok 1");
test_out("ok 2");
Once C<test_out> or C<test_err> (or C<test_fail> or C<test_diag>) have
been called, all further output from L<Test::Builder> will be
captured by L<Test::Builder::Tester>. This means that you will not
be able perform further tests to the normal output in the normal way
until you call C<test_test> (well, unless you manually meddle with the
output filehandles)
=cut
sub test_out {
# do we need to do any setup?
_start_testing() unless $testing;
$out->expect(@_);
}
sub test_err {
# do we need to do any setup?
_start_testing() unless $testing;
$err->expect(@_);
}
=item test_fail
Because the standard failure message that L<Test::Builder> produces
whenever a test fails will be a common occurrence in your test error
output, and because it has changed between Test::Builder versions, rather
than forcing you to call C<test_err> with the string all the time like
so
test_err("# Failed test ($0 at line ".line_num(+1).")");
C<test_fail> exists as a convenience function that can be called
instead. It takes one argument, the offset from the current line that
the line that causes the fail is on.
test_fail(+1);
This means that the example in the synopsis could be rewritten
more simply as:
test_out("not ok 1 - foo");
test_fail(+1);
fail("foo");
test_test("fail works");
=cut
sub test_fail {
# do we need to do any setup?
_start_testing() unless $testing;
# work out what line we should be on
my( $package, $filename, $line ) = caller;
$line = $line + ( shift() || 0 ); # prevent warnings
# expect that on stderr
$err->expect("# Failed test ($filename at line $line)");
}
=item test_diag
As most of the remaining expected output to the error stream will be
created by L<Test::Builder>'s C<diag> function, L<Test::Builder::Tester>
provides a convenience function C<test_diag> that you can use instead of
C<test_err>.
The C<test_diag> function prepends comment hashes and spacing to the
start and newlines to the end of the expected output passed to it and
adds it to the list of expected error output. So, instead of writing
test_err("# Couldn't open file");
you can write
test_diag("Couldn't open file");
Remember that L<Test::Builder>'s diag function will not add newlines to
the end of output and test_diag will. So to check
Test::Builder->new->diag("foo\n","bar\n");
You would do
test_diag("foo","bar")
without the newlines.
=cut
sub test_diag {
# do we need to do any setup?
_start_testing() unless $testing;
# expect the same thing, but prepended with "# "
local $_;
$err->expect( map { "# $_" } @_ );
}
=item test_test
Actually performs the output check testing the tests, comparing the
data (with C<eq>) that we have captured from L<Test::Builder> against
what was declared with C<test_out> and C<test_err>.
This takes name/value pairs that effect how the test is run.
=over
=item title (synonym 'name', 'label')
The name of the test that will be displayed after the C<ok> or C<not
ok>.
=item skip_out
Setting this to a true value will cause the test to ignore if the
output sent by the test to the output stream does not match that
declared with C<test_out>.
=item skip_err
Setting this to a true value will cause the test to ignore if the
output sent by the test to the error stream does not match that
declared with C<test_err>.
=back
As a convenience, if only one argument is passed then this argument
is assumed to be the name of the test (as in the above examples.)
Once C<test_test> has been run test output will be redirected back to
the original filehandles that L<Test::Builder> was connected to
(probably STDOUT and STDERR,) meaning any further tests you run
will function normally and cause success/errors for L<Test::Harness>.
=cut
sub test_test {
# END the hack
delete $INC{'Test/Stream.pm'} if $INC{'Test/Stream.pm'} && $INC{'Test/Stream.pm'} eq 'fake';
# decode the arguments as described in the pod
my $mess;
my %args;
if( @_ == 1 ) {
$mess = shift
}
else {
%args = @_;
$mess = $args{name} if exists( $args{name} );
$mess = $args{title} if exists( $args{title} );
$mess = $args{label} if exists( $args{label} );
}
# er, are we testing?
croak "Not testing. You must declare output with a test function first."
unless $testing;
my $hub = $t->{Hub} || Test2::API::test2_stack->top;
$hub->format($original_formatter);
# okay, reconnect the test suite back to the saved handles
$t->output($original_output_handle);
$t->failure_output($original_failure_handle);
$t->todo_output($original_todo_handle);
# restore the test no, etc, back to the original point
$t->current_test($testing_num);
$testing = 0;
$t->is_passing($original_is_passing);
# re-enable the original setting of the harness
$ENV{HARNESS_ACTIVE} = $original_harness_env;
# check the output we've stashed
unless( $t->ok( ( $args{skip_out} || $out->check ) &&
( $args{skip_err} || $err->check ), $mess )
)
{
# print out the diagnostic information about why this
# test failed
local $_;
$t->diag( map { "$_\n" } $out->complaint )
unless $args{skip_out} || $out->check;
$t->diag( map { "$_\n" } $err->complaint )
unless $args{skip_err} || $err->check;
}
}
=item line_num
A utility function that returns the line number that the function was
called on. You can pass it an offset which will be added to the
result. This is very useful for working out the correct text of
diagnostic functions that contain line numbers.
Essentially this is the same as the C<__LINE__> macro, but the
C<line_num(+3)> idiom is arguably nicer.
=cut
sub line_num {
my( $package, $filename, $line ) = caller;
return $line + ( shift() || 0 ); # prevent warnings
}
=back
In addition to the six exported functions there exists one
function that can only be accessed with a fully qualified function
call.
=over 4
=item color
When C<test_test> is called and the output that your tests generate
does not match that which you declared, C<test_test> will print out
debug information showing the two conflicting versions. As this
output itself is debug information it can be confusing which part of
the output is from C<test_test> and which was the original output from
your original tests. Also, it may be hard to spot things like
extraneous whitespace at the end of lines that may cause your test to
fail even though the output looks similar.
To assist you C<test_test> can colour the background of the debug
information to disambiguate the different types of output. The debug
output will have its background coloured green and red. The green
part represents the text which is the same between the executed and
actual output, the red shows which part differs.
The C<color> function determines if colouring should occur or not.
Passing it a true or false value will enable or disable colouring
respectively, and the function called with no argument will return the
current setting.
To enable colouring from the command line, you can use the
L<Text::Builder::Tester::Color> module like so:
perl -Mlib=Text::Builder::Tester::Color test.t
Or by including the L<Test::Builder::Tester::Color> module directly in
the PERL5LIB.
=cut
my $color;
sub color {
$color = shift if @_;
$color;
}
=back
=head1 BUGS
Test::Builder::Tester does not handle plans well. It has never done anything
special with plans. This means that plans from outside Test::Builder::Tester
will effect Test::Builder::Tester, worse plans when using Test::Builder::Tester
will effect overall testing. At this point there are no plans to fix this bug
as people have come to depend on it, and Test::Builder::Tester is now
discouraged in favor of C<Test2::API::intercept()>. See
L<https://github.com/Test-More/test-more/issues/667>
Calls C<< Test::Builder->no_ending >> turning off the ending tests.
This is needed as otherwise it will trip out because we've run more
tests than we strictly should have and it'll register any failures we
had that we were testing for as real failures.
The color function doesn't work unless L<Term::ANSIColor> is
compatible with your terminal. Additionally, L<Win32::Console::ANSI>
must be installed on windows platforms for color output.
Bugs (and requests for new features) can be reported to the author
though GitHub:
L<https://github.com/Test-More/test-more/issues>
=head1 AUTHOR
Copyright Mark Fowler E<lt>mark@twoshortplanks.comE<gt> 2002, 2004.
Some code taken from L<Test::More> and L<Test::Catch>, written by
Michael G Schwern E<lt>schwern@pobox.comE<gt>. Hence, those parts
Copyright Micheal G Schwern 2001. Used and distributed with
permission.
This program is free software; you can redistribute it
and/or modify it under the same terms as Perl itself.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 NOTES
Thanks to Richard Clamp E<lt>richardc@unixbeard.netE<gt> for letting
me use his testing system to try this module out on.
=head1 SEE ALSO
L<Test::Builder>, L<Test::Builder::Tester::Color>, L<Test::More>.
=cut
1;
####################################################################
# Helper class that is used to remember expected and received data
package Test::Builder::Tester::Tie;
##
# add line(s) to be expected
sub expect {
my $self = shift;
my @checks = @_;
foreach my $check (@checks) {
$check = $self->_account_for_subtest($check);
$check = $self->_translate_Failed_check($check);
push @{ $self->{wanted} }, ref $check ? $check : "$check\n";
}
}
sub _account_for_subtest {
my( $self, $check ) = @_;
my $hub = $t->{Stack}->top;
my $nesting = $hub->isa('Test2::Hub::Subtest') ? $hub->nested : 0;
return ref($check) ? $check : (' ' x $nesting) . $check;
}
sub _translate_Failed_check {
my( $self, $check ) = @_;
if( $check =~ /\A(.*)# (Failed .*test) \((.*?) at line (\d+)\)\Z(?!\n)/ ) {
$check = "/\Q$1\E#\\s+\Q$2\E.*?\\n?.*?\Qat $3\E line \Q$4\E.*\\n?/";
}
return $check;
}
##
# return true iff the expected data matches the got data
sub check {
my $self = shift;
# turn off warnings as these might be undef
local $^W = 0;
my @checks = @{ $self->{wanted} };
my $got = $self->{got};
foreach my $check (@checks) {
$check = "\Q$check\E" unless( $check =~ s,^/(.*)/$,$1, or ref $check );
return 0 unless $got =~ s/^$check//;
}
return length $got == 0;
}
##
# a complaint message about the inputs not matching (to be
# used for debugging messages)
sub complaint {
my $self = shift;
my $type = $self->type;
my $got = $self->got;
my $wanted = join '', @{ $self->wanted };
# are we running in colour mode?
if(Test::Builder::Tester::color) {
# get color
eval { require Term::ANSIColor };
unless($@) {
eval { require Win32::Console::ANSI } if 'MSWin32' eq $^O; # support color on windows platforms
# colours
my $green = Term::ANSIColor::color("black") . Term::ANSIColor::color("on_green");
my $red = Term::ANSIColor::color("black") . Term::ANSIColor::color("on_red");
my $reset = Term::ANSIColor::color("reset");
# work out where the two strings start to differ
my $char = 0;
$char++ while substr( $got, $char, 1 ) eq substr( $wanted, $char, 1 );
# get the start string and the two end strings
my $start = $green . substr( $wanted, 0, $char );
my $gotend = $red . substr( $got, $char ) . $reset;
my $wantedend = $red . substr( $wanted, $char ) . $reset;
# make the start turn green on and off
$start =~ s/\n/$reset\n$green/g;
# make the ends turn red on and off
$gotend =~ s/\n/$reset\n$red/g;
$wantedend =~ s/\n/$reset\n$red/g;
# rebuild the strings
$got = $start . $gotend;
$wanted = $start . $wantedend;
}
}
my @got = split "\n", $got;
my @wanted = split "\n", $wanted;
$got = "";
$wanted = "";
while (@got || @wanted) {
my $g = shift @got || "";
my $w = shift @wanted || "";
if ($g ne $w) {
if($g =~ s/(\s+)$/ |> /g) {
$g .= ($_ eq ' ' ? '_' : '\t') for split '', $1;
}
if($w =~ s/(\s+)$/ |> /g) {
$w .= ($_ eq ' ' ? '_' : '\t') for split '', $1;
}
$g = "> $g";
$w = "> $w";
}
else {
$g = " $g";
$w = " $w";
}
$got = $got ? "$got\n$g" : $g;
$wanted = $wanted ? "$wanted\n$w" : $w;
}
return "$type is:\n" . "$got\nnot:\n$wanted\nas expected";
}
##
# forget all expected and got data
sub reset {
my $self = shift;
%$self = (
type => $self->{type},
got => '',
wanted => [],
);
}
sub got {
my $self = shift;
return $self->{got};
}
sub wanted {
my $self = shift;
return $self->{wanted};
}
sub type {
my $self = shift;
return $self->{type};
}
###
# tie interface
###
sub PRINT {
my $self = shift;
$self->{got} .= join '', @_;
}
sub TIEHANDLE {
my( $class, $type ) = @_;
my $self = bless { type => $type }, $class;
$self->reset;
return $self;
}
sub READ { }
sub READLINE { }
sub GETC { }
sub FILENO { }
1;

View file

@ -0,0 +1,51 @@
package Test::Builder::Tester::Color;
use strict;
our $VERSION = '1.302175';
require Test::Builder::Tester;
=head1 NAME
Test::Builder::Tester::Color - turn on colour in Test::Builder::Tester
=head1 SYNOPSIS
When running a test script
perl -MTest::Builder::Tester::Color test.t
=head1 DESCRIPTION
Importing this module causes the subroutine color in Test::Builder::Tester
to be called with a true value causing colour highlighting to be turned
on in debug output.
The sole purpose of this module is to enable colour highlighting
from the command line.
=cut
sub import {
Test::Builder::Tester::color(1);
}
=head1 AUTHOR
Copyright Mark Fowler E<lt>mark@twoshortplanks.comE<gt> 2002.
This program is free software; you can redistribute it
and/or modify it under the same terms as Perl itself.
=head1 BUGS
This module will have no effect unless Term::ANSIColor is installed.
=head1 SEE ALSO
L<Test::Builder::Tester>, L<Term::ANSIColor>
=cut
1;

View file

@ -0,0 +1,68 @@
package Test::Builder::TodoDiag;
use strict;
use warnings;
our $VERSION = '1.302175';
BEGIN { require Test2::Event::Diag; our @ISA = qw(Test2::Event::Diag) }
sub diagnostics { 0 }
sub facet_data {
my $self = shift;
my $out = $self->SUPER::facet_data();
$out->{info}->[0]->{debug} = 0;
return $out;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test::Builder::TodoDiag - Test::Builder subclass of Test2::Event::Diag
=head1 DESCRIPTION
This is used to encapsulate diag messages created inside TODO.
=head1 SYNOPSIS
You do not need to use this directly.
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

1997
t/lib/Test/More.pm Normal file

File diff suppressed because it is too large Load diff

220
t/lib/Test/Simple.pm Normal file
View file

@ -0,0 +1,220 @@
package Test::Simple;
use 5.006;
use strict;
our $VERSION = '1.302175';
use Test::Builder::Module;
our @ISA = qw(Test::Builder::Module);
our @EXPORT = qw(ok);
my $CLASS = __PACKAGE__;
=head1 NAME
Test::Simple - Basic utilities for writing tests.
=head1 SYNOPSIS
use Test::Simple tests => 1;
ok( $foo eq $bar, 'foo is bar' );
=head1 DESCRIPTION
** If you are unfamiliar with testing B<read L<Test::Tutorial> first!> **
This is an extremely simple, extremely basic module for writing tests
suitable for CPAN modules and other pursuits. If you wish to do more
complicated testing, use the Test::More module (a drop-in replacement
for this one).
The basic unit of Perl testing is the ok. For each thing you want to
test your program will print out an "ok" or "not ok" to indicate pass
or fail. You do this with the C<ok()> function (see below).
The only other constraint is you must pre-declare how many tests you
plan to run. This is in case something goes horribly wrong during the
test and your test program aborts, or skips a test or whatever. You
do this like so:
use Test::Simple tests => 23;
You must have a plan.
=over 4
=item B<ok>
ok( $foo eq $bar, $name );
ok( $foo eq $bar );
C<ok()> is given an expression (in this case C<$foo eq $bar>). If it's
true, the test passed. If it's false, it didn't. That's about it.
C<ok()> prints out either "ok" or "not ok" along with a test number (it
keeps track of that for you).
# This produces "ok 1 - Hell not yet frozen over" (or not ok)
ok( get_temperature($hell) > 0, 'Hell not yet frozen over' );
If you provide a $name, that will be printed along with the "ok/not
ok" to make it easier to find your test when if fails (just search for
the name). It also makes it easier for the next guy to understand
what your test is for. It's highly recommended you use test names.
All tests are run in scalar context. So this:
ok( @stuff, 'I have some stuff' );
will do what you mean (fail if stuff is empty)
=cut
sub ok ($;$) { ## no critic (Subroutines::ProhibitSubroutinePrototypes)
return $CLASS->builder->ok(@_);
}
=back
Test::Simple will start by printing number of tests run in the form
"1..M" (so "1..5" means you're going to run 5 tests). This strange
format lets L<Test::Harness> know how many tests you plan on running in
case something goes horribly wrong.
If all your tests passed, Test::Simple will exit with zero (which is
normal). If anything failed it will exit with how many failed. If
you run less (or more) tests than you planned, the missing (or extras)
will be considered failures. If no tests were ever run Test::Simple
will throw a warning and exit with 255. If the test died, even after
having successfully completed all its tests, it will still be
considered a failure and will exit with 255.
So the exit codes are...
0 all tests successful
255 test died or all passed but wrong # of tests run
any other number how many failed (including missing or extras)
If you fail more than 254 tests, it will be reported as 254.
This module is by no means trying to be a complete testing system.
It's just to get you started. Once you're off the ground its
recommended you look at L<Test::More>.
=head1 EXAMPLE
Here's an example of a simple .t file for the fictional Film module.
use Test::Simple tests => 5;
use Film; # What you're testing.
my $btaste = Film->new({ Title => 'Bad Taste',
Director => 'Peter Jackson',
Rating => 'R',
NumExplodingSheep => 1
});
ok( defined($btaste) && ref $btaste eq 'Film', 'new() works' );
ok( $btaste->Title eq 'Bad Taste', 'Title() get' );
ok( $btaste->Director eq 'Peter Jackson', 'Director() get' );
ok( $btaste->Rating eq 'R', 'Rating() get' );
ok( $btaste->NumExplodingSheep == 1, 'NumExplodingSheep() get' );
It will produce output like this:
1..5
ok 1 - new() works
ok 2 - Title() get
ok 3 - Director() get
not ok 4 - Rating() get
# Failed test 'Rating() get'
# in t/film.t at line 14.
ok 5 - NumExplodingSheep() get
# Looks like you failed 1 tests of 5
Indicating the Film::Rating() method is broken.
=head1 CAVEATS
Test::Simple will only report a maximum of 254 failures in its exit
code. If this is a problem, you probably have a huge test script.
Split it into multiple files. (Otherwise blame the Unix folks for
using an unsigned short integer as the exit status).
Because VMS's exit codes are much, much different than the rest of the
universe, and perl does horrible mangling to them that gets in my way,
it works like this on VMS.
0 SS$_NORMAL all tests successful
4 SS$_ABORT something went wrong
Unfortunately, I can't differentiate any further.
=head1 NOTES
Test::Simple is B<explicitly> tested all the way back to perl 5.6.0.
Test::Simple is thread-safe in perl 5.8.1 and up.
=head1 HISTORY
This module was conceived while talking with Tony Bowden in his
kitchen one night about the problems I was having writing some really
complicated feature into the new Testing module. He observed that the
main problem is not dealing with these edge cases but that people hate
to write tests B<at all>. What was needed was a dead simple module
that took all the hard work out of testing and was really, really easy
to learn. Paul Johnson simultaneously had this idea (unfortunately,
he wasn't in Tony's kitchen). This is it.
=head1 SEE ALSO
=over 4
=item L<Test::More>
More testing functions! Once you outgrow Test::Simple, look at
L<Test::More>. Test::Simple is 100% forward compatible with L<Test::More>
(i.e. you can just use L<Test::More> instead of Test::Simple in your
programs and things will still work).
=back
Look in L<Test::More>'s SEE ALSO for more testing modules.
=head1 AUTHORS
Idea by Tony Bowden and Paul Johnson, code by Michael G Schwern
E<lt>schwern@pobox.comE<gt>, wardrobe by Calvin Klein.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2001-2008 by Michael G Schwern E<lt>schwern@pobox.comE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://www.perl.com/perl/misc/Artistic.html>
=cut
1;

695
t/lib/Test/Tester.pm Normal file
View file

@ -0,0 +1,695 @@
use strict;
package Test::Tester;
BEGIN
{
if (*Test::Builder::new{CODE})
{
warn "You should load Test::Tester before Test::Builder (or anything that loads Test::Builder)"
}
}
use Test::Builder;
use Test::Tester::CaptureRunner;
use Test::Tester::Delegate;
require Exporter;
use vars qw( @ISA @EXPORT );
our $VERSION = '1.302175';
@EXPORT = qw( run_tests check_tests check_test cmp_results show_space );
@ISA = qw( Exporter );
my $Test = Test::Builder->new;
my $Capture = Test::Tester::Capture->new;
my $Delegator = Test::Tester::Delegate->new;
$Delegator->{Object} = $Test;
my $runner = Test::Tester::CaptureRunner->new;
my $want_space = $ENV{TESTTESTERSPACE};
sub show_space
{
$want_space = 1;
}
my $colour = '';
my $reset = '';
if (my $want_colour = $ENV{TESTTESTERCOLOUR} || $ENV{TESTTESTERCOLOR})
{
if (eval { require Term::ANSIColor; 1 })
{
eval { require Win32::Console::ANSI } if 'MSWin32' eq $^O; # support color on windows platforms
my ($f, $b) = split(",", $want_colour);
$colour = Term::ANSIColor::color($f).Term::ANSIColor::color("on_$b");
$reset = Term::ANSIColor::color("reset");
}
}
sub new_new
{
return $Delegator;
}
sub capture
{
return Test::Tester::Capture->new;
}
sub fh
{
# experiment with capturing output, I don't like it
$runner = Test::Tester::FHRunner->new;
return $Test;
}
sub find_run_tests
{
my $d = 1;
my $found = 0;
while ((not $found) and (my ($sub) = (caller($d))[3]) )
{
# print "$d: $sub\n";
$found = ($sub eq "Test::Tester::run_tests");
$d++;
}
# die "Didn't find 'run_tests' in caller stack" unless $found;
return $d;
}
sub run_tests
{
local($Delegator->{Object}) = $Capture;
$runner->run_tests(@_);
return ($runner->get_premature, $runner->get_results);
}
sub check_test
{
my $test = shift;
my $expect = shift;
my $name = shift;
$name = "" unless defined($name);
@_ = ($test, [$expect], $name);
goto &check_tests;
}
sub check_tests
{
my $test = shift;
my $expects = shift;
my $name = shift;
$name = "" unless defined($name);
my ($prem, @results) = eval { run_tests($test, $name) };
$Test->ok(! $@, "Test '$name' completed") || $Test->diag($@);
$Test->ok(! length($prem), "Test '$name' no premature diagnostication") ||
$Test->diag("Before any testing anything, your tests said\n$prem");
local $Test::Builder::Level = $Test::Builder::Level + 1;
cmp_results(\@results, $expects, $name);
return ($prem, @results);
}
sub cmp_field
{
my ($result, $expect, $field, $desc) = @_;
if (defined $expect->{$field})
{
$Test->is_eq($result->{$field}, $expect->{$field},
"$desc compare $field");
}
}
sub cmp_result
{
my ($result, $expect, $name) = @_;
my $sub_name = $result->{name};
$sub_name = "" unless defined($name);
my $desc = "subtest '$sub_name' of '$name'";
{
local $Test::Builder::Level = $Test::Builder::Level + 1;
cmp_field($result, $expect, "ok", $desc);
cmp_field($result, $expect, "actual_ok", $desc);
cmp_field($result, $expect, "type", $desc);
cmp_field($result, $expect, "reason", $desc);
cmp_field($result, $expect, "name", $desc);
}
# if we got no depth then default to 1
my $depth = 1;
if (exists $expect->{depth})
{
$depth = $expect->{depth};
}
# if depth was explicitly undef then don't test it
if (defined $depth)
{
$Test->is_eq($result->{depth}, $depth, "checking depth") ||
$Test->diag('You need to change $Test::Builder::Level');
}
if (defined(my $exp = $expect->{diag}))
{
my $got = '';
if (ref $exp eq 'Regexp') {
if (not $Test->like($result->{diag}, $exp,
"subtest '$sub_name' of '$name' compare diag"))
{
$got = $result->{diag};
}
} else {
# if there actually is some diag then put a \n on the end if it's not
# there already
$exp .= "\n" if (length($exp) and $exp !~ /\n$/);
if (not $Test->ok($result->{diag} eq $exp,
"subtest '$sub_name' of '$name' compare diag"))
{
$got = $result->{diag};
}
}
if ($got) {
my $glen = length($got);
my $elen = length($exp);
for ($got, $exp)
{
my @lines = split("\n", $_);
$_ = join("\n", map {
if ($want_space)
{
$_ = $colour.escape($_).$reset;
}
else
{
"'$colour$_$reset'"
}
} @lines);
}
$Test->diag(<<EOM);
Got diag ($glen bytes):
$got
Expected diag ($elen bytes):
$exp
EOM
}
}
}
sub escape
{
my $str = shift;
my $res = '';
for my $char (split("", $str))
{
my $c = ord($char);
if(($c>32 and $c<125) or $c == 10)
{
$res .= $char;
}
else
{
$res .= sprintf('\x{%x}', $c)
}
}
return $res;
}
sub cmp_results
{
my ($results, $expects, $name) = @_;
$Test->is_num(scalar @$results, scalar @$expects, "Test '$name' result count");
for (my $i = 0; $i < @$expects; $i++)
{
my $expect = $expects->[$i];
my $result = $results->[$i];
local $Test::Builder::Level = $Test::Builder::Level + 1;
cmp_result($result, $expect, $name);
}
}
######## nicked from Test::More
sub plan {
my(@plan) = @_;
my $caller = caller;
$Test->exported_to($caller);
my @imports = ();
foreach my $idx (0..$#plan) {
if( $plan[$idx] eq 'import' ) {
my($tag, $imports) = splice @plan, $idx, 2;
@imports = @$imports;
last;
}
}
$Test->plan(@plan);
__PACKAGE__->_export_to_level(1, __PACKAGE__, @imports);
}
sub import {
my($class) = shift;
{
no warnings 'redefine';
*Test::Builder::new = \&new_new;
}
goto &plan;
}
sub _export_to_level
{
my $pkg = shift;
my $level = shift;
(undef) = shift; # redundant arg
my $callpkg = caller($level);
$pkg->export($callpkg, @_);
}
############
1;
__END__
=head1 NAME
Test::Tester - Ease testing test modules built with Test::Builder
=head1 SYNOPSIS
use Test::Tester tests => 6;
use Test::MyStyle;
check_test(
sub {
is_mystyle_eq("this", "that", "not eq");
},
{
ok => 0, # expect this to fail
name => "not eq",
diag => "Expected: 'this'\nGot: 'that'",
}
);
or
use Test::Tester tests => 6;
use Test::MyStyle;
check_test(
sub {
is_mystyle_qr("this", "that", "not matching");
},
{
ok => 0, # expect this to fail
name => "not matching",
diag => qr/Expected: 'this'\s+Got: 'that'/,
}
);
or
use Test::Tester;
use Test::More tests => 3;
use Test::MyStyle;
my ($premature, @results) = run_tests(
sub {
is_database_alive("dbname");
}
);
# now use Test::More::like to check the diagnostic output
like($results[0]->{diag}, "/^Database ping took \\d+ seconds$"/, "diag");
=head1 DESCRIPTION
If you have written a test module based on Test::Builder then Test::Tester
allows you to test it with the minimum of effort.
=head1 HOW TO USE (THE EASY WAY)
From version 0.08 Test::Tester no longer requires you to included anything
special in your test modules. All you need to do is
use Test::Tester;
in your test script B<before> any other Test::Builder based modules and away
you go.
Other modules based on Test::Builder can be used to help with the
testing. In fact you can even use functions from your module to test
other functions from the same module (while this is possible it is
probably not a good idea, if your module has bugs, then
using it to test itself may give the wrong answers).
The easiest way to test is to do something like
check_test(
sub { is_mystyle_eq("this", "that", "not eq") },
{
ok => 0, # we expect the test to fail
name => "not eq",
diag => "Expected: 'this'\nGot: 'that'",
}
);
this will execute the is_mystyle_eq test, capturing its results and
checking that they are what was expected.
You may need to examine the test results in a more flexible way, for
example, the diagnostic output may be quite long or complex or it may involve
something that you cannot predict in advance like a timestamp. In this case
you can get direct access to the test results:
my ($premature, @results) = run_tests(
sub {
is_database_alive("dbname");
}
);
like($result[0]->{diag}, "/^Database ping took \\d+ seconds$"/, "diag");
or
check_test(
sub { is_mystyle_qr("this", "that", "not matching") },
{
ok => 0, # we expect the test to fail
name => "not matching",
diag => qr/Expected: 'this'\s+Got: 'that'/,
}
);
We cannot predict how long the database ping will take so we use
Test::More's like() test to check that the diagnostic string is of the right
form.
=head1 HOW TO USE (THE HARD WAY)
I<This is here for backwards compatibility only>
Make your module use the Test::Tester::Capture object instead of the
Test::Builder one. How to do this depends on your module but assuming that
your module holds the Test::Builder object in $Test and that all your test
routines access it through $Test then providing a function something like this
sub set_builder
{
$Test = shift;
}
should allow your test scripts to do
Test::YourModule::set_builder(Test::Tester->capture);
and after that any tests inside your module will captured.
=head1 TEST RESULTS
The result of each test is captured in a hash. These hashes are the same as
the hashes returned by Test::Builder->details but with a couple of extra
fields.
These fields are documented in L<Test::Builder> in the details() function
=over 2
=item ok
Did the test pass?
=item actual_ok
Did the test really pass? That is, did the pass come from
Test::Builder->ok() or did it pass because it was a TODO test?
=item name
The name supplied for the test.
=item type
What kind of test? Possibilities include, skip, todo etc. See
L<Test::Builder> for more details.
=item reason
The reason for the skip, todo etc. See L<Test::Builder> for more details.
=back
These fields are exclusive to Test::Tester.
=over 2
=item diag
Any diagnostics that were output for the test. This only includes
diagnostics output B<after> the test result is declared.
Note that Test::Builder ensures that any diagnostics end in a \n and
it in earlier versions of Test::Tester it was essential that you have
the final \n in your expected diagnostics. From version 0.10 onward,
Test::Tester will add the \n if you forgot it. It will not add a \n if
you are expecting no diagnostics. See below for help tracking down
hard to find space and tab related problems.
=item depth
This allows you to check that your test module is setting the correct value
for $Test::Builder::Level and thus giving the correct file and line number
when a test fails. It is calculated by looking at caller() and
$Test::Builder::Level. It should count how many subroutines there are before
jumping into the function you are testing. So for example in
run_tests( sub { my_test_function("a", "b") } );
the depth should be 1 and in
sub deeper { my_test_function("a", "b") }
run_tests(sub { deeper() });
depth should be 2, that is 1 for the sub {} and one for deeper(). This
might seem a little complex but if your tests look like the simple
examples in this doc then you don't need to worry as the depth will
always be 1 and that's what Test::Tester expects by default.
B<Note>: if you do not specify a value for depth in check_test() then it
automatically compares it against 1, if you really want to skip the depth
test then pass in undef.
B<Note>: depth will not be correctly calculated for tests that run from a
signal handler or an END block or anywhere else that hides the call stack.
=back
Some of Test::Tester's functions return arrays of these hashes, just
like Test::Builder->details. That is, the hash for the first test will
be array element 1 (not 0). Element 0 will not be a hash it will be a
string which contains any diagnostic output that came before the first
test. This should usually be empty, if it's not, it means something
output diagnostics before any test results showed up.
=head1 SPACES AND TABS
Appearances can be deceptive, especially when it comes to emptiness. If you
are scratching your head trying to work out why Test::Tester is saying that
your diagnostics are wrong when they look perfectly right then the answer is
probably whitespace. From version 0.10 on, Test::Tester surrounds the
expected and got diag values with single quotes to make it easier to spot
trailing whitespace. So in this example
# Got diag (5 bytes):
# 'abcd '
# Expected diag (4 bytes):
# 'abcd'
it is quite clear that there is a space at the end of the first string.
Another way to solve this problem is to use colour and inverse video on an
ANSI terminal, see below COLOUR below if you want this.
Unfortunately this is sometimes not enough, neither colour nor quotes will
help you with problems involving tabs, other non-printing characters and
certain kinds of problems inherent in Unicode. To deal with this, you can
switch Test::Tester into a mode whereby all "tricky" characters are shown as
\{xx}. Tricky characters are those with ASCII code less than 33 or higher
than 126. This makes the output more difficult to read but much easier to
find subtle differences between strings. To turn on this mode either call
C<show_space()> in your test script or set the C<TESTTESTERSPACE> environment
variable to be a true value. The example above would then look like
# Got diag (5 bytes):
# abcd\x{20}
# Expected diag (4 bytes):
# abcd
=head1 COLOUR
If you prefer to use colour as a means of finding tricky whitespace
characters then you can set the C<TESTTESTCOLOUR> environment variable to a
comma separated pair of colours, the first for the foreground, the second
for the background. For example "white,red" will print white text on a red
background. This requires the Term::ANSIColor module. You can specify any
colour that would be acceptable to the Term::ANSIColor::color function.
If you spell colour differently, that's no problem. The C<TESTTESTERCOLOR>
variable also works (if both are set then the British spelling wins out).
=head1 EXPORTED FUNCTIONS
=head3 ($premature, @results) = run_tests(\&test_sub)
\&test_sub is a reference to a subroutine.
run_tests runs the subroutine in $test_sub and captures the results of any
tests inside it. You can run more than 1 test inside this subroutine if you
like.
$premature is a string containing any diagnostic output from before
the first test.
@results is an array of test result hashes.
=head3 cmp_result(\%result, \%expect, $name)
\%result is a ref to a test result hash.
\%expect is a ref to a hash of expected values for the test result.
cmp_result compares the result with the expected values. If any differences
are found it outputs diagnostics. You may leave out any field from the
expected result and cmp_result will not do the comparison of that field.
=head3 cmp_results(\@results, \@expects, $name)
\@results is a ref to an array of test results.
\@expects is a ref to an array of hash refs.
cmp_results checks that the results match the expected results and if any
differences are found it outputs diagnostics. It first checks that the
number of elements in \@results and \@expects is the same. Then it goes
through each result checking it against the expected result as in
cmp_result() above.
=head3 ($premature, @results) = check_tests(\&test_sub, \@expects, $name)
\&test_sub is a reference to a subroutine.
\@expect is a ref to an array of hash refs which are expected test results.
check_tests combines run_tests and cmp_tests into a single call. It also
checks if the tests died at any stage.
It returns the same values as run_tests, so you can further examine the test
results if you need to.
=head3 ($premature, @results) = check_test(\&test_sub, \%expect, $name)
\&test_sub is a reference to a subroutine.
\%expect is a ref to an hash of expected values for the test result.
check_test is a wrapper around check_tests. It combines run_tests and
cmp_tests into a single call, checking if the test died. It assumes
that only a single test is run inside \&test_sub and include a test to
make sure this is true.
It returns the same values as run_tests, so you can further examine the test
results if you need to.
=head3 show_space()
Turn on the escaping of characters as described in the SPACES AND TABS
section.
=head1 HOW IT WORKS
Normally, a test module (let's call it Test:MyStyle) calls
Test::Builder->new to get the Test::Builder object. Test::MyStyle calls
methods on this object to record information about test results. When
Test::Tester is loaded, it replaces Test::Builder's new() method with one
which returns a Test::Tester::Delegate object. Most of the time this object
behaves as the real Test::Builder object. Any methods that are called are
delegated to the real Test::Builder object so everything works perfectly.
However once we go into test mode, the method calls are no longer passed to
the real Test::Builder object, instead they go to the Test::Tester::Capture
object. This object seems exactly like the real Test::Builder object,
except, instead of outputting test results and diagnostics, it just records
all the information for later analysis.
=head1 CAVEATS
Support for calling Test::Builder->note is minimal. It's implemented
as an empty stub, so modules that use it will not crash but the calls
are not recorded for testing purposes like the others. Patches
welcome.
=head1 SEE ALSO
L<Test::Builder> the source of testing goodness. L<Test::Builder::Tester>
for an alternative approach to the problem tackled by Test::Tester -
captures the strings output by Test::Builder. This means you cannot get
separate access to the individual pieces of information and you must predict
B<exactly> what your test will output.
=head1 AUTHOR
This module is copyright 2005 Fergal Daly <fergal@esatclear.ie>, some parts
are based on other people's work.
Plan handling lifted from Test::More. written by Michael G Schwern
<schwern@pobox.com>.
Test::Tester::Capture is a cut down and hacked up version of Test::Builder.
Test::Builder was written by chromatic <chromatic@wgz.org> and Michael G
Schwern <schwern@pobox.com>.
=head1 LICENSE
Under the same license as Perl itself
See http://www.perl.com/perl/misc/Artistic.html
=cut

View file

@ -0,0 +1,241 @@
use strict;
package Test::Tester::Capture;
our $VERSION = '1.302175';
use Test::Builder;
use vars qw( @ISA );
@ISA = qw( Test::Builder );
# Make Test::Tester::Capture thread-safe for ithreads.
BEGIN {
use Config;
*share = sub { 0 };
*lock = sub { 0 };
}
my $Curr_Test = 0; share($Curr_Test);
my @Test_Results = (); share(@Test_Results);
my $Prem_Diag = {diag => ""}; share($Curr_Test);
sub new
{
# Test::Tester::Capgture::new used to just return __PACKAGE__
# because Test::Builder::new enforced its singleton nature by
# return __PACKAGE__. That has since changed, Test::Builder::new now
# returns a blessed has and around version 0.78, Test::Builder::todo
# started wanting to modify $self. To cope with this, we now return
# a blessed hash. This is a short-term hack, the correct thing to do
# is to detect which style of Test::Builder we're dealing with and
# act appropriately.
my $class = shift;
return bless {}, $class;
}
sub ok {
my($self, $test, $name) = @_;
my $ctx = $self->ctx;
# $test might contain an object which we don't want to accidentally
# store, so we turn it into a boolean.
$test = $test ? 1 : 0;
lock $Curr_Test;
$Curr_Test++;
my($pack, $file, $line) = $self->caller;
my $todo = $self->todo();
my $result = {};
share($result);
unless( $test ) {
@$result{ 'ok', 'actual_ok' } = ( ( $todo ? 1 : 0 ), 0 );
}
else {
@$result{ 'ok', 'actual_ok' } = ( 1, $test );
}
if( defined $name ) {
$name =~ s|#|\\#|g; # # in a name can confuse Test::Harness.
$result->{name} = $name;
}
else {
$result->{name} = '';
}
if( $todo ) {
my $what_todo = $todo;
$result->{reason} = $what_todo;
$result->{type} = 'todo';
}
else {
$result->{reason} = '';
$result->{type} = '';
}
$Test_Results[$Curr_Test-1] = $result;
unless( $test ) {
my $msg = $todo ? "Failed (TODO)" : "Failed";
$result->{fail_diag} = (" $msg test ($file at line $line)\n");
}
$result->{diag} = "";
$result->{_level} = $Test::Builder::Level;
$result->{_depth} = Test::Tester::find_run_tests();
$ctx->release;
return $test ? 1 : 0;
}
sub skip {
my($self, $why) = @_;
$why ||= '';
my $ctx = $self->ctx;
lock($Curr_Test);
$Curr_Test++;
my %result;
share(%result);
%result = (
'ok' => 1,
actual_ok => 1,
name => '',
type => 'skip',
reason => $why,
diag => "",
_level => $Test::Builder::Level,
_depth => Test::Tester::find_run_tests(),
);
$Test_Results[$Curr_Test-1] = \%result;
$ctx->release;
return 1;
}
sub todo_skip {
my($self, $why) = @_;
$why ||= '';
my $ctx = $self->ctx;
lock($Curr_Test);
$Curr_Test++;
my %result;
share(%result);
%result = (
'ok' => 1,
actual_ok => 0,
name => '',
type => 'todo_skip',
reason => $why,
diag => "",
_level => $Test::Builder::Level,
_depth => Test::Tester::find_run_tests(),
);
$Test_Results[$Curr_Test-1] = \%result;
$ctx->release;
return 1;
}
sub diag {
my($self, @msgs) = @_;
return unless @msgs;
# Prevent printing headers when compiling (i.e. -c)
return if $^C;
my $ctx = $self->ctx;
# Escape each line with a #.
foreach (@msgs) {
$_ = 'undef' unless defined;
}
push @msgs, "\n" unless $msgs[-1] =~ /\n\Z/;
my $result = $Curr_Test ? $Test_Results[$Curr_Test - 1] : $Prem_Diag;
$result->{diag} .= join("", @msgs);
$ctx->release;
return 0;
}
sub details {
return @Test_Results;
}
# Stub. Feel free to send me a patch to implement this.
sub note {
}
sub explain {
return Test::Builder::explain(@_);
}
sub premature
{
return $Prem_Diag->{diag};
}
sub current_test
{
if (@_ > 1)
{
die "Don't try to change the test number!";
}
else
{
return $Curr_Test;
}
}
sub reset
{
$Curr_Test = 0;
@Test_Results = ();
$Prem_Diag = {diag => ""};
}
1;
__END__
=head1 NAME
Test::Tester::Capture - Help testing test modules built with Test::Builder
=head1 DESCRIPTION
This is a subclass of Test::Builder that overrides many of the methods so
that they don't output anything. It also keeps track of its own set of test
results so that you can use Test::Builder based modules to perform tests on
other Test::Builder based modules.
=head1 AUTHOR
Most of the code here was lifted straight from Test::Builder and then had
chunks removed by Fergal Daly <fergal@esatclear.ie>.
=head1 LICENSE
Under the same license as Perl itself
See http://www.perl.com/perl/misc/Artistic.html
=cut

View file

@ -0,0 +1,79 @@
# $Header: /home/fergal/my/cvs/Test-Tester/lib/Test/Tester/CaptureRunner.pm,v 1.3 2003/03/05 01:07:55 fergal Exp $
use strict;
package Test::Tester::CaptureRunner;
our $VERSION = '1.302175';
use Test::Tester::Capture;
require Exporter;
sub new
{
my $pkg = shift;
my $self = bless {}, $pkg;
return $self;
}
sub run_tests
{
my $self = shift;
my $test = shift;
capture()->reset;
$self->{StartLevel} = $Test::Builder::Level;
&$test();
}
sub get_results
{
my $self = shift;
my @results = capture()->details;
my $start = $self->{StartLevel};
foreach my $res (@results)
{
next if defined $res->{depth};
my $depth = $res->{_depth} - $res->{_level} - $start - 3;
# print "my $depth = $res->{_depth} - $res->{_level} - $start - 1\n";
$res->{depth} = $depth;
}
return @results;
}
sub get_premature
{
return capture()->premature;
}
sub capture
{
return Test::Tester::Capture->new;
}
__END__
=head1 NAME
Test::Tester::CaptureRunner - Help testing test modules built with Test::Builder
=head1 DESCRIPTION
This stuff if needed to allow me to play with other ways of monitoring the
test results.
=head1 AUTHOR
Copyright 2003 by Fergal Daly <fergal@esatclear.ie>.
=head1 LICENSE
Under the same license as Perl itself
See http://www.perl.com/perl/misc/Artistic.html
=cut

View file

@ -0,0 +1,45 @@
use strict;
use warnings;
package Test::Tester::Delegate;
our $VERSION = '1.302175';
use Scalar::Util();
use vars '$AUTOLOAD';
sub new
{
my $pkg = shift;
my $obj = shift;
my $self = bless {}, $pkg;
return $self;
}
sub AUTOLOAD
{
my ($sub) = $AUTOLOAD =~ /.*::(.*?)$/;
return if $sub eq "DESTROY";
my $obj = $_[0]->{Object};
my $ref = $obj->can($sub);
shift(@_);
unshift(@_, $obj);
goto &$ref;
}
sub can {
my $this = shift;
my ($sub) = @_;
return $this->{Object}->can($sub) if Scalar::Util::blessed($this);
return $this->SUPER::can(@_);
}
1;

64
t/lib/Test/use/ok.pm Normal file
View file

@ -0,0 +1,64 @@
package Test::use::ok;
use 5.005;
our $VERSION = '1.302175';
__END__
=head1 NAME
Test::use::ok - Alternative to Test::More::use_ok
=head1 SYNOPSIS
use ok 'Some::Module';
=head1 DESCRIPTION
According to the B<Test::More> documentation, it is recommended to run
C<use_ok()> inside a C<BEGIN> block, so functions are exported at
compile-time and prototypes are properly honored.
That is, instead of writing this:
use_ok( 'Some::Module' );
use_ok( 'Other::Module' );
One should write this:
BEGIN { use_ok( 'Some::Module' ); }
BEGIN { use_ok( 'Other::Module' ); }
However, people often either forget to add C<BEGIN>, or mistakenly group
C<use_ok> with other tests in a single C<BEGIN> block, which can create subtle
differences in execution order.
With this module, simply change all C<use_ok> in test scripts to C<use ok>,
and they will be executed at C<BEGIN> time. The explicit space after C<use>
makes it clear that this is a single compile-time action.
=head1 SEE ALSO
L<Test::More>
=head1 MAINTAINER
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=encoding utf8
=head1 CC0 1.0 Universal
To the extent possible under law, 唐鳳 has waived all copyright and related
or neighboring rights to L<Test-use-ok>.
This work is published from Taiwan.
L<http://creativecommons.org/publicdomain/zero/1.0>
=cut

213
t/lib/Test2.pm Normal file
View file

@ -0,0 +1,213 @@
package Test2;
use strict;
use warnings;
our $VERSION = '1.302175';
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2 - Framework for writing test tools that all work together.
=head1 DESCRIPTION
Test2 is a new testing framework produced by forking L<Test::Builder>,
completely refactoring it, adding many new features and capabilities.
=head2 WHAT IS NEW?
=over 4
=item Easier to test new testing tools.
From the beginning Test2 was built with introspection capabilities. With
Test::Builder it was difficult at best to capture test tool output for
verification. Test2 Makes it easy with C<Test2::API::intercept()>.
=item Better diagnostics capabilities.
Test2 uses an L<Test2::API::Context> object to track filename, line number, and
tool details. This object greatly simplifies tracking for where errors should
be reported.
=item Event driven.
Test2 based tools produce events which get passed through a processing system
before being output by a formatter. This event system allows for rich plugin
and extension support.
=item More complete API.
Test::Builder only provided a handful of methods for generating lines of TAP.
Test2 took inventory of everything people were doing with Test::Builder that
required hacking it up. Test2 made public API functions for nearly all the
desired functionality people didn't previously have.
=item Support for output other than TAP.
Test::Builder assumed everything would end up as TAP. Test2 makes no such
assumption. Test2 provides ways for you to specify alternative and custom
formatters.
=item Subtest implementation is more sane.
The Test::Builder implementation of subtests was certifiably insane. Test2 uses
a stacked event hub system that greatly improves how subtests are implemented.
=item Support for threading/forking.
Test2 support for forking and threading can be turned on using L<Test2::IPC>.
Once turned on threading and forking operate sanely and work as one would
expect.
=back
=head1 GETTING STARTED
If you are interested in writing tests using new tools then you should look at
L<Test2::Suite>. L<Test2::Suite> is a separate cpan distribution that contains
many tools implemented on Test2.
If you are interested in writing new tools you should take a look at
L<Test2::API> first.
=head1 NAMESPACE LAYOUT
This describes the namespace layout for the Test2 ecosystem. Not all the
namespaces listed here are part of the Test2 distribution, some are implemented
in L<Test2::Suite>.
=head2 Test2::Tools::
This namespace is for sets of tools. Modules in this namespace should export
tools like C<ok()> and C<is()>. Most things written for Test2 should go here.
Modules in this namespace B<MUST NOT> export subs from other tools. See the
L</Test2::Bundle::> namespace if you want to do that.
=head2 Test2::Plugin::
This namespace is for plugins. Plugins are modules that change or enhance the
behavior of Test2. An example of a plugin is a module that sets the encoding to
utf8 globally. Another example is a module that causes a bail-out event after
the first test failure.
=head2 Test2::Bundle::
This namespace is for bundles of tools and plugins. Loading one of these may
load multiple tools and plugins. Modules in this namespace should not implement
tools directly. In general modules in this namespace should load tools and
plugins, then re-export things into the consumers namespace.
=head2 Test2::Require::
This namespace is for modules that cause a test to be skipped when conditions
do not allow it to run. Examples would be modules that skip the test on older
perls, or when non-essential modules have not been installed.
=head2 Test2::Formatter::
Formatters live under this namespace. L<Test2::Formatter::TAP> is the only
formatter currently. It is acceptable for third party distributions to create
new formatters under this namespace.
=head2 Test2::Event::
Events live under this namespace. It is considered acceptable for third party
distributions to add new event types in this namespace.
=head2 Test2::Hub::
Hub subclasses (and some hub utility objects) live under this namespace. It is
perfectly reasonable for third party distributions to add new hub subclasses in
this namespace.
=head2 Test2::IPC::
The IPC subsystem lives in this namespace. There are not many good reasons to
add anything to this namespace, with exception of IPC drivers.
=head3 Test2::IPC::Driver::
IPC drivers live in this namespace. It is fine to create new IPC drivers and to
put them in this namespace.
=head2 Test2::Util::
This namespace is for general utilities used by testing tools. Please be
considerate when adding new modules to this namespace.
=head2 Test2::API::
This is for Test2 API and related packages.
=head2 Test2::
The Test2:: namespace is intended for extensions and frameworks. Tools,
Plugins, etc should not go directly into this namespace. However extensions
that are used to build tools and plugins may go here.
In short: If the module exports anything that should be run directly by a test
script it should probably NOT go directly into C<Test2::XXX>.
=head1 SEE ALSO
L<Test2::API> - Primary API functions.
L<Test2::API::Context> - Detailed documentation of the context object.
L<Test2::IPC> - The IPC system used for threading/fork support.
L<Test2::Formatter> - Formatters such as TAP live here.
L<Test2::Event> - Events live in this namespace.
L<Test2::Hub> - All events eventually funnel through a hub. Custom hubs are how
C<intercept()> and C<run_subtest()> are implemented.
=head1 CONTACTING US
Many Test2 developers and users lurk on L<irc://irc.perl.org/#perl-qa> and
L<irc://irc.perl.org/#toolchain>. We also have a slack team that can be joined
by anyone with an C<@cpan.org> email address L<https://perl-test2.slack.com/>
If you do not have an C<@cpan.org> email you can ask for a slack invite by
emailing Chad Granum E<lt>exodist@cpan.orgE<gt>.
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

1689
t/lib/Test2/API.pm Normal file

File diff suppressed because it is too large Load diff

180
t/lib/Test2/API/Breakage.pm Normal file
View file

@ -0,0 +1,180 @@
package Test2::API::Breakage;
use strict;
use warnings;
our $VERSION = '1.302175';
use Test2::Util qw/pkg_to_file/;
our @EXPORT_OK = qw{
upgrade_suggested
upgrade_required
known_broken
};
BEGIN { require Exporter; our @ISA = qw(Exporter) }
sub upgrade_suggested {
return (
'Test::Exception' => '0.42',
'Test::FITesque' => '0.04',
'Test::Module::Used' => '0.2.5',
'Test::Moose::More' => '0.025',
);
}
sub upgrade_required {
return (
'Test::Builder::Clutch' => '0.07',
'Test::Dist::VersionSync' => '1.1.4',
'Test::Modern' => '0.012',
'Test::SharedFork' => '0.34',
'Test::Alien' => '0.04',
'Test::UseAllModules' => '0.14',
'Test::More::Prefix' => '0.005',
'Test2::Tools::EventDumper' => 0.000007,
'Test2::Harness' => 0.000013,
'Test::DBIx::Class::Schema' => '1.0.9',
'Test::Clustericious::Cluster' => '0.30',
);
}
sub known_broken {
return (
'Net::BitTorrent' => '0.052',
'Test::Able' => '0.11',
'Test::Aggregate' => '0.373',
'Test::Flatten' => '0.11',
'Test::Group' => '0.20',
'Test::ParallelSubtest' => '0.05',
'Test::Pretty' => '0.32',
'Test::Wrapper' => '0.3.0',
'Log::Dispatch::Config::TestLog' => '0.02',
);
}
# Not reportable:
# Device::Chip => 0.07 - Tests will not pass, but not broken if already installed, also no fixed version we can upgrade to.
sub report {
my $class = shift;
my ($require) = @_;
my %suggest = __PACKAGE__->upgrade_suggested();
my %required = __PACKAGE__->upgrade_required();
my %broken = __PACKAGE__->known_broken();
my @warn;
for my $mod (keys %suggest) {
my $file = pkg_to_file($mod);
next unless $INC{$file} || ($require && eval { require $file; 1 });
my $want = $suggest{$mod};
next if eval { $mod->VERSION($want); 1 };
my $error = $@;
chomp $error;
push @warn => " * Module '$mod' is outdated, we recommed updating above $want. error was: '$error'; INC is $INC{$file}";
}
for my $mod (keys %required) {
my $file = pkg_to_file($mod);
next unless $INC{$file} || ($require && eval { require $file; 1 });
my $want = $required{$mod};
next if eval { $mod->VERSION($want); 1 };
push @warn => " * Module '$mod' is outdated and known to be broken, please update to $want or higher.";
}
for my $mod (keys %broken) {
my $file = pkg_to_file($mod);
next unless $INC{$file} || ($require && eval { require $file; 1 });
my $tested = $broken{$mod};
push @warn => " * Module '$mod' is known to be broken in version $tested and below, newer versions have not been tested. You have: " . $mod->VERSION;
}
return @warn;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::API::Breakage - What breaks at what version
=head1 DESCRIPTION
This module provides lists of modules that are broken, or have been broken in
the past, when upgrading L<Test::Builder> to use L<Test2>.
=head1 FUNCTIONS
These can be imported, or called as methods on the class.
=over 4
=item %mod_ver = upgrade_suggested()
=item %mod_ver = Test2::API::Breakage->upgrade_suggested()
This returns key/value pairs. The key is the module name, the value is the
version number. If the installed version of the module is at or below the
specified one then an upgrade would be a good idea, but not strictly necessary.
=item %mod_ver = upgrade_required()
=item %mod_ver = Test2::API::Breakage->upgrade_required()
This returns key/value pairs. The key is the module name, the value is the
version number. If the installed version of the module is at or below the
specified one then an upgrade is required for the module to work properly.
=item %mod_ver = known_broken()
=item %mod_ver = Test2::API::Breakage->known_broken()
This returns key/value pairs. The key is the module name, the value is the
version number. If the installed version of the module is at or below the
specified one then the module will not work. A newer version may work, but is
not tested or verified.
=back
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

1019
t/lib/Test2/API/Context.pm Normal file

File diff suppressed because it is too large Load diff

822
t/lib/Test2/API/Instance.pm Normal file
View file

@ -0,0 +1,822 @@
package Test2::API::Instance;
use strict;
use warnings;
our $VERSION = '1.302175';
our @CARP_NOT = qw/Test2::API Test2::API::Instance Test2::IPC::Driver Test2::Formatter/;
use Carp qw/confess carp/;
use Scalar::Util qw/reftype/;
use Test2::Util qw/get_tid USE_THREADS CAN_FORK pkg_to_file try CAN_SIGSYS/;
use Test2::EventFacet::Trace();
use Test2::API::Stack();
use Test2::Util::HashBase qw{
_pid _tid
no_wait
finalized loaded
ipc stack formatter
contexts
add_uuid_via
-preload
ipc_disabled
ipc_polling
ipc_drivers
ipc_timeout
formatters
exit_callbacks
post_load_callbacks
context_acquire_callbacks
context_init_callbacks
context_release_callbacks
pre_subtest_callbacks
};
sub DEFAULT_IPC_TIMEOUT() { 30 }
sub pid { $_[0]->{+_PID} }
sub tid { $_[0]->{+_TID} }
# Wrap around the getters that should call _finalize.
BEGIN {
for my $finalizer (IPC, FORMATTER) {
my $orig = __PACKAGE__->can($finalizer);
my $new = sub {
my $self = shift;
$self->_finalize unless $self->{+FINALIZED};
$self->$orig;
};
no strict 'refs';
no warnings 'redefine';
*{$finalizer} = $new;
}
}
sub has_ipc { !!$_[0]->{+IPC} }
sub import {
my $class = shift;
return unless @_;
my ($ref) = @_;
$$ref = $class->new;
}
sub init { $_[0]->reset }
sub start_preload {
my $self = shift;
confess "preload cannot be started, Test2::API has already been initialized"
if $self->{+FINALIZED} || $self->{+LOADED};
return $self->{+PRELOAD} = 1;
}
sub stop_preload {
my $self = shift;
return 0 unless $self->{+PRELOAD};
$self->{+PRELOAD} = 0;
$self->post_preload_reset();
return 1;
}
sub post_preload_reset {
my $self = shift;
delete $self->{+_PID};
delete $self->{+_TID};
$self->{+ADD_UUID_VIA} = undef unless exists $self->{+ADD_UUID_VIA};
$self->{+CONTEXTS} = {};
$self->{+FORMATTERS} = [];
$self->{+FINALIZED} = undef;
$self->{+IPC} = undef;
$self->{+IPC_DISABLED} = $ENV{T2_NO_IPC} ? 1 : 0;
$self->{+IPC_TIMEOUT} = DEFAULT_IPC_TIMEOUT() unless defined $self->{+IPC_TIMEOUT};
$self->{+LOADED} = 0;
$self->{+STACK} ||= Test2::API::Stack->new;
}
sub reset {
my $self = shift;
delete $self->{+_PID};
delete $self->{+_TID};
$self->{+ADD_UUID_VIA} = undef;
$self->{+CONTEXTS} = {};
$self->{+IPC_DRIVERS} = [];
$self->{+IPC_POLLING} = undef;
$self->{+FORMATTERS} = [];
$self->{+FORMATTER} = undef;
$self->{+FINALIZED} = undef;
$self->{+IPC} = undef;
$self->{+IPC_DISABLED} = $ENV{T2_NO_IPC} ? 1 : 0;
$self->{+IPC_TIMEOUT} = DEFAULT_IPC_TIMEOUT() unless defined $self->{+IPC_TIMEOUT};
$self->{+NO_WAIT} = 0;
$self->{+LOADED} = 0;
$self->{+EXIT_CALLBACKS} = [];
$self->{+POST_LOAD_CALLBACKS} = [];
$self->{+CONTEXT_ACQUIRE_CALLBACKS} = [];
$self->{+CONTEXT_INIT_CALLBACKS} = [];
$self->{+CONTEXT_RELEASE_CALLBACKS} = [];
$self->{+PRE_SUBTEST_CALLBACKS} = [];
$self->{+STACK} = Test2::API::Stack->new;
}
sub _finalize {
my $self = shift;
my ($caller) = @_;
$caller ||= [caller(1)];
confess "Attempt to initialize Test2::API during preload"
if $self->{+PRELOAD};
$self->{+FINALIZED} = $caller;
$self->{+_PID} = $$ unless defined $self->{+_PID};
$self->{+_TID} = get_tid() unless defined $self->{+_TID};
unless ($self->{+FORMATTER}) {
my ($formatter, $source);
if ($ENV{T2_FORMATTER}) {
$source = "set by the 'T2_FORMATTER' environment variable";
if ($ENV{T2_FORMATTER} =~ m/^(\+)?(.*)$/) {
$formatter = $1 ? $2 : "Test2::Formatter::$2"
}
else {
$formatter = '';
}
}
elsif (@{$self->{+FORMATTERS}}) {
($formatter) = @{$self->{+FORMATTERS}};
$source = "Most recently added";
}
else {
$formatter = 'Test2::Formatter::TAP';
$source = 'default formatter';
}
unless (ref($formatter) || $formatter->can('write')) {
my $file = pkg_to_file($formatter);
my ($ok, $err) = try { require $file };
unless ($ok) {
my $line = "* COULD NOT LOAD FORMATTER '$formatter' ($source) *";
my $border = '*' x length($line);
die "\n\n $border\n $line\n $border\n\n$err";
}
}
$self->{+FORMATTER} = $formatter;
}
# Turn on IPC if threads are on, drivers are registered, or the Test2::IPC
# module is loaded.
return if $self->{+IPC_DISABLED};
return unless USE_THREADS || $INC{'Test2/IPC.pm'} || @{$self->{+IPC_DRIVERS}};
# Turn on polling by default, people expect it.
$self->enable_ipc_polling;
unless (@{$self->{+IPC_DRIVERS}}) {
my ($ok, $error) = try { require Test2::IPC::Driver::Files };
die $error unless $ok;
push @{$self->{+IPC_DRIVERS}} => 'Test2::IPC::Driver::Files';
}
for my $driver (@{$self->{+IPC_DRIVERS}}) {
next unless $driver->can('is_viable') && $driver->is_viable;
$self->{+IPC} = $driver->new or next;
return;
}
die "IPC has been requested, but no viable drivers were found. Aborting...\n";
}
sub formatter_set { $_[0]->{+FORMATTER} ? 1 : 0 }
sub add_formatter {
my $self = shift;
my ($formatter) = @_;
unshift @{$self->{+FORMATTERS}} => $formatter;
return unless $self->{+FINALIZED};
# Why is the @CARP_NOT entry not enough?
local %Carp::Internal = %Carp::Internal;
$Carp::Internal{'Test2::Formatter'} = 1;
carp "Formatter $formatter loaded too late to be used as the global formatter";
}
sub add_context_acquire_callback {
my $self = shift;
my ($code) = @_;
my $rtype = reftype($code) || "";
confess "Context-acquire callbacks must be coderefs"
unless $code && $rtype eq 'CODE';
push @{$self->{+CONTEXT_ACQUIRE_CALLBACKS}} => $code;
}
sub add_context_init_callback {
my $self = shift;
my ($code) = @_;
my $rtype = reftype($code) || "";
confess "Context-init callbacks must be coderefs"
unless $code && $rtype eq 'CODE';
push @{$self->{+CONTEXT_INIT_CALLBACKS}} => $code;
}
sub add_context_release_callback {
my $self = shift;
my ($code) = @_;
my $rtype = reftype($code) || "";
confess "Context-release callbacks must be coderefs"
unless $code && $rtype eq 'CODE';
push @{$self->{+CONTEXT_RELEASE_CALLBACKS}} => $code;
}
sub add_post_load_callback {
my $self = shift;
my ($code) = @_;
my $rtype = reftype($code) || "";
confess "Post-load callbacks must be coderefs"
unless $code && $rtype eq 'CODE';
push @{$self->{+POST_LOAD_CALLBACKS}} => $code;
$code->() if $self->{+LOADED};
}
sub add_pre_subtest_callback {
my $self = shift;
my ($code) = @_;
my $rtype = reftype($code) || "";
confess "Pre-subtest callbacks must be coderefs"
unless $code && $rtype eq 'CODE';
push @{$self->{+PRE_SUBTEST_CALLBACKS}} => $code;
}
sub load {
my $self = shift;
unless ($self->{+LOADED}) {
confess "Attempt to initialize Test2::API during preload"
if $self->{+PRELOAD};
$self->{+_PID} = $$ unless defined $self->{+_PID};
$self->{+_TID} = get_tid() unless defined $self->{+_TID};
# This is for https://github.com/Test-More/test-more/issues/16
# and https://rt.perl.org/Public/Bug/Display.html?id=127774
# END blocks run in reverse order. This insures the END block is loaded
# as late as possible. It will not solve all cases, but it helps.
eval "END { Test2::API::test2_set_is_end() }; 1" or die $@;
$self->{+LOADED} = 1;
$_->() for @{$self->{+POST_LOAD_CALLBACKS}};
}
return $self->{+LOADED};
}
sub add_exit_callback {
my $self = shift;
my ($code) = @_;
my $rtype = reftype($code) || "";
confess "End callbacks must be coderefs"
unless $code && $rtype eq 'CODE';
push @{$self->{+EXIT_CALLBACKS}} => $code;
}
sub ipc_disable {
my $self = shift;
confess "Attempt to disable IPC after it has been initialized"
if $self->{+IPC};
$self->{+IPC_DISABLED} = 1;
}
sub add_ipc_driver {
my $self = shift;
my ($driver) = @_;
unshift @{$self->{+IPC_DRIVERS}} => $driver;
return unless $self->{+FINALIZED};
# Why is the @CARP_NOT entry not enough?
local %Carp::Internal = %Carp::Internal;
$Carp::Internal{'Test2::IPC::Driver'} = 1;
carp "IPC driver $driver loaded too late to be used as the global ipc driver";
}
sub enable_ipc_polling {
my $self = shift;
$self->{+_PID} = $$ unless defined $self->{+_PID};
$self->{+_TID} = get_tid() unless defined $self->{+_TID};
$self->add_context_init_callback(
# This is called every time a context is created, it needs to be fast.
# $_[0] is a context object
sub {
return unless $self->{+IPC_POLLING};
return unless $self->{+IPC};
return unless $self->{+IPC}->pending();
return $_[0]->{hub}->cull;
}
) unless defined $self->ipc_polling;
$self->set_ipc_polling(1);
}
sub get_ipc_pending {
my $self = shift;
return -1 unless $self->{+IPC};
$self->{+IPC}->pending();
}
sub _check_pid {
my $self = shift;
my ($pid) = @_;
return kill(0, $pid);
}
sub set_ipc_pending {
my $self = shift;
return unless $self->{+IPC};
my ($val) = @_;
confess "value is required for set_ipc_pending"
unless $val;
$self->{+IPC}->set_pending($val);
}
sub disable_ipc_polling {
my $self = shift;
return unless defined $self->{+IPC_POLLING};
$self->{+IPC_POLLING} = 0;
}
sub _ipc_wait {
my ($timeout) = @_;
my $fail = 0;
$timeout = DEFAULT_IPC_TIMEOUT() unless defined $timeout;
my $ok = eval {
if (CAN_FORK) {
local $SIG{ALRM} = sub { die "Timeout waiting on child processes" };
alarm $timeout;
while (1) {
my $pid = CORE::wait();
my $err = $?;
last if $pid == -1;
next unless $err;
$fail++;
my $sig = $err & 127;
my $exit = $err >> 8;
warn "Process $pid did not exit cleanly (wstat: $err, exit: $exit, sig: $sig)\n";
}
alarm 0;
}
if (USE_THREADS) {
my $start = time;
while (1) {
last unless threads->list();
die "Timeout waiting on child thread" if time - $start >= $timeout;
sleep 1;
for my $t (threads->list) {
# threads older than 1.34 do not have this :-(
next if $t->can('is_joinable') && !$t->is_joinable;
$t->join;
# In older threads we cannot check if a thread had an error unless
# we control it and its return.
my $err = $t->can('error') ? $t->error : undef;
next unless $err;
my $tid = $t->tid();
$fail++;
chomp($err);
warn "Thread $tid did not end cleanly: $err\n";
}
}
}
1;
};
my $error = $@;
return 0 if $ok && !$fail;
warn $error unless $ok;
return 255;
}
sub set_exit {
my $self = shift;
return if $self->{+PRELOAD};
my $exit = $?;
my $new_exit = $exit;
if ($INC{'Test/Builder.pm'} && $Test::Builder::VERSION ne $Test2::API::VERSION) {
print STDERR <<" EOT";
********************************************************************************
* *
* Test::Builder -- Test2::API version mismatch detected *
* *
********************************************************************************
Test2::API Version: $Test2::API::VERSION
Test::Builder Version: $Test::Builder::VERSION
This is not a supported configuration, you will have problems.
EOT
}
for my $ctx (values %{$self->{+CONTEXTS}}) {
next unless $ctx;
next if $ctx->_aborted && ${$ctx->_aborted};
# Only worry about contexts in this PID
my $trace = $ctx->trace || next;
next unless $trace->pid && $trace->pid == $$;
# Do not worry about contexts that have no hub
my $hub = $ctx->hub || next;
# Do not worry if the state came to a sudden end.
next if $hub->bailed_out;
next if defined $hub->skip_reason;
# now we worry
$trace->alert("context object was never released! This means a testing tool is behaving very badly");
$exit = 255;
$new_exit = 255;
}
if (!defined($self->{+_PID}) or !defined($self->{+_TID}) or $self->{+_PID} != $$ or $self->{+_TID} != get_tid()) {
$? = $exit;
return;
}
my @hubs = $self->{+STACK} ? $self->{+STACK}->all : ();
if (@hubs and $self->{+IPC} and !$self->{+NO_WAIT}) {
local $?;
my %seen;
for my $hub (reverse @hubs) {
my $ipc = $hub->ipc or next;
next if $seen{$ipc}++;
$ipc->waiting();
}
my $ipc_exit = _ipc_wait($self->{+IPC_TIMEOUT});
$new_exit ||= $ipc_exit;
}
# None of this is necessary if we never got a root hub
if(my $root = shift @hubs) {
my $trace = Test2::EventFacet::Trace->new(
frame => [__PACKAGE__, __FILE__, 0, __PACKAGE__ . '::END'],
detail => __PACKAGE__ . ' END Block finalization',
);
my $ctx = Test2::API::Context->new(
trace => $trace,
hub => $root,
);
if (@hubs) {
$ctx->diag("Test ended with extra hubs on the stack!");
$new_exit = 255;
}
unless ($root->no_ending) {
local $?;
$root->finalize($trace) unless $root->ended;
$_->($ctx, $exit, \$new_exit) for @{$self->{+EXIT_CALLBACKS}};
$new_exit ||= $root->failed;
$new_exit ||= 255 unless $root->is_passing;
}
}
$new_exit = 255 if $new_exit > 255;
if ($new_exit && eval { require Test2::API::Breakage; 1 }) {
my @warn = Test2::API::Breakage->report();
if (@warn) {
print STDERR "\nYou have loaded versions of test modules known to have problems with Test2.\nThis could explain some test failures.\n";
print STDERR "$_\n" for @warn;
print STDERR "\n";
}
}
$? = $new_exit;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::API::Instance - Object used by Test2::API under the hood
=head1 DESCRIPTION
This object encapsulates the global shared state tracked by
L<Test2>. A single global instance of this package is stored (and
obscured) by the L<Test2::API> package.
There is no reason to directly use this package. This package is documented for
completeness. This package can change, or go away completely at any time.
Directly using, or monkeypatching this package is not supported in any way
shape or form.
=head1 SYNOPSIS
use Test2::API::Instance;
my $obj = Test2::API::Instance->new;
=over 4
=item $pid = $obj->pid
PID of this instance.
=item $obj->tid
Thread ID of this instance.
=item $obj->reset()
Reset the object to defaults.
=item $obj->load()
Set the internal state to loaded, and run and stored post-load callbacks.
=item $bool = $obj->loaded
Check if the state is set to loaded.
=item $arrayref = $obj->post_load_callbacks
Get the post-load callbacks.
=item $obj->add_post_load_callback(sub { ... })
Add a post-load callback. If C<load()> has already been called then the callback will
be immediately executed. If C<load()> has not been called then the callback will be
stored and executed later when C<load()> is called.
=item $hashref = $obj->contexts()
Get a hashref of all active contexts keyed by hub id.
=item $arrayref = $obj->context_acquire_callbacks
Get all context acquire callbacks.
=item $arrayref = $obj->context_init_callbacks
Get all context init callbacks.
=item $arrayref = $obj->context_release_callbacks
Get all context release callbacks.
=item $arrayref = $obj->pre_subtest_callbacks
Get all pre-subtest callbacks.
=item $obj->add_context_init_callback(sub { ... })
Add a context init callback. Subs are called every time a context is created. Subs
get the newly created context as their only argument.
=item $obj->add_context_release_callback(sub { ... })
Add a context release callback. Subs are called every time a context is released. Subs
get the released context as their only argument. These callbacks should not
call release on the context.
=item $obj->add_pre_subtest_callback(sub { ... })
Add a pre-subtest callback. Subs are called every time a subtest is
going to be run. Subs get the subtest name, coderef, and any
arguments.
=item $obj->set_exit()
This is intended to be called in an C<END { ... }> block. This will look at
test state and set $?. This will also call any end callbacks, and wait on child
processes/threads.
=item $obj->set_ipc_pending($val)
Tell other processes and threads there is a pending event. C<$val> should be a
unique value no other thread/process will generate.
B<Note:> This will also make the current process see a pending event.
=item $pending = $obj->get_ipc_pending()
This returns -1 if it is not possible to know.
This returns 0 if there are no pending events.
This returns 1 if there are pending events.
=item $timeout = $obj->ipc_timeout;
=item $obj->set_ipc_timeout($timeout);
How long to wait for child processes and threads before aborting.
=item $drivers = $obj->ipc_drivers
Get the list of IPC drivers.
=item $obj->add_ipc_driver($DRIVER_CLASS)
Add an IPC driver to the list. The most recently added IPC driver will become
the global one during initialization. If a driver is added after initialization
has occurred a warning will be generated:
"IPC driver $driver loaded too late to be used as the global ipc driver"
=item $bool = $obj->ipc_polling
Check if polling is enabled.
=item $obj->enable_ipc_polling
Turn on polling. This will cull events from other processes and threads every
time a context is created.
=item $obj->disable_ipc_polling
Turn off IPC polling.
=item $bool = $obj->no_wait
=item $bool = $obj->set_no_wait($bool)
Get/Set no_wait. This option is used to turn off process/thread waiting at exit.
=item $arrayref = $obj->exit_callbacks
Get the exit callbacks.
=item $obj->add_exit_callback(sub { ... })
Add an exit callback. This callback will be called by C<set_exit()>.
=item $bool = $obj->finalized
Check if the object is finalized. Finalization happens when either C<ipc()>,
C<stack()>, or C<format()> are called on the object. Once finalization happens
these fields are considered unchangeable (not enforced here, enforced by
L<Test2>).
=item $ipc = $obj->ipc
Get the one true IPC instance.
=item $obj->ipc_disable
Turn IPC off
=item $bool = $obj->ipc_disabled
Check if IPC is disabled
=item $stack = $obj->stack
Get the one true hub stack.
=item $formatter = $obj->formatter
Get the global formatter. By default this is the C<'Test2::Formatter::TAP'>
package. This could be any package that implements the C<write()> method. This
can also be an instantiated object.
=item $bool = $obj->formatter_set()
Check if a formatter has been set.
=item $obj->add_formatter($class)
=item $obj->add_formatter($obj)
Add a formatter. The most recently added formatter will become the global one
during initialization. If a formatter is added after initialization has occurred
a warning will be generated:
"Formatter $formatter loaded too late to be used as the global formatter"
=item $obj->set_add_uuid_via(sub { ... })
=item $sub = $obj->add_uuid_via()
This allows you to provide a UUID generator. If provided UUIDs will be attached
to all events, hubs, and contexts. This is useful for storing, tracking, and
linking these objects.
The sub you provide should always return a unique identifier. Most things will
expect a proper UUID string, however nothing in Test2::API enforces this.
The sub will receive exactly 1 argument, the type of thing being tagged
'context', 'hub', or 'event'. In the future additional things may be tagged, in
which case new strings will be passed in. These are purely informative, you can
(and usually should) ignore them.
=back
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

226
t/lib/Test2/API/Stack.pm Normal file
View file

@ -0,0 +1,226 @@
package Test2::API::Stack;
use strict;
use warnings;
our $VERSION = '1.302175';
use Test2::Hub();
use Carp qw/confess/;
sub new {
my $class = shift;
return bless [], $class;
}
sub new_hub {
my $self = shift;
my %params = @_;
my $class = delete $params{class} || 'Test2::Hub';
my $hub = $class->new(%params);
if (@$self) {
$hub->inherit($self->[-1], %params);
}
else {
require Test2::API;
$hub->format(Test2::API::test2_formatter()->new_root)
unless $hub->format || exists($params{formatter});
my $ipc = Test2::API::test2_ipc();
if ($ipc && !$hub->ipc && !exists($params{ipc})) {
$hub->set_ipc($ipc);
$ipc->add_hub($hub->hid);
}
}
push @$self => $hub;
$hub;
}
sub top {
my $self = shift;
return $self->new_hub unless @$self;
return $self->[-1];
}
sub peek {
my $self = shift;
return @$self ? $self->[-1] : undef;
}
sub cull {
my $self = shift;
$_->cull for reverse @$self;
}
sub all {
my $self = shift;
return @$self;
}
sub root {
my $self = shift;
return unless @$self;
return $self->[0];
}
sub clear {
my $self = shift;
@$self = ();
}
# Do these last without keywords in order to prevent them from getting used
# when we want the real push/pop.
{
no warnings 'once';
*push = sub {
my $self = shift;
my ($hub) = @_;
$hub->inherit($self->[-1]) if @$self;
push @$self => $hub;
};
*pop = sub {
my $self = shift;
my ($hub) = @_;
confess "No hubs on the stack"
unless @$self;
confess "You cannot pop the root hub"
if 1 == @$self;
confess "Hub stack mismatch, attempted to pop incorrect hub"
unless $self->[-1] == $hub;
pop @$self;
};
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::API::Stack - Object to manage a stack of L<Test2::Hub>
instances.
=head1 ***INTERNALS NOTE***
B<The internals of this package are subject to change at any time!> The public
methods provided will not change in backwards incompatible ways, but the
underlying implementation details might. B<Do not break encapsulation here!>
=head1 DESCRIPTION
This module is used to represent and manage a stack of L<Test2::Hub>
objects. Hubs are usually in a stack so that you can push a new hub into place
that can intercept and handle events differently than the primary hub.
=head1 SYNOPSIS
my $stack = Test2::API::Stack->new;
my $hub = $stack->top;
=head1 METHODS
=over 4
=item $stack = Test2::API::Stack->new()
This will create a new empty stack instance. All arguments are ignored.
=item $hub = $stack->new_hub()
=item $hub = $stack->new_hub(%params)
=item $hub = $stack->new_hub(%params, class => $class)
This will generate a new hub and push it to the top of the stack. Optionally
you can provide arguments that will be passed into the constructor for the
L<Test2::Hub> object.
If you specify the C<< 'class' => $class >> argument, the new hub will be an
instance of the specified class.
Unless your parameters specify C<'formatter'> or C<'ipc'> arguments, the
formatter and IPC instance will be inherited from the current top hub. You can
set the parameters to C<undef> to avoid having a formatter or IPC instance.
If there is no top hub, and you do not ask to leave IPC and formatter undef,
then a new formatter will be created, and the IPC instance from
L<Test2::API> will be used.
=item $hub = $stack->top()
This will return the top hub from the stack. If there is no top hub yet this
will create it.
=item $hub = $stack->peek()
This will return the top hub from the stack. If there is no top hub yet this
will return undef.
=item $stack->cull
This will call C<< $hub->cull >> on all hubs in the stack.
=item @hubs = $stack->all
This will return all the hubs in the stack as a list.
=item $stack->clear
This will completely remove all hubs from the stack. Normally you do not want
to do this, but there are a few valid reasons for it.
=item $stack->push($hub)
This will push the new hub onto the stack.
=item $stack->pop($hub)
This will pop a hub from the stack, if the hub at the top of the stack does not
match the hub you expect (passed in as an argument) it will throw an exception.
=back
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

778
t/lib/Test2/Event.pm Normal file
View file

@ -0,0 +1,778 @@
package Test2::Event;
use strict;
use warnings;
our $VERSION = '1.302175';
use Scalar::Util qw/blessed reftype/;
use Carp qw/croak/;
use Test2::Util::HashBase qw/trace -amnesty uuid -_eid -hubs/;
use Test2::Util::ExternalMeta qw/meta get_meta set_meta delete_meta/;
use Test2::Util qw/pkg_to_file gen_uid/;
use Test2::EventFacet::About();
use Test2::EventFacet::Amnesty();
use Test2::EventFacet::Assert();
use Test2::EventFacet::Control();
use Test2::EventFacet::Error();
use Test2::EventFacet::Info();
use Test2::EventFacet::Meta();
use Test2::EventFacet::Parent();
use Test2::EventFacet::Plan();
use Test2::EventFacet::Trace();
use Test2::EventFacet::Hub();
# Legacy tools will expect this to be loaded now
require Test2::Util::Trace;
my %LOADED_FACETS = (
'about' => 'Test2::EventFacet::About',
'amnesty' => 'Test2::EventFacet::Amnesty',
'assert' => 'Test2::EventFacet::Assert',
'control' => 'Test2::EventFacet::Control',
'errors' => 'Test2::EventFacet::Error',
'info' => 'Test2::EventFacet::Info',
'meta' => 'Test2::EventFacet::Meta',
'parent' => 'Test2::EventFacet::Parent',
'plan' => 'Test2::EventFacet::Plan',
'trace' => 'Test2::EventFacet::Trace',
'hubs' => 'Test2::EventFacet::Hub',
);
sub FACET_TYPES { sort values %LOADED_FACETS }
sub load_facet {
my $class = shift;
my ($facet) = @_;
return $LOADED_FACETS{$facet} if exists $LOADED_FACETS{$facet};
my @check = ($facet);
if ('s' eq substr($facet, -1, 1)) {
push @check => substr($facet, 0, -1);
}
else {
push @check => $facet . 's';
}
my $found;
for my $check (@check) {
my $mod = "Test2::EventFacet::" . ucfirst($facet);
my $file = pkg_to_file($mod);
next unless eval { require $file; 1 };
$found = $mod;
last;
}
return undef unless $found;
$LOADED_FACETS{$facet} = $found;
}
sub causes_fail { 0 }
sub increments_count { 0 }
sub diagnostics { 0 }
sub no_display { 0 }
sub subtest_id { undef }
sub callback { }
sub terminate { () }
sub global { () }
sub sets_plan { () }
sub summary { ref($_[0]) }
sub related {
my $self = shift;
my ($event) = @_;
my $tracea = $self->trace or return undef;
my $traceb = $event->trace or return undef;
my $uuida = $tracea->uuid;
my $uuidb = $traceb->uuid;
if ($uuida && $uuidb) {
return 1 if $uuida eq $uuidb;
return 0;
}
my $siga = $tracea->signature or return undef;
my $sigb = $traceb->signature or return undef;
return 1 if $siga eq $sigb;
return 0;
}
sub add_hub {
my $self = shift;
unshift @{$self->{+HUBS}} => @_;
}
sub add_amnesty {
my $self = shift;
for my $am (@_) {
$am = {%$am} if ref($am) ne 'ARRAY';
$am = Test2::EventFacet::Amnesty->new($am);
push @{$self->{+AMNESTY}} => $am;
}
}
sub eid { $_[0]->{+_EID} ||= gen_uid() }
sub common_facet_data {
my $self = shift;
my %out;
$out{about} = {package => ref($self) || undef};
if (my $uuid = $self->uuid) {
$out{about}->{uuid} = $uuid;
}
$out{about}->{eid} = $self->{+_EID} || $self->eid;
if (my $trace = $self->trace) {
$out{trace} = { %$trace };
}
if (my $hubs = $self->hubs) {
$out{hubs} = $hubs;
}
$out{amnesty} = [map {{ %{$_} }} @{$self->{+AMNESTY}}]
if $self->{+AMNESTY};
if (my $meta = $self->meta_facet_data) {
$out{meta} = $meta;
}
return \%out;
}
sub meta_facet_data {
my $self = shift;
my $key = Test2::Util::ExternalMeta::META_KEY();
my $hash = $self->{$key} or return undef;
return {%$hash};
}
sub facet_data {
my $self = shift;
my $out = $self->common_facet_data;
$out->{about}->{details} = $self->summary || undef;
$out->{about}->{no_display} = $self->no_display || undef;
# Might be undef, we want to preserve that
my $terminate = $self->terminate;
$out->{control} = {
global => $self->global || 0,
terminate => $terminate,
has_callback => $self->can('callback') == \&callback ? 0 : 1,
};
$out->{assert} = {
no_debug => 1, # Legacy behavior
pass => $self->causes_fail ? 0 : 1,
details => $self->summary,
} if $self->increments_count;
$out->{parent} = {hid => $self->subtest_id} if $self->subtest_id;
if (my @plan = $self->sets_plan) {
$out->{plan} = {};
$out->{plan}->{count} = $plan[0] if defined $plan[0];
$out->{plan}->{details} = $plan[2] if defined $plan[2];
if ($plan[1]) {
$out->{plan}->{skip} = 1 if $plan[1] eq 'SKIP';
$out->{plan}->{none} = 1 if $plan[1] eq 'NO PLAN';
}
$out->{control}->{terminate} ||= 0 if $out->{plan}->{skip};
}
if ($self->causes_fail && !$out->{assert}) {
$out->{errors} = [
{
tag => 'FAIL',
fail => 1,
details => $self->summary,
}
];
}
my %IGNORE = (trace => 1, about => 1, control => 1);
my $do_info = !grep { !$IGNORE{$_} } keys %$out;
if ($do_info && !$self->no_display && $self->diagnostics) {
$out->{info} = [
{
tag => 'DIAG',
debug => 1,
details => $self->summary,
}
];
}
return $out;
}
sub facets {
my $self = shift;
my %out;
my $data = $self->facet_data;
my @errors = $self->validate_facet_data($data);
die join "\n" => @errors if @errors;
for my $facet (keys %$data) {
my $class = $self->load_facet($facet);
my $val = $data->{$facet};
unless($class) {
$out{$facet} = $val;
next;
}
my $is_list = reftype($val) eq 'ARRAY' ? 1 : 0;
if ($is_list) {
$out{$facet} = [map { $class->new($_) } @$val];
}
else {
$out{$facet} = $class->new($val);
}
}
return \%out;
}
sub validate_facet_data {
my $class_or_self = shift;
my ($f, %params);
$f = shift if @_ && (reftype($_[0]) || '') eq 'HASH';
%params = @_;
$f ||= $class_or_self->facet_data if blessed($class_or_self);
croak "No facet data" unless $f;
my @errors;
for my $k (sort keys %$f) {
my $fclass = $class_or_self->load_facet($k);
push @errors => "Could not find a facet class for facet '$k'"
if $params{require_facet_class} && !$fclass;
next unless $fclass;
my $v = $f->{$k};
next unless defined($v); # undef is always fine
my $is_list = $fclass->is_list();
my $got_list = reftype($v) eq 'ARRAY' ? 1 : 0;
push @errors => "Facet '$k' should be a list, but got a single item ($v)"
if $is_list && !$got_list;
push @errors => "Facet '$k' should not be a list, but got a a list ($v)"
if $got_list && !$is_list;
}
return @errors;
}
sub nested {
my $self = shift;
Carp::cluck("Use of Test2::Event->nested() is deprecated, use Test2::Event->trace->nested instead")
if $ENV{AUTHOR_TESTING};
if (my $hubs = $self->{+HUBS}) {
return $hubs->[0]->{nested} if @$hubs;
}
my $trace = $self->{+TRACE} or return undef;
return $trace->{nested};
}
sub in_subtest {
my $self = shift;
Carp::cluck("Use of Test2::Event->in_subtest() is deprecated, use Test2::Event->trace->hid instead")
if $ENV{AUTHOR_TESTING};
my $hubs = $self->{+HUBS};
if ($hubs && @$hubs) {
return undef unless $hubs->[0]->{nested};
return $hubs->[0]->{hid}
}
my $trace = $self->{+TRACE} or return undef;
return undef unless $trace->{nested};
return $trace->{hid};
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::Event - Base class for events
=head1 DESCRIPTION
Base class for all event objects that get passed through
L<Test2>.
=head1 SYNOPSIS
package Test2::Event::MyEvent;
use strict;
use warnings;
# This will make our class an event subclass (required)
use base 'Test2::Event';
# Add some accessors (optional)
# You are not obligated to use HashBase, you can use any object tool you
# want, or roll your own accessors.
use Test2::Util::HashBase qw/foo bar baz/;
# Use this if you want the legacy API to be written for you, for this to
# work you will need to implement a facet_data() method.
use Test2::Util::Facets2Legacy;
# Chance to initialize some defaults
sub init {
my $self = shift;
# no other args in @_
$self->set_foo('xxx') unless defined $self->foo;
...
}
# This is the new way for events to convey data to the Test2 system
sub facet_data {
my $self = shift;
# Get common facets such as 'about', 'trace' 'amnesty', and 'meta'
my $facet_data = $self->common_facet_data();
# Are you making an assertion?
$facet_data->{assert} = {pass => 1, details => 'my assertion'};
...
return $facet_data;
}
1;
=head1 METHODS
=head2 GENERAL
=over 4
=item $trace = $e->trace
Get a snapshot of the L<Test2::EventFacet::Trace> as it was when this event was
generated
=item $bool_or_undef = $e->related($e2)
Check if 2 events are related. In this case related means their traces share a
signature meaning they were created with the same context (or at the very least
by contexts which share an id, which is the same thing unless someone is doing
something very bad).
This can be used to reliably link multiple events created by the same tool. For
instance a failing test like C<ok(0, "fail"> will generate 2 events, one being
a L<Test2::Event::Ok>, the other being a L<Test2::Event::Diag>, both of these
events are related having been created under the same context and by the same
initial tool (though multiple tools may have been nested under the initial
one).
This will return C<undef> if the relationship cannot be checked, which happens
if either event has an incomplete or missing trace. This will return C<0> if
the traces are complete, but do not match. C<1> will be returned if there is a
match.
=item $e->add_amnesty({tag => $TAG, details => $DETAILS});
This can be used to add amnesty to this event. Amnesty only effects failing
assertions in most cases, but some formatters may display them for passing
assertions, or even non-assertions as well.
Amnesty will prevent a failed assertion from causing the overall test to fail.
In other words it marks a failure as expected and allowed.
B<Note:> This is how 'TODO' is implemented under the hood. TODO is essentially
amnesty with the 'TODO' tag. The details are the reason for the TODO.
=item $uuid = $e->uuid
If UUID tagging is enabled (See L<Test::API>) then any event that has made its
way through a hub will be tagged with a UUID. A newly created event will not
yet be tagged in most cases.
=item $class = $e->load_facet($name)
This method is used to load a facet by name (or key). It will attempt to load
the facet class, if it succeeds it will return the class it loaded. If it fails
it will return C<undef>. This caches the result at the class level so that
future calls will be faster.
The C<$name> variable should be the key used to access the facet in a facets
hashref. For instance the assertion facet has the key 'assert', the information
facet has the 'info' key, and the error facet has the key 'errors'. You may
include or omit the 's' at the end of the name, the method is smart enough to
try both the 's' and no-'s' forms, it will check what you provided first, and
if that is not found it will add or strip the 's and try again.
=item @classes = $e->FACET_TYPES()
=item @classes = Test2::Event->FACET_TYPES()
This returns a list of all facets that have been loaded using the
C<load_facet()> method. This will not return any classes that have not been
loaded, or have been loaded directly without a call to C<load_facet()>.
B<Note:> The core facet types are automatically loaded and populated in this
list.
=back
=head2 NEW API
=over 4
=item $hashref = $e->common_facet_data();
This can be used by subclasses to generate a starting facet data hashref. This
will populate the hashref with the trace, meta, amnesty, and about facets.
These facets are nearly always produced the same way for all events.
=item $hashref = $e->facet_data()
If you do not override this then the default implementation will attempt to
generate facets from the legacy API. This generation is limited only to what
the legacy API can provide. It is recommended that you override this method and
write out explicit facet data.
=item $hashref = $e->facets()
This takes the hashref from C<facet_data()> and blesses each facet into the
proper C<Test2::EventFacet::*> subclass. If no class can be found for any given
facet it will be passed along unchanged.
=item @errors = $e->validate_facet_data();
=item @errors = $e->validate_facet_data(%params);
=item @errors = $e->validate_facet_data(\%facets, %params);
=item @errors = Test2::Event->validate_facet_data(%params);
=item @errors = Test2::Event->validate_facet_data(\%facets, %params);
This method will validate facet data and return a list of errors. If no errors
are found this will return an empty list.
This can be called as an object method with no arguments, in which case the
C<facet_data()> method will be called to get the facet data to be validated.
When used as an object method the C<\%facet_data> argument may be omitted.
When used as a class method the C<\%facet_data> argument is required.
Remaining arguments will be slurped into a C<%params> hash.
Currently only 1 parameter is defined:
=over 4
=item require_facet_class => $BOOL
When set to true (default is false) this will reject any facets where a facet
class cannot be found. Normally facets without classes are assumed to be custom
and are ignored.
=back
=back
=head3 WHAT ARE FACETS?
Facets are how events convey their purpose to the Test2 internals and
formatters. An event without facets will have no intentional effect on the
overall test state, and will not be displayed at all by most formatters, except
perhaps to say that an event of an unknown type was seen.
Facets are produced by the C<facet_data()> subroutine, which you should
nearly-always override. C<facet_data()> is expected to return a hashref where
each key is the facet type, and the value is either a hashref with the data for
that facet, or an array of hashrefs. Some facets must be defined as single
hashrefs, some must be defined as an array of hashrefs, No facets allow both.
C<facet_data()> B<MUST NOT> bless the data it returns, the main hashref, and
nested facet hashrefs B<MUST> be bare, though items contained within each
facet may be blessed. The data returned by this method B<should> also be copies
of the internal data in order to prevent accidental state modification.
C<facets()> takes the data from C<facet_data()> and blesses it into the
C<Test2::EventFacet::*> packages. This is rarely used however, the EventFacet
packages are primarily for convenience and documentation. The EventFacet
classes are not used at all internally, instead the raw data is used.
Here is a list of facet types by package. The packages are not used internally,
but are where the documentation for each type is kept.
B<Note:> Every single facet type has the C<'details'> field. This field is
always intended for human consumption, and when provided, should explain the
'why' for the facet. All other fields are facet specific.
=over 4
=item about => {...}
L<Test2::EventFacet::About>
This contains information about the event itself such as the event package
name. The C<details> field for this facet is an overall summary of the event.
=item assert => {...}
L<Test2::EventFacet::Assert>
This facet is used if an assertion was made. The C<details> field of this facet
is the description of the assertion.
=item control => {...}
L<Test2::EventFacet::Control>
This facet is used to tell the L<Test2::Event::Hub> about special actions the
event causes. Things like halting all testing, terminating the current test,
etc. In this facet the C<details> field explains why any special action was
taken.
B<Note:> This is how bail-out is implemented.
=item meta => {...}
L<Test2::EventFacet::Meta>
The meta facet contains all the meta-data attached to the event. In this case
the C<details> field has no special meaning, but may be present if something
sets the 'details' meta-key on the event.
=item parent => {...}
L<Test2::EventFacet::Parent>
This facet contains nested events and similar details for subtests. In this
facet the C<details> field will typically be the name of the subtest.
=item plan => {...}
L<Test2::EventFacet::Plan>
This facet tells the system that a plan has been set. The C<details> field of
this is usually left empty, but when present explains why the plan is what it
is, this is most useful if the plan is to skip-all.
=item trace => {...}
L<Test2::EventFacet::Trace>
This facet contains information related to when and where the event was
generated. This is how the test file and line number of a failure is known.
This facet can also help you to tell if tests are related.
In this facet the C<details> field overrides the "failed at test_file.t line
42." message provided on assertion failure.
=item amnesty => [{...}, ...]
L<Test2::EventFacet::Amnesty>
The amnesty facet is a list instead of a single item, this is important as
amnesty can come from multiple places at once.
For each instance of amnesty the C<details> field explains why amnesty was
granted.
B<Note:> Outside of formatters amnesty only acts to forgive a failing
assertion.
=item errors => [{...}, ...]
L<Test2::EventFacet::Error>
The errors facet is a list instead of a single item, any number of errors can
be listed. In this facet C<details> describes the error, or may contain the raw
error message itself (such as an exception). In perl exception may be blessed
objects, as such the raw data for this facet may contain nested items which are
blessed.
Not all errors are considered fatal, there is a C<fail> field that must be set
for an error to cause the test to fail.
B<Note:> This facet is unique in that the field name is 'errors' while the
package is 'Error'. This is because this is the only facet type that is both a
list, and has a name where the plural is not the same as the singular. This may
cause some confusion, but I feel it will be less confusing than the
alternative.
=item info => [{...}, ...]
L<Test2::EventFacet::Info>
The 'info' facet is a list instead of a single item, any quantity of extra
information can be attached to an event. Some information may be critical
diagnostics, others may be simply commentary in nature, this is determined by
the C<debug> flag.
For this facet the C<details> flag is the info itself. This info may be a
string, or it may be a data structure to display. This is one of the few facet
types that may contain blessed items.
=back
=head2 LEGACY API
=over 4
=item $bool = $e->causes_fail
Returns true if this event should result in a test failure. In general this
should be false.
=item $bool = $e->increments_count
Should be true if this event should result in a test count increment.
=item $e->callback($hub)
If your event needs to have extra effects on the L<Test2::Hub> you can override
this method.
This is called B<BEFORE> your event is passed to the formatter.
=item $num = $e->nested
If this event is nested inside of other events, this should be the depth of
nesting. (This is mainly for subtests)
=item $bool = $e->global
Set this to true if your event is global, that is ALL threads and processes
should see it no matter when or where it is generated. This is not a common
thing to want, it is used by bail-out and skip_all to end testing.
=item $code = $e->terminate
This is called B<AFTER> your event has been passed to the formatter. This
should normally return undef, only change this if your event should cause the
test to exit immediately.
If you want this event to cause the test to exit you should return the exit
code here. Exit code of 0 means exit success, any other integer means exit with
failure.
This is used by L<Test2::Event::Plan> to exit 0 when the plan is
'skip_all'. This is also used by L<Test2::Event:Bail> to force the test
to exit with a failure.
This is called after the event has been sent to the formatter in order to
ensure the event is seen and understood.
=item $msg = $e->summary
This is intended to be a human readable summary of the event. This should
ideally only be one line long, but you can use multiple lines if necessary. This
is intended for human consumption. You do not need to make it easy for machines
to understand.
The default is to simply return the event package name.
=item ($count, $directive, $reason) = $e->sets_plan()
Check if this event sets the testing plan. It will return an empty list if it
does not. If it does set the plan it will return a list of 1 to 3 items in
order: Expected Test Count, Test Directive, Reason for directive.
=item $bool = $e->diagnostics
True if the event contains diagnostics info. This is useful because a
non-verbose harness may choose to hide events that are not in this category.
Some formatters may choose to send these to STDERR instead of STDOUT to ensure
they are seen.
=item $bool = $e->no_display
False by default. This will return true on events that should not be displayed
by formatters.
=item $id = $e->in_subtest
If the event is inside a subtest this should have the subtest ID.
=item $id = $e->subtest_id
If the event is a final subtest event, this should contain the subtest ID.
=back
=head1 THIRD PARTY META-DATA
This object consumes L<Test2::Util::ExternalMeta> which provides a consistent
way for you to attach meta-data to instances of this class. This is useful for
tools, plugins, and other extensions.
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

109
t/lib/Test2/Event/Bail.pm Normal file
View file

@ -0,0 +1,109 @@
package Test2::Event::Bail;
use strict;
use warnings;
our $VERSION = '1.302175';
BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) }
use Test2::Util::HashBase qw{reason buffered};
# Make sure the tests terminate
sub terminate { 255 };
sub global { 1 };
sub causes_fail { 1 }
sub summary {
my $self = shift;
return "Bail out! " . $self->{+REASON}
if $self->{+REASON};
return "Bail out!";
}
sub diagnostics { 1 }
sub facet_data {
my $self = shift;
my $out = $self->common_facet_data;
$out->{control} = {
global => 1,
halt => 1,
details => $self->{+REASON},
terminate => 255,
};
return $out;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::Event::Bail - Bailout!
=head1 DESCRIPTION
The bailout event is generated when things go horribly wrong and you need to
halt all testing in the current file.
=head1 SYNOPSIS
use Test2::API qw/context/;
use Test2::Event::Bail;
my $ctx = context();
my $event = $ctx->bail('Stuff is broken');
=head1 METHODS
Inherits from L<Test2::Event>. Also defines:
=over 4
=item $reason = $e->reason
The reason for the bailout.
=back
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

99
t/lib/Test2/Event/Diag.pm Normal file
View file

@ -0,0 +1,99 @@
package Test2::Event::Diag;
use strict;
use warnings;
our $VERSION = '1.302175';
BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) }
use Test2::Util::HashBase qw/message/;
sub init {
$_[0]->{+MESSAGE} = 'undef' unless defined $_[0]->{+MESSAGE};
}
sub summary { $_[0]->{+MESSAGE} }
sub diagnostics { 1 }
sub facet_data {
my $self = shift;
my $out = $self->common_facet_data;
$out->{info} = [
{
tag => 'DIAG',
debug => 1,
details => $self->{+MESSAGE},
}
];
return $out;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::Event::Diag - Diag event type
=head1 DESCRIPTION
Diagnostics messages, typically rendered to STDERR.
=head1 SYNOPSIS
use Test2::API qw/context/;
use Test2::Event::Diag;
my $ctx = context();
my $event = $ctx->diag($message);
=head1 ACCESSORS
=over 4
=item $diag->message
The message for the diag.
=back
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

View file

@ -0,0 +1,97 @@
package Test2::Event::Encoding;
use strict;
use warnings;
our $VERSION = '1.302175';
use Carp qw/croak/;
BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) }
use Test2::Util::HashBase qw/encoding/;
sub init {
my $self = shift;
defined $self->{+ENCODING} or croak "'encoding' is a required attribute";
}
sub summary { 'Encoding set to ' . $_[0]->{+ENCODING} }
sub facet_data {
my $self = shift;
my $out = $self->common_facet_data;
$out->{control}->{encoding} = $self->{+ENCODING};
$out->{about}->{details} = $self->summary;
return $out;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::Event::Encoding - Set the encoding for the output stream
=head1 DESCRIPTION
The encoding event is generated when a test file wants to specify the encoding
to be used when formatting its output. This event is intended to be produced
by formatter classes and used for interpreting test names, message contents,
etc.
=head1 SYNOPSIS
use Test2::API qw/context/;
use Test2::Event::Encoding;
my $ctx = context();
my $event = $ctx->send_event('Encoding', encoding => 'UTF-8');
=head1 METHODS
Inherits from L<Test2::Event>. Also defines:
=over 4
=item $encoding = $e->encoding
The encoding being specified.
=back
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

View file

@ -0,0 +1,113 @@
package Test2::Event::Exception;
use strict;
use warnings;
our $VERSION = '1.302175';
BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) }
use Test2::Util::HashBase qw{error};
sub init {
my $self = shift;
$self->{+ERROR} = "$self->{+ERROR}";
}
sub causes_fail { 1 }
sub summary {
my $self = shift;
chomp(my $msg = "Exception: " . $self->{+ERROR});
return $msg;
}
sub diagnostics { 1 }
sub facet_data {
my $self = shift;
my $out = $self->common_facet_data;
$out->{errors} = [
{
tag => 'ERROR',
fail => 1,
details => $self->{+ERROR},
}
];
return $out;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::Event::Exception - Exception event
=head1 DESCRIPTION
An exception event will display to STDERR, and will prevent the overall test
file from passing.
=head1 SYNOPSIS
use Test2::API qw/context/;
use Test2::Event::Exception;
my $ctx = context();
my $event = $ctx->send_event('Exception', error => 'Stuff is broken');
=head1 METHODS
Inherits from L<Test2::Event>. Also defines:
=over 4
=item $reason = $e->error
The reason for the exception.
=back
=head1 CAVEATS
Be aware that all exceptions are stringified during construction.
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

118
t/lib/Test2/Event/Fail.pm Normal file
View file

@ -0,0 +1,118 @@
package Test2::Event::Fail;
use strict;
use warnings;
our $VERSION = '1.302175';
use Test2::EventFacet::Info;
BEGIN {
require Test2::Event;
our @ISA = qw(Test2::Event);
*META_KEY = \&Test2::Util::ExternalMeta::META_KEY;
}
use Test2::Util::HashBase qw{ -name -info };
#############
# Old API
sub summary { "fail" }
sub increments_count { 1 }
sub diagnostics { 0 }
sub no_display { 0 }
sub subtest_id { undef }
sub terminate { () }
sub global { () }
sub sets_plan { () }
sub causes_fail {
my $self = shift;
return 0 if $self->{+AMNESTY} && @{$self->{+AMNESTY}};
return 1;
}
#############
# New API
sub add_info {
my $self = shift;
for my $in (@_) {
$in = {%$in} if ref($in) ne 'ARRAY';
$in = Test2::EventFacet::Info->new($in);
push @{$self->{+INFO}} => $in;
}
}
sub facet_data {
my $self = shift;
my $out = $self->common_facet_data;
$out->{about}->{details} = 'fail';
$out->{assert} = {pass => 0, details => $self->{+NAME}};
$out->{info} = [map {{ %{$_} }} @{$self->{+INFO}}] if $self->{+INFO};
return $out;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::Event::Fail - Event for a simple failed assertion
=head1 DESCRIPTION
This is an optimal representation of a failed assertion.
=head1 SYNOPSIS
use Test2::API qw/context/;
sub fail {
my ($name) = @_;
my $ctx = context();
$ctx->fail($name);
$ctx->release;
}
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

View file

@ -0,0 +1,280 @@
package Test2::Event::Generic;
use strict;
use warnings;
use Carp qw/croak/;
use Scalar::Util qw/reftype/;
our $VERSION = '1.302175';
BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) }
use Test2::Util::HashBase;
my @FIELDS = qw{
causes_fail increments_count diagnostics no_display callback terminate
global sets_plan summary facet_data
};
my %DEFAULTS = (
causes_fail => 0,
increments_count => 0,
diagnostics => 0,
no_display => 0,
);
sub init {
my $self = shift;
for my $field (@FIELDS) {
my $val = defined $self->{$field} ? delete $self->{$field} : $DEFAULTS{$field};
next unless defined $val;
my $set = "set_$field";
$self->$set($val);
}
}
for my $field (@FIELDS) {
no strict 'refs';
*$field = sub { exists $_[0]->{$field} ? $_[0]->{$field} : () }
unless exists &{$field};
*{"set_$field"} = sub { $_[0]->{$field} = $_[1] }
unless exists &{"set_$field"};
}
sub can {
my $self = shift;
my ($name) = @_;
return $self->SUPER::can($name) unless $name eq 'callback';
return $self->{callback} || \&Test2::Event::callback;
}
sub facet_data {
my $self = shift;
return $self->{facet_data} || $self->SUPER::facet_data();
}
sub summary {
my $self = shift;
return $self->{summary} if defined $self->{summary};
$self->SUPER::summary();
}
sub sets_plan {
my $self = shift;
return unless $self->{sets_plan};
return @{$self->{sets_plan}};
}
sub callback {
my $self = shift;
my $cb = $self->{callback} || return;
$self->$cb(@_);
}
sub set_global {
my $self = shift;
my ($bool) = @_;
if(!defined $bool) {
delete $self->{global};
return undef;
}
$self->{global} = $bool;
}
sub set_callback {
my $self = shift;
my ($cb) = @_;
if(!defined $cb) {
delete $self->{callback};
return undef;
}
croak "callback must be a code reference"
unless ref($cb) && reftype($cb) eq 'CODE';
$self->{callback} = $cb;
}
sub set_terminate {
my $self = shift;
my ($exit) = @_;
if(!defined $exit) {
delete $self->{terminate};
return undef;
}
croak "terminate must be a positive integer"
unless $exit =~ m/^\d+$/;
$self->{terminate} = $exit;
}
sub set_sets_plan {
my $self = shift;
my ($plan) = @_;
if(!defined $plan) {
delete $self->{sets_plan};
return undef;
}
croak "'sets_plan' must be an array reference"
unless ref($plan) && reftype($plan) eq 'ARRAY';
$self->{sets_plan} = $plan;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::Event::Generic - Generic event type.
=head1 DESCRIPTION
This is a generic event that lets you customize all fields in the event API.
This is useful if you have need for a custom event that does not make sense as
a published reusable event subclass.
=head1 SYNOPSIS
use Test2::API qw/context/;
sub send_custom_fail {
my $ctx = shift;
$ctx->send_event('Generic', causes_fail => 1, summary => 'The sky is falling');
$ctx->release;
}
send_custom_fail();
=head1 METHODS
=over 4
=item $e->facet_data($data)
=item $data = $e->facet_data
Get or set the facet data (see L<Test2::Event>). If no facet_data is set then
C<< Test2::Event->facet_data >> will be called to produce facets from the other
data.
=item $e->callback($hub)
Call the custom callback if one is set, otherwise this does nothing.
=item $e->set_callback(sub { ... })
Set the custom callback. The custom callback must be a coderef. The first
argument to your callback will be the event itself, the second will be the
L<Test2::Event::Hub> that is using the callback.
=item $bool = $e->causes_fail
=item $e->set_causes_fail($bool)
Get/Set the C<causes_fail> attribute. This defaults to C<0>.
=item $bool = $e->diagnostics
=item $e->set_diagnostics($bool)
Get/Set the C<diagnostics> attribute. This defaults to C<0>.
=item $bool_or_undef = $e->global
=item @bool_or_empty = $e->global
=item $e->set_global($bool_or_undef)
Get/Set the C<diagnostics> attribute. This defaults to an empty list which is
undef in scalar context.
=item $bool = $e->increments_count
=item $e->set_increments_count($bool)
Get/Set the C<increments_count> attribute. This defaults to C<0>.
=item $bool = $e->no_display
=item $e->set_no_display($bool)
Get/Set the C<no_display> attribute. This defaults to C<0>.
=item @plan = $e->sets_plan
Get the plan if this event sets one. The plan is a list of up to 3 items:
C<($count, $directive, $reason)>. C<$count> must be defined, the others may be
undef, or may not exist at all.
=item $e->set_sets_plan(\@plan)
Set the plan. You must pass in an arrayref with up to 3 elements.
=item $summary = $e->summary
=item $e->set_summary($summary_or_undef)
Get/Set the summary. This will default to the event package
C<'Test2::Event::Generic'>. You can set it to any value. Setting this to
C<undef> will reset it to the default.
=item $int_or_undef = $e->terminate
=item @int_or_empty = $e->terminate
=item $e->set_terminate($int_or_undef)
This will get/set the C<terminate> attribute. This defaults to undef in scalar
context, or an empty list in list context. Setting this to undef will clear it
completely. This must be set to a positive integer (0 or larger).
=back
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

97
t/lib/Test2/Event/Note.pm Normal file
View file

@ -0,0 +1,97 @@
package Test2::Event::Note;
use strict;
use warnings;
our $VERSION = '1.302175';
BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) }
use Test2::Util::HashBase qw/message/;
sub init {
$_[0]->{+MESSAGE} = 'undef' unless defined $_[0]->{+MESSAGE};
}
sub summary { $_[0]->{+MESSAGE} }
sub facet_data {
my $self = shift;
my $out = $self->common_facet_data;
$out->{info} = [
{
tag => 'NOTE',
debug => 0,
details => $self->{+MESSAGE},
}
];
return $out;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::Event::Note - Note event type
=head1 DESCRIPTION
Notes, typically rendered to STDOUT.
=head1 SYNOPSIS
use Test2::API qw/context/;
use Test2::Event::Note;
my $ctx = context();
my $event = $ctx->Note($message);
=head1 ACCESSORS
=over 4
=item $note->message
The message for the note.
=back
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

162
t/lib/Test2/Event/Ok.pm Normal file
View file

@ -0,0 +1,162 @@
package Test2::Event::Ok;
use strict;
use warnings;
our $VERSION = '1.302175';
BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) }
use Test2::Util::HashBase qw{
pass effective_pass name todo
};
sub init {
my $self = shift;
# Do not store objects here, only true or false
$self->{+PASS} = $self->{+PASS} ? 1 : 0;
$self->{+EFFECTIVE_PASS} = $self->{+PASS} || (defined($self->{+TODO}) ? 1 : 0);
}
{
no warnings 'redefine';
sub set_todo {
my $self = shift;
my ($todo) = @_;
$self->{+TODO} = $todo;
$self->{+EFFECTIVE_PASS} = defined($todo) ? 1 : $self->{+PASS};
}
}
sub increments_count { 1 };
sub causes_fail { !$_[0]->{+EFFECTIVE_PASS} }
sub summary {
my $self = shift;
my $name = $self->{+NAME} || "Nameless Assertion";
my $todo = $self->{+TODO};
if ($todo) {
$name .= " (TODO: $todo)";
}
elsif (defined $todo) {
$name .= " (TODO)"
}
return $name;
}
sub extra_amnesty {
my $self = shift;
return unless defined($self->{+TODO}) || ($self->{+EFFECTIVE_PASS} && !$self->{+PASS});
return {
tag => 'TODO',
details => $self->{+TODO},
};
}
sub facet_data {
my $self = shift;
my $out = $self->common_facet_data;
$out->{assert} = {
no_debug => 1, # Legacy behavior
pass => $self->{+PASS},
details => $self->{+NAME},
};
if (my @exra_amnesty = $self->extra_amnesty) {
unshift @{$out->{amnesty}} => @exra_amnesty;
}
return $out;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::Event::Ok - Ok event type
=head1 DESCRIPTION
Ok events are generated whenever you run a test that produces a result.
Examples are C<ok()>, and C<is()>.
=head1 SYNOPSIS
use Test2::API qw/context/;
use Test2::Event::Ok;
my $ctx = context();
my $event = $ctx->ok($bool, $name, \@diag);
or:
my $ctx = context();
my $event = $ctx->send_event(
'Ok',
pass => $bool,
name => $name,
);
=head1 ACCESSORS
=over 4
=item $rb = $e->pass
The original true/false value of whatever was passed into the event (but
reduced down to 1 or 0).
=item $name = $e->name
Name of the test.
=item $b = $e->effective_pass
This is the true/false value of the test after TODO and similar modifiers are
taken into account.
=back
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

114
t/lib/Test2/Event/Pass.pm Normal file
View file

@ -0,0 +1,114 @@
package Test2::Event::Pass;
use strict;
use warnings;
our $VERSION = '1.302175';
use Test2::EventFacet::Info;
BEGIN {
require Test2::Event;
our @ISA = qw(Test2::Event);
*META_KEY = \&Test2::Util::ExternalMeta::META_KEY;
}
use Test2::Util::HashBase qw{ -name -info };
##############
# Old API
sub summary { "pass" }
sub increments_count { 1 }
sub causes_fail { 0 }
sub diagnostics { 0 }
sub no_display { 0 }
sub subtest_id { undef }
sub terminate { () }
sub global { () }
sub sets_plan { () }
##############
# New API
sub add_info {
my $self = shift;
for my $in (@_) {
$in = {%$in} if ref($in) ne 'ARRAY';
$in = Test2::EventFacet::Info->new($in);
push @{$self->{+INFO}} => $in;
}
}
sub facet_data {
my $self = shift;
my $out = $self->common_facet_data;
$out->{about}->{details} = 'pass';
$out->{assert} = {pass => 1, details => $self->{+NAME}};
$out->{info} = [map {{ %{$_} }} @{$self->{+INFO}}] if $self->{+INFO};
return $out;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::Event::Pass - Event for a simple passing assertion
=head1 DESCRIPTION
This is an optimal representation of a passing assertion.
=head1 SYNOPSIS
use Test2::API qw/context/;
sub pass {
my ($name) = @_;
my $ctx = context();
$ctx->pass($name);
$ctx->release;
}
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

169
t/lib/Test2/Event/Plan.pm Normal file
View file

@ -0,0 +1,169 @@
package Test2::Event::Plan;
use strict;
use warnings;
our $VERSION = '1.302175';
BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) }
use Test2::Util::HashBase qw{max directive reason};
use Carp qw/confess/;
my %ALLOWED = (
'SKIP' => 1,
'NO PLAN' => 1,
);
sub init {
if ($_[0]->{+DIRECTIVE}) {
$_[0]->{+DIRECTIVE} = 'SKIP' if $_[0]->{+DIRECTIVE} eq 'skip_all';
$_[0]->{+DIRECTIVE} = 'NO PLAN' if $_[0]->{+DIRECTIVE} eq 'no_plan';
confess "'" . $_[0]->{+DIRECTIVE} . "' is not a valid plan directive"
unless $ALLOWED{$_[0]->{+DIRECTIVE}};
}
else {
confess "Cannot have a reason without a directive!"
if defined $_[0]->{+REASON};
confess "No number of tests specified"
unless defined $_[0]->{+MAX};
confess "Plan test count '" . $_[0]->{+MAX} . "' does not appear to be a valid positive integer"
unless $_[0]->{+MAX} =~ m/^\d+$/;
$_[0]->{+DIRECTIVE} = '';
}
}
sub sets_plan {
my $self = shift;
return (
$self->{+MAX},
$self->{+DIRECTIVE},
$self->{+REASON},
);
}
sub terminate {
my $self = shift;
# On skip_all we want to terminate the hub
return 0 if $self->{+DIRECTIVE} && $self->{+DIRECTIVE} eq 'SKIP';
return undef;
}
sub summary {
my $self = shift;
my $max = $self->{+MAX};
my $directive = $self->{+DIRECTIVE};
my $reason = $self->{+REASON};
return "Plan is $max assertions"
if $max || !$directive;
return "Plan is '$directive', $reason"
if $reason;
return "Plan is '$directive'";
}
sub facet_data {
my $self = shift;
my $out = $self->common_facet_data;
$out->{control}->{terminate} = $self->{+DIRECTIVE} eq 'SKIP' ? 0 : undef
unless defined $out->{control}->{terminate};
$out->{plan} = {count => $self->{+MAX}};
$out->{plan}->{details} = $self->{+REASON} if defined $self->{+REASON};
if (my $dir = $self->{+DIRECTIVE}) {
$out->{plan}->{skip} = 1 if $dir eq 'SKIP';
$out->{plan}->{none} = 1 if $dir eq 'NO PLAN';
}
return $out;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::Event::Plan - The event of a plan
=head1 DESCRIPTION
Plan events are fired off whenever a plan is declared, done testing is called,
or a subtext completes.
=head1 SYNOPSIS
use Test2::API qw/context/;
use Test2::Event::Plan;
my $ctx = context();
# Plan for 10 tests to run
my $event = $ctx->plan(10);
# Plan to skip all tests (will exit 0)
$ctx->plan(0, skip_all => "These tests need to be skipped");
=head1 ACCESSORS
=over 4
=item $num = $plan->max
Get the number of expected tests
=item $dir = $plan->directive
Get the directive (such as TODO, skip_all, or no_plan).
=item $reason = $plan->reason
Get the reason for the directive.
=back
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

127
t/lib/Test2/Event/Skip.pm Normal file
View file

@ -0,0 +1,127 @@
package Test2::Event::Skip;
use strict;
use warnings;
our $VERSION = '1.302175';
BEGIN { require Test2::Event::Ok; our @ISA = qw(Test2::Event::Ok) }
use Test2::Util::HashBase qw{reason};
sub init {
my $self = shift;
$self->SUPER::init;
$self->{+EFFECTIVE_PASS} = 1;
}
sub causes_fail { 0 }
sub summary {
my $self = shift;
my $out = $self->SUPER::summary(@_);
if (my $reason = $self->reason) {
$out .= " (SKIP: $reason)";
}
else {
$out .= " (SKIP)";
}
return $out;
}
sub extra_amnesty {
my $self = shift;
my @out;
push @out => {
tag => 'TODO',
details => $self->{+TODO},
} if defined $self->{+TODO};
push @out => {
tag => 'skip',
details => $self->{+REASON},
inherited => 0,
};
return @out;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::Event::Skip - Skip event type
=head1 DESCRIPTION
Skip events bump test counts just like L<Test2::Event::Ok> events, but
they can never fail.
=head1 SYNOPSIS
use Test2::API qw/context/;
use Test2::Event::Skip;
my $ctx = context();
my $event = $ctx->skip($name, $reason);
or:
my $ctx = context();
my $event = $ctx->send_event(
'Skip',
name => $name,
reason => $reason,
);
=head1 ACCESSORS
=over 4
=item $reason = $e->reason
The original true/false value of whatever was passed into the event (but
reduced down to 1 or 0).
=back
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://www.perl.com/perl/misc/Artistic.html>
=cut

View file

@ -0,0 +1,160 @@
package Test2::Event::Subtest;
use strict;
use warnings;
our $VERSION = '1.302175';
BEGIN { require Test2::Event::Ok; our @ISA = qw(Test2::Event::Ok) }
use Test2::Util::HashBase qw{subevents buffered subtest_id subtest_uuid};
sub init {
my $self = shift;
$self->SUPER::init();
$self->{+SUBEVENTS} ||= [];
if ($self->{+EFFECTIVE_PASS}) {
$_->set_effective_pass(1) for grep { $_->can('effective_pass') } @{$self->{+SUBEVENTS}};
}
}
{
no warnings 'redefine';
sub set_subevents {
my $self = shift;
my @subevents = @_;
if ($self->{+EFFECTIVE_PASS}) {
$_->set_effective_pass(1) for grep { $_->can('effective_pass') } @subevents;
}
$self->{+SUBEVENTS} = \@subevents;
}
sub set_effective_pass {
my $self = shift;
my ($pass) = @_;
if ($pass) {
$_->set_effective_pass(1) for grep { $_->can('effective_pass') } @{$self->{+SUBEVENTS}};
}
elsif ($self->{+EFFECTIVE_PASS} && !$pass) {
for my $s (grep { $_->can('effective_pass') } @{$self->{+SUBEVENTS}}) {
$_->set_effective_pass(0) unless $s->can('todo') && defined $s->todo;
}
}
$self->{+EFFECTIVE_PASS} = $pass;
}
}
sub summary {
my $self = shift;
my $name = $self->{+NAME} || "Nameless Subtest";
my $todo = $self->{+TODO};
if ($todo) {
$name .= " (TODO: $todo)";
}
elsif (defined $todo) {
$name .= " (TODO)";
}
return $name;
}
sub facet_data {
my $self = shift;
my $out = $self->SUPER::facet_data();
$out->{parent} = {
hid => $self->subtest_id,
children => [map {$_->facet_data} @{$self->{+SUBEVENTS}}],
buffered => $self->{+BUFFERED},
};
return $out;
}
sub add_amnesty {
my $self = shift;
for my $am (@_) {
$am = {%$am} if ref($am) ne 'ARRAY';
$am = Test2::EventFacet::Amnesty->new($am);
push @{$self->{+AMNESTY}} => $am;
for my $e (@{$self->{+SUBEVENTS}}) {
$e->add_amnesty($am->clone(inherited => 1));
}
}
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::Event::Subtest - Event for subtest types
=head1 DESCRIPTION
This class represents a subtest. This class is a subclass of
L<Test2::Event::Ok>.
=head1 ACCESSORS
This class inherits from L<Test2::Event::Ok>.
=over 4
=item $arrayref = $e->subevents
Returns the arrayref containing all the events from the subtest
=item $bool = $e->buffered
True if the subtest is buffered, that is all subevents render at once. If this
is false it means all subevents render as they are produced.
=back
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

View file

@ -0,0 +1,101 @@
package Test2::Event::TAP::Version;
use strict;
use warnings;
our $VERSION = '1.302175';
use Carp qw/croak/;
BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) }
use Test2::Util::HashBase qw/version/;
sub init {
my $self = shift;
defined $self->{+VERSION} or croak "'version' is a required attribute";
}
sub summary { 'TAP version ' . $_[0]->{+VERSION} }
sub facet_data {
my $self = shift;
my $out = $self->common_facet_data;
$out->{about}->{details} = $self->summary;
push @{$out->{info}} => {
tag => 'INFO',
debug => 0,
details => $self->summary,
};
return $out;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::Event::TAP::Version - Event for TAP version.
=head1 DESCRIPTION
This event is used if a TAP formatter wishes to set a version.
=head1 SYNOPSIS
use Test2::API qw/context/;
use Test2::Event::Encoding;
my $ctx = context();
my $event = $ctx->send_event('TAP::Version', version => 42);
=head1 METHODS
Inherits from L<Test2::Event>. Also defines:
=over 4
=item $version = $e->version
The TAP version being parsed.
=back
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

238
t/lib/Test2/Event/V2.pm Normal file
View file

@ -0,0 +1,238 @@
package Test2::Event::V2;
use strict;
use warnings;
our $VERSION = '1.302175';
use Scalar::Util qw/reftype/;
use Carp qw/croak/;
BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) }
use Test2::Util::Facets2Legacy qw{
causes_fail diagnostics global increments_count no_display sets_plan
subtest_id summary terminate
};
use Test2::Util::HashBase qw/-about/;
sub non_facet_keys {
return (
+UUID,
Test2::Util::ExternalMeta::META_KEY(),
);
}
sub init {
my $self = shift;
my $uuid;
if ($uuid = $self->{+UUID}) {
croak "uuid '$uuid' passed to constructor, but uuid '$self->{+ABOUT}->{uuid}' is already set in the 'about' facet"
if $self->{+ABOUT}->{uuid} && $self->{+ABOUT}->{uuid} ne $uuid;
$self->{+ABOUT}->{uuid} = $uuid;
}
elsif ($uuid = $self->{+ABOUT}->{uuid}) {
$self->SUPER::set_uuid($uuid);
}
# Clone the trace, make sure it is blessed
if (my $trace = $self->{+TRACE}) {
$self->{+TRACE} = Test2::EventFacet::Trace->new(%$trace);
}
}
sub set_uuid {
my $self = shift;
my ($uuid) = @_;
$self->{+ABOUT}->{uuid} = $uuid;
$self->SUPER::set_uuid($uuid);
}
sub facet_data {
my $self = shift;
my $f = { %{$self} };
delete $f->{$_} for $self->non_facet_keys;
my %out;
for my $k (keys %$f) {
next if substr($k, 0, 1) eq '_';
my $data = $f->{$k} or next; # Key is there, but no facet
my $is_list = 'ARRAY' eq (reftype($data) || '');
$out{$k} = $is_list ? [ map { {%{$_}} } @$data ] : {%$data};
}
if (my $meta = $self->meta_facet_data) {
$out{meta} = {%$meta, %{$out{meta} || {}}};
}
return \%out;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::Event::V2 - Second generation event.
=head1 DESCRIPTION
This is the event type that should be used instead of L<Test2::Event> or its
legacy subclasses.
=head1 SYNOPSIS
=head2 USING A CONTEXT
use Test2::API qw/context/;
sub my_tool {
my $ctx = context();
my $event = $ctx->send_ev2(info => [{tag => 'NOTE', details => "This is a note"}]);
$ctx->release;
return $event;
}
=head2 USING THE CONSTRUCTOR
use Test2::Event::V2;
my $e = Test2::Event::V2->new(
trace => {frame => [$PKG, $FILE, $LINE, $SUBNAME]},
info => [{tag => 'NOTE', details => "This is a note"}],
);
=head1 METHODS
This class inherits from L<Test2::Event>.
=over 4
=item $fd = $e->facet_data()
This will return a hashref of facet data. Each facet hash will be a shallow
copy of the original.
=item $about = $e->about()
This will return the 'about' facet hashref.
B<NOTE:> This will return the internal hashref, not a copy.
=item $trace = $e->trace()
This will return the 'trace' facet, normally blessed (but this is not enforced
when the trace is set using C<set_trace()>.
B<NOTE:> This will return the internal trace, not a copy.
=back
=head2 MUTATION
=over 4
=item $e->add_amnesty({...})
Inherited from L<Test2::Event>. This can be used to add 'amnesty' facets to an
existing event. Each new item is added to the B<END> of the list.
B<NOTE:> Items B<ARE> blessed when added.
=item $e->add_hub({...})
Inherited from L<Test2::Event>. This is used by hubs to stamp events as they
pass through. New items are added to the B<START> of the list.
B<NOTE:> Items B<ARE NOT> blessed when added.
=item $e->set_uuid($UUID)
Inherited from L<Test2::Event>, overridden to also vivify/mutate the 'about'
facet.
=item $e->set_trace($trace)
Inherited from L<Test2::Event> which allows you to change the trace.
B<Note:> This method does not bless/clone the trace for you. Many things will
expect the trace to be blessed, so you should probably do that.
=back
=head2 LEGACY SUPPORT METHODS
These are all imported from L<Test2::Util::Facets2Legacy>, see that module or
L<Test2::Event> for documentation on what they do.
=over 4
=item causes_fail
=item diagnostics
=item global
=item increments_count
=item no_display
=item sets_plan
=item subtest_id
=item summary
=item terminate
=back
=head1 THIRD PARTY META-DATA
This object consumes L<Test2::Util::ExternalMeta> which provides a consistent
way for you to attach meta-data to instances of this class. This is useful for
tools, plugins, and other extensions.
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

View file

@ -0,0 +1,76 @@
package Test2::Event::Waiting;
use strict;
use warnings;
our $VERSION = '1.302175';
BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) }
use Test2::Util::HashBase;
sub global { 1 };
sub summary { "IPC is waiting for children to finish..." }
sub facet_data {
my $self = shift;
my $out = $self->common_facet_data;
push @{$out->{info}} => {
tag => 'INFO',
debug => 0,
details => $self->summary,
};
return $out;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::Event::Waiting - Tell all procs/threads it is time to be done
=head1 DESCRIPTION
This event has no data of its own. This event is sent out by the IPC system
when the main process/thread is ready to end.
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

93
t/lib/Test2/EventFacet.pm Normal file
View file

@ -0,0 +1,93 @@
package Test2::EventFacet;
use strict;
use warnings;
our $VERSION = '1.302175';
use Test2::Util::HashBase qw/-details/;
use Carp qw/croak/;
my $SUBLEN = length(__PACKAGE__ . '::');
sub facet_key {
my $key = ref($_[0]) || $_[0];
substr($key, 0, $SUBLEN, '');
return lc($key);
}
sub is_list { 0 }
sub clone {
my $self = shift;
my $type = ref($self);
return bless {%$self, @_}, $type;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::EventFacet - Base class for all event facets.
=head1 DESCRIPTION
Base class for all event facets.
=head1 METHODS
=over 4
=item $key = $facet_class->facet_key()
This will return the key for the facet in the facet data hash.
=item $bool = $facet_class->is_list()
This will return true if the facet should be in a list instead of a single
item.
=item $clone = $facet->clone()
=item $clone = $facet->clone(%replace)
This will make a shallow clone of the facet. You may specify fields to override
as arguments.
=back
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

View file

@ -0,0 +1,92 @@
package Test2::EventFacet::About;
use strict;
use warnings;
our $VERSION = '1.302175';
BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) }
use Test2::Util::HashBase qw{ -package -no_display -uuid -eid };
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::EventFacet::About - Facet with event details.
=head1 DESCRIPTION
This facet has information about the event, such as event package.
=head1 FIELDS
=over 4
=item $string = $about->{details}
=item $string = $about->details()
Summary about the event.
=item $package = $about->{package}
=item $package = $about->package()
Event package name.
=item $bool = $about->{no_display}
=item $bool = $about->no_display()
True if the event should be skipped by formatters.
=item $uuid = $about->{uuid}
=item $uuid = $about->uuid()
Will be set to a uuid if uuid tagging was enabled.
=item $uuid = $about->{eid}
=item $uuid = $about->eid()
A unique (for the test job) identifier for the event.
=back
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

View file

@ -0,0 +1,91 @@
package Test2::EventFacet::Amnesty;
use strict;
use warnings;
our $VERSION = '1.302175';
sub is_list { 1 }
BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) }
use Test2::Util::HashBase qw{ -tag -inherited };
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::EventFacet::Amnesty - Facet for assertion amnesty.
=head1 DESCRIPTION
This package represents what is expected in units of amnesty.
=head1 NOTES
This facet appears in a list instead of being a single item.
=head1 FIELDS
=over 4
=item $string = $amnesty->{details}
=item $string = $amnesty->details()
Human readable explanation of why amnesty was granted.
Example: I<Not implemented yet, will fix>
=item $short_string = $amnesty->{tag}
=item $short_string = $amnesty->tag()
Short string (usually 10 characters or less, not enforced, but may be truncated
by renderers) categorizing the amnesty.
=item $bool = $amnesty->{inherited}
=item $bool = $amnesty->inherited()
This will be true if the amnesty was granted to a parent event and inherited by
this event, which is a child, such as an assertion within a subtest that is
marked todo.
=back
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

View file

@ -0,0 +1,93 @@
package Test2::EventFacet::Assert;
use strict;
use warnings;
our $VERSION = '1.302175';
BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) }
use Test2::Util::HashBase qw{ -pass -no_debug -number };
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::EventFacet::Assert - Facet representing an assertion.
=head1 DESCRIPTION
The assertion facet is provided by any event representing an assertion that was
made.
=head1 FIELDS
=over 4
=item $string = $assert->{details}
=item $string = $assert->details()
Human readable description of the assertion.
=item $bool = $assert->{pass}
=item $bool = $assert->pass()
True if the assertion passed.
=item $bool = $assert->{no_debug}
=item $bool = $assert->no_debug()
Set this to true if you have provided custom diagnostics and do not want the
defaults to be displayed.
=item $int = $assert->{number}
=item $int = $assert->number()
(Optional) assertion number. This may be omitted or ignored. This is usually
only useful when parsing/processing TAP.
B<Note>: This is not set by the Test2 system, assertion number is not known
until AFTER the assertion has been processed. This attribute is part of the
spec only for harnesses.
=back
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

View file

@ -0,0 +1,107 @@
package Test2::EventFacet::Control;
use strict;
use warnings;
our $VERSION = '1.302175';
BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) }
use Test2::Util::HashBase qw{ -global -terminate -halt -has_callback -encoding -phase };
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::EventFacet::Control - Facet for hub actions and behaviors.
=head1 DESCRIPTION
This facet is used when the event needs to give instructions to the Test2
internals.
=head1 FIELDS
=over 4
=item $string = $control->{details}
=item $string = $control->details()
Human readable explanation for the special behavior.
=item $bool = $control->{global}
=item $bool = $control->global()
True if the event is global in nature and should be seen by all hubs.
=item $exit = $control->{terminate}
=item $exit = $control->terminate()
Defined if the test should immediately exit, the value is the exit code and may
be C<0>.
=item $bool = $control->{halt}
=item $bool = $control->halt()
True if all testing should be halted immediately.
=item $bool = $control->{has_callback}
=item $bool = $control->has_callback()
True if the C<callback($hub)> method on the event should be called.
=item $encoding = $control->{encoding}
=item $encoding = $control->encoding()
This can be used to change the encoding from this event onward.
=item $phase = $control->{phase}
=item $phase = $control->phase()
Used to signal that a phase change has occurred. Currently only the perl END
phase is signaled.
=back
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

View file

@ -0,0 +1,93 @@
package Test2::EventFacet::Error;
use strict;
use warnings;
our $VERSION = '1.302175';
sub facet_key { 'errors' }
sub is_list { 1 }
BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) }
use Test2::Util::HashBase qw{ -tag -fail };
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::EventFacet::Error - Facet for errors that need to be shown.
=head1 DESCRIPTION
This facet is used when an event needs to convey errors.
=head1 NOTES
This facet has the hash key C<'errors'>, and is a list of facets instead of a
single item.
=head1 FIELDS
=over 4
=item $string = $error->{details}
=item $string = $error->details()
Explanation of the error, or the error itself (such as an exception). In perl
exceptions may be blessed objects, so this field may contain a blessed object.
=item $short_string = $error->{tag}
=item $short_string = $error->tag()
Short tag to categorize the error. This is usually 10 characters or less,
formatters may truncate longer tags.
=item $bool = $error->{fail}
=item $bool = $error->fail()
Not all errors are fatal, some are displayed having already been handled. Set
this to true if you want the error to cause the test to fail. Without this the
error is simply a diagnostics message that has no effect on the overall
pass/fail result.
=back
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

View file

@ -0,0 +1,109 @@
package Test2::EventFacet::Hub;
use strict;
use warnings;
our $VERSION = '1.302175';
sub is_list { 1 }
sub facet_key { 'hubs' }
BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) }
use Test2::Util::HashBase qw{-pid -tid -hid -nested -buffered -uuid -ipc};
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::EventFacet::Hub - Facet for the hubs an event passes through.
=head1 DESCRIPTION
These are a record of the hubs an event passes through. Most recent hub is the
first one in the list.
=head1 FACET FIELDS
=over 4
=item $string = $trace->{details}
=item $string = $trace->details()
The hub class or subclass
=item $int = $trace->{pid}
=item $int = $trace->pid()
PID of the hub this event was sent to.
=item $int = $trace->{tid}
=item $int = $trace->tid()
The thread ID of the hub the event was sent to.
=item $hid = $trace->{hid}
=item $hid = $trace->hid()
The ID of the hub that the event was send to.
=item $huuid = $trace->{huuid}
=item $huuid = $trace->huuid()
The UUID of the hub that the event was sent to.
=item $int = $trace->{nested}
=item $int = $trace->nested()
How deeply nested the hub was.
=item $bool = $trace->{buffered}
=item $bool = $trace->buffered()
True if the event was buffered and not sent to the formatter independent of a
parent (This should never be set when nested is C<0> or C<undef>).
=back
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

View file

@ -0,0 +1,132 @@
package Test2::EventFacet::Info;
use strict;
use warnings;
our $VERSION = '1.302175';
sub is_list { 1 }
BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) }
use Test2::Util::HashBase qw{-tag -debug -important -table};
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::EventFacet::Info - Facet for information a developer might care about.
=head1 DESCRIPTION
This facet represents messages intended for humans that will help them either
understand a result, or diagnose a failure.
=head1 NOTES
This facet appears in a list instead of being a single item.
=head1 FIELDS
=over 4
=item $string_or_structure = $info->{details}
=item $string_or_structure = $info->details()
Human readable string or data structure, this is the information to display.
Formatters are free to render the structures however they please. This may
contain a blessed object.
If the C<table> attribute (see below) is set then a renderer may choose to
display the table instead of the details.
=item $structure = $info->{table}
=item $structure = $info->table()
If the data the C<info> facet needs to convey can be represented as a table
then the data may be placed in this attribute in a more raw form for better
display. The data must also be represented in the C<details> attribute for
renderers which do not support rendering tables directly.
The table structure:
my %table = {
header => [ 'column 1 header', 'column 2 header', ... ], # Optional
rows => [
['row 1 column 1', 'row 1, column 2', ... ],
['row 2 column 1', 'row 2, column 2', ... ],
...
],
# Allow the renderer to hide empty columns when true, Optional
collapse => $BOOL,
# List by name or number columns that should never be collapsed
no_collapse => \@LIST,
}
=item $short_string = $info->{tag}
=item $short_string = $info->tag()
Short tag to categorize the info. This is usually 10 characters or less,
formatters may truncate longer tags.
=item $bool = $info->{debug}
=item $bool = $info->debug()
Set this to true if the message is critical, or explains a failure. This is
info that should be displayed by formatters even in less-verbose modes.
When false the information is not considered critical and may not be rendered
in less-verbose modes.
=item $bool = $info->{important}
=item $bool = $info->important
This should be set for non debug messages that are still important enough to
show when a formatter is in quiet mode. A formatter should send these to STDOUT
not STDERR, but should show them even in non-verbose mode.
=back
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

View file

@ -0,0 +1,144 @@
package Test2::EventFacet::Info::Table;
use strict;
use warnings;
our $VERSION = '1.302175';
use Carp qw/confess/;
use Test2::Util::HashBase qw{-header -rows -collapse -no_collapse -as_string};
sub init {
my $self = shift;
confess "Table may not be empty" unless ref($self->{+ROWS}) eq 'ARRAY' && @{$self->{+ROWS}};
$self->{+AS_STRING} ||= '<TABLE NOT DISPLAYED>';
}
sub as_hash { my $out = +{%{$_[0]}}; delete $out->{as_string}; $out }
sub info_args {
my $self = shift;
my $hash = $self->as_hash;
my $desc = $self->as_string;
return (table => $hash, details => $desc);
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::EventFacet::Info::Table - Intermediary representation of a table.
=head1 DESCRIPTION
Intermediary representation of a table for use in specialized
L<Test::API::Context> methods which generate L<Test2::EventFacet::Info> facets.
=head1 SYNOPSIS
use Test2::EventFacet::Info::Table;
use Test2::API qw/context/;
sub my_tool {
my $ctx = context();
...
$ctx->fail(
$name,
"failure diag message",
Test2::EventFacet::Info::Table->new(
# Required
rows => [['a', 'b'], ['c', 'd'], ...],
# Strongly Recommended
as_string => "... string to print when table cannot be rendered ...",
# Optional
header => ['col1', 'col2'],
collapse => $bool,
no_collapse => ['col1', ...],
),
);
...
$ctx->release;
}
my_tool();
=head1 ATTRIBUTES
=over 4
=item $header_aref = $t->header()
=item $rows_aref = $t->rows()
=item $bool = $t->collapse()
=item $aref = $t->no_collapse()
The above are all directly tied to the table hashref structure described in
L<Test2::EventFacet::Info>.
=item $str = $t->as_string()
This returns the string form of the table if it was set, otherwise it returns
the string C<< "<TABLE NOT DISPLAYED>" >>.
=item $href = $t->as_hash()
This returns the data structure used for tables by L<Test2::EventFacet::Info>.
=item %args = $t->info_args()
This returns the arguments that should be used to construct the proper
L<Test2::EventFacet::Info> structure.
return (table => $t->as_hash(), details => $t->as_string());
=back
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

View file

@ -0,0 +1,104 @@
package Test2::EventFacet::Meta;
use strict;
use warnings;
our $VERSION = '1.302175';
BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) }
use vars qw/$AUTOLOAD/;
# replace set_details
{
no warnings 'redefine';
sub set_details { $_[0]->{'set_details'} }
}
sub can {
my $self = shift;
my ($name) = @_;
my $existing = $self->SUPER::can($name);
return $existing if $existing;
# Only vivify when called on an instance, do not vivify for a class. There
# are a lot of magic class methods used in things like serialization (or
# the forks.pm module) which cause problems when vivified.
return undef unless ref($self);
my $sub = sub { $_[0]->{$name} };
{
no strict 'refs';
*$name = $sub;
}
return $sub;
}
sub AUTOLOAD {
my $name = $AUTOLOAD;
$name =~ s/^.*:://g;
my $sub = $_[0]->can($name);
goto &$sub;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Test2::EventFacet::Meta - Facet for meta-data
=head1 DESCRIPTION
This facet can contain any random meta-data that has been attached to the
event.
=head1 METHODS AND FIELDS
Any/all fields and accessors are autovivified into existence. There is no way
to know what metadata may be added, so any is allowed.
=over 4
=item $anything = $meta->{anything}
=item $anything = $meta->anything()
=back
=head1 SOURCE
The source code repository for Test2 can be found at
F<http://github.com/Test-More/test-more/>.
=head1 MAINTAINERS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 AUTHORS
=over 4
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
=back
=head1 COPYRIGHT
Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>
=cut

Some files were not shown because too many files have changed in this diff Show more