mirror of
https://github.com/EV21/dynb.git
synced 2025-12-26 16:39:32 +01:00
Compare commits
13 Commits
0.1.1
...
ab330e9731
| Author | SHA1 | Date | |
|---|---|---|---|
|
ab330e9731
|
|||
|
262f7c3709
|
|||
|
5210c35400
|
|||
|
522a0f99bb
|
|||
|
3bf6b69ae8
|
|||
|
d139022295
|
|||
|
8997835903
|
|||
|
d6dc223794
|
|||
|
dc12f71d00
|
|||
|
5ba730cff1
|
|||
|
1104cf8505
|
|||
|
99a446f4c7
|
|||
|
f056e96e25
|
295
.gitchangelog.rc
Normal file
295
.gitchangelog.rc
Normal file
@@ -0,0 +1,295 @@
|
|||||||
|
# -*- coding: utf-8; mode: python -*-
|
||||||
|
##
|
||||||
|
## Format
|
||||||
|
##
|
||||||
|
## ACTION: [AUDIENCE:] COMMIT_MSG [!TAG ...]
|
||||||
|
##
|
||||||
|
## Description
|
||||||
|
##
|
||||||
|
## ACTION is one of 'chg', 'fix', 'new'
|
||||||
|
##
|
||||||
|
## Is WHAT the change is about.
|
||||||
|
##
|
||||||
|
## 'chg' is for refactor, small improvement, cosmetic changes...
|
||||||
|
## 'fix' is for bug fixes
|
||||||
|
## 'new' is for new features, big improvement
|
||||||
|
##
|
||||||
|
## AUDIENCE is optional and one of 'dev', 'usr', 'pkg', 'test', 'doc'
|
||||||
|
##
|
||||||
|
## Is WHO is concerned by the change.
|
||||||
|
##
|
||||||
|
## 'dev' is for developpers (API changes, refactors...)
|
||||||
|
## 'usr' is for final users (UI changes)
|
||||||
|
## 'pkg' is for packagers (packaging changes)
|
||||||
|
## 'test' is for testers (test only related changes)
|
||||||
|
## 'doc' is for doc guys (doc only changes)
|
||||||
|
##
|
||||||
|
## COMMIT_MSG is ... well ... the commit message itself.
|
||||||
|
##
|
||||||
|
## TAGs are additionnal adjective as 'refactor' 'minor' 'cosmetic'
|
||||||
|
##
|
||||||
|
## They are preceded with a '!' or a '@' (prefer the former, as the
|
||||||
|
## latter is wrongly interpreted in github.) Commonly used tags are:
|
||||||
|
##
|
||||||
|
## 'refactor' is obviously for refactoring code only
|
||||||
|
## 'minor' is for a very meaningless change (a typo, adding a comment)
|
||||||
|
## 'cosmetic' is for cosmetic driven change (re-indentation, 80-col...)
|
||||||
|
## 'wip' is for partial functionality but complete subfunctionality.
|
||||||
|
##
|
||||||
|
## Example:
|
||||||
|
##
|
||||||
|
## new: usr: support of bazaar implemented
|
||||||
|
## chg: re-indentend some lines !cosmetic
|
||||||
|
## new: dev: updated code to be compatible with last version of killer lib.
|
||||||
|
## fix: pkg: updated year of licence coverage.
|
||||||
|
## new: test: added a bunch of test around user usability of feature X.
|
||||||
|
## fix: typo in spelling my name in comment. !minor
|
||||||
|
##
|
||||||
|
## Please note that multi-line commit message are supported, and only the
|
||||||
|
## first line will be considered as the "summary" of the commit message. So
|
||||||
|
## tags, and other rules only applies to the summary. The body of the commit
|
||||||
|
## message will be displayed in the changelog without reformatting.
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
## ``ignore_regexps`` is a line of regexps
|
||||||
|
##
|
||||||
|
## Any commit having its full commit message matching any regexp listed here
|
||||||
|
## will be ignored and won't be reported in the changelog.
|
||||||
|
##
|
||||||
|
ignore_regexps = [
|
||||||
|
r'@minor', r'!minor',
|
||||||
|
r'@cosmetic', r'!cosmetic',
|
||||||
|
r'@refactor', r'!refactor',
|
||||||
|
r'@wip', r'!wip',
|
||||||
|
r'^([cC]hg|[fF]ix|[nN]ew)\s*:\s*[p|P]kg:',
|
||||||
|
r'^([cC]hg|[fF]ix|[nN]ew)\s*:\s*[d|D]ev:',
|
||||||
|
r'^(.{3,3}\s*:)?\s*[fF]irst commit.?\s*$',
|
||||||
|
r'^$', ## ignore commits with empty messages
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
## ``section_regexps`` is a list of 2-tuples associating a string label and a
|
||||||
|
## list of regexp
|
||||||
|
##
|
||||||
|
## Commit messages will be classified in sections thanks to this. Section
|
||||||
|
## titles are the label, and a commit is classified under this section if any
|
||||||
|
## of the regexps associated is matching.
|
||||||
|
##
|
||||||
|
## Please note that ``section_regexps`` will only classify commits and won't
|
||||||
|
## make any changes to the contents. So you'll probably want to go check
|
||||||
|
## ``subject_process`` (or ``body_process``) to do some changes to the subject,
|
||||||
|
## whenever you are tweaking this variable.
|
||||||
|
##
|
||||||
|
section_regexps = [
|
||||||
|
('New', [
|
||||||
|
r'^:sparkles\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
|
||||||
|
]),
|
||||||
|
('Changes', [
|
||||||
|
r'^:wrench\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
|
||||||
|
]),
|
||||||
|
('Fix', [
|
||||||
|
r'^:bug\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
|
||||||
|
]),
|
||||||
|
('Documentation', [
|
||||||
|
r'^:memo\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
|
||||||
|
]),
|
||||||
|
('Remove', [
|
||||||
|
r'^:fire\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
|
||||||
|
]),
|
||||||
|
|
||||||
|
('Other', None ## Match all lines
|
||||||
|
),
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
## ``body_process`` is a callable
|
||||||
|
##
|
||||||
|
## This callable will be given the original body and result will
|
||||||
|
## be used in the changelog.
|
||||||
|
##
|
||||||
|
## Available constructs are:
|
||||||
|
##
|
||||||
|
## - any python callable that take one txt argument and return txt argument.
|
||||||
|
##
|
||||||
|
## - ReSub(pattern, replacement): will apply regexp substitution.
|
||||||
|
##
|
||||||
|
## - Indent(chars=" "): will indent the text with the prefix
|
||||||
|
## Please remember that template engines gets also to modify the text and
|
||||||
|
## will usually indent themselves the text if needed.
|
||||||
|
##
|
||||||
|
## - Wrap(regexp=r"\n\n"): re-wrap text in separate paragraph to fill 80-Columns
|
||||||
|
##
|
||||||
|
## - noop: do nothing
|
||||||
|
##
|
||||||
|
## - ucfirst: ensure the first letter is uppercase.
|
||||||
|
## (usually used in the ``subject_process`` pipeline)
|
||||||
|
##
|
||||||
|
## - final_dot: ensure text finishes with a dot
|
||||||
|
## (usually used in the ``subject_process`` pipeline)
|
||||||
|
##
|
||||||
|
## - strip: remove any spaces before or after the content of the string
|
||||||
|
##
|
||||||
|
## - SetIfEmpty(msg="No commit message."): will set the text to
|
||||||
|
## whatever given ``msg`` if the current text is empty.
|
||||||
|
##
|
||||||
|
## Additionally, you can `pipe` the provided filters, for instance:
|
||||||
|
#body_process = Wrap(regexp=r'\n(?=\w+\s*:)') | Indent(chars=" ")
|
||||||
|
#body_process = Wrap(regexp=r'\n(?=\w+\s*:)')
|
||||||
|
#body_process = noop
|
||||||
|
body_process = ReSub(r'((^|\n)[A-Z]\w+(-\w+)*: .*(\n\s+.*)*)+$', r'') | strip
|
||||||
|
|
||||||
|
|
||||||
|
## ``subject_process`` is a callable
|
||||||
|
##
|
||||||
|
## This callable will be given the original subject and result will
|
||||||
|
## be used in the changelog.
|
||||||
|
##
|
||||||
|
## Available constructs are those listed in ``body_process`` doc.
|
||||||
|
subject_process = (strip |
|
||||||
|
ReSub(r'^([cC]hg|[fF]ix|[nN]ew)\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n@]*)(@[a-z]+\s+)*$', r'\4') |
|
||||||
|
SetIfEmpty("No commit message.") | ucfirst | final_dot)
|
||||||
|
|
||||||
|
|
||||||
|
## ``tag_filter_regexp`` is a regexp
|
||||||
|
##
|
||||||
|
## Tags that will be used for the changelog must match this regexp.
|
||||||
|
##
|
||||||
|
tag_filter_regexp = r'^[0-9]+\.[0-9]+(\.[0-9]+)?$'
|
||||||
|
|
||||||
|
|
||||||
|
## ``unreleased_version_label`` is a string or a callable that outputs a string
|
||||||
|
##
|
||||||
|
## This label will be used as the changelog Title of the last set of changes
|
||||||
|
## between last valid tag and HEAD if any.
|
||||||
|
unreleased_version_label = "(unreleased)"
|
||||||
|
|
||||||
|
|
||||||
|
## ``output_engine`` is a callable
|
||||||
|
##
|
||||||
|
## This will change the output format of the generated changelog file
|
||||||
|
##
|
||||||
|
## Available choices are:
|
||||||
|
##
|
||||||
|
## - rest_py
|
||||||
|
##
|
||||||
|
## Legacy pure python engine, outputs ReSTructured text.
|
||||||
|
## This is the default.
|
||||||
|
##
|
||||||
|
## - mustache(<template_name>)
|
||||||
|
##
|
||||||
|
## Template name could be any of the available templates in
|
||||||
|
## ``templates/mustache/*.tpl``.
|
||||||
|
## Requires python package ``pystache``.
|
||||||
|
## Examples:
|
||||||
|
## - mustache("markdown")
|
||||||
|
## - mustache("restructuredtext")
|
||||||
|
##
|
||||||
|
## - makotemplate(<template_name>)
|
||||||
|
##
|
||||||
|
## Template name could be any of the available templates in
|
||||||
|
## ``templates/mako/*.tpl``.
|
||||||
|
## Requires python package ``mako``.
|
||||||
|
## Examples:
|
||||||
|
## - makotemplate("restructuredtext")
|
||||||
|
##
|
||||||
|
#output_engine = rest_py
|
||||||
|
#output_engine = mustache("restructuredtext")
|
||||||
|
output_engine = mustache("markdown")
|
||||||
|
#output_engine = makotemplate("restructuredtext")
|
||||||
|
|
||||||
|
|
||||||
|
## ``include_merge`` is a boolean
|
||||||
|
##
|
||||||
|
## This option tells git-log whether to include merge commits in the log.
|
||||||
|
## The default is to include them.
|
||||||
|
include_merge = True
|
||||||
|
|
||||||
|
|
||||||
|
## ``log_encoding`` is a string identifier
|
||||||
|
##
|
||||||
|
## This option tells gitchangelog what encoding is outputed by ``git log``.
|
||||||
|
## The default is to be clever about it: it checks ``git config`` for
|
||||||
|
## ``i18n.logOutputEncoding``, and if not found will default to git's own
|
||||||
|
## default: ``utf-8``.
|
||||||
|
#log_encoding = 'utf-8'
|
||||||
|
|
||||||
|
|
||||||
|
## ``publish`` is a callable
|
||||||
|
##
|
||||||
|
## Sets what ``gitchangelog`` should do with the output generated by
|
||||||
|
## the output engine. ``publish`` is a callable taking one argument
|
||||||
|
## that is an interator on lines from the output engine.
|
||||||
|
##
|
||||||
|
## Some helper callable are provided:
|
||||||
|
##
|
||||||
|
## Available choices are:
|
||||||
|
##
|
||||||
|
## - stdout
|
||||||
|
##
|
||||||
|
## Outputs directly to standard output
|
||||||
|
## (This is the default)
|
||||||
|
##
|
||||||
|
## - FileInsertAtFirstRegexMatch(file, pattern, idx=lamda m: m.start())
|
||||||
|
##
|
||||||
|
## Creates a callable that will parse given file for the given
|
||||||
|
## regex pattern and will insert the output in the file.
|
||||||
|
## ``idx`` is a callable that receive the matching object and
|
||||||
|
## must return a integer index point where to insert the
|
||||||
|
## the output in the file. Default is to return the position of
|
||||||
|
## the start of the matched string.
|
||||||
|
##
|
||||||
|
## - FileRegexSubst(file, pattern, replace, flags)
|
||||||
|
##
|
||||||
|
## Apply a replace inplace in the given file. Your regex pattern must
|
||||||
|
## take care of everything and might be more complex. Check the README
|
||||||
|
## for a complete copy-pastable example.
|
||||||
|
##
|
||||||
|
# publish = FileInsertIntoFirstRegexMatch(
|
||||||
|
# "CHANGELOG.rst",
|
||||||
|
# r'/(?P<rev>[0-9]+\.[0-9]+(\.[0-9]+)?)\s+\([0-9]+-[0-9]{2}-[0-9]{2}\)\n--+\n/',
|
||||||
|
# idx=lambda m: m.start(1)
|
||||||
|
# )
|
||||||
|
#publish = stdout
|
||||||
|
|
||||||
|
|
||||||
|
## ``revs`` is a list of callable or a list of string
|
||||||
|
##
|
||||||
|
## callable will be called to resolve as strings and allow dynamical
|
||||||
|
## computation of these. The result will be used as revisions for
|
||||||
|
## gitchangelog (as if directly stated on the command line). This allows
|
||||||
|
## to filter exaclty which commits will be read by gitchangelog.
|
||||||
|
##
|
||||||
|
## To get a full documentation on the format of these strings, please
|
||||||
|
## refer to the ``git rev-list`` arguments. There are many examples.
|
||||||
|
##
|
||||||
|
## Using callables is especially useful, for instance, if you
|
||||||
|
## are using gitchangelog to generate incrementally your changelog.
|
||||||
|
##
|
||||||
|
## Some helpers are provided, you can use them::
|
||||||
|
##
|
||||||
|
## - FileFirstRegexMatch(file, pattern): will return a callable that will
|
||||||
|
## return the first string match for the given pattern in the given file.
|
||||||
|
## If you use named sub-patterns in your regex pattern, it'll output only
|
||||||
|
## the string matching the regex pattern named "rev".
|
||||||
|
##
|
||||||
|
## - Caret(rev): will return the rev prefixed by a "^", which is a
|
||||||
|
## way to remove the given revision and all its ancestor.
|
||||||
|
##
|
||||||
|
## Please note that if you provide a rev-list on the command line, it'll
|
||||||
|
## replace this value (which will then be ignored).
|
||||||
|
##
|
||||||
|
## If empty, then ``gitchangelog`` will act as it had to generate a full
|
||||||
|
## changelog.
|
||||||
|
##
|
||||||
|
## The default is to use all commits to make the changelog.
|
||||||
|
#revs = ["^1.0.3", ]
|
||||||
|
#revs = [
|
||||||
|
# Caret(
|
||||||
|
# FileFirstRegexMatch(
|
||||||
|
# "CHANGELOG.rst",
|
||||||
|
# r"(?P<rev>[0-9]+\.[0-9]+(\.[0-9]+)?)\s+\([0-9]+-[0-9]{2}-[0-9]{2}\)\n--+\n")),
|
||||||
|
# "HEAD"
|
||||||
|
#]
|
||||||
|
revs = []
|
||||||
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.env*
|
||||||
46
CHANGELOG.md
Normal file
46
CHANGELOG.md
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
|
||||||
|
## (unreleased)
|
||||||
|
|
||||||
|
### New
|
||||||
|
|
||||||
|
* :sparkles: add completion. [Eduard Veit]
|
||||||
|
|
||||||
|
:sparkles: add man page
|
||||||
|
|
||||||
|
* :sparkles: replace getopt with argbash. [Eduard Veit]
|
||||||
|
|
||||||
|
* :sparkles: add interpretaton of status codes and act accordingly. [Eduard Veit]
|
||||||
|
|
||||||
|
* :sparkles: make network interface configurable. [Eduard Veit]
|
||||||
|
|
||||||
|
* :sparkles: add DynDNS2 support for dynv6.com. [Eduard Veit]
|
||||||
|
|
||||||
|
* :sparkles: add .gitchangelog.rc. [Eduard Veit]
|
||||||
|
|
||||||
|
* :sparkles: add dynb.sh. [Eduard Veit]
|
||||||
|
|
||||||
|
### Fix
|
||||||
|
|
||||||
|
* :bug: fix sourcing of config file. [Eduard Veit]
|
||||||
|
|
||||||
|
:recycle: do some shellcheck fixes
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
|
||||||
|
* :memo: add CHANGELOG.md. [Eduard Veit]
|
||||||
|
|
||||||
|
* :memo: add example.env. [Eduard Veit]
|
||||||
|
|
||||||
|
* :memo: write README.md. [Eduard Veit]
|
||||||
|
|
||||||
|
### Other
|
||||||
|
|
||||||
|
* :recycle: refactor, fix and debug error handling. [Eduard Veit]
|
||||||
|
|
||||||
|
* :recycle: refactor main code. [Eduard Veit]
|
||||||
|
|
||||||
|
* Initial commit. [EV21]
|
||||||
|
|
||||||
|
|
||||||
108
README.md
108
README.md
@@ -1,2 +1,106 @@
|
|||||||
# dynb
|
# 🔃 DynB
|
||||||
dynb - dynamic DNS update script for bash
|
DynB - dynamic DNS update script, written in bash
|
||||||
|
|
||||||
|
IPv4 (A) and IPv6 (AAAA) record updates are supported.
|
||||||
|
<!-- TOC -->
|
||||||
|
- [✨ Update Methods](#-update-methods)
|
||||||
|
- [APIs](#apis)
|
||||||
|
- [DynDNS2](#dyndns2)
|
||||||
|
- [📦 Requirements](#-requirements)
|
||||||
|
- [🚀 Installation](#-installation)
|
||||||
|
- [⚙ Configuration](#-configuration)
|
||||||
|
- [🏃 Run](#-run)
|
||||||
|
- [⏰ Cron](#-cron)
|
||||||
|
<!-- /TOC -->
|
||||||
|
|
||||||
|
## ✨ Update Methods
|
||||||
|
The following update methods are currently implemented:
|
||||||
|
|
||||||
|
### APIs
|
||||||
|
|
||||||
|
* INWX.com Domrobot JSON-RPC-API
|
||||||
|
Limitations:
|
||||||
|
- minimum TTL is 300 (5 minutes)
|
||||||
|
|
||||||
|
### DynDNS2
|
||||||
|
|
||||||
|
* INWX.com
|
||||||
|
* dynv6.com
|
||||||
|
|
||||||
|
## 📦 Requirements
|
||||||
|
|
||||||
|
* `curl` - The minimum requirement for running DynDNS2 operations
|
||||||
|
|
||||||
|
also essential if you are using other APIs:
|
||||||
|
|
||||||
|
* `jq` - Command-line JSON processor
|
||||||
|
|
||||||
|
## 🚀 Installation
|
||||||
|
|
||||||
|
Download the latest release
|
||||||
|
|
||||||
|
or simply clone this repo
|
||||||
|
```
|
||||||
|
git clone https://github.com/EV21/dynb.git
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to add the script to you PATH, run :point_down:
|
||||||
|
```
|
||||||
|
bash dynb.sh --link
|
||||||
|
```
|
||||||
|
This convenience function only works if `util-linux` is installed on your system.
|
||||||
|
|
||||||
|
## ⚙ Configuration
|
||||||
|
|
||||||
|
You can use a config in form of an `.env` file.
|
||||||
|
Or you can just use CLI parameters.
|
||||||
|
|
||||||
|
Create `.env` in the app root directory or at `~/.local/share/dynb/.env`.
|
||||||
|
```
|
||||||
|
_dyn_domain=dyndns.example.com
|
||||||
|
|
||||||
|
## service provider could be inwx
|
||||||
|
_serviceProvider=inwx
|
||||||
|
|
||||||
|
## update method options: domrobot, dyndns
|
||||||
|
_update_method=domrobot
|
||||||
|
|
||||||
|
## ip mode could be either: 4, 6 or dual for dualstack
|
||||||
|
_ip_mode=dual
|
||||||
|
|
||||||
|
## If you are using the DomRobot RPC-API enter your credentials for the web interface login here
|
||||||
|
## If you are using the DynDNS2 protocol enter your credentials here
|
||||||
|
_username=
|
||||||
|
_password=
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🏃 Run
|
||||||
|
|
||||||
|
If you have a config file just run :point_down:
|
||||||
|
```
|
||||||
|
dynb
|
||||||
|
```
|
||||||
|
Alternatively you can use parameters if your system meets the relevant requirements. This example shows the long form parameter, there are also short ones.
|
||||||
|
Call the help function :point_down:
|
||||||
|
```
|
||||||
|
dynb --help
|
||||||
|
```
|
||||||
|
```
|
||||||
|
dynb --ip-mode dualstack --update-method domrobot --domain dyndns.example.com --username user42 --password SuperSecretPassword
|
||||||
|
```
|
||||||
|
```
|
||||||
|
dynb --ip-mode dualstack --update-method dyndns --provider inwx --domain dyndns.example.com --username user42 --password SuperSecretPassword
|
||||||
|
```
|
||||||
|
|
||||||
|
## ⏰ Cron
|
||||||
|
To automatically call the script you can use cron.
|
||||||
|
|
||||||
|
execute :point_down:
|
||||||
|
```
|
||||||
|
crontab -e
|
||||||
|
```
|
||||||
|
then enter :point_down: to run dynb every five minutes.
|
||||||
|
```
|
||||||
|
*/5 * * * * $HOME/.local/bin/dynb >> $HOME/.local/share/dynb/dynb-cron.log
|
||||||
|
```
|
||||||
|
Note, cron typically does not use the users PATH variable.
|
||||||
|
|||||||
41
_dynb.sh
Executable file
41
_dynb.sh
Executable file
@@ -0,0 +1,41 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Put this file to /etc/bash_completion.d/dynb.sh
|
||||||
|
# needed because of Argbash --> m4_ignore([
|
||||||
|
### START OF CODE GENERATED BY Argbash v2.10.0 one line above ###
|
||||||
|
# Argbash is a bash code generator used to get arguments parsing right.
|
||||||
|
# Argbash is FREE SOFTWARE, see https://argbash.io for more info
|
||||||
|
|
||||||
|
_dynb_sh ()
|
||||||
|
{
|
||||||
|
local cur prev opts base
|
||||||
|
COMPREPLY=()
|
||||||
|
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
|
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||||
|
all_long_opts="--version --link --reset --debug --update-method --ip-mode --domain --service-provider --username --password --token --help "
|
||||||
|
all_short_opts="-v -l -r -m -i -d -s -u -p -t -h "
|
||||||
|
case "$prev" in
|
||||||
|
--update-method|-m|--ip-mode|-i|--domain|-d|--service-provider|-s|--username|-u|--password|-p|--token|-t)
|
||||||
|
COMPREPLY=( $(compgen -o bashdefault -o default -- "${cur}") )
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
case "$cur" in
|
||||||
|
--*)
|
||||||
|
COMPREPLY=( $(compgen -W "${all_long_opts}" -- "${cur}") )
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
COMPREPLY=( $(compgen -W "${all_short_opts}" -- "${cur}") )
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
COMPREPLY=( $(compgen -o bashdefault -o default -- "${cur}") )
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
esac
|
||||||
|
|
||||||
|
}
|
||||||
|
complete -F _dynb_sh dynb.sh dynb
|
||||||
|
### END OF CODE GENERATED BY Argbash (sortof) ### ])
|
||||||
817
dynb.sh
Executable file
817
dynb.sh
Executable file
@@ -0,0 +1,817 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
## Copyright (c) 2021 Eduard Veit
|
||||||
|
## All rights reserved. This program and the accompanying materials
|
||||||
|
## are made available under the terms of the MIT license
|
||||||
|
## which accompanies this distribution, and is available at
|
||||||
|
## https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
###################
|
||||||
|
## Configuration ##
|
||||||
|
###################
|
||||||
|
|
||||||
|
_dyn_domain=
|
||||||
|
|
||||||
|
## service provider could be inwx
|
||||||
|
_serviceProvider=
|
||||||
|
|
||||||
|
## update method options: domrobot, dyndns
|
||||||
|
_update_method=
|
||||||
|
|
||||||
|
## ip mode could be either: 4, 6 or dual for dualstack
|
||||||
|
_ip_mode=
|
||||||
|
|
||||||
|
## If you are using the DomRobot RPC-API enter your credentials for the web interface login here
|
||||||
|
## If you are using the DynDNS2 protocol enter your credentials here
|
||||||
|
_username=
|
||||||
|
_password=
|
||||||
|
## or use a token
|
||||||
|
_token=
|
||||||
|
|
||||||
|
## TTL (time to live) for the DNS record
|
||||||
|
## This setting is only relevant for API based record updates (not DnyDNS2!)
|
||||||
|
## minimum allowed TTL value by inwx is 300 (5 minutes)
|
||||||
|
TTL=300
|
||||||
|
|
||||||
|
## The IP-Check sites (some sites have different urls for v4 and v6)
|
||||||
|
## Pro tip: use your own ip check server for privacy
|
||||||
|
## it could be as simple as that...
|
||||||
|
## create an index.php with <?php echo $_SERVER['REMOTE_ADDR']; ?>
|
||||||
|
_ipv4_checker=api64.ipify.org
|
||||||
|
_ipv6_checker=api64.ipify.org
|
||||||
|
|
||||||
|
## An exernal DNS check server prevents wrong info from local DNS servers/resolvers
|
||||||
|
_DNS_checkServer=1.1.1.1
|
||||||
|
|
||||||
|
## if you are actively using multiple network interfaces you might want to specify this
|
||||||
|
## normally the default value is okay
|
||||||
|
#_network_interface=eth0
|
||||||
|
_network_interface=
|
||||||
|
|
||||||
|
######################################################
|
||||||
|
## You don't need to change the following variables ##
|
||||||
|
_INWX_JSON_API_URL=https://api.domrobot.com/jsonrpc/
|
||||||
|
_new_IPv4=
|
||||||
|
_new_IPv6=
|
||||||
|
_dns_records=
|
||||||
|
_main_domain=
|
||||||
|
_is_IPv4_enabled=false
|
||||||
|
_is_IPv6_enabled=false
|
||||||
|
_interface_str=
|
||||||
|
_status=
|
||||||
|
_eventTime=0
|
||||||
|
_errorCounter=0
|
||||||
|
_response=
|
||||||
|
_statusHostname=
|
||||||
|
_statusUsername=
|
||||||
|
_statusPassword=
|
||||||
|
_version=0.0.1
|
||||||
|
_userAgent="DynB/$_version github.com/EV21/dynb"
|
||||||
|
_configFile=$HOME/.local/share/dynb/.env
|
||||||
|
_statusFile=/tmp/dynb.status
|
||||||
|
_debug=1
|
||||||
|
|
||||||
|
# Created by argbash-init v2.10.0
|
||||||
|
# Rearrange the order of options below according to what you would like to see in the help message.
|
||||||
|
# ARG_OPTIONAL_BOOLEAN([version],[v],[outputs the client version],[off])
|
||||||
|
# ARG_OPTIONAL_BOOLEAN([link],[l],[links to your script at ~/.local/bin/dynb],[off])
|
||||||
|
# ARG_OPTIONAL_BOOLEAN([reset],[r],[deletes the client blocking status file],[off])
|
||||||
|
# ARG_OPTIONAL_BOOLEAN([debug],[],[enables debug mode],[off])
|
||||||
|
# ARG_OPTIONAL_SINGLE([update-method],[m],[choose if you want to use DynDNS2 or the DomRobot RPC-API],[])
|
||||||
|
# ARG_OPTIONAL_SINGLE([ip-mode],[i],[updates type A (IPv4) and AAAA (IPv6) records],[])
|
||||||
|
# ARG_OPTIONAL_SINGLE([domain],[d],[set the domain you want to update],[])
|
||||||
|
# ARG_OPTIONAL_SINGLE([service-provider],[s],[set your provider in case you are using DynDNS2],[])
|
||||||
|
# ARG_OPTIONAL_SINGLE([username],[u],[depends on your selected update method and your provider],[])
|
||||||
|
# ARG_OPTIONAL_SINGLE([password],[p],[depends on your selected update method and your provider],[])
|
||||||
|
# ARG_OPTIONAL_SINGLE([token],[t],[depends on your selected update method and your provider],[])
|
||||||
|
# ARG_HELP([DynB - dynamic DNS update script for bash])
|
||||||
|
# ARGBASH_GO()
|
||||||
|
# needed because of Argbash --> m4_ignore([
|
||||||
|
### START OF CODE GENERATED BY Argbash v2.10.0 one line above ###
|
||||||
|
# Argbash is a bash code generator used to get arguments parsing right.
|
||||||
|
# Argbash is FREE SOFTWARE, see https://argbash.io for more info
|
||||||
|
|
||||||
|
|
||||||
|
die()
|
||||||
|
{
|
||||||
|
local _ret="${2:-1}"
|
||||||
|
test "${_PRINT_HELP:-no}" = yes && print_help >&2
|
||||||
|
echo "$1" >&2
|
||||||
|
exit "${_ret}"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
begins_with_short_option()
|
||||||
|
{
|
||||||
|
local first_option all_short_options='vlrmidsupth'
|
||||||
|
first_option="${1:0:1}"
|
||||||
|
test "$all_short_options" = "${all_short_options/$first_option/}" && return 1 || return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# THE DEFAULTS INITIALIZATION - OPTIONALS
|
||||||
|
_arg_version="off"
|
||||||
|
_arg_link="off"
|
||||||
|
_arg_reset="off"
|
||||||
|
_arg_debug="off"
|
||||||
|
_arg_update_method=
|
||||||
|
_arg_ip_mode=
|
||||||
|
_arg_domain=
|
||||||
|
_arg_service_provider=
|
||||||
|
_arg_username=
|
||||||
|
_arg_password=
|
||||||
|
_arg_token=
|
||||||
|
|
||||||
|
|
||||||
|
print_help()
|
||||||
|
{
|
||||||
|
printf '%s\n' "DynB - dynamic DNS update script for bash"
|
||||||
|
printf 'Usage: %s [-v|--(no-)version] [-l|--(no-)link] [-r|--(no-)reset] [--(no-)debug] [-m|--update-method <arg>] [-i|--ip-mode <arg>] [-d|--domain <arg>] [-s|--service-provider <arg>] [-u|--username <arg>] [-p|--password <arg>] [-t|--token <arg>] [-h|--help]\n' "$0"
|
||||||
|
printf '\t%s\n' "-v, --version, --no-version: outputs the client version (off by default)"
|
||||||
|
printf '\t%s\n' "-l, --link, --no-link: links to your script at ~/.local/bin/dynb (off by default)"
|
||||||
|
printf '\t%s\n' "-r, --reset, --no-reset: deletes the client blocking status file (off by default)"
|
||||||
|
printf '\t%s\n' "--debug, --no-debug: enables debug mode (off by default)"
|
||||||
|
printf '\t%s\n' "-m, --update-method: choose if you want to use DynDNS2 or the DomRobot RPC-API (no default)"
|
||||||
|
printf '\t%s\n' "-i, --ip-mode: updates type A (IPv4) and AAAA (IPv6) records (no default)"
|
||||||
|
printf '\t%s\n' "-d, --domain: set the domain you want to update (no default)"
|
||||||
|
printf '\t%s\n' "-s, --service-provider: set your provider in case you are using DynDNS2 (no default)"
|
||||||
|
printf '\t%s\n' "-u, --username: depends on your selected update method and your provider (no default)"
|
||||||
|
printf '\t%s\n' "-p, --password: depends on your selected update method and your provider (no default)"
|
||||||
|
printf '\t%s\n' "-t, --token: depends on your selected update method and your provider (no default)"
|
||||||
|
printf '\t%s\n' "-h, --help: Prints help"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
parse_commandline()
|
||||||
|
{
|
||||||
|
while test $# -gt 0
|
||||||
|
do
|
||||||
|
_key="$1"
|
||||||
|
case "$_key" in
|
||||||
|
-v|--no-version|--version)
|
||||||
|
_arg_version="on"
|
||||||
|
test "${1:0:5}" = "--no-" && _arg_version="off"
|
||||||
|
;;
|
||||||
|
-v*)
|
||||||
|
_arg_version="on"
|
||||||
|
_next="${_key##-v}"
|
||||||
|
if test -n "$_next" -a "$_next" != "$_key"
|
||||||
|
then
|
||||||
|
{ begins_with_short_option "$_next" && shift && set -- "-v" "-${_next}" "$@"; } || die "The short option '$_key' can't be decomposed to ${_key:0:2} and -${_key:2}, because ${_key:0:2} doesn't accept value and '-${_key:2:1}' doesn't correspond to a short option."
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
-l|--no-link|--link)
|
||||||
|
_arg_link="on"
|
||||||
|
test "${1:0:5}" = "--no-" && _arg_link="off"
|
||||||
|
;;
|
||||||
|
-l*)
|
||||||
|
_arg_link="on"
|
||||||
|
_next="${_key##-l}"
|
||||||
|
if test -n "$_next" -a "$_next" != "$_key"
|
||||||
|
then
|
||||||
|
{ begins_with_short_option "$_next" && shift && set -- "-l" "-${_next}" "$@"; } || die "The short option '$_key' can't be decomposed to ${_key:0:2} and -${_key:2}, because ${_key:0:2} doesn't accept value and '-${_key:2:1}' doesn't correspond to a short option."
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
-r|--no-reset|--reset)
|
||||||
|
_arg_reset="on"
|
||||||
|
test "${1:0:5}" = "--no-" && _arg_reset="off"
|
||||||
|
;;
|
||||||
|
-r*)
|
||||||
|
_arg_reset="on"
|
||||||
|
_next="${_key##-r}"
|
||||||
|
if test -n "$_next" -a "$_next" != "$_key"
|
||||||
|
then
|
||||||
|
{ begins_with_short_option "$_next" && shift && set -- "-r" "-${_next}" "$@"; } || die "The short option '$_key' can't be decomposed to ${_key:0:2} and -${_key:2}, because ${_key:0:2} doesn't accept value and '-${_key:2:1}' doesn't correspond to a short option."
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
--no-debug|--debug)
|
||||||
|
_arg_debug="on"
|
||||||
|
test "${1:0:5}" = "--no-" && _arg_debug="off"
|
||||||
|
;;
|
||||||
|
-m|--update-method)
|
||||||
|
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
|
||||||
|
_arg_update_method="$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--update-method=*)
|
||||||
|
_arg_update_method="${_key##--update-method=}"
|
||||||
|
;;
|
||||||
|
-m*)
|
||||||
|
_arg_update_method="${_key##-m}"
|
||||||
|
;;
|
||||||
|
-i|--ip-mode)
|
||||||
|
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
|
||||||
|
_arg_ip_mode="$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--ip-mode=*)
|
||||||
|
_arg_ip_mode="${_key##--ip-mode=}"
|
||||||
|
;;
|
||||||
|
-i*)
|
||||||
|
_arg_ip_mode="${_key##-i}"
|
||||||
|
;;
|
||||||
|
-d|--domain)
|
||||||
|
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
|
||||||
|
_arg_domain="$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--domain=*)
|
||||||
|
_arg_domain="${_key##--domain=}"
|
||||||
|
;;
|
||||||
|
-d*)
|
||||||
|
_arg_domain="${_key##-d}"
|
||||||
|
;;
|
||||||
|
-s|--service-provider)
|
||||||
|
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
|
||||||
|
_arg_service_provider="$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--service-provider=*)
|
||||||
|
_arg_service_provider="${_key##--service-provider=}"
|
||||||
|
;;
|
||||||
|
-s*)
|
||||||
|
_arg_service_provider="${_key##-s}"
|
||||||
|
;;
|
||||||
|
-u|--username)
|
||||||
|
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
|
||||||
|
_arg_username="$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--username=*)
|
||||||
|
_arg_username="${_key##--username=}"
|
||||||
|
;;
|
||||||
|
-u*)
|
||||||
|
_arg_username="${_key##-u}"
|
||||||
|
;;
|
||||||
|
-p|--password)
|
||||||
|
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
|
||||||
|
_arg_password="$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--password=*)
|
||||||
|
_arg_password="${_key##--password=}"
|
||||||
|
;;
|
||||||
|
-p*)
|
||||||
|
_arg_password="${_key##-p}"
|
||||||
|
;;
|
||||||
|
-t|--token)
|
||||||
|
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
|
||||||
|
_arg_token="$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--token=*)
|
||||||
|
_arg_token="${_key##--token=}"
|
||||||
|
;;
|
||||||
|
-t*)
|
||||||
|
_arg_token="${_key##-t}"
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
print_help
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-h*)
|
||||||
|
print_help
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
_PRINT_HELP=yes die "FATAL ERROR: Got an unexpected argument '$1'" 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_commandline "$@"
|
||||||
|
|
||||||
|
# OTHER STUFF GENERATED BY Argbash
|
||||||
|
|
||||||
|
### END OF CODE GENERATED BY Argbash (sortof) ### ])
|
||||||
|
# [ <-- needed because of Argbash
|
||||||
|
|
||||||
|
_help_message="$(cat << 'EOF'
|
||||||
|
dynb - dynamic DNS update script for bash
|
||||||
|
|
||||||
|
Usage
|
||||||
|
=====
|
||||||
|
dynb [options]
|
||||||
|
|
||||||
|
-h, --help displays this help message
|
||||||
|
--version outputs the client version
|
||||||
|
--link links to your script at ~/.local/bin/dynb
|
||||||
|
--reset deletes the client blocking status file
|
||||||
|
|
||||||
|
Configuration options
|
||||||
|
---------------------
|
||||||
|
-i | --ip-mode [ 4 | 6 | dual ] updates type A (IPv4) and AAAA (IPv6) records
|
||||||
|
-m | --update-method [dyndns | domrobot] choose if you want to use DynDNS2 or the DomRobot RPC-API
|
||||||
|
-s | --service-provider inwx set your provider in case you are using DynDNS2
|
||||||
|
-d | --domain "dyndns.example.com" set the domain you want to update
|
||||||
|
-u | --username "user42" depends on your selected update method and your provider
|
||||||
|
-p | --password "SuperSecretPassword" depends on your selected update method and your provider
|
||||||
|
-t | --token "YourProviderGivenToken" depends on your selected update method and your provider
|
||||||
|
|
||||||
|
##### examples #####
|
||||||
|
dynb --ip-mode dual --update-method domrobot --domain dyndns.example.com --username user42 --password SuperSecretPassword
|
||||||
|
dynb --ip-mode dual --update-method dyndns --service-provider inwx --domain dyndns.example.com --username user42 --password SuperSecretPassword
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
|
||||||
|
function debugMode() {
|
||||||
|
if [[ $_debug -eq 1 ]]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function debugMessage() {
|
||||||
|
if debugMode; then
|
||||||
|
echo "Debug: ${1}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function echoerr() { printf "%s\n" "$*" >&2; }
|
||||||
|
|
||||||
|
# The main domain as an identifier for the dns zone is required for the updateRecord call
|
||||||
|
function getMainDomain() {
|
||||||
|
request=$( echo "{}" | \
|
||||||
|
jq '(.method="nameserver.list")' | \
|
||||||
|
jq "(.params.user=\"$_username\")" | \
|
||||||
|
jq "(.params.pass=\"$_password\")"
|
||||||
|
)
|
||||||
|
|
||||||
|
_response=$(curl --silent \
|
||||||
|
"$_interface_str" \
|
||||||
|
--user-agent "$_userAgent" \
|
||||||
|
--header "Content-Type: application/json" \
|
||||||
|
--request POST $_INWX_JSON_API_URL \
|
||||||
|
--data "$request" | jq ".resData.domains[] | select(inside(.domain=\"$_dyn_domain\"))"
|
||||||
|
)
|
||||||
|
_main_domain=$( echo "$_response" | jq --raw-output '.domain' )
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchDNSRecords() {
|
||||||
|
request=$( echo "{}" | \
|
||||||
|
jq '(.method="'nameserver.info'")' | \
|
||||||
|
jq "(.params.user=\"$_username\")" | \
|
||||||
|
jq "(.params.pass=\"$_password\")" | \
|
||||||
|
jq "(.params.domain=\"$_main_domain\")" | \
|
||||||
|
jq "(.params.name=\"$_dyn_domain\")"
|
||||||
|
)
|
||||||
|
|
||||||
|
_response=$( curl --silent \
|
||||||
|
"$_interface_str" \
|
||||||
|
--user-agent "$_userAgent" \
|
||||||
|
--header "Content-Type: application/json" \
|
||||||
|
--request POST $_INWX_JSON_API_URL \
|
||||||
|
--data "$request"
|
||||||
|
)
|
||||||
|
|
||||||
|
_dns_records=$( echo "$_response" | jq '.resData.record[]' )
|
||||||
|
}
|
||||||
|
|
||||||
|
# requires parameter A or AAAA
|
||||||
|
# result to stdout
|
||||||
|
function getRecordID() {
|
||||||
|
echo "$_dns_records" | jq "select(.type == \"${1}\") | .id"
|
||||||
|
}
|
||||||
|
|
||||||
|
# requires parameter A or AAAA
|
||||||
|
# result to stdout
|
||||||
|
function getDNSIP() {
|
||||||
|
echo "$_dns_records" | jq --raw-output "select(.type == \"${1}\") | .content"
|
||||||
|
}
|
||||||
|
|
||||||
|
# requires parameter
|
||||||
|
# 1. param: 4 or 6 for ip version
|
||||||
|
# 2. param: IP check server address
|
||||||
|
# result to stdout
|
||||||
|
function getRemoteIP() {
|
||||||
|
curl --silent "$_interface_str" --user-agent "$_userAgent" \
|
||||||
|
--ipv"${1}" --dns-servers 1.1.1.1 --location "${2}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# requires parameter
|
||||||
|
# 1. param: 4 or 6 as ip version
|
||||||
|
function updateRecord() {
|
||||||
|
if [[ ${1} == 4 ]]; then
|
||||||
|
ID=$(getRecordID A)
|
||||||
|
IP=$_new_IPv4
|
||||||
|
fi
|
||||||
|
if [[ ${1} == 6 ]]; then
|
||||||
|
ID=$(getRecordID AAAA)
|
||||||
|
IP=$_new_IPv6
|
||||||
|
fi
|
||||||
|
if [[ $IP != "" ]]; then
|
||||||
|
request=$( echo "{}" | \
|
||||||
|
jq '(.method="nameserver.updateRecord")' | \
|
||||||
|
jq "(.params.user=\"$_username\")" | \
|
||||||
|
jq "(.params.pass=\"$_password\")" | \
|
||||||
|
jq "(.params.id=\"$ID\")" | \
|
||||||
|
jq "(.params.content=\"$IP\")" | \
|
||||||
|
jq "(.params.ttl=\"$TTL\")"
|
||||||
|
)
|
||||||
|
|
||||||
|
_response=$(curl --silent \
|
||||||
|
"$_interface_str" \
|
||||||
|
--user-agent "$_userAgent" \
|
||||||
|
--header "Content-Type: application/json" \
|
||||||
|
--request POST $_INWX_JSON_API_URL \
|
||||||
|
--data "$request"
|
||||||
|
)
|
||||||
|
echo -e "$(echo "$_response" | jq --raw-output '.msg')\n Domain: $_dyn_domain\n new IPv${1}: $IP"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# using DynDNS2 protocol
|
||||||
|
function dynupdate() {
|
||||||
|
# default parameter values
|
||||||
|
myip_str=myip
|
||||||
|
myipv6_str=myipv6
|
||||||
|
|
||||||
|
INWX_DYNDNS_UPDATE_URL="https://dyndns.inwx.com/nic/update?"
|
||||||
|
DYNV6_DYNDNS_UPDATE_URL="https://dynv6.com/api/update?zone=$_dyn_domain&token=$_token&"
|
||||||
|
|
||||||
|
if [[ $_serviceProvider == "inwx" ]]; then
|
||||||
|
dyndns_update_url=$INWX_DYNDNS_UPDATE_URL
|
||||||
|
fi
|
||||||
|
if [[ $_serviceProvider == "dynv6" ]]; then
|
||||||
|
dyndns_update_url="${DYNV6_DYNDNS_UPDATE_URL}"
|
||||||
|
myip_str=ipv4
|
||||||
|
myipv6_str=ipv6
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $_is_IPv4_enabled == true ]] && [[ $_is_IPv6_enabled == true ]]; then
|
||||||
|
dyndns_update_url="${dyndns_update_url}${myip_str}=${_new_IPv4}&${myipv6_str}=${_new_IPv6}"
|
||||||
|
fi
|
||||||
|
if [[ $_is_IPv4_enabled == true ]] && [[ $_is_IPv6_enabled == false ]]; then
|
||||||
|
dyndns_update_url="${dyndns_update_url}${myip_str}=${_new_IPv4}"
|
||||||
|
fi
|
||||||
|
if [[ $_is_IPv4_enabled == false ]] && [[ $_is_IPv6_enabled == true ]]; then
|
||||||
|
dyndns_update_url="${dyndns_update_url}${myipv6_str}=${_new_IPv6}"
|
||||||
|
fi
|
||||||
|
debugMessage "Update URL was: $dyndns_update_url"
|
||||||
|
## request ##
|
||||||
|
if [[ $_serviceProvider == "dynv6" ]]; then
|
||||||
|
_response=$(curl --silent "$_interface_str" \
|
||||||
|
--user-agent "$_userAgent" \
|
||||||
|
"${dyndns_update_url}"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
if [[ $_serviceProvider == "inwx" ]]; then
|
||||||
|
_response=$(curl --silent "$_interface_str" \
|
||||||
|
--user-agent "$_userAgent" \
|
||||||
|
--user "$_username":"$_password" \
|
||||||
|
"${dyndns_update_url}" )
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $_response in
|
||||||
|
good* )
|
||||||
|
if [[ $_response == "good 127.0.0.1" ]]; then
|
||||||
|
echoerr "Error: $_response: Request ignored."
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
echo "$_response: The DynDNS update has been executed."
|
||||||
|
_errorCounter=0
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
nochg* )
|
||||||
|
echo "$_response: Nothing has changed, IP addresses are still up to date."
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
abuse )
|
||||||
|
echoerr "Error: $_response: Username is blocked due to abuse."
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
badauth | 401 )
|
||||||
|
echoerr "Error: $_response: Invalid username password combination."
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
badagent )
|
||||||
|
echoerr "Error: $_response: Client disabled. Something is very wrong!"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
!donator )
|
||||||
|
echoerr "Error: $_response: An update request was sent, including a feature that is not available to that particular user such as offline options."
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
!yours )
|
||||||
|
echoerr "Error: $_response: The domain does not belong to your user account"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
notfqdn )
|
||||||
|
echoerr "Error: $_response: Hostname $_dyn_domain is invalid"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
nohost )
|
||||||
|
echoerr "Error: $_response: Hostname supplied does not exist under specified account, enter new login credentials before performing an additional request."
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
numhost )
|
||||||
|
echoerr "Error: $_response: Too many hostnames have been specified for this update"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
dnserr )
|
||||||
|
echoerr "Error: $_response: There is an internal error in the dyndns update system. Retry update no sooner than 30 minutes."
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
911 | 5* )
|
||||||
|
echoerr "Error: $_response: A fatal error on provider side such as a database outage. Retry update no sooner than 30 minutes."
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
if [[ "$_response" == "$_status" ]]; then
|
||||||
|
echoerr "Error: An unknown response code has been received. $_response"
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
echoerr "Error: unknown respnse code: $_response"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
function setStatus() {
|
||||||
|
echo "_status=$1; _eventTime=$2; _errorCounter=$3; _statusHostname=$4; _statusUsername=$5; _statusPassword=$6" > /tmp/dynb.status
|
||||||
|
}
|
||||||
|
|
||||||
|
# handle errors from past update requests
|
||||||
|
function checkStatus() {
|
||||||
|
case $_status in
|
||||||
|
nochg* )
|
||||||
|
if [[ _errorCounter -gt 1 ]]; then
|
||||||
|
echoerr "Error: The update client was spamming unnecessary update requests, something might be wrong with your IP-Check site."
|
||||||
|
echoerr "Fix your config an then delete $_statusFile"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
nohost | !yours )
|
||||||
|
if [[ "$_statusHostname" == "$_dyn_domain" && ( "$_statusUsername" == "$_username" || $_statusUsername == "$_token" ) ]]; then
|
||||||
|
echoerr "Error: Hostname supplied does not exist under specified account, enter new login credentials before performing an additional request."
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
rm "$_statusFile"
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
badauth | 401 )
|
||||||
|
if [[ "$_statusUsername" == "$_username" && "$_statusPassword" == "$_password" ]]; then
|
||||||
|
echoerr "Error: Invalid username password combination."
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
rm "$_statusFile"
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
badagent )
|
||||||
|
echoerr "Error: Client is deactivated by provider."
|
||||||
|
echo "Fix your config and then manually remove $_statusFile to reset the client blockade."
|
||||||
|
echo "If it still fails file an issue at github or try another client :)"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
!donator )
|
||||||
|
echoerr "Error: An update request was sent, including a feature that is not available to that particular user such as offline options."
|
||||||
|
echo "Fix your config and then manually remove $_statusFile to reset the client blockade"
|
||||||
|
echo "If it still fails file an issue at github or try another client :)"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
abuse )
|
||||||
|
echoerr "Error: Username is blocked due to abuse."
|
||||||
|
echo "Fix your config and then manually remove $_statusFile to reset the client blockade"
|
||||||
|
echo "If it still fails file an issue at github or try another client :)"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
911 | 5* )
|
||||||
|
delta=$(( $(date +%s) - _eventTime ))
|
||||||
|
if [[ $delta -lt 1800 ]]; then
|
||||||
|
echoerr "$_status: The provider currently has an fatal error. DynB will wait for next update until 30 minutes have passed since last request, $(date --date=@$delta -u +%M) minutes already passed."
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
rm "$_statusFile"
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
if [[ _errorCounter -gt 1 ]]; then
|
||||||
|
echoerr "Error: An unknown response code has repeatedly been received. $_response"
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# requires parameter
|
||||||
|
# 1. param: 4 or 6 for IP version
|
||||||
|
function ipHasChanged() {
|
||||||
|
if [[ ${1} == 4 ]]; then
|
||||||
|
remote_ip=$(getRemoteIP 4 $_ipv4_checker)
|
||||||
|
if [[ $_update_method == domrobot ]]; then
|
||||||
|
dns_ip=$(getDNSIP A)
|
||||||
|
else
|
||||||
|
dns_ip=$(dig @${_DNS_checkServer} in a +short "$_dyn_domain")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ ${1} == 6 ]]; then
|
||||||
|
remote_ip=$(getRemoteIP 6 $_ipv6_checker)
|
||||||
|
if [[ $_update_method == domrobot ]]; then
|
||||||
|
dns_ip=$(getDNSIP AAAA)
|
||||||
|
else
|
||||||
|
dns_ip=$(dig @${_DNS_checkServer} in aaaa +short "$_dyn_domain")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ${1} == 4 ]]; then
|
||||||
|
_new_IPv4=$remote_ip
|
||||||
|
#echo "New IPv4: $_new_IPv4 old was: $dns_ip"
|
||||||
|
else
|
||||||
|
_new_IPv6=$remote_ip
|
||||||
|
#echo "New IPv6: $_new_IPv6 old was: $dns_ip"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$remote_ip" == "$dns_ip" ]]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
################
|
||||||
|
## parameters ##
|
||||||
|
################
|
||||||
|
|
||||||
|
function handleParameters() {
|
||||||
|
if [[ $_arg_version == "on" ]]; then
|
||||||
|
echo $_version
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
if [[ $_arg_link == "on" ]]; then
|
||||||
|
ln --verbose --symbolic "$(realpath "$0")" "$HOME/.local/bin/dynb"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
if [[ $_arg_reset == "on" ]]; then
|
||||||
|
rm --verbose "$_statusFile"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
if [[ $_arg_update_method != "" ]]; then
|
||||||
|
_update_method=$_arg_update_method
|
||||||
|
fi
|
||||||
|
if [[ $_arg_ip_mode != "" ]]; then
|
||||||
|
_ip_mode=$_arg_ip_mode
|
||||||
|
fi
|
||||||
|
if [[ $_arg_domain != "" ]]; then
|
||||||
|
_dyn_domain=$_arg_domain
|
||||||
|
fi
|
||||||
|
if [[ $_arg_service_provider != "" ]]; then
|
||||||
|
_serviceProvider=$_arg_service_provider
|
||||||
|
fi
|
||||||
|
if [[ $_arg_username != "" ]]; then
|
||||||
|
_username=$_arg_username
|
||||||
|
fi
|
||||||
|
if [[ $_arg_password != "" ]]; then
|
||||||
|
_password=$_arg_password
|
||||||
|
fi
|
||||||
|
if [[ $_arg_token != "" ]]; then
|
||||||
|
_token=$_arg_token
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
##################
|
||||||
|
## dependencies ##
|
||||||
|
##################
|
||||||
|
|
||||||
|
function checkDependencies() {
|
||||||
|
## If there will be more general dependencies use a loop
|
||||||
|
# for i in curl and some other stuff; do
|
||||||
|
# if ! command -v $i >/dev/null 2>&1; then
|
||||||
|
# echoerr "Error: could not find \"$i\", DynB depends on it. "
|
||||||
|
# exit 1
|
||||||
|
# fi
|
||||||
|
# done
|
||||||
|
[[ -x $(command -v jq 2> /dev/null) ]] || {
|
||||||
|
if [[ $_update_method != dyndns* ]]; then
|
||||||
|
echo "This script depends on jq and it is not available." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function doUnsets() {
|
||||||
|
unset _network_interface
|
||||||
|
unset _DNS_checkServer
|
||||||
|
unset _dns_records
|
||||||
|
unset _dyn_domain
|
||||||
|
unset _has_getopt
|
||||||
|
unset _help_message
|
||||||
|
unset _INWX_JSON_API_URL
|
||||||
|
unset _ip_mode
|
||||||
|
unset _ipv4_checker
|
||||||
|
unset _ipv6_checker
|
||||||
|
unset _is_IPv4_enabled
|
||||||
|
unset _is_IPv6_enabled
|
||||||
|
unset _main_domain
|
||||||
|
unset _new_IPv4
|
||||||
|
unset _new_IPv6
|
||||||
|
unset _password
|
||||||
|
unset _username
|
||||||
|
unset _serviceProvider
|
||||||
|
unset _version
|
||||||
|
}
|
||||||
|
|
||||||
|
#################
|
||||||
|
## MAIN method ##
|
||||||
|
#################
|
||||||
|
function dynb() {
|
||||||
|
## parameters and checks
|
||||||
|
checkDependencies
|
||||||
|
|
||||||
|
# shellcheck source=.env
|
||||||
|
if test -f "$_configFile"; then
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$_configFile"
|
||||||
|
else
|
||||||
|
alternativeConfig="$(dirname "$(realpath "$0")")/.env"
|
||||||
|
if test -f "$alternativeConfig"; then
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$alternativeConfig"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if test -f "$_statusFile"; then
|
||||||
|
debugMessage "read previous status file"
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
source "$_statusFile"
|
||||||
|
fi
|
||||||
|
|
||||||
|
handleParameters
|
||||||
|
|
||||||
|
if [[ $_network_interface != "" ]]; then
|
||||||
|
_interface_str="--interface $_network_interface"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $_ip_mode == d* ]]; then
|
||||||
|
_is_IPv4_enabled=true
|
||||||
|
_is_IPv6_enabled=true
|
||||||
|
fi
|
||||||
|
if [[ $_ip_mode == *4* ]]; then
|
||||||
|
_is_IPv4_enabled=true
|
||||||
|
fi
|
||||||
|
if [[ $_ip_mode == *6* ]]; then
|
||||||
|
_is_IPv6_enabled=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
## execute operations
|
||||||
|
|
||||||
|
if [[ $_update_method == "domrobot" ]]; then
|
||||||
|
getMainDomain
|
||||||
|
fetchDNSRecords
|
||||||
|
if [[ $_is_IPv4_enabled == true ]]; then
|
||||||
|
ipHasChanged 4
|
||||||
|
if [[ $? == 1 ]]; then
|
||||||
|
updateRecord 4
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ $_is_IPv6_enabled == true ]]; then
|
||||||
|
ipHasChanged 6
|
||||||
|
if [[ $? == 1 ]]; then
|
||||||
|
updateRecord 6
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $_update_method == "dyndns" ]]; then
|
||||||
|
changed=0
|
||||||
|
if [[ $_is_IPv4_enabled == true ]]; then
|
||||||
|
ipHasChanged 4
|
||||||
|
(( changed += $? ))
|
||||||
|
fi
|
||||||
|
if [[ $_is_IPv6_enabled == true ]]; then
|
||||||
|
ipHasChanged 6
|
||||||
|
(( changed += $? ))
|
||||||
|
fi
|
||||||
|
if [[ $changed -gt 0 ]]; then
|
||||||
|
if checkStatus; then
|
||||||
|
debugMessage "checkStatus has no errors"
|
||||||
|
if dynupdate; then
|
||||||
|
debugMessage "DynDNS2 update success"
|
||||||
|
else
|
||||||
|
debugMessage "Save new status after dynupdate has failed"
|
||||||
|
setStatus "$_response" "$(date +%s)" $(( _errorCounter += 1 )) "$_dyn_domain" "${_username}${_token}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
debugMessage "Skip DynDNS2 update, checkStatus fetched previous error."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
doUnsets
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
######################
|
||||||
|
## END MAIN section ##
|
||||||
|
######################
|
||||||
|
|
||||||
|
dynb "${@}"
|
||||||
|
exit $?
|
||||||
|
|
||||||
|
# ] <-- needed because of Argbash
|
||||||
7
example.env
Normal file
7
example.env
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
_dyn_domain=dyndns.example.com
|
||||||
|
_serviceProvider=inwx
|
||||||
|
_update_method=domrobot
|
||||||
|
_ip_mode=dual
|
||||||
|
_username=User42
|
||||||
|
_password=SuperSecretPassword
|
||||||
|
_token=
|
||||||
109
man/dynb.1
Normal file
109
man/dynb.1
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
.\" Man page generated from reStructuredText.
|
||||||
|
.
|
||||||
|
.TH MAN 1 "2021-04-03" "" ""
|
||||||
|
.SH NAME
|
||||||
|
man \- DynB - dynamic DNS update script for bash
|
||||||
|
.
|
||||||
|
.nr rst2man-indent-level 0
|
||||||
|
.
|
||||||
|
.de1 rstReportMargin
|
||||||
|
\\$1 \\n[an-margin]
|
||||||
|
level \\n[rst2man-indent-level]
|
||||||
|
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
|
-
|
||||||
|
\\n[rst2man-indent0]
|
||||||
|
\\n[rst2man-indent1]
|
||||||
|
\\n[rst2man-indent2]
|
||||||
|
..
|
||||||
|
.de1 INDENT
|
||||||
|
.\" .rstReportMargin pre:
|
||||||
|
. RS \\$1
|
||||||
|
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||||
|
. nr rst2man-indent-level +1
|
||||||
|
.\" .rstReportMargin post:
|
||||||
|
..
|
||||||
|
.de UNINDENT
|
||||||
|
. RE
|
||||||
|
.\" indent \\n[an-margin]
|
||||||
|
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
|
.nr rst2man-indent-level -1
|
||||||
|
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
|
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||||
|
..
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.sp
|
||||||
|
\fBman [\-\-version] [\-\-link] [\-\-reset] [\-\-debug] [\-\-update\-method UPDATE\-METHOD] [\-\-ip\-mode IP\-MODE] [\-\-domain DOMAIN] [\-\-service\-provider SERVICE\-PROVIDER] [\-\-username USERNAME] [\-\-password PASSWORD] [\-\-token TOKEN] [\-\-help]\fP
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.sp
|
||||||
|
IPv4 (A) and IPv6 (AAAA) record updates are supported.
|
||||||
|
.SH ARGUMENTS
|
||||||
|
.INDENT 0.0
|
||||||
|
.TP
|
||||||
|
.B \-v\fP,\fB \-\-version
|
||||||
|
outputs the client version.
|
||||||
|
[Default: off]
|
||||||
|
.sp
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B \-l\fP,\fB \-\-link
|
||||||
|
links to your script at ~/.local/bin/dynb.
|
||||||
|
[Default: off]
|
||||||
|
.sp
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B \-r\fP,\fB \-\-reset
|
||||||
|
deletes the client blocking status file.
|
||||||
|
[Default: off]
|
||||||
|
.sp
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B \-\-debug
|
||||||
|
enables debug mode.
|
||||||
|
[Default: off]
|
||||||
|
.sp
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BI \-m \ UPDATE\-METHOD\fR,\fB \ \-\-update\-method \ UPDATE\-METHOD
|
||||||
|
choose if you want to use DynDNS2 or the DomRobot RPC\-API.
|
||||||
|
.sp
|
||||||
|
dyndns | domrobot
|
||||||
|
.TP
|
||||||
|
.BI \-i \ IP\-MODE\fR,\fB \ \-\-ip\-mode \ IP\-MODE
|
||||||
|
updates type A (IPv4) and AAAA (IPv6) records.
|
||||||
|
.sp
|
||||||
|
4 | 6 | dual
|
||||||
|
.TP
|
||||||
|
.BI \-d \ DOMAIN\fR,\fB \ \-\-domain \ DOMAIN
|
||||||
|
set the domain you want to update.
|
||||||
|
.sp
|
||||||
|
dyndns.example.com
|
||||||
|
.TP
|
||||||
|
.BI \-s \ SERVICE\-PROVIDER\fR,\fB \ \-\-service\-provider \ SERVICE\-PROVIDER
|
||||||
|
set your provider in case you are using DynDNS2.
|
||||||
|
.sp
|
||||||
|
inwx | dynv6
|
||||||
|
.TP
|
||||||
|
.BI \-u \ USERNAME\fR,\fB \ \-\-username \ USERNAME
|
||||||
|
depends on your selected update method and your provider.
|
||||||
|
.sp
|
||||||
|
e.g. user42
|
||||||
|
.TP
|
||||||
|
.BI \-p \ PASSWORD\fR,\fB \ \-\-password \ PASSWORD
|
||||||
|
depends on your selected update method and your provider.
|
||||||
|
.sp
|
||||||
|
e.g. SuperSecretPassword
|
||||||
|
.TP
|
||||||
|
.BI \-t \ TOKEN\fR,\fB \ \-\-token \ TOKEN
|
||||||
|
depends on your selected update method and your provider.
|
||||||
|
.sp
|
||||||
|
YourProviderGivenToken
|
||||||
|
.TP
|
||||||
|
.B \-h\fP,\fB \-\-help
|
||||||
|
Prints help.
|
||||||
|
.sp
|
||||||
|
|
||||||
|
.UNINDENT
|
||||||
|
.SH AUTHOR
|
||||||
|
Eduard Veit
|
||||||
|
.\" Generated by docutils manpage writer.
|
||||||
|
.
|
||||||
33
man/man-defs.rst
Normal file
33
man/man-defs.rst
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
|
||||||
|
.. |AUTHOR| replace:: Eduard Veit
|
||||||
|
|
||||||
|
.. |VERSION| replace:: \
|
||||||
|
|
||||||
|
.. |MAN_SECTION| replace:: 1
|
||||||
|
|
||||||
|
.. |DESCRIPTION| replace::
|
||||||
|
IPv4 (A) and IPv6 (AAAA) record updates are supported.
|
||||||
|
|
||||||
|
.. |OPTION_VERSION| replace:: \
|
||||||
|
|
||||||
|
.. |OPTION_LINK| replace:: \
|
||||||
|
|
||||||
|
.. |OPTION_RESET| replace:: \
|
||||||
|
|
||||||
|
.. |OPTION_DEBUG| replace:: \
|
||||||
|
|
||||||
|
.. |OPTION_UPDATE_METHOD| replace:: dyndns | domrobot
|
||||||
|
|
||||||
|
.. |OPTION_IP_MODE| replace:: 4 | 6 | dual
|
||||||
|
|
||||||
|
.. |OPTION_DOMAIN| replace:: dyndns.example.com
|
||||||
|
|
||||||
|
.. |OPTION_SERVICE_PROVIDER| replace:: inwx | dynv6
|
||||||
|
|
||||||
|
.. |OPTION_USERNAME| replace:: e.g. user42
|
||||||
|
|
||||||
|
.. |OPTION_PASSWORD| replace:: e.g. SuperSecretPassword
|
||||||
|
|
||||||
|
.. |OPTION_TOKEN| replace:: YourProviderGivenToken
|
||||||
|
|
||||||
|
.. |OPTION_HELP| replace:: \
|
||||||
84
man/man-template.rst
Normal file
84
man/man-template.rst
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
|
||||||
|
.. include:: man-defs.rst
|
||||||
|
|
||||||
|
|
||||||
|
===
|
||||||
|
man
|
||||||
|
===
|
||||||
|
|
||||||
|
-----------------------------------------
|
||||||
|
DynB - dynamic DNS update script for bash
|
||||||
|
-----------------------------------------
|
||||||
|
|
||||||
|
:Author: |AUTHOR|
|
||||||
|
:Date: 2021-04-03
|
||||||
|
:Version: |VERSION|
|
||||||
|
:Manual section: |MAN_SECTION|
|
||||||
|
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
========
|
||||||
|
|
||||||
|
``man [--version] [--link] [--reset] [--debug] [--update-method UPDATE-METHOD] [--ip-mode IP-MODE] [--domain DOMAIN] [--service-provider SERVICE-PROVIDER] [--username USERNAME] [--password PASSWORD] [--token TOKEN] [--help]``
|
||||||
|
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
===========
|
||||||
|
|
||||||
|
|DESCRIPTION|
|
||||||
|
|
||||||
|
|
||||||
|
ARGUMENTS
|
||||||
|
=========
|
||||||
|
|
||||||
|
-v, --version outputs the client version.
|
||||||
|
[Default: off]
|
||||||
|
|
||||||
|
|OPTION_VERSION|
|
||||||
|
|
||||||
|
-l, --link links to your script at ~/.local/bin/dynb.
|
||||||
|
[Default: off]
|
||||||
|
|
||||||
|
|OPTION_LINK|
|
||||||
|
|
||||||
|
-r, --reset deletes the client blocking status file.
|
||||||
|
[Default: off]
|
||||||
|
|
||||||
|
|OPTION_RESET|
|
||||||
|
|
||||||
|
--debug enables debug mode.
|
||||||
|
[Default: off]
|
||||||
|
|
||||||
|
|OPTION_DEBUG|
|
||||||
|
|
||||||
|
-m UPDATE-METHOD, --update-method UPDATE-METHOD choose if you want to use DynDNS2 or the DomRobot RPC-API.
|
||||||
|
|
||||||
|
|OPTION_UPDATE_METHOD|
|
||||||
|
|
||||||
|
-i IP-MODE, --ip-mode IP-MODE updates type A (IPv4) and AAAA (IPv6) records.
|
||||||
|
|
||||||
|
|OPTION_IP_MODE|
|
||||||
|
|
||||||
|
-d DOMAIN, --domain DOMAIN set the domain you want to update.
|
||||||
|
|
||||||
|
|OPTION_DOMAIN|
|
||||||
|
|
||||||
|
-s SERVICE-PROVIDER, --service-provider SERVICE-PROVIDER set your provider in case you are using DynDNS2.
|
||||||
|
|
||||||
|
|OPTION_SERVICE_PROVIDER|
|
||||||
|
|
||||||
|
-u USERNAME, --username USERNAME depends on your selected update method and your provider.
|
||||||
|
|
||||||
|
|OPTION_USERNAME|
|
||||||
|
|
||||||
|
-p PASSWORD, --password PASSWORD depends on your selected update method and your provider.
|
||||||
|
|
||||||
|
|OPTION_PASSWORD|
|
||||||
|
|
||||||
|
-t TOKEN, --token TOKEN depends on your selected update method and your provider.
|
||||||
|
|
||||||
|
|OPTION_TOKEN|
|
||||||
|
|
||||||
|
-h, --help Prints help.
|
||||||
|
|
||||||
|
|OPTION_HELP|
|
||||||
Reference in New Issue
Block a user