diff --git a/.gitignore b/.gitignore index 8abdc284..cf89f870 100644 --- a/.gitignore +++ b/.gitignore @@ -9,8 +9,5 @@ # html files (as generated from markdown) *.html -# checksums file as used by $ScriptInstallUpdate -checksums.json - # Mac OS X folder settings file .DS_Store diff --git a/BRANCHES.md b/BRANCHES.md index df7eb0d5..5d94077b 100644 --- a/BRANCHES.md +++ b/BRANCHES.md @@ -4,7 +4,7 @@ Installing from branches [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -13,7 +13,7 @@ Installing from branches > ⚠️ **Warning**: Living on the edge? Great, read on! > If not: Please use the `main` branch and leave this page! -These scripts are developed in a [git ↗️](https://git-scm.com/) repository. +These scripts are developed in a [git](https://git-scm.com/) repository. Development and experimental branches are used to provide early access for specific changes. You can install scripts from these branches for testing. diff --git a/CERTIFICATES.md b/CERTIFICATES.md index 3eae6c5c..589d4801 100644 --- a/CERTIFICATES.md +++ b/CERTIFICATES.md @@ -4,7 +4,7 @@ Certificate name from browser [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -21,7 +21,7 @@ first step of [installation](README.md#the-long-way-in-detail) is importing the certificate. The scripts can install additional certificates when required. This happens -from this repository if available, or from [mkcert.org ↗️](https://mkcert.org) +from this repository if available, or from [mkcert.org](https://mkcert.org) as a fallback. Get the certificate's CommonName @@ -29,7 +29,7 @@ Get the certificate's CommonName But how to determine what certificate may be required? Often easiest way is to use a desktop browser to get that information. This demonstration uses -[Mozilla Firefox ↗️](https://www.mozilla.org/firefox/). +[Mozilla Firefox](https://www.mozilla.org/firefox/). Let's assume we want to make sure the certificate for [git.eworm.de](https://git.eworm.de/) is available. Open that page in the @@ -61,7 +61,7 @@ Import a certificate by CommonName Running the function `$CertificateAvailable` with that name as parameter makes sure the certificate is available in the device's store: - $CertificateAvailable "ISRG Root X2" "fetch"; + $CertificateAvailable "ISRG Root X2"; If the certificate is actually available already nothing happens, and there is no output. Otherwise the certificate is downloaded and imported. @@ -74,7 +74,6 @@ See also * [Download, import and update firewall address-lists](doc/fw-addr-lists.md) * [Manage DNS and DoH servers from netwatch](doc/netwatch-dns.md) -* [Send notifications via Gotify](doc/mod/notification-gotify.md) * [Send notifications via Matrix](doc/mod/notification-matrix.md) * [Send notifications via Ntfy](doc/mod/notification-ntfy.md) diff --git a/CONTRIBUTIONS.md b/CONTRIBUTIONS.md index c7e05b21..ef1bd8bf 100644 --- a/CONTRIBUTIONS.md +++ b/CONTRIBUTIONS.md @@ -4,7 +4,7 @@ Past Contributions [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -21,8 +21,6 @@ for details! * [Ben Harris](mailto:mail@bharr.is) (@bharrisau) * [Daniel Ziegenberg](mailto:daniel@ziegenberg.at) (@ziegenberg) * [Ignacio Serrano](mailto:ignic@ignic.com) (@ignic) -* [Ilya Kulakov](mailto:kulakov.ilya@gmail.com) (@Kentzo) -* [Leonardo David Monteiro](mailto:leo@cub3.xyz) (@leosfsm) * [Michael Gisbers](mailto:michael@gisbers.de) (@mgisbers) * [Miquel Bonastre](mailto:mbonastre@yahoo.com) (@mbonastre) * @netravnen @@ -32,10 +30,9 @@ for details! ## Donations Add yourself to the list, -[donate with PayPal ↗️](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)! +[donate with PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J)! * Abdul Mannan Abbasi -* Alex Maier * Andrea Ruffini Perico * Andrew Cox * Christoph Boss (@Kampfwurst) diff --git a/DEBUG.md b/DEBUG.md deleted file mode 100644 index 69c1eaa3..00000000 --- a/DEBUG.md +++ /dev/null @@ -1,63 +0,0 @@ -Debug output and logs -===================== - -[![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) -[![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) -[![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) -[![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) -[![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) - -[⬅️ Go back to main README](README.md) - -Sometimes scripts do not behave as expected. In these cases debug output -or logs can help. - -## Debug output - -Run this command in a terminal: - - :set PrintDebug true; - -You will then see debug output when running the script from terminal. - -To revert to default output run: - - :set PrintDebug false; - -### Debug output for specific script - -Even having debug output for a specific script or function only (or a -set of) is possible. To enable debug output for `telegram-chat` run: - - :set ($PrintDebugOverride->"telegram-chat") true; - -## Debug logs - -The debug info can go to system log. To make it show up in `memory` run: - - /system/logging/add topics=script,debug action=memory; - -Other actions (`disk`, `email`, `remote` or `support`) can be used as -well. I do not recommend using `echo` - use [debug output](#debug-output) -instead. - -Disable or remove that setting to restore regular logging. - -## Verbose output - -Specific scripts can generate huge amount of output. These do use a function -`$LogPrintVerbose`, which is declared, but has no code, intentionally. - -If you *really* want that output set the function to be the same as -`$LogPrint`: - - :set LogPrintVerbose $LogPrint; - -To revert that change just run: - - :set LogPrintVerbose; - ---- -[⬅️ Go back to main README](README.md) -[⬆️ Go back to top](#top) diff --git a/INITIAL-COMMANDS.md b/INITIAL-COMMANDS.md index eb06ad29..84a88fee 100644 --- a/INITIAL-COMMANDS.md +++ b/INITIAL-COMMANDS.md @@ -4,52 +4,36 @@ Initial commands [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) [⬅️ Go back to main README](README.md) -> ⚠️ **Warning**: These commands are intended for initial setup. If you are +> ⚠️ **Warning**: These command are inteneded for initial setup. If you are > not aware of the procedure please follow > [the long way in detail](README.md#the-long-way-in-detail). Run the complete base installation: { - :local BaseUrl "https://rsc.eworm.de/main/"; - :local CertCommonName "ISRG Root X2"; - :local CertFileName "ISRG-Root-X2.pem"; - :local CertFingerprint "69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470"; - - :local CertSettings [ /certificate/settings/get ]; - :if (!((($CertSettings->"builtin-trust-anchors") = "trusted" || \ - ($CertSettings->"builtin-trust-store") ~ "fetch" || \ - ($CertSettings->"builtin-trust-store") = "all") && \ - [[ :parse (":return [ :len [ /certificate/builtin/find where common-name=\"" . $CertCommonName . "\" ] ]") ]] > 0)) do={ - :put "Importing certificate..."; - /tool/fetch ($BaseUrl . "certs/" . $CertFileName) dst-path=$CertFileName as-value; - :delay 1s; - /certificate/import file-name=$CertFileName passphrase=""; - :if ([ :len [ /certificate/find where fingerprint=$CertFingerprint ] ] != 1) do={ - :error "Something is wrong with your certificates!"; - }; - :delay 1s; + /tool/fetch "https://git.eworm.de/cgit/routeros-scripts/plain/certs/ISRG-Root-X2.pem" dst-path="isrg-root-x2.pem" as-value; + :delay 1s; + /certificate/import file-name=isrg-root-x2.pem passphrase=""; + :if ([ :len [ /certificate/find where fingerprint="69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470" ] ] != 1) do={ + :error "Something is wrong with your certificates!"; }; - :put "Renaming global-config-overlay, if exists..."; + :delay 1s; /system/script/set name=("global-config-overlay-" . [ /system/clock/get date ] . "-" . [ /system/clock/get time ]) [ find where name="global-config-overlay" ]; :foreach Script in={ "global-config"; "global-config-overlay"; "global-functions" } do={ - :put "Installing $Script..."; /system/script/remove [ find where name=$Script ]; - /system/script/add name=$Script owner=$Script source=([ /tool/fetch check-certificate=yes-without-crl ($BaseUrl . $Script . ".rsc") output=user as-value ]->"data"); + /system/script/add name=$Script owner=$Script source=([ /tool/fetch check-certificate=yes-without-crl ("https://git.eworm.de/cgit/routeros-scripts/plain/" . $Script . ".rsc") output=user as-value]->"data"); }; - :put "Loading configuration and functions..."; /system/script { run global-config; run global-functions; }; - :if ([ :len [ /certificate/find where fingerprint=$CertFingerprint ] ] > 0) do={ - :put "Renaming certificate by its common-name..."; - :global CertificateNameByCN; - $CertificateNameByCN $CertFingerprint; - }; + /system/scheduler/remove [ find where name="global-scripts" ]; + /system/scheduler/add name="global-scripts" start-time=startup on-event="/system/script { run global-config; run global-functions; }"; + :global CertificateNameByCN; + $CertificateNameByCN "ISRG Root X2"; }; Then continue setup with diff --git a/Makefile b/Makefile index 5db0a303..d21713c2 100644 --- a/Makefile +++ b/Makefile @@ -2,45 +2,35 @@ # template scripts -> final scripts # markdown files -> html files -ALL_RSC := $(wildcard *.rsc */*.rsc) -GEN_RSC := $(wildcard *.capsman.rsc *.local.rsc *.wifi.rsc) +CAPSMAN = $(wildcard *.capsman.rsc) +LOCAL = $(wildcard *.local.rsc) +WIFI = $(wildcard *.wifi.rsc) -MARKDOWN := $(wildcard *.md doc/*.md doc/mod/*.md) -HTML := $(MARKDOWN:.md=.html) +MARKDOWN = $(wildcard *.md doc/*.md doc/mod/*.md) +HTML = $(MARKDOWN:.md=.html) -DATE ?= $(shell date --rfc-email) -VERSION ?= $(shell git symbolic-ref --short HEAD 2>/dev/null)/$(shell git rev-list --count HEAD 2>/dev/null)/$(shell git rev-parse --short=8 HEAD 2>/dev/null) -export DATE VERSION +all: $(CAPSMAN) $(LOCAL) $(WIFI) $(HTML) -.PHONY: all checksums commitinfo docs rsc clean +%.html: %.md Makefile + markdown $< | sed 's/href="\([-_\./[:alnum:]]*\)\.md"/href="\1.html"/g' > $@ -all: checksums docs rsc +%.capsman.rsc: %.template.rsc Makefile + sed -e '/\/interface\/wifi\//d' -e '/\/interface\/wireless\//d' -e 's|%TEMPL%|.capsman|' \ + -e '/^# NOT \/caps-man\/ #$$/,/^# NOT \/caps-man\/ #$$/d' \ + -e '/^# !!/,/^# !!/c # !! Do not edit this file, it is generated from template!' \ + < $< > $@ -checksums: checksums.json +%.local.rsc: %.template.rsc Makefile + sed -e '/\/caps-man\//d' -e '/\/interface\/wifi\//d' -e 's|%TEMPL%|.local|' \ + -e '/^# NOT \/interface\/wireless\/ #$$/,/^# NOT \/interface\/wireless\/ #$$/d' \ + -e '/^# !!/,/^# !!/c # !! Do not edit this file, it is generated from template!' \ + < $< > $@ -checksums.json: contrib/checksums.sh $(ALL_RSC) - contrib/checksums.sh > $@ - -commitinfo: global-functions.rsc - contrib/commitinfo.sh $< > $<~ - mv $<~ $< - -docs: $(HTML) - -%.html: %.md general/style.css contrib/html.sh contrib/html.sh.d/head.html contrib/html.sh.d/foot.html - contrib/html.sh $< > $@ - -rsc: $(GEN_RSC) - -%.capsman.rsc: %.template.rsc contrib/template-capsman.sh - contrib/template-capsman.sh $< > $@ - -%.local.rsc: %.template.rsc contrib/template-local.sh - contrib/template-local.sh $< > $@ - -%.wifi.rsc: %.template.rsc contrib/template-wifi.sh - contrib/template-wifi.sh $< > $@ +%.wifi.rsc: %.template.rsc Makefile + sed -e '/\/caps-man\//d' -e '/\/interface\/wireless\//d' -e 's|%TEMPL%|.wifi|' \ + -e '/^# NOT \/interface\/wifi\/ #$$/,/^# NOT \/interface\/wifi\/ #$$/d' \ + -e '/^# !!/,/^# !!/c # !! Do not edit this file, it is generated from template!' \ + < $< > $@ clean: - rm -f $(HTML) checksums.json - make -C contrib/ clean + rm -f $(HTML) diff --git a/README.d/01-download-certs.avif b/README.d/01-download-certs.avif index f2afeb54..d41ca059 100644 Binary files a/README.d/01-download-certs.avif and b/README.d/01-download-certs.avif differ diff --git a/README.d/02-import-certs.avif b/README.d/02-import-certs.avif index b31343cd..bf7d5771 100644 Binary files a/README.d/02-import-certs.avif and b/README.d/02-import-certs.avif differ diff --git a/README.d/03-check-certs.avif b/README.d/03-check-certs.avif index 1f03ad2c..4717b3ea 100644 Binary files a/README.d/03-check-certs.avif and b/README.d/03-check-certs.avif differ diff --git a/README.d/04-import-scripts.avif b/README.d/04-import-scripts.avif index c09949ab..53439e4e 100644 Binary files a/README.d/04-import-scripts.avif and b/README.d/04-import-scripts.avif differ diff --git a/README.d/05-run-and-schedule-scripts.avif b/README.d/05-run-and-schedule-scripts.avif new file mode 100644 index 00000000..37e1173f Binary files /dev/null and b/README.d/05-run-and-schedule-scripts.avif differ diff --git a/README.d/05-run-scripts.avif b/README.d/05-run-scripts.avif deleted file mode 100644 index 12d812c0..00000000 Binary files a/README.d/05-run-scripts.avif and /dev/null differ diff --git a/README.d/06-schedule-update.avif b/README.d/06-schedule-update.avif index 158e13f5..7c96f3aa 100644 Binary files a/README.d/06-schedule-update.avif and b/README.d/06-schedule-update.avif differ diff --git a/README.d/07-edit-global-config-overlay.avif b/README.d/07-edit-global-config-overlay.avif index 9a5b9037..f87fda88 100644 Binary files a/README.d/07-edit-global-config-overlay.avif and b/README.d/07-edit-global-config-overlay.avif differ diff --git a/README.d/08-apply-configuration.avif b/README.d/08-apply-configuration.avif index ab22cae3..b66af1a7 100644 Binary files a/README.d/08-apply-configuration.avif and b/README.d/08-apply-configuration.avif differ diff --git a/README.d/09-update-scripts.avif b/README.d/09-update-scripts.avif index e713ac2c..f549fef5 100644 Binary files a/README.d/09-update-scripts.avif and b/README.d/09-update-scripts.avif differ diff --git a/README.d/10-install-scripts.avif b/README.d/10-install-scripts.avif index cf26b168..00225b16 100644 Binary files a/README.d/10-install-scripts.avif and b/README.d/10-install-scripts.avif differ diff --git a/README.d/11-schedule-script.avif b/README.d/11-schedule-script.avif index 558614f8..d6eb0f89 100644 Binary files a/README.d/11-schedule-script.avif and b/README.d/11-schedule-script.avif differ diff --git a/README.d/12-setup-lease-script.avif b/README.d/12-setup-lease-script.avif index 2a8bcb24..fb4024e2 100644 Binary files a/README.d/12-setup-lease-script.avif and b/README.d/12-setup-lease-script.avif differ diff --git a/README.d/13-install-custom-script.avif b/README.d/13-install-custom-script.avif index 221b84e2..2f01c43c 100644 Binary files a/README.d/13-install-custom-script.avif and b/README.d/13-install-custom-script.avif differ diff --git a/README.d/14-remove-script.avif b/README.d/14-remove-script.avif index 3e4c105a..a5c7dafc 100644 Binary files a/README.d/14-remove-script.avif and b/README.d/14-remove-script.avif differ diff --git a/README.d/notification-news-and-changes.avif b/README.d/notification-news-and-changes.avif index d2e8aa7f..d91b8a08 100644 Binary files a/README.d/notification-news-and-changes.avif and b/README.d/notification-news-and-changes.avif differ diff --git a/general/qr-code.png b/README.d/upstream.png similarity index 100% rename from general/qr-code.png rename to README.d/upstream.png diff --git a/README.md b/README.md index f9149217..8594f58a 100644 --- a/README.md +++ b/README.md @@ -4,22 +4,19 @@ RouterOS Scripts [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) -**a collection of scripts for MikroTik RouterOS** - ![RouterOS Scripts Logo](logo.svg) -[RouterOS ↗️](https://mikrotik.com/software) is the operating system developed -by [MikroTik ↗️](https://mikrotik.com/aboutus) for networking tasks. This -repository holds a number of [scripts ↗️](https://wiki.mikrotik.com/wiki/Manual:Scripting) +[RouterOS](https://mikrotik.com/software) is the operating system developed +by [MikroTik](https://mikrotik.com/aboutus) for networking tasks. This +repository holds a number of [scripts](https://wiki.mikrotik.com/wiki/Manual:Scripting) to manage RouterOS devices or extend their functionality. *Use at your own risk*, pay attention to -[license and warranty](#license-and-warranty), and -[disclaimer on external links](#disclaimer-on-external-links)! +[license and warranty](#license-and-warranty)! Requirements ------------ @@ -27,38 +24,18 @@ Requirements ### Software (RouterOS) Latest version of the scripts require recent RouterOS to function properly. -Make sure to install latest updates before you begin. This is supposed to -work flawlessly with these channels: +Make sure to install latest updates before you begin. If new functionality +or a breaking change in RouterOS `7.n` is used in my scripts I push my +change some time after `7.(n+1)` was released. At any time you should have +at least two minor and their bugfix releases to choose from. -* `stable` - the latest version considered stable for daily use, including - new features -* `long-term` - a version considered rock-solid, usually one minor version - behind `stable` (`7.(n-1)`) - -New functionality or breaking changes in RouterOS are adopted fairly quick. -These changes are pushed for general availability once a version of -RouterOS supporting this had been released to the `long-term` channel a -reasonable time ago. - -At any time you should have at least two minor versions and their bugfix -releases to choose from. Often way older versions of RouterOS work just -fine. - -On the other hand in seldom cases and for good reasons *specific* scripts -may require an even newer RouterOS version, so only `stable` is supported -temporarily. - -> 💡️ **Hint**: If in doubt have a look at the badge at the top of each -> page showing the minimum version required: -> ![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat) +Specific scripts may require even newer RouterOS version. > ℹ️ **Info**: The `main` branch is now RouterOS v7 only. If you are still > running RouterOS v6 switch to `routeros-v6` branch! -#### Prerequisite configuration - Starting with RouterOS 7.17 the -[device-mode ↗️](https://help.mikrotik.com/docs/spaces/ROS/pages/93749258/Device-mode) +[device-mode](https://help.mikrotik.com/docs/spaces/ROS/pages/93749258/Device-mode) has been extended to give more fine-grained control over what features are available. You need to enable `scheduler` and `fetch` at least, specific scripts may require additional features. @@ -77,19 +54,16 @@ Initial setup ### Get me ready! If you know how things work just copy and paste the -[initial commands](INITIAL-COMMANDS.md). These also support fixing an -existing but broken installation. Remember to edit and rerun +[initial commands](INITIAL-COMMANDS.md). Remember to edit and rerun `global-config-overlay`! - -> 💡️ **Hint**: First time users should take -> [the long way in detail](#the-long-way-in-detail) below. +First time users should take the long way below. ### Live presentation Want to see it in action? I've had a presentation [Repository based -RouterOS script distribution ↗️](https://www.youtube.com/watch?v=B9neG3oAhcY) -including demonstration recorded live at [MUM Europe -2019 ↗️](https://mum.mikrotik.com/2019/EU/) in Vienna. +RouterOS script distribution](https://www.youtube.com/watch?v=B9neG3oAhcY) +including demonstation recorded live at [MUM Europe +2019](https://mum.mikrotik.com/2019/EU/) in Vienna. > ⚠️ **Warning**: Some details changed. So see the presentation, then follow > the steps below for up-to-date commands. @@ -97,22 +71,11 @@ including demonstration recorded live at [MUM Europe ### The long way in detail The update script does server certificate verification, so first step is to -download the certificates. - -> 💡️ **Hint**: RouterOS 7.19 comes with a builtin certificate store. You -> can skip the steps regarding certificate download and import and jump -> to [installation of scripts](#installation-of-scripts) if you set the -> trust for these builtin trust anchors: -> `/certificate/settings/set builtin-trust-anchors=trusted;` -> With RouterOS 7.21 the functionality was changed. Set this at minimum, -> but make sure not to drop other targets: -> `/certificate/settings/set builtin-trust-store=fetch;` - -If you intend to download the scripts from a +download the certificates. If you intend to download the scripts from a different location (for example from github.com) install the corresponding certificate chain. - /tool/fetch "https://rsc.eworm.de/main/certs/ISRG-Root-X2.pem" dst-path="isrg-root-x2.pem"; + /tool/fetch "https://git.eworm.de/cgit/routeros-scripts/plain/certs/ISRG-Root-X2.pem" dst-path="isrg-root-x2.pem"; ![screenshot: download certs](README.d/01-download-certs.avif) @@ -120,11 +83,11 @@ Note that the commands above do *not* verify server certificate, so if you want to be safe download with your workstations's browser and transfer the file to your MikroTik device. -* [ISRG Root X2 ↗️](https://letsencrypt.org/certs/isrg-root-x2.pem) +* [ISRG Root X2](https://letsencrypt.org/certs/isrg-root-x2.pem) Then we import the certificate. - /certificate/import file-name="isrg-root-x2.pem" passphrase=""; + /certificate/import file-name=isrg-root-x2.pem passphrase=""; Do not worry that the command is not shown - that happens because it contains a sensitive property, the passphrase. @@ -142,27 +105,22 @@ is shown. Always make sure there are no certificates installed you do not know or want! -#### Installation of scripts - All following commands will verify the server certificate. For validity the certificate's lifetime is checked with local time, so make sure the device's date and time is set correctly! Now let's download the main scripts and add them in configuration on the fly. - :foreach Script in={ "global-config"; "global-config-overlay"; "global-functions" } do={ /system/script/add name=$Script owner=$Script source=([ /tool/fetch check-certificate=yes-without-crl ("https://rsc.eworm.de/main/" . $Script . ".rsc") output=user as-value ]->"data"); }; + :foreach Script in={ "global-config"; "global-config-overlay"; "global-functions" } do={ /system/script/add name=$Script owner=$Script source=([ /tool/fetch check-certificate=yes-without-crl ("https://git.eworm.de/cgit/routeros-scripts/plain/" . $Script . ".rsc") output=user as-value]->"data"); }; ![screenshot: import scripts](README.d/04-import-scripts.avif) -And finally run configuration and functions. This will also add the -scheduler for loading at system startup automatically. +And finally load configuration and functions and add the scheduler. /system/script { run global-config; run global-functions; }; + /system/scheduler/add name="global-scripts" start-time=startup on-event="/system/script { run global-config; run global-functions; }"; -![screenshot: run scripts](README.d/05-run-scripts.avif) - -> 💡️ **Hint**: You see complaints regarding syntax errors? Most likely the -> RouterOS on your device is too old. Check for updates! +![screenshot: run and schedule scripts](README.d/05-run-and-schedule-scripts.avif) ### Scheduled automatic updates @@ -201,7 +159,7 @@ This last step is required when ever you make changes to your configuration. > ℹ️ **Info**: It is recommended to edit the configuration using the command > line interface. If using Winbox on Windows OS, the line endings may be -> missing. To fix this run: +> missing. To fix this run: > `/system/script/set source=[ :tocrlf [ get global-config-overlay source ] ] global-config-overlay;` Updating scripts @@ -233,7 +191,7 @@ Scheduler and events -------------------- Most scripts are designed to run regularly from -[scheduler ↗️](https://wiki.mikrotik.com/wiki/Manual:System/Scheduler). We just +[scheduler](https://wiki.mikrotik.com/wiki/Manual:System/Scheduler). We just added `check-routeros-update`, so let's run it daily to make sure not to miss an update. @@ -247,7 +205,7 @@ cleanup add a scheduler entry. $ScriptInstallUpdate dhcp-to-dns,lease-script; /ip/dhcp-server/set lease-script=lease-script [ find ]; - /system/scheduler/add name="dhcp-to-dns" interval=5m start-time=startup on-event="/system/script/run dhcp-to-dns;"; + /system/scheduler/add name="dhcp-to-dns" interval=5m on-event="/system/script/run dhcp-to-dns;"; ![screenshot: setup lease script](README.d/12-setup-lease-script.avif) @@ -256,62 +214,60 @@ There's much more to explore... Have fun! Available scripts ----------------- -* [Find and remove access list duplicates](doc/accesslist-duplicates.md) (`accesslist-duplicates`) -* [Upload backup to Mikrotik cloud](doc/backup-cloud.md) (`backup-cloud`) -* [Send backup via e-mail](doc/backup-email.md) (`backup-email`) -* [Save configuration to fallback partition](doc/backup-partition.md) (`backup-partition`) -* [Upload backup to server](doc/backup-upload.md) (`backup-upload`) -* [Download packages for CAP upgrade from CAPsMAN](doc/capsman-download-packages.md) (`capsman-download-packages`) -* [Run rolling CAP upgrades from CAPsMAN](doc/capsman-rolling-upgrade.md) (`capsman-rolling-upgrade`) -* [Renew locally issued certificates](doc/certificate-renew-issued.md) (`certificate-renew-issued`) -* [Renew certificates and notify on expiration](doc/check-certificates.md) (`check-certificates`) -* [Notify about health state](doc/check-health.md) (`check-health`) -* [Notify on LTE firmware upgrade](doc/check-lte-firmware-upgrade.md) (`check-lte-firmware-upgrade`) -* [Check perpetual license on CHR](doc/check-perpetual-license.md) (`check-perpetual-license`) -* [Notify on RouterOS update](doc/check-routeros-update.md) (`check-routeros-update`) -* [Collect MAC addresses in wireless access list](doc/collect-wireless-mac.md) (`collect-wireless-mac`) -* [Use wireless network with daily psk](doc/daily-psk.md) (`daily-psk`) -* [Comment DHCP leases with info from access list](doc/dhcp-lease-comment.md) (`dhcp-lease-comment`) -* [Create DNS records for DHCP leases](doc/dhcp-to-dns.md) (`dhcp-to-dns`) -* [Automatically upgrade firmware and reboot](doc/firmware-upgrade-reboot.md) (`firmware-upgrade-reboot`) -* [Download, import and update firewall address-lists](doc/fw-addr-lists.md) (`fw-addr-lists`) -* [Wait for global functions und modules](doc/global-wait.md) (`global-wait`) -* [Send GPS position to server](doc/gps-track.md) (`gps-track`) -* [Use WPA network with hotspot credentials](doc/hotspot-to-wpa.md) (`hotspot-to-wpa` & `hotspot-to-wpa-cleanup`) -* [Create DNS records for IPSec peers](doc/ipsec-to-dns.md) (`ipsec-to-dns`) -* [Update configuration on IPv6 prefix change](doc/ipv6-update.md) (`ipv6-update`) -* [Manage IP addresses with bridge status](doc/ip-addr-bridge.md) (`ip-addr-bridge`) -* [Run other scripts on DHCP lease](doc/lease-script.md) (`lease-script`) -* [Manage LEDs dark mode](doc/leds-mode.md) (`leds-day-mode`, `leds-night-mode` & `leds-toggle-mode`) -* [Forward log messages via notification](doc/log-forward.md) (`log-forward`) -* [Mode button with multiple presses](doc/mode-button.md) (`mode-button`) -* [Manage DNS and DoH servers from netwatch](doc/netwatch-dns.md) (`netwatch-dns`) -* [Notify on host up and down](doc/netwatch-notify.md) (`netwatch-notify`) -* [Visualize OSPF state via LEDs](doc/ospf-to-leds.md) (`ospf-to-leds`) -* [Manage system update](doc/packages-update.md) (`packages-update`) -* [Run scripts on ppp connection](doc/ppp-on-up.md) (`ppp-on-up`) -* [Act on received SMS](doc/sms-action.md) (`sms-action`) -* [Forward received SMS](doc/sms-forward.md) (`sms-forward`) -* [Play Super Mario theme](doc/super-mario-theme.md) (`super-mario-theme`) -* [Chat with your router and send commands via Telegram bot](doc/telegram-chat.md) (`telegram-chat`) -* [Install LTE firmware upgrade](doc/unattended-lte-firmware-upgrade.md) (`unattended-lte-firmware-upgrade`) -* [Update GRE configuration with dynamic addresses](doc/update-gre-address.md) (`update-gre-address`) -* [Update tunnelbroker configuration](doc/update-tunnelbroker.md) (`update-tunnelbroker`) +* [Find and remove access list duplicates](doc/accesslist-duplicates.md) +* [Upload backup to Mikrotik cloud](doc/backup-cloud.md) +* [Send backup via e-mail](doc/backup-email.md) +* [Save configuration to fallback partition](doc/backup-partition.md) +* [Upload backup to server](doc/backup-upload.md) +* [Download packages for CAP upgrade from CAPsMAN](doc/capsman-download-packages.md) +* [Run rolling CAP upgrades from CAPsMAN](doc/capsman-rolling-upgrade.md) +* [Renew locally issued certificates](doc/certificate-renew-issued.md) +* [Renew certificates and notify on expiration](doc/check-certificates.md) +* [Notify about health state](doc/check-health.md) +* [Notify on LTE firmware upgrade](doc/check-lte-firmware-upgrade.md) +* [Notify on RouterOS update](doc/check-routeros-update.md) +* [Collect MAC addresses in wireless access list](doc/collect-wireless-mac.md) +* [Use wireless network with daily psk](doc/daily-psk.md) +* [Comment DHCP leases with info from access list](doc/dhcp-lease-comment.md) +* [Create DNS records for DHCP leases](doc/dhcp-to-dns.md) +* [Automatically upgrade firmware and reboot](doc/firmware-upgrade-reboot.md) +* [Download, import and update firewall address-lists](doc/fw-addr-lists.md) +* [Wait for global functions und modules](doc/global-wait.md) +* [Send GPS position to server](doc/gps-track.md) +* [Use WPA network with hotspot credentials](doc/hotspot-to-wpa.md) +* [Create DNS records for IPSec peers](doc/ipsec-to-dns.md) +* [Update configuration on IPv6 prefix change](doc/ipv6-update.md) +* [Manage IP addresses with bridge status](doc/ip-addr-bridge.md) +* [Run other scripts on DHCP lease](doc/lease-script.md) +* [Manage LEDs dark mode](doc/leds-mode.md) +* [Forward log messages via notification](doc/log-forward.md) +* [Mode button with multiple presses](doc/mode-button.md) +* [Manage DNS and DoH servers from netwatch](doc/netwatch-dns.md) +* [Notify on host up and down](doc/netwatch-notify.md) +* [Visualize OSPF state via LEDs](doc/ospf-to-leds.md) +* [Manage system update](doc/packages-update.md) +* [Run scripts on ppp connection](doc/ppp-on-up.md) +* [Act on received SMS](doc/sms-action.md) +* [Forward received SMS](doc/sms-forward.md) +* [Play Super Mario theme](doc/super-mario-theme.md) +* [Chat with your router and send commands via Telegram bot](doc/telegram-chat.md) +* [Install LTE firmware upgrade](doc/unattended-lte-firmware-upgrade.md) +* [Update GRE configuration with dynamic addresses](doc/update-gre-address.md) +* [Update tunnelbroker configuration](doc/update-tunnelbroker.md) Available modules ----------------- -* [Manage ports in bridge](doc/mod/bridge-port-to.md) (`mod/bridge-port-to`) -* [Manage VLANs on bridge ports](doc/mod/bridge-port-vlan.md) (`mod/bridge-port-vlan`) -* [Inspect variables](doc/mod/inspectvar.md) (`mod/inspectvar`) -* [IP address calculation](doc/mod/ipcalc.md) (`mod/ipcalc`) -* [Send notifications via e-mail](doc/mod/notification-email.md) (`mod/notification-email`) -* [Send notifications via Gotify](doc/mod/notification-gotify.md) (`mod/notification-gotify`) -* [Send notifications via Matrix](doc/mod/notification-matrix.md) (`mod/notification-matrix`) -* [Send notifications via Ntfy](doc/mod/notification-ntfy.md) (`mod/notification-ntfy`) -* [Send notifications via Telegram](doc/mod/notification-telegram.md) (`mod/notification-telegram`) -* [Download script and run it once](doc/mod/scriptrunonce.md) (`mod/scriptrunonce`) -* [Import ssh keys for public key authentication](doc/mod/ssh-keys-import.md) (`mod/ssh-keys-import`) +* [Manage ports in bridge](doc/mod/bridge-port-to.md) +* [Manage VLANs on bridge ports](doc/mod/bridge-port-vlan.md) +* [Inspect variables](doc/mod/inspectvar.md) +* [IP address calculation](doc/mod/ipcalc.md) +* [Send notifications via e-mail](doc/mod/notification-email.md) +* [Send notifications via Matrix](doc/mod/notification-matrix.md) +* [Send notifications via Ntfy](doc/mod/notification-ntfy.md) +* [Send notifications via Telegram](doc/mod/notification-telegram.md) +* [Download script and run it once](doc/mod/scriptrunonce.md) +* [Import ssh keys for public key authentication](doc/mod/ssh-keys-import.md) Installing custom scripts & modules ----------------------------------- @@ -368,7 +324,7 @@ Possibly a scheduler and other configuration has to be removed as well. Contact ------- -We have a Telegram Group [RouterOS-Scripts ↗️](https://t.me/routeros_scripts)! +We have a Telegram Group [RouterOS-Scripts](https://t.me/routeros_scripts)! [![RouterOS Scripts Telegram Group](README.d/telegram-group.avif)](https://t.me/routeros_scripts) @@ -392,7 +348,7 @@ at github. This project is developed in private spare time and usage is free of charge for you. If you like the scripts and think this is of value for you or your business please consider to -[donate with PayPal ↗️](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J). +[donate with PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J). [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=for-the-badge)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -411,33 +367,17 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the [GNU General Public License](COPYING.md) for more details. -Disclaimer on external links ----------------------------- - -Our website contains links to the websites of third parties ("external -links"). As the content of these websites is not under our control, we -cannot assume any liability for such external content. In all cases, the -provider of information of the linked websites is liable for the content -and accuracy of the information provided. At the point in time when the -links were placed, no infringements of the law were recognisable to us. -As soon as an infringement of the law becomes known to us, we will -immediately remove the link in question. - -> 💡️ **Hint**: All external links are marked with an arrow pointing -> diagonally in an up-right (or north-east) direction (↗️). - Upstream -------- -[rsc.eworm.de](https://rsc.eworm.de/) +[![upstream](README.d/upstream.png)](https://rsc.eworm.de/) -[![upstream](general/qr-code.png)](https://rsc.eworm.de/) +URL: +[GitHub.com](https://github.com/eworm-de/routeros-scripts#routeros-scripts) -### Code hosting - -* [git.eworm.de](https://git.eworm.de/cgit/routeros-scripts/about/) -* [GitHub.com](https://github.com/eworm-de/routeros-scripts#routeros-scripts) -* [GitLab.com](https://gitlab.com/eworm-de/routeros-scripts#routeros-scripts) +Mirror: +[eworm.de](https://git.eworm.de/cgit/routeros-scripts/about/) +[GitLab.com](https://gitlab.com/eworm-de/routeros-scripts#routeros-scripts) --- [⬆️ Go back to top](#top) diff --git a/accesslist-duplicates.capsman.rsc b/accesslist-duplicates.capsman.rsc index c7784f3b..0c4eaaf5 100644 --- a/accesslist-duplicates.capsman.rsc +++ b/accesslist-duplicates.capsman.rsc @@ -1,20 +1,20 @@ #!rsc by RouterOS # RouterOS script: accesslist-duplicates.capsman -# Copyright (c) 2018-2026 Christian Hesse +# Copyright (c) 2018-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # print duplicate antries in wireless access list # https://rsc.eworm.de/doc/accesslist-duplicates.md # # !! Do not edit this file, it is generated from template! +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :local Seen ({}); @@ -22,7 +22,7 @@ :foreach AccList in=[ /caps-man/access-list/find where mac-address!="00:00:00:00:00:00" ] do={ :local Mac [ /caps-man/access-list/get $AccList mac-address ]; :if ($Seen->$Mac = 1) do={ - /caps-man/access-list/print without-paging where mac-address=$Mac; + /caps-man/access-list/print where mac-address=$Mac; :local Remove [ :tonum [ /terminal/ask prompt="\nNumeric id to remove, any key to skip!" ] ]; :if ([ :typeof $Remove ] = "num") do={ @@ -32,6 +32,6 @@ } :set ($Seen->$Mac) 1; } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/accesslist-duplicates.local.rsc b/accesslist-duplicates.local.rsc index 0eee485b..353fe1fc 100644 --- a/accesslist-duplicates.local.rsc +++ b/accesslist-duplicates.local.rsc @@ -1,20 +1,20 @@ #!rsc by RouterOS # RouterOS script: accesslist-duplicates.local -# Copyright (c) 2018-2026 Christian Hesse +# Copyright (c) 2018-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # print duplicate antries in wireless access list # https://rsc.eworm.de/doc/accesslist-duplicates.md # # !! Do not edit this file, it is generated from template! +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :local Seen ({}); @@ -22,7 +22,7 @@ :foreach AccList in=[ /interface/wireless/access-list/find where mac-address!="00:00:00:00:00:00" ] do={ :local Mac [ /interface/wireless/access-list/get $AccList mac-address ]; :if ($Seen->$Mac = 1) do={ - /interface/wireless/access-list/print without-paging where mac-address=$Mac; + /interface/wireless/access-list/print where mac-address=$Mac; :local Remove [ :tonum [ /terminal/ask prompt="\nNumeric id to remove, any key to skip!" ] ]; :if ([ :typeof $Remove ] = "num") do={ @@ -32,6 +32,6 @@ } :set ($Seen->$Mac) 1; } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/accesslist-duplicates.template.rsc b/accesslist-duplicates.template.rsc index e780a475..4219014f 100644 --- a/accesslist-duplicates.template.rsc +++ b/accesslist-duplicates.template.rsc @@ -1,9 +1,9 @@ #!rsc by RouterOS # RouterOS script: accesslist-duplicates%TEMPL% -# Copyright (c) 2018-2026 Christian Hesse +# Copyright (c) 2018-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # print duplicate antries in wireless access list # https://rsc.eworm.de/doc/accesslist-duplicates.md @@ -11,11 +11,11 @@ # !! This is just a template to generate the real script! # !! Pattern '%TEMPL%' is replaced, paths are filtered. +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :local Seen ({}); @@ -27,9 +27,9 @@ :local Mac [ /interface/wifi/access-list/get $AccList mac-address ]; :local Mac [ /interface/wireless/access-list/get $AccList mac-address ]; :if ($Seen->$Mac = 1) do={ - /caps-man/access-list/print without-paging where mac-address=$Mac; - /interface/wifi/access-list/print without-paging where mac-address=$Mac; - /interface/wireless/access-list/print without-paging where mac-address=$Mac; + /caps-man/access-list/print where mac-address=$Mac; + /interface/wifi/access-list/print where mac-address=$Mac; + /interface/wireless/access-list/print where mac-address=$Mac; :local Remove [ :tonum [ /terminal/ask prompt="\nNumeric id to remove, any key to skip!" ] ]; :if ([ :typeof $Remove ] = "num") do={ @@ -41,6 +41,6 @@ } :set ($Seen->$Mac) 1; } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/accesslist-duplicates.wifi.rsc b/accesslist-duplicates.wifi.rsc index c0a8b4f9..3ee53d8c 100644 --- a/accesslist-duplicates.wifi.rsc +++ b/accesslist-duplicates.wifi.rsc @@ -1,20 +1,20 @@ #!rsc by RouterOS # RouterOS script: accesslist-duplicates.wifi -# Copyright (c) 2018-2026 Christian Hesse +# Copyright (c) 2018-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # print duplicate antries in wireless access list # https://rsc.eworm.de/doc/accesslist-duplicates.md # # !! Do not edit this file, it is generated from template! +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :local Seen ({}); @@ -22,7 +22,7 @@ :foreach AccList in=[ /interface/wifi/access-list/find where mac-address!="00:00:00:00:00:00" ] do={ :local Mac [ /interface/wifi/access-list/get $AccList mac-address ]; :if ($Seen->$Mac = 1) do={ - /interface/wifi/access-list/print without-paging where mac-address=$Mac; + /interface/wifi/access-list/print where mac-address=$Mac; :local Remove [ :tonum [ /terminal/ask prompt="\nNumeric id to remove, any key to skip!" ] ]; :if ([ :typeof $Remove ] = "num") do={ @@ -32,6 +32,6 @@ } :set ($Seen->$Mac) 1; } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/backup-cloud.rsc b/backup-cloud.rsc index e5f25d34..efae055f 100644 --- a/backup-cloud.rsc +++ b/backup-cloud.rsc @@ -1,19 +1,19 @@ #!rsc by RouterOS # RouterOS script: backup-cloud -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # # provides: backup-script, order=40 -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # upload backup to MikroTik cloud # https://rsc.eworm.de/doc/backup-cloud.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global BackupRandomDelay; @@ -26,7 +26,6 @@ :global LogPrint; :global MkDir; :global RandomDelay; - :global RmDir; :global ScriptFromTerminal; :global ScriptLock; :global SendNotification2; @@ -98,7 +97,7 @@ $LogPrint error $ScriptName ("Failed uploading backup for " . $Identity . " to cloud!"); :set PackagesUpdateBackupFailure true; } - $RmDir "tmpfs/backup-cloud"; -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; + /file/remove "tmpfs/backup-cloud"; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/backup-email.rsc b/backup-email.rsc index c12942a2..f6ebad0b 100644 --- a/backup-email.rsc +++ b/backup-email.rsc @@ -1,19 +1,19 @@ #!rsc by RouterOS # RouterOS script: backup-email -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # # provides: backup-script, order=20 -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # create and email backup and config file # https://rsc.eworm.de/doc/backup-email.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global BackupPassword; @@ -27,7 +27,6 @@ :global CleanName; :global DeviceInfo; - :global FileExists; :global FormatLine; :global LogPrint; :global MkDir; @@ -125,19 +124,17 @@ attach=$Attach; remove-attach=true }); # wait for the mail to be sent - :do { - :retry { - :if ([ $FileExists ($FilePath . ".conf") ".conf file" ] = true || \ - [ $FileExists ($FilePath . ".backup") "backup" ] = true || \ - [ $FileExists ($FilePath . ".rsc") "script" ] = true) do={ - :error "Files are still available."; - } - } delay=1s max=120; - } on-error={ - $LogPrint warning $ScriptName ("Files are still available, sending e-mail failed."); - :set PackagesUpdateBackupFailure true; + :local I 0; + :while ([ :len [ /file/find where name ~ ($FilePath . "\\.(backup|rsc)\$") ] ] > 0) do={ + :if ($I >= 120) do={ + $LogPrint warning $ScriptName ("Files are still available, sending e-mail failed."); + :set PackagesUpdateBackupFailure true; + :set ExitOK true; + :error false; + } + :delay 1s; + :set I ($I + 1); } - # do not remove the files here, as the mail is still queued! -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/backup-partition.rsc b/backup-partition.rsc index a9f11a59..bfa7765c 100644 --- a/backup-partition.rsc +++ b/backup-partition.rsc @@ -1,20 +1,20 @@ #!rsc by RouterOS # RouterOS script: backup-partition -# Copyright (c) 2022-2026 Christian Hesse +# Copyright (c) 2022-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # # provides: backup-script, order=70 -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # requires device-mode, scheduler # # save configuration to fallback partition # https://rsc.eworm.de/doc/backup-partition.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global BackupPartitionCopyBeforeFeatureUpdate; @@ -32,15 +32,14 @@ :global LogPrint; - :onerror Err { + :do { /partitions/copy-to $FallbackTo; $LogPrint info $ScriptName ("Copied RouterOS to partition '" . $FallbackToName . "'."); - } do={ - $LogPrint error $ScriptName ("Failed copying RouterOS to partition '" . \ - $FallbackToName . "': " . $Err); + :return true; + } on-error={ + $LogPrint error $ScriptName ("Failed copying RouterOS to partition '" . $FallbackToName . "'!"); :return false; } - :return true; } :if ([ $ScriptLock $ScriptName ] = false) do={ @@ -108,21 +107,20 @@ } } - :onerror Err { + :do { /system/scheduler/add start-time=startup name="running-from-backup-partition" \ on-event=(":log warning (\"Running from partition '\" . " . \ "[ /partitions/get [ find where running ] name ] . \"'!\")"); /partitions/save-config-to $FallbackTo; /system/scheduler/remove "running-from-backup-partition"; $LogPrint info $ScriptName ("Saved configuration to partition '" . $FallbackToName . "'."); - } do={ + } on-error={ /system/scheduler/remove [ find where name="running-from-backup-partition" ]; - $LogPrint error $ScriptName ("Failed saving configuration to partition '" . \ - $FallbackToName . "': " . $Err); + $LogPrint error $ScriptName ("Failed saving configuration to partition '" . $FallbackToName . "'!"); :set PackagesUpdateBackupFailure true; :set ExitOK true; :error false; } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/backup-upload.rsc b/backup-upload.rsc index cae67bfa..dc5120f5 100644 --- a/backup-upload.rsc +++ b/backup-upload.rsc @@ -1,20 +1,20 @@ #!rsc by RouterOS # RouterOS script: backup-upload -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # # provides: backup-script, order=50 -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # requires device-mode, fetch # # create and upload backup and config file # https://rsc.eworm.de/doc/backup-upload.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global BackupPassword; @@ -35,8 +35,6 @@ :global LogPrint; :global MkDir; :global RandomDelay; - :global RmDir; - :global RmFile; :global ScriptFromTerminal; :global ScriptLock; :global SendNotification2; @@ -90,18 +88,18 @@ /system/backup/save encryption=aes-sha256 name=$FilePath password=$BackupPassword; $WaitForFile ($FilePath . ".backup"); - :onerror Err { + :do { /tool/fetch upload=yes url=($BackupUploadUrl . "/" . $FileName . ".backup") \ user=$BackupUploadUser password=$BackupUploadPass src-path=($FilePath . ".backup"); :set BackupFile [ /file/get ($FilePath . ".backup") ]; :set ($BackupFile->"name") ($FileName . ".backup"); - } do={ - $LogPrint error $ScriptName ("Uploading backup file failed: " . $Err); + } on-error={ + $LogPrint error $ScriptName ("Uploading backup file failed!"); :set BackupFile "failed"; :set Failed 1; } - $RmFile ($FilePath . ".backup"); + /file/remove ($FilePath . ".backup"); } # create configuration export @@ -109,18 +107,18 @@ /export terse show-sensitive file=$FilePath; $WaitForFile ($FilePath . ".rsc"); - :onerror Err { + :do { /tool/fetch upload=yes url=($BackupUploadUrl . "/" . $FileName . ".rsc") \ user=$BackupUploadUser password=$BackupUploadPass src-path=($FilePath . ".rsc"); :set ExportFile [ /file/get ($FilePath . ".rsc") ]; :set ($ExportFile->"name") ($FileName . ".rsc"); - } do={ - $LogPrint error $ScriptName ("Uploading configuration export failed: " . $Err); + } on-error={ + $LogPrint error $ScriptName ("Uploading configuration export failed!"); :set ExportFile "failed"; :set Failed 1; } - $RmFile ($FilePath . ".rsc"); + /file/remove ($FilePath . ".rsc"); } # global-config-overlay @@ -130,18 +128,18 @@ file=($FilePath . ".conf\00"); $WaitForFile ($FilePath . ".conf"); - :onerror Err { + :do { /tool/fetch upload=yes url=($BackupUploadUrl . "/" . $FileName . ".conf") \ user=$BackupUploadUser password=$BackupUploadPass src-path=($FilePath . ".conf"); :set ConfigFile [ /file/get ($FilePath . ".conf") ]; :set ($ConfigFile->"name") ($FileName . ".conf"); - } do={ - $LogPrint error $ScriptName ("Uploading global-config-overlay failed: " . $Err); + } on-error={ + $LogPrint error $ScriptName ("Uploading global-config-overlay failed!"); :set ConfigFile "failed"; :set Failed 1; } - $RmFile ($FilePath . ".conf"); + /file/remove ($FilePath . ".conf"); } :local FileInfo do={ @@ -172,7 +170,7 @@ :if ($Failed = 1) do={ :set PackagesUpdateBackupFailure true; } - $RmDir $DirName; -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; + /file/remove $DirName; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/capsman-download-packages.capsman.rsc b/capsman-download-packages.capsman.rsc index 838f41b9..fa76ff5f 100644 --- a/capsman-download-packages.capsman.rsc +++ b/capsman-download-packages.capsman.rsc @@ -1,29 +1,27 @@ #!rsc by RouterOS # RouterOS script: capsman-download-packages.capsman -# Copyright (c) 2018-2026 Christian Hesse +# Copyright (c) 2018-2025 Christian Hesse # Michael Gisbers # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # download and cleanup packages for CAP installation from CAPsMAN # https://rsc.eworm.de/doc/capsman-download-packages.md # # !! Do not edit this file, it is generated from template! +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global CleanFilePath; :global DownloadPackage; - :global FileGet; :global LogPrint; :global MkDir; - :global RmFile; :global ScriptLock; :global WaitFullyConnected; @@ -43,7 +41,7 @@ :error false; } - :if ([ $FileGet $PackagePath ] = false) do={ + :if ([ :len [ /file/find where name=$PackagePath type="directory" ] ] = 0) do={ :if ([ $MkDir $PackagePath ] = false) do={ $LogPrint warning $ScriptName ("Creating directory at CAPsMAN package path (" . \ $PackagePath . ") failed!"); @@ -54,7 +52,7 @@ "). Please place your packages!"); } - :foreach Package in=[ /file/find where type="package" \ + :foreach Package in=[ /file/find where type=package \ package-version!=$InstalledVersion name~("^" . $PackagePath) ] do={ :local File [ /file/get $Package ]; :if ($File->"package-architecture" = "mips") do={ @@ -63,11 +61,11 @@ :if ([ $DownloadPackage ($File->"package-name") $InstalledVersion \ ($File->"package-architecture") $PackagePath ] = true) do={ :set Updated true; - $RmFile ($File->"name"); + /file/remove $Package; } } - :if ([ :len [ /file/find where type="package" name~("^" . $PackagePath) ] ] = 0) do={ + :if ([ :len [ /file/find where type=package name~("^" . $PackagePath) ] ] = 0) do={ $LogPrint info $ScriptName ("No packages available, downloading default set."); :foreach Arch in={ "arm"; "mipsbe" } do={ :foreach Package in={ "routeros"; "wireless" } do={ @@ -88,6 +86,6 @@ /caps-man/remote-cap/upgrade [ find where version!=$InstalledVersion ]; } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/capsman-download-packages.template.rsc b/capsman-download-packages.template.rsc index 1d31eb5a..912e2795 100644 --- a/capsman-download-packages.template.rsc +++ b/capsman-download-packages.template.rsc @@ -1,10 +1,10 @@ #!rsc by RouterOS # RouterOS script: capsman-download-packages%TEMPL% -# Copyright (c) 2018-2026 Christian Hesse +# Copyright (c) 2018-2025 Christian Hesse # Michael Gisbers # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # download and cleanup packages for CAP installation from CAPsMAN # https://rsc.eworm.de/doc/capsman-download-packages.md @@ -12,19 +12,17 @@ # !! This is just a template to generate the real script! # !! Pattern '%TEMPL%' is replaced, paths are filtered. +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global CleanFilePath; :global DownloadPackage; - :global FileGet; :global LogPrint; :global MkDir; - :global RmFile; :global ScriptLock; :global WaitFullyConnected; @@ -45,7 +43,7 @@ :error false; } - :if ([ $FileGet $PackagePath ] = false) do={ + :if ([ :len [ /file/find where name=$PackagePath type="directory" ] ] = 0) do={ :if ([ $MkDir $PackagePath ] = false) do={ $LogPrint warning $ScriptName ("Creating directory at CAPsMAN package path (" . \ $PackagePath . ") failed!"); @@ -56,7 +54,7 @@ "). Please place your packages!"); } - :foreach Package in=[ /file/find where type="package" \ + :foreach Package in=[ /file/find where type=package \ package-version!=$InstalledVersion name~("^" . $PackagePath) ] do={ :local File [ /file/get $Package ]; :if ($File->"package-architecture" = "mips") do={ @@ -65,11 +63,11 @@ :if ([ $DownloadPackage ($File->"package-name") $InstalledVersion \ ($File->"package-architecture") $PackagePath ] = true) do={ :set Updated true; - $RmFile ($File->"name"); + /file/remove $Package; } } - :if ([ :len [ /file/find where type="package" name~("^" . $PackagePath) ] ] = 0) do={ + :if ([ :len [ /file/find where type=package name~("^" . $PackagePath) ] ] = 0) do={ $LogPrint info $ScriptName ("No packages available, downloading default set."); # NOT /interface/wifi/ # :foreach Arch in={ "arm"; "mipsbe" } do={ @@ -99,6 +97,6 @@ /interface/wifi/capsman/remote-cap/upgrade [ find where version!=$InstalledVersion ]; } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/capsman-download-packages.wifi.rsc b/capsman-download-packages.wifi.rsc index 242bb0c8..3a5e7d1e 100644 --- a/capsman-download-packages.wifi.rsc +++ b/capsman-download-packages.wifi.rsc @@ -1,29 +1,27 @@ #!rsc by RouterOS # RouterOS script: capsman-download-packages.wifi -# Copyright (c) 2018-2026 Christian Hesse +# Copyright (c) 2018-2025 Christian Hesse # Michael Gisbers # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # download and cleanup packages for CAP installation from CAPsMAN # https://rsc.eworm.de/doc/capsman-download-packages.md # # !! Do not edit this file, it is generated from template! +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global CleanFilePath; :global DownloadPackage; - :global FileGet; :global LogPrint; :global MkDir; - :global RmFile; :global ScriptLock; :global WaitFullyConnected; @@ -43,7 +41,7 @@ :error false; } - :if ([ $FileGet $PackagePath ] = false) do={ + :if ([ :len [ /file/find where name=$PackagePath type="directory" ] ] = 0) do={ :if ([ $MkDir $PackagePath ] = false) do={ $LogPrint warning $ScriptName ("Creating directory at CAPsMAN package path (" . \ $PackagePath . ") failed!"); @@ -54,7 +52,7 @@ "). Please place your packages!"); } - :foreach Package in=[ /file/find where type="package" \ + :foreach Package in=[ /file/find where type=package \ package-version!=$InstalledVersion name~("^" . $PackagePath) ] do={ :local File [ /file/get $Package ]; :if ($File->"package-architecture" = "mips") do={ @@ -63,11 +61,11 @@ :if ([ $DownloadPackage ($File->"package-name") $InstalledVersion \ ($File->"package-architecture") $PackagePath ] = true) do={ :set Updated true; - $RmFile ($File->"name"); + /file/remove $Package; } } - :if ([ :len [ /file/find where type="package" name~("^" . $PackagePath) ] ] = 0) do={ + :if ([ :len [ /file/find where type=package name~("^" . $PackagePath) ] ] = 0) do={ $LogPrint info $ScriptName ("No packages available, downloading default set."); :foreach Arch in={ "arm"; "arm64" } do={ :local Packages { "arm"={ "routeros"; "wifi-qcom"; "wifi-qcom-ac" }; @@ -90,6 +88,6 @@ /interface/wifi/capsman/remote-cap/upgrade [ find where version!=$InstalledVersion ]; } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/capsman-rolling-upgrade.capsman.rsc b/capsman-rolling-upgrade.capsman.rsc index bb1b17b1..abe066e8 100644 --- a/capsman-rolling-upgrade.capsman.rsc +++ b/capsman-rolling-upgrade.capsman.rsc @@ -1,22 +1,22 @@ #!rsc by RouterOS # RouterOS script: capsman-rolling-upgrade.capsman -# Copyright (c) 2018-2026 Christian Hesse +# Copyright (c) 2018-2025 Christian Hesse # Michael Gisbers # https://rsc.eworm.de/COPYING.md # # provides: capsman-rolling-upgrade.capsman -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # upgrade CAPs one after another # https://rsc.eworm.de/doc/capsman-rolling-upgrade.md # # !! Do not edit this file, it is generated from template! +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global LogPrint; @@ -45,6 +45,6 @@ :delay ($Delay . "s"); } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/capsman-rolling-upgrade.template.rsc b/capsman-rolling-upgrade.template.rsc index 919765a0..c1c7ff1e 100644 --- a/capsman-rolling-upgrade.template.rsc +++ b/capsman-rolling-upgrade.template.rsc @@ -1,11 +1,11 @@ #!rsc by RouterOS # RouterOS script: capsman-rolling-upgrade%TEMPL% -# Copyright (c) 2018-2026 Christian Hesse +# Copyright (c) 2018-2025 Christian Hesse # Michael Gisbers # https://rsc.eworm.de/COPYING.md # # provides: capsman-rolling-upgrade%TEMPL% -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # upgrade CAPs one after another # https://rsc.eworm.de/doc/capsman-rolling-upgrade.md @@ -13,11 +13,11 @@ # !! This is just a template to generate the real script! # !! Pattern '%TEMPL%' is replaced, paths are filtered. +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global LogPrint; @@ -53,6 +53,6 @@ :delay ($Delay . "s"); } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/capsman-rolling-upgrade.wifi.rsc b/capsman-rolling-upgrade.wifi.rsc index b0c9d034..44c99db7 100644 --- a/capsman-rolling-upgrade.wifi.rsc +++ b/capsman-rolling-upgrade.wifi.rsc @@ -1,22 +1,22 @@ #!rsc by RouterOS # RouterOS script: capsman-rolling-upgrade.wifi -# Copyright (c) 2018-2026 Christian Hesse +# Copyright (c) 2018-2025 Christian Hesse # Michael Gisbers # https://rsc.eworm.de/COPYING.md # # provides: capsman-rolling-upgrade.wifi -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # upgrade CAPs one after another # https://rsc.eworm.de/doc/capsman-rolling-upgrade.md # # !! Do not edit this file, it is generated from template! +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global LogPrint; @@ -46,6 +46,6 @@ :delay ($Delay . "s"); } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/certificate-renew-issued.rsc b/certificate-renew-issued.rsc index fc8bff32..5a4043d2 100644 --- a/certificate-renew-issued.rsc +++ b/certificate-renew-issued.rsc @@ -1,18 +1,18 @@ #!rsc by RouterOS # RouterOS script: certificate-renew-issued -# Copyright (c) 2019-2026 Christian Hesse +# Copyright (c) 2019-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # renew locally issued certificates # https://rsc.eworm.de/doc/certificate-renew-issued.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global CertIssuedExportPass; @@ -47,6 +47,6 @@ $LogPrint info $ScriptName ("Issued a new certificate for '" . $CertVal->"common-name" . "'."); } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/certs/GlobalSign.pem b/certs/GlobalSign.pem new file mode 100644 index 00000000..47035e48 --- /dev/null +++ b/certs/GlobalSign.pem @@ -0,0 +1,28 @@ +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Label: "GlobalSign Root CA - R3" +# Serial: 4835703278459759426209954 +# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28 +# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad +# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 +MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 +RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT +gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm +KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd +QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ +XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o +LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU +RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp +jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK +6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX +mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs +Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH +WD9f +-----END CERTIFICATE----- diff --git a/certs/Makefile b/certs/Makefile index 3ccad6e2..ba25303b 100644 --- a/certs/Makefile +++ b/certs/Makefile @@ -15,7 +15,7 @@ DOMAINS_DUAL = \ git.eworm.de/ISRG-Root-X2 \ lists.blocklist.de/Certum-Trusted-Network-CA \ matrix.org/GTS-Root-R4 \ - raw.githubusercontent.com/USERTrust-RSA-Certification-Authority \ + raw.githubusercontent.com/DigiCert-Global-Root-G2 \ rsc.eworm.de/ISRG-Root-X2 \ upgrade.mikrotik.com/ISRG-Root-X1 DOMAINS_IPV4 = \ @@ -23,10 +23,12 @@ DOMAINS_IPV4 = \ 8.8.8.8/GTS-Root-R1 \ 9.9.9.9/DigiCert-Global-Root-G3 \ api.mullvad.net/ISRG-Root-X1 \ + feodotracker.abuse.ch/GlobalSign \ ipv4.showipv6.de/ISRG-Root-X1 \ ipv4.tunnelbroker.net/Starfield-Root-Certificate-Authority-G2 \ mkcert.org/ISRG-Root-X1 \ ntfy.sh/ISRG-Root-X1 \ + sslbl.abuse.ch/GlobalSign \ www.dshield.org/ISRG-Root-X1 \ www.spamhaus.org/GTS-Root-R4 DOMAINS_IPV6 = \ diff --git a/certs/USERTrust-RSA-Certification-Authority.pem b/certs/USERTrust-RSA-Certification-Authority.pem deleted file mode 100644 index 0fbeef63..00000000 --- a/certs/USERTrust-RSA-Certification-Authority.pem +++ /dev/null @@ -1,41 +0,0 @@ -# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network -# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network -# Label: "USERTrust RSA Certification Authority" -# Serial: 2645093764781058787591871645665788717 -# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5 -# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e -# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2 ------BEGIN CERTIFICATE----- -MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB -iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl -cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV -BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw -MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV -BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU -aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy -dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK -AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B -3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY -tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ -Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 -VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT -79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 -c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT -Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l -c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee -UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE -Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd -BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G -A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF -Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO -VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 -ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs -8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR -iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze -Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ -XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ -qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB -VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB -L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG -jjxDah2nGN59PRbxYvnKkKj9 ------END CERTIFICATE----- diff --git a/check-certificates.rsc b/check-certificates.rsc index 1dd61299..34e7537c 100644 --- a/check-certificates.rsc +++ b/check-certificates.rsc @@ -1,19 +1,19 @@ #!rsc by RouterOS # RouterOS script: check-certificates -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # requires device-mode, fetch # # check for certificate validity # https://rsc.eworm.de/doc/check-certificates.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global CertRenewTime; @@ -21,7 +21,7 @@ :global CertWarnTime; :global Identity; - :global CertificateAvailable; + :global CertificateAvailable :global EscapeForRegEx; :global IfThenElse; :global LogPrint; @@ -44,32 +44,26 @@ :global EscapeForRegEx; :global FetchUserAgentStr; :global LogPrint; - :global RmFile; :global UrlEncode; :global WaitForFile; - :foreach Type in={ "p12"; "pem" } do={ - :local CertFileName ([ $UrlEncode $FetchName ] . "." . $Type); - $LogPrint debug $ScriptName ("Trying type '" . $Type . "' for '" . $CertName . \ - "' (file '" . $CertFileName . "')..."); + :local Return false; + :foreach Type in={ ".pem"; ".p12" } do={ + :local CertFileName ([ $UrlEncode $FetchName ] . $Type); :do { /tool/fetch check-certificate=yes-without-crl http-header-field=({ [ $FetchUserAgentStr $ScriptName ] }) \ ($CertRenewUrl . $CertFileName) dst-path=$CertFileName as-value; $WaitForFile $CertFileName; :local DecryptionFailed true; - :foreach I,PassPhrase in=$CertRenewPass do={ - :do { - $LogPrint debug $ScriptName ("Trying " . $I . ". passphrase... "); - :local Result [ /certificate/import file-name=$CertFileName passphrase=$PassPhrase as-value ]; - :if ($Result->"decryption-failures" = 0) do={ - $LogPrint debug $ScriptName ("Success!"); - :set DecryptionFailed false; - } - } on-error={ } + :foreach PassPhrase in=$CertRenewPass do={ + :local Result [ /certificate/import file-name=$CertFileName passphrase=$PassPhrase as-value ]; + :if ($Result->"decryption-failures" = 0) do={ + :set DecryptionFailed false; + } } - $RmFile $CertFileName; + /file/remove [ find where name=$CertFileName ]; :if ($DecryptionFailed = true) do={ $LogPrint warning $ScriptName ("Decryption failed for certificate file '" . $CertFileName . "'."); @@ -82,13 +76,13 @@ $CertificateNameByCN [ /certificate/get $CertInChain common-name ]; } - :return true; + :set Return true; } on-error={ $LogPrint debug $ScriptName ("Could not download certificate file '" . $CertFileName . "'."); } } - :return false; + :return $Return; } :local FormatInfo do={ @@ -106,6 +100,7 @@ :local FormatCertChain do={ :local Cert $1; + :global EitherOr; :global ParseKeyValueStore; :local CertVal [ /certificate/get $Cert ]; @@ -116,18 +111,9 @@ :local Return ""; :for I from=0 to=5 do={ - :set Return ($Return . [ $ParseKeyValueStore ($CertVal->"issuer") ]->"CN"); - :local CertSettings [ /certificate/settings/get ]; - :if (([ :len ($CertSettings->"builtin-trust-anchors") ] > 0 || \ - [ :len ($CertSettings->"builtin-trust-store") ] > 0) && \ - [[ :parse (":return [ :len [ /certificate/builtin/find where skid=\"" . ($CertVal->"akid") . "\" ] ]") ]] > 0) do={ - :return $Return; - } - :do { - :set CertVal [ /certificate/get [ find where skid=($CertVal->"akid") ] ]; - } on-error={ - :return ($Return . " (possibly incomplete!)"); - } + :set Return ($Return . [ $EitherOr ([ $ParseKeyValueStore ($CertVal->"issuer") ]->"CN") \ + ([ $ParseKeyValueStore (($CertVal->"issuer")->0) ]->"CN") ]); + :set CertVal [ /certificate/get [ find where skid=($CertVal->"akid") ] ]; :if (($CertVal->"akid") = "" || ($CertVal->"akid") = ($CertVal->"skid")) do={ :return $Return; } @@ -197,7 +183,7 @@ fingerprint!=[ :tostr ($CertVal->"fingerprint") ] expires-after>$CertRenewTime ]; :local CertNewVal [ /certificate/get $CertNew ]; - :if ([ $CertificateAvailable ([ $ParseKeyValueStore ($CertNewVal->"issuer") ]->"CN") "fetch" ] = false) do={ + :if ([ $CertificateAvailable ([ $ParseKeyValueStore ($CertNewVal->"issuer") ]->"CN") ] = false) do={ $LogPrint warning $ScriptName ("The certificate chain is not available!"); } @@ -239,12 +225,12 @@ :local State [ $IfThenElse (($CertVal->"expired") = true) "expired" "is about to expire" ]; $SendNotification2 ({ origin=$ScriptName; \ - subject=([ $SymbolForNotification "lock-with-ink-pen,warning-sign" ] . "Certificate warning: " . ($CertVal->"name")); \ + subject=([ $SymbolForNotification "warning-sign" ] . "Certificate warning: " . ($CertVal->"name")); \ message=("A certificate on " . $Identity . " " . $State . ".\n\n" . [ $FormatInfo $Cert ]) }); $LogPrint info $ScriptName ("The certificate '" . ($CertVal->"name") . "' " . $State . \ ", it is invalid after " . ($CertVal->"invalid-after") . "."); } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/check-health.d/state.rsc b/check-health.d/state.rsc index bbba31e0..bcc1fbcc 100644 --- a/check-health.d/state.rsc +++ b/check-health.d/state.rsc @@ -1,9 +1,9 @@ #!rsc by RouterOS # RouterOS script: check-health.d/state -# Copyright (c) 2019-2026 Christian Hesse +# Copyright (c) 2019-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # check for RouterOS health state - state plugin # https://rsc.eworm.de/doc/check-health.md @@ -11,8 +11,7 @@ :global CheckHealthPlugins; :set ($CheckHealthPlugins->[ :jobname ]) do={ - :local FuncName [ :tostr $0 ]; - :local ScriptName [ :tostr $1 ]; + :local FuncName [ :tostr $0 ]; :global CheckHealthLast; :global Identity; @@ -33,13 +32,13 @@ :if ([ :typeof ($CheckHealthLast->$Name) ] != "nothing") do={ :if ($CheckHealthLast->$Name = "ok" && \ $Value != "ok") do={ - $SendNotification2 ({ origin=$ScriptName; \ + $SendNotification2 ({ origin=$FuncName; \ subject=([ $SymbolForNotification "cross-mark" ] . "Health warning: " . $Name); \ message=("The device '" . $Name . "' on " . $Identity . " failed!") }); } :if ($CheckHealthLast->$Name != "ok" && \ $Value = "ok") do={ - $SendNotification2 ({ origin=$ScriptName; \ + $SendNotification2 ({ origin=$FuncName; \ subject=([ $SymbolForNotification "white-heavy-check-mark" ] . "Health recovery: " . $Name); \ message=("The device '" . $Name . "' on " . $Identity . " recovered!") }); } diff --git a/check-health.d/temperature.rsc b/check-health.d/temperature.rsc index 64fc6bf3..9b847821 100644 --- a/check-health.d/temperature.rsc +++ b/check-health.d/temperature.rsc @@ -1,9 +1,9 @@ #!rsc by RouterOS # RouterOS script: check-health.d/temperature -# Copyright (c) 2019-2026 Christian Hesse +# Copyright (c) 2019-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # check for RouterOS health state - temperature plugin # https://rsc.eworm.de/doc/check-health.md @@ -11,8 +11,7 @@ :global CheckHealthPlugins; :set ($CheckHealthPlugins->[ :jobname ]) do={ - :local FuncName [ :tostr $0 ]; - :local ScriptName [ :tostr $1 ]; + :local FuncName [ :tostr $0 ]; :global CheckHealthLast; :global CheckHealthTemperature; @@ -55,7 +54,7 @@ } :if ($Value > $CheckHealthTemperature->$Name && \ $CheckHealthTemperatureNotified->$Name != true) do={ - $SendNotification2 ({ origin=$ScriptName; \ + $SendNotification2 ({ origin=$FuncName; \ subject=([ $SymbolForNotification "fire" ] . "Health warning: " . $Name); \ message=("The " . $Name . " on " . $Identity . " is above threshold: " . \ $Value . "\C2\B0" . "C") }); @@ -63,7 +62,7 @@ } :if ($Value <= ($CheckHealthTemperature->$Name - $CheckHealthTemperatureDeviation) && \ $CheckHealthTemperatureNotified->$Name = true) do={ - $SendNotification2 ({ origin=$ScriptName; \ + $SendNotification2 ({ origin=$FuncName; \ subject=([ $SymbolForNotification "white-heavy-check-mark" ] . "Health recovery: " . $Name); \ message=("The " . $Name . " on " . $Identity . " dropped below threshold: " . \ $Value . "\C2\B0" . "C") }); diff --git a/check-health.d/voltage.rsc b/check-health.d/voltage.rsc index 1121c23c..6394795f 100644 --- a/check-health.d/voltage.rsc +++ b/check-health.d/voltage.rsc @@ -1,9 +1,9 @@ #!rsc by RouterOS # RouterOS script: check-health.d/voltage -# Copyright (c) 2019-2026 Christian Hesse +# Copyright (c) 2019-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # check for RouterOS health state - voltage plugin # https://rsc.eworm.de/doc/check-health.md @@ -11,8 +11,7 @@ :global CheckHealthPlugins; :set ($CheckHealthPlugins->[ :jobname ]) do={ - :local FuncName [ :tostr $0 ]; - :local ScriptName [ :tostr $1 ]; + :local FuncName [ :tostr $0 ]; :global CheckHealthLast; :global CheckHealthVoltageLow; @@ -40,7 +39,7 @@ :if ($NumLast * (100 + $CheckHealthVoltagePercent) < $NumCurr * 100 || \ $NumLast * 100 > $NumCurr * (100 + $CheckHealthVoltagePercent)) do={ - $SendNotification2 ({ origin=$ScriptName; \ + $SendNotification2 ({ origin=$FuncName; \ subject=([ $SymbolForNotification ("high-voltage-sign,chart-" . [ $IfThenElse ($NumLast < \ $NumCurr) "in" "de" ] . "creasing") ] . "Health warning: " . $Name); \ message=("The " . $Name . " on " . $Identity . " jumped more than " . $CheckHealthVoltagePercent . "%.\n\n" . \ @@ -48,12 +47,12 @@ [ $FormatLine "new value" ($Value . " V") 12 ]) }); } else={ :if ($NumCurr <= $CheckHealthVoltageLow && $NumLast > $CheckHealthVoltageLow) do={ - $SendNotification2 ({ origin=$ScriptName; \ + $SendNotification2 ({ origin=$FuncName; \ subject=([ $SymbolForNotification "high-voltage-sign,chart-decreasing" ] . "Health warning: Low " . $Name); \ message=("The " . $Name . " on " . $Identity . " dropped to " . $Value . " V below hard limit.") }); } :if ($NumCurr > $CheckHealthVoltageLow && $NumLast <= $CheckHealthVoltageLow) do={ - $SendNotification2 ({ origin=$ScriptName; \ + $SendNotification2 ({ origin=$FuncName; \ subject=([ $SymbolForNotification "high-voltage-sign,chart-increasing" ] . "Health recovery: Low " . $Name); \ message=("The " . $Name . " on " . $Identity . " recovered to " . $Value . " V above hard limit.") }); } diff --git a/check-health.rsc b/check-health.rsc index eea31701..827f5974 100644 --- a/check-health.rsc +++ b/check-health.rsc @@ -1,18 +1,18 @@ #!rsc by RouterOS # RouterOS script: check-health -# Copyright (c) 2019-2026 Christian Hesse +# Copyright (c) 2019-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # check for RouterOS health state # https://rsc.eworm.de/doc/check-health.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global CheckHealthCPUUtilization; @@ -74,7 +74,7 @@ :set CheckHealthRAMUtilizationNotified false; } - :local Plugins [ /system/script/find where name~"^check-health\\.d/." ]; + :local Plugins [ /system/script/find where name~"^check-health.d/." ]; :if ([ :len $Plugins ] = 0) do={ $LogPrint debug $ScriptName ("No plugins installed."); :set ExitOK true; @@ -89,22 +89,22 @@ :foreach Plugin in=$Plugins do={ :local PluginVal [ /system/script/get $Plugin ]; :if ([ $ValidateSyntax ($PluginVal->"source") ] = true) do={ - :onerror Err { + :do { /system/script/run $Plugin; - } do={ - $LogPrint error $ScriptName ("Plugin '" . $PluginVal->"name" . "' failed to run: " . $Err); + } on-error={ + $LogPrint error $ScriptName ("Plugin '" . $ScriptVal->"name" . "' failed to run."); } } else={ - $LogPrint error $ScriptName ("Plugin '" . $PluginVal->"name" . "' failed syntax validation, skipping."); + $LogPrint error $ScriptName ("Plugin '" . $ScriptVal->"name" . "' failed syntax validation, skipping."); } } :foreach PluginName,Discard in=$CheckHealthPlugins do={ ($CheckHealthPlugins->$PluginName) \ - ("\$CheckHealthPlugins->\"" . $PluginName . "\"") $ScriptName; + ("\$CheckHealthPlugins->\"" . $PluginName . "\""); } :set CheckHealthPlugins; -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/check-lte-firmware-upgrade.rsc b/check-lte-firmware-upgrade.rsc index da268e4c..562b8fe6 100644 --- a/check-lte-firmware-upgrade.rsc +++ b/check-lte-firmware-upgrade.rsc @@ -1,18 +1,18 @@ #!rsc by RouterOS # RouterOS script: check-lte-firmware-upgrade -# Copyright (c) 2018-2026 Christian Hesse +# Copyright (c) 2018-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # check for LTE firmware upgrade, send notification # https://rsc.eworm.de/doc/check-lte-firmware-upgrade.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global SentLteFirmwareUpgradeNotification; @@ -45,12 +45,12 @@ :local IntName [ /interface/lte/get $Interface name ]; :local Firmware; :local Info; - :onerror Err { + :do { :set Firmware [ /interface/lte/firmware-upgrade $Interface as-value ]; :set Info [ /interface/lte/monitor $Interface once as-value ]; - } do={ + } on-error={ $LogPrint debug $ScriptName ("Could not get latest LTE firmware version for interface " . \ - $IntName . ": " . $Err); + $IntName . "."); :return false; } @@ -102,6 +102,6 @@ :foreach Interface in=[ /interface/lte/find ] do={ $CheckInterface $ScriptName $Interface; } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/check-perpetual-license.rsc b/check-perpetual-license.rsc deleted file mode 100644 index 4326a2f5..00000000 --- a/check-perpetual-license.rsc +++ /dev/null @@ -1,78 +0,0 @@ -#!rsc by RouterOS -# RouterOS script: check-perpetual-license -# Copyright (c) 2025-2026 Christian Hesse -# https://rsc.eworm.de/COPYING.md -# -# requires RouterOS, version=7.17 -# -# check perpetual license on CHR -# https://rsc.eworm.de/doc/check-perpetual-license.md - -:local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; - :local ScriptName [ :jobname ]; - - :global Identity; - :global SentCertificateNotification; - - :global LogPrint; - :global ScriptLock; - :global SendNotification2; - :global SymbolForNotification; - :global WaitFullyConnected; - - :if ([ $ScriptLock $ScriptName ] = false) do={ - :set ExitOK true; - :error false; - } - - $WaitFullyConnected; - - :local License [ /system/license/get ]; - :if ([ :typeof ($License->"deadline-at") ] != "str") do={ - $LogPrint info $ScriptName ("This device does not have a perpetual license."); - :set ExitOK true; - :error true; - } - - :if ([ :len ($License->"next-renewal-at") ] = 0 && ($License->"limited-upgrades") = true) do={ - $LogPrint warning $ScriptName ("Your license expired on " . ($License->"deadline-at") . "!"); - :if ($SentCertificateNotification != "expired") do={ - $SendNotification2 ({ origin=$ScriptName; \ - subject=([ $SymbolForNotification "scroll,cross-mark" ] . "License expired!"); \ - message=("Your license expired on " . ($License->"deadline-at") . \ - ", can no longer update RouterOS on " . $Identity . "...") }); - :set SentCertificateNotification "expired"; - } - :set ExitOK true; - :error true; - } - - :if ([ :totime ($License->"deadline-at") ] - 3w < [ :timestamp ]) do={ - $LogPrint warning $ScriptName ("Your license will expire on " . ($License->"deadline-at") . "!"); - :if ($SentCertificateNotification != "warning") do={ - $SendNotification2 ({ origin=$ScriptName; \ - subject=([ $SymbolForNotification "scroll,warning-sign" ] . "License about to expire!"); \ - message=("Your license failed to renew and is about to expire on " . \ - ($License->"deadline-at") . " on " . $Identity . "...") }); - :set SentCertificateNotification "warning"; - } - :set ExitOK true; - :error true; - } - - :if ([ :typeof $SentCertificateNotification ] = "str" && \ - [ :totime ($License->"deadline-at") ] - 4w > [ :timestamp ]) do={ - $LogPrint info $ScriptName ("Your license was successfully renewed."); - $SendNotification2 ({ origin=$ScriptName; \ - subject=([ $SymbolForNotification "scroll,white-heavy-check-mark" ] . "License renewed"); \ - message=("Your license was successfully renewed on " . $Identity . \ - ". It is now valid until " . ($License->"deadline-at") . ".") }); - :set SentCertificateNotification; - } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; -} diff --git a/check-routeros-update.rsc b/check-routeros-update.rsc index 98edb366..5c9b392f 100644 --- a/check-routeros-update.rsc +++ b/check-routeros-update.rsc @@ -1,19 +1,19 @@ #!rsc by RouterOS # RouterOS script: check-routeros-update -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # requires device-mode, fetch, scheduler # # check for RouterOS update, send notification and/or install # https://rsc.eworm.de/doc/check-routeros-update.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global Identity; @@ -28,7 +28,6 @@ :global EscapeForRegEx; :global FetchUserAgentStr; :global LogPrint; - :global RebootForUpdate; :global ScriptFromTerminal; :global ScriptLock; :global SendNotification2; @@ -39,11 +38,14 @@ :local DoUpdate do={ :local ScriptName [ :tostr $1 ]; + :global LogPrint; + :if ([ :len [ /system/script/find where name="packages-update" ] ] > 0) do={ /system/script/run packages-update; } else={ /system/package/update/install without-paging; } + $LogPrint info $ScriptName ("Waiting for system to reboot."); } :if ([ $ScriptLock $ScriptName ] = false) do={ @@ -60,14 +62,8 @@ $WaitFullyConnected; :if ([ :len [ /system/scheduler/find where name="_RebootForUpdate" ] ] > 0) do={ - :if ([ :typeof $RebootForUpdate ] = "nothing") do={ - $LogPrint info $ScriptName ("Found a stale scheduler for reboot, removing."); - /system/scheduler/remove "_RebootForUpdate"; - } else={ - $LogPrint info $ScriptName ("A reboot for update is already scheduled."); - :set ExitOK true; - :error false; - } + :set ExitOK true; + :error "A reboot for update is already scheduled."; } $LogPrint debug $ScriptName ("Checking for updates..."); @@ -144,13 +140,13 @@ :if ([ :len $SafeUpdateUrl ] > 0) do={ :local Result; - :onerror Err { + :do { :set Result [ /tool/fetch check-certificate=yes-without-crl \ ($SafeUpdateUrl . $Update->"channel" . "?installed=" . $Update->"installed-version" . \ "&latest=" . $Update->"latest-version") http-header-field=({ [ $FetchUserAgentStr $ScriptName ] }) \ output=user as-value ]; - } do={ - $LogPrint warning $ScriptName ("Failed receiving safe version for " . $Update->"channel" . ": " . $Err); + } on-error={ + $LogPrint warning $ScriptName ("Failed receiving safe version for " . $Update->"channel" . "."); } :if ($Result->"status" = "finished" && $Result->"data" = $Update->"latest-version") do={ $LogPrint info $ScriptName ("Version " . $Update->"latest-version" . " is considered safe, updating..."); @@ -217,6 +213,6 @@ " is available for downgrade."); :set SentRouterosUpdateNotification ($Update->"latest-version"); } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/collect-wireless-mac.capsman.rsc b/collect-wireless-mac.capsman.rsc index 0ef08b0d..f718e0bc 100644 --- a/collect-wireless-mac.capsman.rsc +++ b/collect-wireless-mac.capsman.rsc @@ -1,21 +1,21 @@ #!rsc by RouterOS # RouterOS script: collect-wireless-mac.capsman -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # # provides: lease-script, order=40 -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # collect wireless mac adresses in access list # https://rsc.eworm.de/doc/collect-wireless-mac.md # # !! Do not edit this file, it is generated from template! +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global Identity; @@ -95,6 +95,6 @@ $LogPrint debug $ScriptName ("No mac address available... Ignoring."); } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/collect-wireless-mac.local.rsc b/collect-wireless-mac.local.rsc index 263ef164..00178752 100644 --- a/collect-wireless-mac.local.rsc +++ b/collect-wireless-mac.local.rsc @@ -1,21 +1,21 @@ #!rsc by RouterOS # RouterOS script: collect-wireless-mac.local -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # # provides: lease-script, order=40 -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # collect wireless mac adresses in access list # https://rsc.eworm.de/doc/collect-wireless-mac.md # # !! Do not edit this file, it is generated from template! +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global Identity; @@ -96,6 +96,6 @@ $LogPrint debug $ScriptName ("No mac address available... Ignoring."); } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/collect-wireless-mac.template.rsc b/collect-wireless-mac.template.rsc index 37933250..527e9851 100644 --- a/collect-wireless-mac.template.rsc +++ b/collect-wireless-mac.template.rsc @@ -1,10 +1,10 @@ #!rsc by RouterOS # RouterOS script: collect-wireless-mac%TEMPL% -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # # provides: lease-script, order=40 -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # collect wireless mac adresses in access list # https://rsc.eworm.de/doc/collect-wireless-mac.md @@ -12,11 +12,11 @@ # !! This is just a template to generate the real script! # !! Pattern '%TEMPL%' is replaced, paths are filtered. +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global Identity; @@ -113,6 +113,6 @@ $LogPrint debug $ScriptName ("No mac address available... Ignoring."); } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/collect-wireless-mac.wifi.rsc b/collect-wireless-mac.wifi.rsc index 342351b1..5f9de7d2 100644 --- a/collect-wireless-mac.wifi.rsc +++ b/collect-wireless-mac.wifi.rsc @@ -1,21 +1,21 @@ #!rsc by RouterOS # RouterOS script: collect-wireless-mac.wifi -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # # provides: lease-script, order=40 -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # collect wireless mac adresses in access list # https://rsc.eworm.de/doc/collect-wireless-mac.md # # !! Do not edit this file, it is generated from template! +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global Identity; @@ -95,6 +95,6 @@ $LogPrint debug $ScriptName ("No mac address available... Ignoring."); } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/contrib/Makefile b/contrib/Makefile deleted file mode 100644 index e755a1d5..00000000 --- a/contrib/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# Makefile - -HTML := $(shell grep -xl '' *.html) - -.PHONY: all docs clean - -all: docs - -badges.html: badges.md - markdown $< > $@ - -docs: static-html.sh $(HTML) badges.html - ./static-html.sh $(HTML) - -clean: - rm -f badges.html - git checkout HEAD -- $(HTML) diff --git a/contrib/badges.md b/contrib/badges.md deleted file mode 100644 index a23090b5..00000000 --- a/contrib/badges.md +++ /dev/null @@ -1,6 +0,0 @@ -[![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) -[![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) -[![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) -[![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) -[![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/contrib/checksums.sh b/contrib/checksums.sh deleted file mode 100755 index ab4e9738..00000000 --- a/contrib/checksums.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -# generate a checksums file as used by $ScriptInstallUpdate - -set -e - -md5sum $(find -name '*.rsc' | sort) | \ - sed -e "s| \./||" -e 's|.rsc$||' | \ - jq --raw-input --null-input '[ inputs | split (" ") | { (.[1]): (.[0]) }] | add' diff --git a/contrib/commitinfo.sh b/contrib/commitinfo.sh deleted file mode 100755 index 21faf9fc..00000000 --- a/contrib/commitinfo.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -sed \ - -e "/^:global CommitId/c :global CommitId \"${COMMITID:-unknown}\";" \ - -e "/^:global CommitInfo/c :global CommitInfo \"${COMMITINFO:-unknown}\";" \ - < "${1}" diff --git a/contrib/html.sh b/contrib/html.sh deleted file mode 100755 index 03eba23d..00000000 --- a/contrib/html.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh - -set -e - -RELTO="$(dirname "${1}")" - -sed \ - -e "s|__TITLE__|$(head -n1 "${1}")|" \ - -e "s|__GENERAL__|$(realpath --relative-to="${RELTO}" general/)|" \ - -e "s|__ROOT__|$(realpath --relative-to="${RELTO}" ./)|" \ - < "${0}.d/head.html" - -markdown -f toc,idanchor "${1}" | sed \ - -e 's/href="\([-_\./[:alnum:]]*\)\.md\(#[-[:alnum:]]*\)\?"/href="\1.html\2"/g' \ - -e '/| id="\L\1">|' \ - -e '//s|pre|pre class="code" onclick="CopyToClipboard(this)"|g' \ - -e '/The above link may be broken on code hosting sites/s|blockquote|blockquote style="display: none;"|' - -sed \ - -e "s|__DATE__|${DATE:-$(date --rfc-email)}|" \ - -e "s|__VERSION__|${VERSION:-unknown}|" \ - < "${0}.d/foot.html" diff --git a/contrib/html.sh.d/foot.html b/contrib/html.sh.d/foot.html deleted file mode 100644 index 9e28e115..00000000 --- a/contrib/html.sh.d/foot.html +++ /dev/null @@ -1,5 +0,0 @@ - -

RouterOS Scripts documentation generated on __DATE__ for __VERSION__
-Copyright © 2013-2026 Christian Hesse <mail@eworm.de>

- - diff --git a/contrib/html.sh.d/head.html b/contrib/html.sh.d/head.html deleted file mode 100644 index 656a63c0..00000000 --- a/contrib/html.sh.d/head.html +++ /dev/null @@ -1,16 +0,0 @@ - - -RouterOS Scripts :: __TITLE__ - - - - - - - - - -
eworm on meadowQR code: rsc.eworm.deRouterOS Scripts
- a collection of scripts for MikroTik RouterOS
-
- diff --git a/contrib/logo-color.d/style.css b/contrib/logo-color.d/style.css new file mode 100644 index 00000000..eb2ec6a1 --- /dev/null +++ b/contrib/logo-color.d/style.css @@ -0,0 +1,5 @@ +body { + font-family: fira-sans, sans-serif; + font-size: 10pt; + background-color: transparent; +} diff --git a/contrib/logo-color.html b/contrib/logo-color.html index 3e9c05fe..17942cea 100644 --- a/contrib/logo-color.html +++ b/contrib/logo-color.html @@ -1,30 +1,14 @@ - - - -RouterOS Scripts :: Logo Color Changer - - + + + + +RouterOS-Scripts Logo Color Changer + - + + - - - - -
eworm on meadowQR code: rsc.eworm.deRouterOS Scripts
- a collection of scripts for MikroTik RouterOS
-
- -

Logo Color Changer

- - - -

⬅️ Go back to main README

- -

💡️ Hint: This site or links -on it may be broken on code hosting sites. Use -Logo Color Changer -instead.

+

RouterOS-Scripts Logo Color Changer

You want the logo for your own notifications? But you joined the Telegram Group and want @@ -40,23 +24,17 @@ something that differentiates? Color it!

Then right-click, click "Take Screenshot" and finally select the logo and download it.

-

Screenshot Browser 01

-

Screenshot Browser 02

-

Screenshot Browser 03

+

Screenshot Browser 01 +Screenshot Browser 02 +Screenshot Browser 03

(This example is with Firefox. The workflow for other browsers may differ.)

See how to -Set +Set a profile photo for your Telegram bot.

-
- -

⬅️ Go back to main README
-⬆️ Go back to top

- -

Copyright © 2013-2026 Christian Hesse <mail@eworm.de>

- - + + diff --git a/contrib/notification.d/style.css b/contrib/notification.d/style.css new file mode 100644 index 00000000..648ea23c --- /dev/null +++ b/contrib/notification.d/style.css @@ -0,0 +1,36 @@ +body { + font-family: fira-sans, sans-serif; + font-size: 10pt; + background-color: transparent; +} +div.notification { + position: relative; + float: right; + width: 600px; + border: 3px outset #6c5d53; + /* border-radius: 5px; */ + padding: 10px; + background-color: #e6e6e6; +} +div.content { + padding-left: 60px; +} +img.logo { + float: left; + border-radius: 50%; +} +p.heading { + margin: 0px; + font-weight: bold; + text-decoration: underline; +} +p.hint { + display: none; +} +pre { + font-family: fira-mono, monospace; + white-space: pre-wrap; +} +span.link { + color: #863600; +} diff --git a/contrib/notification.html b/contrib/notification.html index 239bc52c..78750362 100644 --- a/contrib/notification.html +++ b/contrib/notification.html @@ -1,57 +1,35 @@ - - - -RouterOS Scripts :: Notification Generator - - - - + + + + +RouterOS-Scripts Notification Generator + + + + - - - - -
eworm on meadowQR code: rsc.eworm.deRouterOS Scripts
- a collection of scripts for MikroTik RouterOS
-
- -

Notification Generator

- - - -

⬅️ Go back to main README

- -

💡️ Hint: This site or links -on it may be broken on code hosting sites. Use -Notification Generator -instead.

+

RouterOS-Scripts Notification Generator

[MikroTik] ℹ️ Subject

Message
- -

⏰ This message was queued since 2025-10-29 16:06:18 and may be obsolete.

-

✂️ The message was too long and has been truncated, cut off 13%!

+ +

⏰ This message was queued since oct/18/2022 18:30:48 and may be obsolete.

+

✂️ The message was too long and has been truncated, cut off 13%!

Hostname:

Subject:

Message:

-

Show link:

-

Queued since

+

Show link:

+

Queued since

Cut-off with percent

Then right-click, click "Take Screenshot" and finally select the notification and download it.

-
- -

⬅️ Go back to main README
-⬆️ Go back to top

- -

Copyright © 2013-2026 Christian Hesse <mail@eworm.de>

- - + + diff --git a/contrib/static-html.sh b/contrib/static-html.sh deleted file mode 100755 index 7acf1041..00000000 --- a/contrib/static-html.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -set -e - -sed -i \ - -e '/href=/s|\.md|\.html|' \ - -e '/blockquote/s|/\* display \*/|display: none;|' \ - -e '//r badges.html' \ - -e '//d' \ - "${@}" diff --git a/contrib/telegram.md b/contrib/telegram.md deleted file mode 100644 index ead4ab10..00000000 --- a/contrib/telegram.md +++ /dev/null @@ -1,274 +0,0 @@ -Telegram -======== - -[![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) -[![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) -[![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) -[![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) -[![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) - -[⬅️ Go back to main README](../README.md) - -We have [Miss Rose Bot ↗️](https://t.me/MissRose_bot) in our -[RouterOS-Scripts ↗️](https://t.me/routeros_scripts) Telegram group, -always kind and ready to help moderate. - -Notes ------ - -### README - - /save readme Please read the [main README](https://rsc.eworm.de/) to understand how things work and to get the base installation right. - -### Available scripts - -#### accesslist-duplicates - - /save accesslist-duplicates Find and remove access list duplicates with [accesslist-duplicates](https://rsc.eworm.de/doc/accesslist-duplicates.md). - -#### backup-cloud - - /save backup-cloud Upload backup to Mikrotik cloud with [backup-cloud](https://rsc.eworm.de/doc/backup-cloud.md). - -#### backup-email - - /save backup-email Send backup via e-mail with [backup-email](https://rsc.eworm.de/doc/backup-email.md). - -#### backup-partition - - /save backup-partition Save configuration to fallback partition with [backup-partition](https://rsc.eworm.de/doc/backup-partition.md). - -#### backup-upload - - /save backup-upload Upload backup to server with [backup-upload](https://rsc.eworm.de/doc/backup-upload.md). - -#### capsman-download-packages - - /save capsman-download-packages Download packages for CAP upgrade from CAPsMAN with [capsman-download-packages](https://rsc.eworm.de/doc/capsman-download-packages.md). - -#### capsman-rolling-upgrade - - /save capsman-rolling-upgrade Run rolling CAP upgrades from CAPsMAN with [capsman-rolling-upgrade](https://rsc.eworm.de/doc/capsman-rolling-upgrade.md). - -#### certificate-renew-issued - - /save certificate-renew-issued Renew locally issued certificates with [certificate-renew-issued](https://rsc.eworm.de/doc/certificate-renew-issued.md). - -#### check-certificates - - /save check-certificates Renew certificates and notify on expiration with [check-certificates](https://rsc.eworm.de/doc/check-certificates.md). - -#### check-health - - /save check-health Notify about health state with [check-health](https://rsc.eworm.de/doc/check-health.md). - -#### check-lte-firmware-upgrade - - /save check-lte-firmware-upgrade Notify on LTE firmware upgrade with [check-lte-firmware-upgrade](https://rsc.eworm.de/doc/check-lte-firmware-upgrade.md). - -#### check-perpetual-license - - /save check-perpetual-license Check perpetual license on CHR with [check-perpetual-license](https://rsc.eworm.de/doc/check-perpetual-license.md). - -#### check-routeros-update - - /save check-routeros-update Notify on RouterOS update with [check-routeros-update](https://rsc.eworm.de/doc/check-routeros-update.md). - -#### collect-wireless-mac - - /save collect-wireless-mac Collect MAC addresses in wireless access list with [collect-wireless-mac](https://rsc.eworm.de/doc/collect-wireless-mac.md). - -#### daily-psk - - /save daily-psk Use wireless network with [daily-psk](https://rsc.eworm.de/doc/daily-psk.md). - -#### dhcp-lease-comment - - /save dhcp-lease-comment Comment DHCP leases with [dhcp-lease-comment](https://rsc.eworm.de/doc/dhcp-lease-comment.md). - -#### dhcp-to-dns - - /save dhcp-to-dns Create DNS records for DHCP leases with [dhcp-to-dns](https://rsc.eworm.de/doc/dhcp-to-dns.md). - -#### firmware-upgrade-reboot - - /save firmware-upgrade-reboot Automatically upgrade firmware and reboot with [firmware-upgrade-reboot](https://rsc.eworm.de/doc/firmware-upgrade-reboot.md). - -#### fw-addr-lists - - /save fw-addr-lists Download, import and update firewall address-lists with [fw-addr-lists](https://rsc.eworm.de/doc/fw-addr-lists.md). - -#### global-wait - - /save global-wait Wait for global functions und modules with [global-wait](https://rsc.eworm.de/doc/global-wait.md). - -#### gps-track - - /save gps-track Send GPS position to server with [gps-track](https://rsc.eworm.de/doc/gps-track.md). - -#### hotspot-to-wpa - - /save hotspot-to-wpa Use WPA network with [hotspot-to-wpa](https://rsc.eworm.de/doc/hotspot-to-wpa.md). - -#### ipsec-to-dns - - /save ipsec-to-dns Create DNS records for IPSec peers with [ipsec-to-dns](https://rsc.eworm.de/doc/ipsec-to-dns.md). - -#### ipv6-update - - /save ipv6-update Update configuration on IPv6 prefix change with [ipv6-update](https://rsc.eworm.de/doc/ipv6-update.md). - -#### ip-addr-bridge - - /save ip-addr-bridge Manage IP addresses with [ip-addr-bridge](https://rsc.eworm.de/doc/ip-addr-bridge.md). - -#### lease-script - - /save lease-script Run other scripts on DHCP lease with [lease-script](https://rsc.eworm.de/doc/lease-script.md). - -#### leds-mode - - /save leds-mode Manage LEDs dark mode with [leds-mode](https://rsc.eworm.de/doc/leds-mode.md). - -#### log-forward - - /save log-forward Forward log messages via notification with [log-forward](https://rsc.eworm.de/doc/log-forward.md). - -#### mode-button - - /save mode-button Mode button with [mode-button](https://rsc.eworm.de/doc/mode-button.md). - -#### netwatch-dns - - /save netwatch-dns Manage DNS and DoH servers from netwatch with [netwatch-dns](https://rsc.eworm.de/doc/netwatch-dns.md). - -#### netwatch-notify - - /save netwatch-notify Notify on host up and down with [netwatch-notify](https://rsc.eworm.de/doc/netwatch-notify.md). - -#### ospf-to-leds - - /save ospf-to-leds Visualize OSPF state via LEDs with [ospf-to-leds](https://rsc.eworm.de/doc/ospf-to-leds.md). - -#### packages-update - - /save packages-update Manage system update with [packages-update](https://rsc.eworm.de/doc/packages-update.md). - -#### ppp-on-up - - /save ppp-on-up Run scripts on ppp connection with [ppp-on-up](https://rsc.eworm.de/doc/ppp-on-up.md). - -#### sms-action - - /save sms-action Act on received SMS with [sms-action](https://rsc.eworm.de/doc/sms-action.md). - -#### sms-forward - - /save sms-forward Forward received SMS with [sms-forward](https://rsc.eworm.de/doc/sms-forward.md). - -#### super-mario-theme - - /save super-mario-theme Play Super Mario theme with [super-mario-theme](https://rsc.eworm.de/doc/super-mario-theme.md). - -#### telegram-chat - - /save telegram-chat Chat with [telegram-chat](https://rsc.eworm.de/doc/telegram-chat.md). - -#### unattended-lte-firmware-upgrade - - /save unattended-lte-firmware-upgrade Install LTE firmware upgrade with [unattended-lte-firmware-upgrade](https://rsc.eworm.de/doc/unattended-lte-firmware-upgrade.md). - -#### update-gre-address - - /save update-gre-address Update GRE configuration with [update-gre-address](https://rsc.eworm.de/doc/update-gre-address.md). - -#### update-tunnelbroker - - /save update-tunnelbroker Update tunnelbroker configuration with [update-tunnelbroker](https://rsc.eworm.de/doc/update-tunnelbroker.md). - -### Available modules - -#### mod/bridge-port-to - - /save mod/bridge-port-to Manage ports in bridge with [mod/bridge-port-to](https://rsc.eworm.de/doc/mod/bridge-port-to.md). - -#### mod/bridge-port-vlan - - /save mod/bridge-port-vlan Manage VLANs on bridge ports with [mod/bridge-port-vlan](https://rsc.eworm.de/doc/mod/bridge-port-vlan.md). - -#### mod/inspectvar - - /save mod/inspectvar Inspect variables with [mod/inspectvar](https://rsc.eworm.de/doc/mod/inspectvar.md). - -#### mod/ipcalc - - /save mod/ipcalc IP address calculation with [mod/ipcalc](https://rsc.eworm.de/doc/mod/ipcalc.md). - -#### mod/notification-email - - /save mod/notification-email Send notifications via e-mail with [mod/notification-email](https://rsc.eworm.de/doc/mod/notification-email.md). - -#### mod/notification-gotify - - /save mod/notification-gotify Send notifications via Gotify with [mod/notification-gotify](https://rsc.eworm.de/doc/mod/notification-gotify.md). - -#### mod/notification-matrix - - /save mod/notification-matrix Send notifications via Matrix with [mod/notification-matrix](https://rsc.eworm.de/doc/mod/notification-matrix.md). - -#### mod/notification-ntfy - - /save mod/notification-ntfy Send notifications via Ntfy with [mod/notification-ntfy](https://rsc.eworm.de/doc/mod/notification-ntfy.md). - -#### mod/notification-telegram - - /save mod/notification-telegram Send notifications via Telegram with [mod/notification-telegram](https://rsc.eworm.de/doc/mod/notification-telegram.md). - -#### mod/scriptrunonce - - /save mod/scriptrunonce Download script and run it once with [mod/scriptrunonce](https://rsc.eworm.de/doc/mod/scriptrunonce.md). - -#### mod/ssh-keys-import - - /save mod/ssh-keys-import Import ssh keys for public key authentication with [mod/ssh-keys-import](https://rsc.eworm.de/doc/mod/ssh-keys-import.md). - -### Other - -#### Installing from branches - - /save branches Living on the edge or testing new features? Learn how to [switch specific scripts or the complete installation to different branches](https://rsc.eworm.de/BRANCHES.md). - -#### Certificate name from browser - - /save certificate-name-from-browser Running or accessing a custom service and looking for the CA certificate? Get the [certificate name from browser](https://rsc.eworm.de/CERTIFICATES.md). - -#### Debug output and logs - - /save debug Enable [debug output and logs](https://rsc.eworm.de/DEBUG.md) for more information on what happens. - -#### Donate - - /save donate This project is developed in private spare time and usage is free of charge for you. If you like the scripts and think this is of value for you or your business [please consider a donation](https://rsc.eworm.de/#donate). Thanks! - -#### Fix existing installation - - /save fix-installation [Fix existing installation] Your installation broke and you do not know back and forth? See how to [fix an existing installation](https://rsc.eworm.de/INITIAL-COMMANDS.md#fix-existing-installation). - -#### Next! - - /save next Another satisfied user. 😊 Next, please! - -#### Off-topic - - /save off-topic Please note this group is not about MikroTik RouterOS in general, but [RouterOS Scripts](https://rsc.eworm.de/). Your request is not about scripting at all, so please discuss somewhere else. See the [MikroTik RouterOS users (english)](https://t.me/RouterOS_users_english) group or official Mikrotik forums (https://forum.mikrotik.com/). - -Greeting --------- - - /setwelcome Hello {mention}, and welcome to {chatname}! - Please note this group is not about RouterOS in general, but [RouterOS Scripts](https://rsc.eworm.de/). Also pay attention to [rules](https://t.me/routeros_scripts/4), thanks! - ---- -[⬅️ Go back to main README](../README.md) -[⬆️ Go back to top](#top) diff --git a/contrib/template-capsman.sh b/contrib/template-capsman.sh deleted file mode 100755 index 5771b53c..00000000 --- a/contrib/template-capsman.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -set -e - -sed \ - -e '/\/interface\/wifi\//d' \ - -e '/\/interface\/wireless\//d' \ - -e 's|%TEMPL%|.capsman|' \ - -e '/^# NOT \/caps-man\/ #$/,/^# NOT \/caps-man\/ #$/d' \ - -e '/^# !!/,/^# !!/c # !! Do not edit this file, it is generated from template!' \ - < "${1}" diff --git a/contrib/template-local.sh b/contrib/template-local.sh deleted file mode 100755 index bc5b3272..00000000 --- a/contrib/template-local.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -set -e - -sed \ - -e '/\/caps-man\//d' \ - -e '/\/interface\/wifi\//d' \ - -e 's|%TEMPL%|.local|' \ - -e '/^# NOT \/interface\/wireless\/ #$/,/^# NOT \/interface\/wireless\/ #$/d' \ - -e '/^# !!/,/^# !!/c # !! Do not edit this file, it is generated from template!' \ - < "${1}" diff --git a/contrib/template-wifi.sh b/contrib/template-wifi.sh deleted file mode 100755 index 5e297d9e..00000000 --- a/contrib/template-wifi.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -set -e - -sed \ - -e '/\/caps-man\//d' \ - -e '/\/interface\/wireless\//d' \ - -e 's|%TEMPL%|.wifi|' \ - -e '/^# NOT \/interface\/wifi\/ #$/,/^# NOT \/interface\/wifi\/ #$/d' \ - -e '/^# !!/,/^# !!/c # !! Do not edit this file, it is generated from template!' \ - < "${1}" diff --git a/daily-psk.capsman.rsc b/daily-psk.capsman.rsc index 284d4a11..56729315 100644 --- a/daily-psk.capsman.rsc +++ b/daily-psk.capsman.rsc @@ -1,21 +1,21 @@ #!rsc by RouterOS # RouterOS script: daily-psk.capsman -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # Michael Gisbers # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.15 # # update daily PSK (pre shared key) # https://rsc.eworm.de/doc/daily-psk.md # # !! Do not edit this file, it is generated from template! +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global DailyPskMatchComment; @@ -91,6 +91,6 @@ } } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/daily-psk.local.rsc b/daily-psk.local.rsc index 7a07898c..9dea4692 100644 --- a/daily-psk.local.rsc +++ b/daily-psk.local.rsc @@ -1,21 +1,21 @@ #!rsc by RouterOS # RouterOS script: daily-psk.local -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # Michael Gisbers # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.15 # # update daily PSK (pre shared key) # https://rsc.eworm.de/doc/daily-psk.md # # !! Do not edit this file, it is generated from template! +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global DailyPskMatchComment; @@ -90,6 +90,6 @@ } } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/daily-psk.template.rsc b/daily-psk.template.rsc index 5105b63b..8202eeba 100644 --- a/daily-psk.template.rsc +++ b/daily-psk.template.rsc @@ -1,10 +1,10 @@ #!rsc by RouterOS # RouterOS script: daily-psk%TEMPL% -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # Michael Gisbers # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.15 # # update daily PSK (pre shared key) # https://rsc.eworm.de/doc/daily-psk.md @@ -12,11 +12,11 @@ # !! This is just a template to generate the real script! # !! Pattern '%TEMPL%' is replaced, paths are filtered. +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global DailyPskMatchComment; @@ -106,6 +106,6 @@ } } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/daily-psk.wifi.rsc b/daily-psk.wifi.rsc index a2df10e4..3de3c5b6 100644 --- a/daily-psk.wifi.rsc +++ b/daily-psk.wifi.rsc @@ -1,21 +1,21 @@ #!rsc by RouterOS # RouterOS script: daily-psk.wifi -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # Michael Gisbers # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.15 # # update daily PSK (pre shared key) # https://rsc.eworm.de/doc/daily-psk.md # # !! Do not edit this file, it is generated from template! +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global DailyPskMatchComment; @@ -91,6 +91,6 @@ } } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/dhcp-lease-comment.capsman.rsc b/dhcp-lease-comment.capsman.rsc index 5427a889..38039637 100644 --- a/dhcp-lease-comment.capsman.rsc +++ b/dhcp-lease-comment.capsman.rsc @@ -1,21 +1,21 @@ #!rsc by RouterOS # RouterOS script: dhcp-lease-comment.capsman -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # # provides: lease-script, order=60 -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # update dhcp-server lease comment with infos from access-list # https://rsc.eworm.de/doc/dhcp-lease-comment.md # # !! Do not edit this file, it is generated from template! +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global LogPrint; @@ -38,6 +38,6 @@ /ip/dhcp-server/lease/set comment=$NewComment $Lease; } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/dhcp-lease-comment.local.rsc b/dhcp-lease-comment.local.rsc index e25305e3..d5f14613 100644 --- a/dhcp-lease-comment.local.rsc +++ b/dhcp-lease-comment.local.rsc @@ -1,21 +1,21 @@ #!rsc by RouterOS # RouterOS script: dhcp-lease-comment.local -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # # provides: lease-script, order=60 -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # update dhcp-server lease comment with infos from access-list # https://rsc.eworm.de/doc/dhcp-lease-comment.md # # !! Do not edit this file, it is generated from template! +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global LogPrint; @@ -38,6 +38,6 @@ /ip/dhcp-server/lease/set comment=$NewComment $Lease; } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/dhcp-lease-comment.template.rsc b/dhcp-lease-comment.template.rsc index 3fcf6e01..2bddc268 100644 --- a/dhcp-lease-comment.template.rsc +++ b/dhcp-lease-comment.template.rsc @@ -1,10 +1,10 @@ #!rsc by RouterOS # RouterOS script: dhcp-lease-comment%TEMPL% -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # # provides: lease-script, order=60 -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # update dhcp-server lease comment with infos from access-list # https://rsc.eworm.de/doc/dhcp-lease-comment.md @@ -12,11 +12,11 @@ # !! This is just a template to generate the real script! # !! Pattern '%TEMPL%' is replaced, paths are filtered. +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global LogPrint; @@ -43,6 +43,6 @@ /ip/dhcp-server/lease/set comment=$NewComment $Lease; } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/dhcp-lease-comment.wifi.rsc b/dhcp-lease-comment.wifi.rsc index 6b752bab..515b4384 100644 --- a/dhcp-lease-comment.wifi.rsc +++ b/dhcp-lease-comment.wifi.rsc @@ -1,21 +1,21 @@ #!rsc by RouterOS # RouterOS script: dhcp-lease-comment.wifi -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # # provides: lease-script, order=60 -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # update dhcp-server lease comment with infos from access-list # https://rsc.eworm.de/doc/dhcp-lease-comment.md # # !! Do not edit this file, it is generated from template! +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global LogPrint; @@ -38,6 +38,6 @@ /ip/dhcp-server/lease/set comment=$NewComment $Lease; } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/dhcp-to-dns.rsc b/dhcp-to-dns.rsc index 8c6ee30b..9b940984 100644 --- a/dhcp-to-dns.rsc +++ b/dhcp-to-dns.rsc @@ -1,19 +1,19 @@ #!rsc by RouterOS # RouterOS script: dhcp-to-dns -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # # provides: lease-script, order=20 -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.16 # # check DHCP leases and add/remove/update DNS entries # https://rsc.eworm.de/doc/dhcp-to-dns.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global Domain; @@ -125,6 +125,6 @@ $LogPrint debug $ScriptName ("No address available... Ignoring."); } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/doc/accesslist-duplicates.d/01-example.avif b/doc/accesslist-duplicates.d/01-example.avif index d290a771..11b3fc5f 100644 Binary files a/doc/accesslist-duplicates.d/01-example.avif and b/doc/accesslist-duplicates.d/01-example.avif differ diff --git a/doc/accesslist-duplicates.md b/doc/accesslist-duplicates.md index 1b77140f..a6302f5a 100644 --- a/doc/accesslist-duplicates.md +++ b/doc/accesslist-duplicates.md @@ -4,7 +4,7 @@ Find and remove access list duplicates [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/backup-cloud.d/notification.avif b/doc/backup-cloud.d/notification.avif index 5918a623..e533908f 100644 Binary files a/doc/backup-cloud.d/notification.avif and b/doc/backup-cloud.d/notification.avif differ diff --git a/doc/backup-cloud.md b/doc/backup-cloud.md index 7d58c769..d6587609 100644 --- a/doc/backup-cloud.md +++ b/doc/backup-cloud.md @@ -4,7 +4,7 @@ Upload backup to Mikrotik cloud [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -17,7 +17,7 @@ Description ----------- This script uploads -[binary backup to Mikrotik cloud ↗️](https://wiki.mikrotik.com/wiki/Manual:IP/Cloud#Backup). +[binary backup to Mikrotik cloud](https://wiki.mikrotik.com/wiki/Manual:IP/Cloud#Backup). > ⚠️ **Warning**: The used command can hit errors that a script can with > workaround only. A notification *should* be sent anyway. But it can result @@ -49,7 +49,6 @@ The configuration goes to `global-config-overlay`, these are the parameters: Also notification settings are required for [e-mail](mod/notification-email.md), -[gotify](mod/notification-gotify.md), [matrix](mod/notification-matrix.md), [ntfy](mod/notification-ntfy.md) and/or [telegram](mod/notification-telegram.md). diff --git a/doc/backup-email.md b/doc/backup-email.md index 91b49c94..aedae4d8 100644 --- a/doc/backup-email.md +++ b/doc/backup-email.md @@ -4,7 +4,7 @@ Send backup via e-mail [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/backup-partition.md b/doc/backup-partition.md index f046bf12..9f62967b 100644 --- a/doc/backup-partition.md +++ b/doc/backup-partition.md @@ -4,7 +4,7 @@ Save configuration to fallback partition [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -17,7 +17,7 @@ Description ----------- This script saves the current configuration to fallback -[partition ↗️](https://wiki.mikrotik.com/wiki/Manual:Partitions). +[partition](https://wiki.mikrotik.com/wiki/Manual:Partitions). It can also copy-over the RouterOS installation when run interactively or just before a feature update. diff --git a/doc/backup-upload.d/notification.avif b/doc/backup-upload.d/notification.avif index 3bcc1f4d..83cfb18a 100644 Binary files a/doc/backup-upload.d/notification.avif and b/doc/backup-upload.d/notification.avif differ diff --git a/doc/backup-upload.md b/doc/backup-upload.md index 179a2d7f..f2858b29 100644 --- a/doc/backup-upload.md +++ b/doc/backup-upload.md @@ -4,7 +4,7 @@ Upload backup to server [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -55,7 +55,6 @@ The configuration goes to `global-config-overlay`, these are the parameters: Also notification settings are required for [e-mail](mod/notification-email.md), -[gotify](mod/notification-gotify.md), [matrix](mod/notification-matrix.md), [ntfy](mod/notification-ntfy.md) and/or [telegram](mod/notification-telegram.md). diff --git a/doc/capsman-download-packages.md b/doc/capsman-download-packages.md index 2d0065bb..d7199347 100644 --- a/doc/capsman-download-packages.md +++ b/doc/capsman-download-packages.md @@ -4,7 +4,7 @@ Download packages for CAP upgrade from CAPsMAN [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/capsman-rolling-upgrade.md b/doc/capsman-rolling-upgrade.md index 17169996..f366d403 100644 --- a/doc/capsman-rolling-upgrade.md +++ b/doc/capsman-rolling-upgrade.md @@ -4,7 +4,7 @@ Run rolling CAP upgrades from CAPsMAN [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/certificate-renew-issued.md b/doc/certificate-renew-issued.md index f47f9149..096e07b9 100644 --- a/doc/certificate-renew-issued.md +++ b/doc/certificate-renew-issued.md @@ -4,7 +4,7 @@ Renew locally issued certificates [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/check-certificates.d/notification-01-warn.avif b/doc/check-certificates.d/notification-01-warn.avif deleted file mode 100644 index e32e54b3..00000000 Binary files a/doc/check-certificates.d/notification-01-warn.avif and /dev/null differ diff --git a/doc/check-certificates.d/notification-02-renew.avif b/doc/check-certificates.d/notification-02-renew.avif deleted file mode 100644 index 9ff1400a..00000000 Binary files a/doc/check-certificates.d/notification-02-renew.avif and /dev/null differ diff --git a/doc/check-certificates.d/notification.avif b/doc/check-certificates.d/notification.avif new file mode 100644 index 00000000..7c250da1 Binary files /dev/null and b/doc/check-certificates.d/notification.avif differ diff --git a/doc/check-certificates.md b/doc/check-certificates.md index 456d4b1f..4188815b 100644 --- a/doc/check-certificates.md +++ b/doc/check-certificates.md @@ -4,7 +4,7 @@ Renew certificates and notify on expiration [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -19,10 +19,9 @@ Description This script tries to download and renew certificates, then notifies about certificates that are still about to expire. -### Sample notifications +### Sample notification -![check-certificates notification warning](check-certificates.d/notification-01-warn.avif) -![check-certificates notification renew](check-certificates.d/notification-02-renew.avif) +![check-certificates notification](check-certificates.d/notification.avif) Requirements and installation ----------------------------- @@ -52,7 +51,6 @@ subject alternative name (aka *Subject Alt Name* or *SAN*) can be used. Also notification settings are required for [e-mail](mod/notification-email.md), -[gotify](mod/notification-gotify.md), [matrix](mod/notification-matrix.md), [ntfy](mod/notification-ntfy.md) and/or [telegram](mod/notification-telegram.md). diff --git a/doc/check-health.d/notification-01-cpu-utilization-high.avif b/doc/check-health.d/notification-01-cpu-utilization-high.avif index 7fbce3ce..326e7fed 100644 Binary files a/doc/check-health.d/notification-01-cpu-utilization-high.avif and b/doc/check-health.d/notification-01-cpu-utilization-high.avif differ diff --git a/doc/check-health.d/notification-02-cpu-utilization-ok.avif b/doc/check-health.d/notification-02-cpu-utilization-ok.avif index f8e91a3a..811ccd70 100644 Binary files a/doc/check-health.d/notification-02-cpu-utilization-ok.avif and b/doc/check-health.d/notification-02-cpu-utilization-ok.avif differ diff --git a/doc/check-health.d/notification-03-ram-utilization-high.avif b/doc/check-health.d/notification-03-ram-utilization-high.avif index 9015b4a3..59155c56 100644 Binary files a/doc/check-health.d/notification-03-ram-utilization-high.avif and b/doc/check-health.d/notification-03-ram-utilization-high.avif differ diff --git a/doc/check-health.d/notification-04-ram-utilization-ok.avif b/doc/check-health.d/notification-04-ram-utilization-ok.avif index 8f949ecf..d995b9a1 100644 Binary files a/doc/check-health.d/notification-04-ram-utilization-ok.avif and b/doc/check-health.d/notification-04-ram-utilization-ok.avif differ diff --git a/doc/check-health.d/notification-05-voltage.avif b/doc/check-health.d/notification-05-voltage.avif index 9ef2d943..17a385ba 100644 Binary files a/doc/check-health.d/notification-05-voltage.avif and b/doc/check-health.d/notification-05-voltage.avif differ diff --git a/doc/check-health.d/notification-06-temperature-high.avif b/doc/check-health.d/notification-06-temperature-high.avif index 908e8f2e..60d38027 100644 Binary files a/doc/check-health.d/notification-06-temperature-high.avif and b/doc/check-health.d/notification-06-temperature-high.avif differ diff --git a/doc/check-health.d/notification-07-temperature-ok.avif b/doc/check-health.d/notification-07-temperature-ok.avif index 8f509e8d..4afed02d 100644 Binary files a/doc/check-health.d/notification-07-temperature-ok.avif and b/doc/check-health.d/notification-07-temperature-ok.avif differ diff --git a/doc/check-health.d/notification-08-state-fail.avif b/doc/check-health.d/notification-08-state-fail.avif index 8ba7bb97..ad049ac8 100644 Binary files a/doc/check-health.d/notification-08-state-fail.avif and b/doc/check-health.d/notification-08-state-fail.avif differ diff --git a/doc/check-health.d/notification-09-state-ok.avif b/doc/check-health.d/notification-09-state-ok.avif index 91977416..26f5a745 100644 Binary files a/doc/check-health.d/notification-09-state-ok.avif and b/doc/check-health.d/notification-09-state-ok.avif differ diff --git a/doc/check-health.md b/doc/check-health.md index f389ff24..51e71bc3 100644 --- a/doc/check-health.md +++ b/doc/check-health.md @@ -4,7 +4,7 @@ Notify about health state [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -113,7 +113,6 @@ The configuration goes to `global-config-overlay`, these are the parameters: Also notification settings are required for [e-mail](mod/notification-email.md), -[gotify](mod/notification-gotify.md), [matrix](mod/notification-matrix.md), [ntfy](mod/notification-ntfy.md) and/or [telegram](mod/notification-telegram.md). diff --git a/doc/check-lte-firmware-upgrade.d/notification.avif b/doc/check-lte-firmware-upgrade.d/notification.avif index 2c2f692d..c440da59 100644 Binary files a/doc/check-lte-firmware-upgrade.d/notification.avif and b/doc/check-lte-firmware-upgrade.d/notification.avif differ diff --git a/doc/check-lte-firmware-upgrade.md b/doc/check-lte-firmware-upgrade.md index 029dabcd..66b2cf57 100644 --- a/doc/check-lte-firmware-upgrade.md +++ b/doc/check-lte-firmware-upgrade.md @@ -4,7 +4,7 @@ Notify on LTE firmware upgrade [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -44,9 +44,7 @@ Configuration Also notification settings are required for [e-mail](mod/notification-email.md), -[gotify](mod/notification-gotify.md), -[matrix](mod/notification-matrix.md), -[ntfy](mod/notification-ntfy.md) and/or +[matrix](mod/notification-matrix.md) and/or [telegram](mod/notification-telegram.md). See also diff --git a/doc/check-perpetual-license.d/notification-01-warn.avif b/doc/check-perpetual-license.d/notification-01-warn.avif deleted file mode 100644 index aa36e45f..00000000 Binary files a/doc/check-perpetual-license.d/notification-01-warn.avif and /dev/null differ diff --git a/doc/check-perpetual-license.d/notification-02-renew.avif b/doc/check-perpetual-license.d/notification-02-renew.avif deleted file mode 100644 index 471a22e4..00000000 Binary files a/doc/check-perpetual-license.d/notification-02-renew.avif and /dev/null differ diff --git a/doc/check-perpetual-license.md b/doc/check-perpetual-license.md deleted file mode 100644 index a2d41e79..00000000 --- a/doc/check-perpetual-license.md +++ /dev/null @@ -1,72 +0,0 @@ -Check perpetual license on CHR -============================== - -[![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) -[![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) -[![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) -[![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) -[![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) - -[⬅️ Go back to main README](../README.md) - -> ℹ️ **Info**: This script can not be used on its own but requires the base -> installation. See [main README](../README.md) for details. - -Description ------------ - -On *Cloud Hosted Router* (*CHR*) the licensing is perpetual: Buy once, use -forever - but it needs regular renewal. This script checks licensing state -and sends a notification to warn before expiration. - -### Sample notifications - -![check-perpetual-license notification warn](check-perpetual-license.d/notification-01-warn.avif) -![check-perpetual-license notification renew](check-perpetual-license.d/notification-02-renew.avif) - -Requirements and installation ------------------------------ - -Just install the script: - - $ScriptInstallUpdate check-perpetual-license; - -And add a scheduler for automatic update notification: - - /system/scheduler/add interval=1d name=check-perpetual-license on-event="/system/script/run check-perpetual-license;" start-time=startup; - -Configuration -------------- - -No extra configuration is required for this script, but notification -settings are required for -[e-mail](mod/notification-email.md), -[gotify](mod/notification-gotify.md), -[matrix](mod/notification-matrix.md), -[ntfy](mod/notification-ntfy.md) and/or -[telegram](mod/notification-telegram.md). - -Usage and invocation --------------------- - -Be notified when run from scheduler or run it manually: - - /system/script/run check-perpetual-license; - -Tips & Tricks -------------- - -The script checks for full connectivity before acting, so scheduling at -startup is perfectly valid: - - /system/scheduler/add name=check-perpetual-license@startup on-event="/system/script/run check-perpetual-license;" start-time=startup; - -See also --------- - -* [Notify on RouterOS update](check-routeros-update.md) - ---- -[⬅️ Go back to main README](../README.md) -[⬆️ Go back to top](#top) diff --git a/doc/check-routeros-update.d/notification-01-found.avif b/doc/check-routeros-update.d/notification-01-found.avif deleted file mode 100644 index 54dd2df6..00000000 Binary files a/doc/check-routeros-update.d/notification-01-found.avif and /dev/null differ diff --git a/doc/check-routeros-update.d/notification-02-neighbor.avif b/doc/check-routeros-update.d/notification-02-neighbor.avif deleted file mode 100644 index db4e9807..00000000 Binary files a/doc/check-routeros-update.d/notification-02-neighbor.avif and /dev/null differ diff --git a/doc/check-routeros-update.d/notification.avif b/doc/check-routeros-update.d/notification.avif new file mode 100644 index 00000000..50317cf7 Binary files /dev/null and b/doc/check-routeros-update.d/notification.avif differ diff --git a/doc/check-routeros-update.d/terminal.avif b/doc/check-routeros-update.d/terminal.avif deleted file mode 100644 index af950593..00000000 Binary files a/doc/check-routeros-update.d/terminal.avif and /dev/null differ diff --git a/doc/check-routeros-update.md b/doc/check-routeros-update.md index 52373a16..2e9b8aa2 100644 --- a/doc/check-routeros-update.md +++ b/doc/check-routeros-update.md @@ -4,7 +4,7 @@ Notify on RouterOS update [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -30,15 +30,14 @@ automatically is supported. > ⚠️ **Warning**: Installing updates is important from a security point > of view. At the same time it can be source of serve breakage. So test > versions in lab and read -> [changelog ↗️](https://mikrotik.com/download/changelogs/) and -> [forum ↗️](https://forum.mikrotik.com/c/announcements/5) before deploying +> [changelog](https://mikrotik.com/download/changelogs/) and +> [forum](https://forum.mikrotik.com/viewforum.php?f=21) before deploying > to your production environment! Automatic updates should be handled > with care! -### Sample notifications +### Sample notification -![check-routeros-update notification found](check-routeros-update.d/notification-01-found.avif) -![check-routeros-update notification neighbor](check-routeros-update.d/notification-02-neighbor.avif) +![check-routeros-update notification](check-routeros-update.d/notification.avif) Requirements and installation ----------------------------- @@ -74,7 +73,6 @@ The configuration goes to `global-config-overlay`, these are the parameters: Also notification settings are required for [e-mail](mod/notification-email.md), -[gotify](mod/notification-gotify.md), [matrix](mod/notification-matrix.md), [ntfy](mod/notification-ntfy.md) and/or [telegram](mod/notification-telegram.md). @@ -88,8 +86,6 @@ Be notified when run from scheduler or run it manually: If an update is found you can install it right away. -![Terminal](check-routeros-update.d/terminal.avif) - Installing script [packages-update](packages-update.md) gives extra options. Tips & Tricks @@ -103,7 +99,6 @@ startup is perfectly valid: See also -------- -* [Check perpetual license on CHR](check-perpetual-license.md) * [Automatically upgrade firmware and reboot](firmware-upgrade-reboot.md) * [Manage system update](packages-update.md) diff --git a/doc/collect-wireless-mac.d/notification.avif b/doc/collect-wireless-mac.d/notification.avif index 4b21b2f5..a2833f09 100644 Binary files a/doc/collect-wireless-mac.d/notification.avif and b/doc/collect-wireless-mac.d/notification.avif differ diff --git a/doc/collect-wireless-mac.md b/doc/collect-wireless-mac.md index ab4f07ad..84c111d6 100644 --- a/doc/collect-wireless-mac.md +++ b/doc/collect-wireless-mac.md @@ -4,7 +4,7 @@ Collect MAC addresses in wireless access list [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -54,7 +54,6 @@ entries are to be added. Also notification settings are required for [e-mail](mod/notification-email.md), -[gotify](mod/notification-gotify.md), [matrix](mod/notification-matrix.md), [ntfy](mod/notification-ntfy.md) and/or [telegram](mod/notification-telegram.md). diff --git a/doc/daily-psk.d/notification.avif b/doc/daily-psk.d/notification.avif index 79cfc3e2..dd0b1b62 100644 Binary files a/doc/daily-psk.d/notification.avif and b/doc/daily-psk.d/notification.avif differ diff --git a/doc/daily-psk.md b/doc/daily-psk.md index 02fd0e39..4a3de64e 100644 --- a/doc/daily-psk.md +++ b/doc/daily-psk.md @@ -4,7 +4,7 @@ Use wireless network with daily psk [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.15-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -79,7 +79,6 @@ For legacy local interface: Also notification settings are required for [e-mail](mod/notification-email.md), -[gotify](mod/notification-gotify.md), [trix](mod/notification-matrix.md), [ntfy](mod/notification-ntfy.md) and/or [telegram](mod/notification-telegram.md). diff --git a/doc/dhcp-lease-comment.md b/doc/dhcp-lease-comment.md index b51952f4..6a4c930a 100644 --- a/doc/dhcp-lease-comment.md +++ b/doc/dhcp-lease-comment.md @@ -4,7 +4,7 @@ Comment DHCP leases with info from access list [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/dhcp-to-dns.md b/doc/dhcp-to-dns.md index af5b8c6d..4211d854 100644 --- a/doc/dhcp-to-dns.md +++ b/doc/dhcp-to-dns.md @@ -4,7 +4,7 @@ Create DNS records for DHCP leases [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.16-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/firmware-upgrade-reboot.md b/doc/firmware-upgrade-reboot.md index 3cb80875..7ab6ac57 100644 --- a/doc/firmware-upgrade-reboot.md +++ b/doc/firmware-upgrade-reboot.md @@ -4,7 +4,7 @@ Automatically upgrade firmware and reboot [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/fw-addr-lists.md b/doc/fw-addr-lists.md index 5ad02f13..f581fd29 100644 --- a/doc/fw-addr-lists.md +++ b/doc/fw-addr-lists.md @@ -4,7 +4,7 @@ Download, import and update firewall address-lists [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.16-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -18,11 +18,10 @@ Description This script downloads, imports and updates firewall address-lists. Its main purpose is to block attacking ip addresses, spam hosts, command-and-control -servers and similar malicious entities. The default configuration contains a -[collective list by GitHub user @stamparm ↗️](https://github.com/stamparm/ipsum), -lists from [dshield.org ↗️](https://dshield.org/) and -[blocklist.de ↗️](https://www.blocklist.de/), and lists from -[spamhaus.org ↗️](https://spamhaus.org/) are prepared. +servers and similar malicious entities. The default configuration contains +lists from [abuse.ch](https://abuse.ch/), [dshield.org](https://dshield.org/) +and [blocklist.de](https://www.blocklist.de/), and +lists from [spamhaus.org](https://spamhaus.org/) are prepared. The address-lists are updated in place, so after initial import you will not see situation when the lists are not populated. @@ -32,10 +31,7 @@ certificate is checked. > ⚠️ **Warning**: The script does not limit the size of a list, but keep in > mind that huge lists can exhaust your device's resources (RAM and CPU), -> and may take a long time to process. -> Even crashes for the complete scripting (and CLI) subsystem are possible. -> This should be logged accordingly with warnings when global functions are -> reloaded from scheduler. +> and may take a long time to process. Requirements and installation ----------------------------- diff --git a/doc/global-wait.md b/doc/global-wait.md index 84d05941..6787d209 100644 --- a/doc/global-wait.md +++ b/doc/global-wait.md @@ -4,7 +4,7 @@ Wait for global functions and modules [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/gps-track.md b/doc/gps-track.md index 3b501f77..9685899f 100644 --- a/doc/gps-track.md +++ b/doc/gps-track.md @@ -4,7 +4,7 @@ Send GPS position to server [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/hotspot-to-wpa.md b/doc/hotspot-to-wpa.md index dacee672..07d07dc8 100644 --- a/doc/hotspot-to-wpa.md +++ b/doc/hotspot-to-wpa.md @@ -4,7 +4,7 @@ Use WPA network with hotspot credentials [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/ip-addr-bridge.md b/doc/ip-addr-bridge.md index 079c5f02..ddbcc0a7 100644 --- a/doc/ip-addr-bridge.md +++ b/doc/ip-addr-bridge.md @@ -4,7 +4,7 @@ Manage IP addresses with bridge status [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/ipsec-to-dns.md b/doc/ipsec-to-dns.md index ad666790..a688e809 100644 --- a/doc/ipsec-to-dns.md +++ b/doc/ipsec-to-dns.md @@ -4,7 +4,7 @@ Create DNS records for IPSec peers [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/ipv6-update.md b/doc/ipv6-update.md index 01922d24..42f0fe4c 100644 --- a/doc/ipv6-update.md +++ b/doc/ipv6-update.md @@ -4,7 +4,7 @@ Update configuration on IPv6 prefix change [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/lease-script.md b/doc/lease-script.md index eab7c76b..1b59ff7a 100644 --- a/doc/lease-script.md +++ b/doc/lease-script.md @@ -4,7 +4,7 @@ Run other scripts on DHCP lease [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/leds-mode.md b/doc/leds-mode.md index 5e2ffc13..c01472e2 100644 --- a/doc/leds-mode.md +++ b/doc/leds-mode.md @@ -4,7 +4,7 @@ Manage LEDs dark mode [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/log-forward.d/notification-01-info.avif b/doc/log-forward.d/notification-01-info.avif deleted file mode 100644 index 6d25467b..00000000 Binary files a/doc/log-forward.d/notification-01-info.avif and /dev/null differ diff --git a/doc/log-forward.d/notification-02-warn.avif b/doc/log-forward.d/notification-02-warn.avif deleted file mode 100644 index ff61c0c0..00000000 Binary files a/doc/log-forward.d/notification-02-warn.avif and /dev/null differ diff --git a/doc/log-forward.d/notification.avif b/doc/log-forward.d/notification.avif new file mode 100644 index 00000000..a0f9ab33 Binary files /dev/null and b/doc/log-forward.d/notification.avif differ diff --git a/doc/log-forward.md b/doc/log-forward.md index 25991fba..55b15405 100644 --- a/doc/log-forward.md +++ b/doc/log-forward.md @@ -4,7 +4,7 @@ Forward log messages via notification [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -22,23 +22,22 @@ server (see `/system/logging`). This has some limitation, however: * does not work early after boot if network connectivity is not yet established, or breaks intermittently * lots of messages generate a flood of mails -* Gotify, Matrix, Ntfy and Telegram are not supported +* Matrix and Telegram are not supported The script works around the limitations, for example it does: * read from `/log`, including messages from early boot * skip multi-repeated messages * rate-limit itself to mitigate flooding -* forward via notification (which includes *e-mail*, *Gotify*, *Matrix*, - *Ntfy* and *Telegram* when installed and configured, see below) +* forward via notification (which includes *e-mail*, *Matrix* and *Telegram* + when installed and configured, see below) It is intended to be run periodically from scheduler, then collects new log messages and forwards them via notification. -### Sample notifications +### Sample notification -![log-forward notification info](log-forward.d/notification-01-info.avif) -![log-forward notification warn](log-forward.d/notification-02-warn.avif) +![log-forward notification](log-forward.d/notification.avif) Requirements and installation ----------------------------- @@ -54,12 +53,6 @@ Just install the script: Configuration ------------- -The default configuration should provide reasonable presets, filtering -*info*, and effectively forwarding *warning* and *error*. - -> 💡️ **Hint**: Please try with defaults first, especially if you are not -> familiar with regular expressions! - The configuration goes to `global-config-overlay`, these are the parameters: * `LogForwardFilter`: define topics *not* to be forwarded @@ -73,7 +66,7 @@ The configuration goes to `global-config-overlay`, these are the parameters: > your local `global-config-overlay` and modify it to your specific needs. These patterns are matched as -[regular expressions ↗️](https://wiki.mikrotik.com/wiki/Manual:Regular_Expressions). +[regular expressions](https://wiki.mikrotik.com/wiki/Manual:Regular_Expressions). To forward **all** (ignoring severity) log messages with topics `account` (which includes user logins) and `dhcp` you need something like: @@ -81,7 +74,6 @@ To forward **all** (ignoring severity) log messages with topics `account` Also notification settings are required for [e-mail](mod/notification-email.md), -[gotify](mod/notification-gotify.md), [matrix](mod/notification-matrix.md), [ntfy](mod/notification-ntfy.md) and/or [telegram](mod/notification-telegram.md). diff --git a/doc/mod/bridge-port-to.md b/doc/mod/bridge-port-to.md index 18127560..2ed9dc7d 100644 --- a/doc/mod/bridge-port-to.md +++ b/doc/mod/bridge-port-to.md @@ -4,7 +4,7 @@ Manage ports in bridge [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/mod/bridge-port-vlan.md b/doc/mod/bridge-port-vlan.md index b6065cb0..ded26039 100644 --- a/doc/mod/bridge-port-vlan.md +++ b/doc/mod/bridge-port-vlan.md @@ -4,7 +4,7 @@ Manage VLANs on bridge ports [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/mod/inspectvar.d/01-inspectvar.avif b/doc/mod/inspectvar.d/01-inspectvar.avif deleted file mode 100644 index e4e9bd5a..00000000 Binary files a/doc/mod/inspectvar.d/01-inspectvar.avif and /dev/null differ diff --git a/doc/mod/inspectvar.d/inspectvar.avif b/doc/mod/inspectvar.d/inspectvar.avif new file mode 100644 index 00000000..f1da1d4d Binary files /dev/null and b/doc/mod/inspectvar.d/inspectvar.avif differ diff --git a/doc/mod/inspectvar.md b/doc/mod/inspectvar.md index fcbc3afa..4e2f4c1d 100644 --- a/doc/mod/inspectvar.md +++ b/doc/mod/inspectvar.md @@ -4,7 +4,7 @@ Inspect variables [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -33,7 +33,7 @@ Call the function `$InspectVar` with a variable as parameter: $InspectVar $ModeButton; -![InspectVar](inspectvar.d/01-inspectvar.avif) +![InspectVar](inspectvar.d/inspectvar.avif) --- [⬅️ Go back to main README](../../README.md) diff --git a/doc/mod/ipcalc.d/01-ipcalc.avif b/doc/mod/ipcalc.d/01-ipcalc.avif deleted file mode 100644 index aaad6167..00000000 Binary files a/doc/mod/ipcalc.d/01-ipcalc.avif and /dev/null differ diff --git a/doc/mod/ipcalc.d/02-ipcalcreturn.avif b/doc/mod/ipcalc.d/02-ipcalcreturn.avif deleted file mode 100644 index 2459eaf3..00000000 Binary files a/doc/mod/ipcalc.d/02-ipcalcreturn.avif and /dev/null differ diff --git a/doc/mod/ipcalc.d/ipcalc.avif b/doc/mod/ipcalc.d/ipcalc.avif new file mode 100644 index 00000000..fe726e8c Binary files /dev/null and b/doc/mod/ipcalc.d/ipcalc.avif differ diff --git a/doc/mod/ipcalc.d/ipcalcreturn.avif b/doc/mod/ipcalc.d/ipcalcreturn.avif new file mode 100644 index 00000000..5e4dd570 Binary files /dev/null and b/doc/mod/ipcalc.d/ipcalcreturn.avif differ diff --git a/doc/mod/ipcalc.md b/doc/mod/ipcalc.md index 94d11fe7..9f394293 100644 --- a/doc/mod/ipcalc.md +++ b/doc/mod/ipcalc.md @@ -4,7 +4,7 @@ IP address calculation [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -43,7 +43,7 @@ It expects an IP address in CIDR notation as argument. $IPCalc 192.168.88.1/24; -![IPCalc](ipcalc.d/01-ipcalc.avif) +![IPCalc](ipcalc.d/ipcalc.avif) ### IPCalcReturn @@ -53,7 +53,7 @@ the information in a named array. :put ([ $IPCalcReturn 192.168.88.1/24 ]->"broadcast"); -![IPCalcReturn](ipcalc.d/02-ipcalcreturn.avif) +![IPCalcReturn](ipcalc.d/ipcalcreturn.avif) --- [⬅️ Go back to main README](../../README.md) diff --git a/doc/mod/notification-email.md b/doc/mod/notification-email.md index 126e9284..0bef4553 100644 --- a/doc/mod/notification-email.md +++ b/doc/mod/notification-email.md @@ -4,7 +4,7 @@ Send notifications via e-mail [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -32,7 +32,7 @@ Configuration ------------- Set up your device's -[e-mail settings ↗️](https://wiki.mikrotik.com/wiki/Manual:Tools/email). +[e-mail settings](https://wiki.mikrotik.com/wiki/Manual:Tools/email). Also make sure the device has correct time configured, best is to set up the ntp client. @@ -79,7 +79,6 @@ function available: See also -------- -* [Send notifications via Gotify](notification-gotify.md) * [Send notifications via Matrix](notification-matrix.md) * [Send notifications via Ntfy](notification-ntfy.md) * [Send notifications via Telegram](notification-telegram.md) diff --git a/doc/mod/notification-gotify.d/appsetup.avif b/doc/mod/notification-gotify.d/appsetup.avif deleted file mode 100644 index 58f57a80..00000000 Binary files a/doc/mod/notification-gotify.d/appsetup.avif and /dev/null differ diff --git a/doc/mod/notification-gotify.md b/doc/mod/notification-gotify.md deleted file mode 100644 index 097a81c9..00000000 --- a/doc/mod/notification-gotify.md +++ /dev/null @@ -1,97 +0,0 @@ -Send notifications via Gotify -=========================== - -[![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) -[![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) -[![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) -[![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) -[![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) - -[⬅️ Go back to main README](../../README.md) - -> ℹ️️ **Info**: This module can not be used on its own but requires the base -> installation. See [main README](../../README.md) for details. - -Description ------------ - -This module adds support for sending notifications via -[Gotify ↗️](https://gotify.net/). A queue is used to make sure -notifications are not lost on failure but sent later. - -Requirements and installation ------------------------------ - -Just install the module: - - $ScriptInstallUpdate mod/notification-gotify; - -Also deploy the [Gotify server ↗️](https://github.com/gotify/server) and -optionally install a Gotify client on your mobile device. - -Configuration -------------- - -Follow the [Installation ↗️](https://gotify.net/docs/install) instructions -and the [First Login ↗️](https://gotify.net/docs/first-login) setup. Once -you have a user and account you can start creating apps. Each app is an -independent notification feed for a device or application. - -![Create new app](notification-gotify.d/appsetup.avif) - -On creation apps are assigned a *Token* for authentification, you will need -that in configuration. - -Edit `global-config-overlay`, add `GotifyServer` with your server address -(just the address, no protocol - `https://` is assumed) and `GotifyToken` -with the *Token* from your configured app on the Gotify server. Then reload -the configuration. - -> ℹ️ **Info**: Copy relevant configuration from -> [`global-config`](../../global-config.rsc) (the one without `-overlay`) to -> your local `global-config-overlay` and modify it to your specific needs. - -For a custom service installing an additional certificate may be required. -You may want to install that certificate manually, after finding the -[certificate name from browser](../../CERTIFICATES.md). - -Usage and invocation --------------------- - -There's nothing special to do. Every script or function sending a notification -will now send it to your Gotify application feed. - -But of course you can use the function to send notifications directly. Give -it a try: - - $SendGotify "Subject..." "Body..."; - -Alternatively this sends a notification with all available and configured -methods: - - $SendNotification "Subject..." "Body..."; - -To use the functions in your own scripts you have to declare them first. -Place this before you call them: - - :global SendGotify; - :global SendNotification; - -In case there is a situation when the queue needs to be purged there is a -function available: - - $PurgeGotifyQueue; - -See also --------- - -* [Certificate name from browser](../../CERTIFICATES.md) -* [Send notifications via e-mail](notification-email.md) -* [Send notifications via Matrix](notification-matrix.md) -* [Send notifications via Ntfy](notification-ntfy.md) -* [Send notifications via Telegram](notification-telegram.md) - ---- -[⬅️ Go back to main README](../../README.md) -[⬆️ Go back to top](#top) diff --git a/doc/mod/notification-matrix.d/01-authenticate.avif b/doc/mod/notification-matrix.d/01-authenticate.avif index d5b80256..b897943b 100644 Binary files a/doc/mod/notification-matrix.d/01-authenticate.avif and b/doc/mod/notification-matrix.d/01-authenticate.avif differ diff --git a/doc/mod/notification-matrix.d/02-join-room.avif b/doc/mod/notification-matrix.d/02-join-room.avif index 20c4e799..ad99ffde 100644 Binary files a/doc/mod/notification-matrix.d/02-join-room.avif and b/doc/mod/notification-matrix.d/02-join-room.avif differ diff --git a/doc/mod/notification-matrix.md b/doc/mod/notification-matrix.md index 4f92d8b7..fbc9b912 100644 --- a/doc/mod/notification-matrix.md +++ b/doc/mod/notification-matrix.md @@ -4,7 +4,7 @@ Send notifications via Matrix [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -17,7 +17,7 @@ Description ----------- This module adds support for sending notifications via -[Matrix ↗️](https://matrix.org/) via client server api. A queue is used to +[Matrix](https://matrix.org/) via client server api. A queue is used to make sure notifications are not lost on failure but sent later. Requirements and installation @@ -49,7 +49,7 @@ your server in device's certificate store. The example below is for `matrix.org`, which uses a trust chain from *Google Trust Services*. Run this to import the required certificate: - $CertificateAvailable "GTS Root R4" "fetch"; + $CertificateAvailable "GTS Root R4"; Replace the CA certificate name with what ever is needed for your server. You may want to find the @@ -131,7 +131,6 @@ See also * [Certificate name from browser](../../CERTIFICATES.md) * [Send notifications via e-mail](notification-email.md) -* [Send notifications via Gotify](notification-gotify.md) * [Send notifications via Ntfy](notification-ntfy.md) * [Send notifications via Telegram](notification-telegram.md) diff --git a/doc/mod/notification-ntfy.md b/doc/mod/notification-ntfy.md index 5555c534..04dee355 100644 --- a/doc/mod/notification-ntfy.md +++ b/doc/mod/notification-ntfy.md @@ -4,7 +4,7 @@ Send notifications via Ntfy [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -17,7 +17,7 @@ Description ----------- This module adds support for sending notifications via -[Ntfy ↗️](https://ntfy.sh/). A queue is used to make sure +[Ntfy](https://ntfy.sh/). A queue is used to make sure notifications are not lost on failure but sent later. Requirements and installation @@ -28,7 +28,7 @@ Just install the module: $ScriptInstallUpdate mod/notification-ntfy; Also install the Ntfy app on your mobile device or use the -[web app ↗️](https://ntfy.sh/app) in a browser of your choice. +[web app](https://ntfy.sh/app) in a browser of your choice. Configuration ------------- @@ -90,7 +90,6 @@ See also * [Certificate name from browser](../../CERTIFICATES.md) * [Send notifications via e-mail](notification-email.md) -* [Send notifications via Gotify](notification-gotify.md) * [Send notifications via Matrix](notification-matrix.md) * [Send notifications via Telegram](notification-telegram.md) diff --git a/doc/mod/notification-telegram.d/02-getchatid.avif b/doc/mod/notification-telegram.d/02-getchatid.avif deleted file mode 100644 index 0112449c..00000000 Binary files a/doc/mod/notification-telegram.d/02-getchatid.avif and /dev/null differ diff --git a/doc/mod/notification-telegram.d/01-newbot.avif b/doc/mod/notification-telegram.d/newbot.avif similarity index 100% rename from doc/mod/notification-telegram.d/01-newbot.avif rename to doc/mod/notification-telegram.d/newbot.avif diff --git a/doc/mod/notification-telegram.d/03-setuserpic.avif b/doc/mod/notification-telegram.d/setuserpic.avif similarity index 100% rename from doc/mod/notification-telegram.d/03-setuserpic.avif rename to doc/mod/notification-telegram.d/setuserpic.avif diff --git a/doc/mod/notification-telegram.md b/doc/mod/notification-telegram.md index 22ab0d71..f55f936d 100644 --- a/doc/mod/notification-telegram.md +++ b/doc/mod/notification-telegram.md @@ -4,7 +4,7 @@ Send notifications via Telegram [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -17,7 +17,7 @@ Description ----------- This module adds support for sending notifications via -[Telegram ↗️](https://telegram.org/) via bot api. A queue is used to make sure +[Telegram](https://telegram.org/) via bot api. A queue is used to make sure notifications are not lost on failure but sent later. Requirements and installation @@ -33,26 +33,19 @@ and create an account. Configuration ------------- -Open Telegram, then start a chat with [BotFather ↗️](https://t.me/BotFather) and +Open Telegram, then start a chat with [BotFather](https://t.me/BotFather) and create your own bot: -![create new bot](notification-telegram.d/01-newbot.avif) +![create new bot](notification-telegram.d/newbot.avif) -Set that token from *BotFather* (use your own!) to `TelegramTokenId`, for -now just temporarily: +Now open a chat with your bot and start it by clicking the `START` button. - :set TelegramTokenId "5214364459:AAHLwf1o7ybbKDo6pY24Kd2bZ5rjCakDXTc"; - -Now open a chat with your bot and start it by clicking the `START` button, -then send your first message. Any text will do. On your device run -`$GetTelegramChatId` to retrieve the chat id: - - $GetTelegramChatId; - -![get chat id](notification-telegram.d/02-getchatid.avif) +Open just another chat with [GetIDs Bot](https://t.me/getidsbot), again start +with the `START` button. It will send you some information, including the +`id`, just below `You`. Finally edit `global-config-overlay`, add `TelegramTokenId` with the token -from *BotFather* and `TelegramChatId` with your retrieved chat id. Then +from *BotFather* and `TelegramChatId` with your id from *GetIDs Bot*. Then reload the configuration. > ℹ️ **Info**: Copy relevant configuration from @@ -61,13 +54,9 @@ reload the configuration. ### Notifications to a group -Sending notifications to a group is possible as well. Add your bot to a group -and make it an admin (required for read access!) and send a message and run -`$GetTelegramChatId` again. Then use that chat id (which starts with a dash) -for `TelegramChatId`. - -Groups can enable the `Topics` feature. Use `TelegramThreadId` to send to a -specific topic in a group. +Sending notifications to a group is possible as well. Add your bot and the +*GetIDs Bot* to a group, then use the group's id (which starts with a dash) +for `TelegramChatId`. Then remove *GetIDs Bot* from group. Usage and invocation -------------------- @@ -102,23 +91,19 @@ Tips & Tricks ### Set a profile photo You can use a profile photo for your bot to make it recognizable. Open the -chat with [BotFather ↗️](https://t.me/BotFather) and set it there. +chat with [BotFather](https://t.me/BotFather) and set it there. -![set profile photo](notification-telegram.d/03-setuserpic.avif) +![set profile photo](notification-telegram.d/setuserpic.avif) -Have a look at my [Logo Color Changer](../../contrib/logo-color.html) +Have a look at my +[RouterOS-Scripts Logo Color Changer](https://git.eworm.de/cgit/routeros-scripts/plain/contrib/logo-color.html) to create a colored version of this scripts' logo. -> 💡️ **Hint**: The above link may be broken on code hosting sites. -> Use [Logo Color Changer](https://rsc.eworm.de/main/contrib/logo-color.html) -> instead. - See also -------- * [Chat with your router and send commands via Telegram bot](../telegram-chat.md) * [Send notifications via e-mail](notification-email.md) -* [Send notifications via Gotify](notification-gotify.md) * [Send notifications via Matrix](notification-matrix.md) * [Send notifications via Ntfy](notification-ntfy.md) diff --git a/doc/mod/scriptrunonce.d/01-scriptrunonce.avif b/doc/mod/scriptrunonce.d/01-scriptrunonce.avif deleted file mode 100644 index 461c3981..00000000 Binary files a/doc/mod/scriptrunonce.d/01-scriptrunonce.avif and /dev/null differ diff --git a/doc/mod/scriptrunonce.d/scriptrunonce.avif b/doc/mod/scriptrunonce.d/scriptrunonce.avif new file mode 100644 index 00000000..27ccd41f Binary files /dev/null and b/doc/mod/scriptrunonce.d/scriptrunonce.avif differ diff --git a/doc/mod/scriptrunonce.md b/doc/mod/scriptrunonce.md index 66b181fa..0127c6d3 100644 --- a/doc/mod/scriptrunonce.md +++ b/doc/mod/scriptrunonce.md @@ -4,7 +4,7 @@ Download script and run it once [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -48,9 +48,9 @@ Usage and invocation The function `$ScriptRunOnce` expects an URL (or name if `ScriptRunOnceBaseUrl` is given) pointing to a script as parameter. - $ScriptRunOnce https://rsc.eworm.de/main/doc/mod/scriptrunonce.d/hello-world.rsc; + $ScriptRunOnce https://git.eworm.de/cgit/routeros-scripts/plain/doc/mod/scriptrunonce.d/hello-world.rsc; -![ScriptRunOnce](scriptrunonce.d/01-scriptrunonce.avif) +![ScriptRunOnce](scriptrunonce.d/scriptrunonce.avif) Giving multiple scripts is possible, separated by comma. diff --git a/doc/mod/ssh-keys-import.md b/doc/mod/ssh-keys-import.md index 02cd804e..344f4bc2 100644 --- a/doc/mod/ssh-keys-import.md +++ b/doc/mod/ssh-keys-import.md @@ -4,7 +4,7 @@ Import ssh keys for public key authentication [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.16-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -38,9 +38,8 @@ import that key: $SSHKeysImport "ssh-rsa AAAAB3Nza...QYZk8= user" admin; The third part of the key (`user` in this example) is inherited as -`key-owner` in RouterOS (or `info` starting with RouterOS 7.21beta2). Also -the `MD5` fingerprint is recorded, this helps to audit and verify the -available keys. +`key-owner` in RouterOS. Also the `MD5` fingerprint is recorded, this helps +to audit and verify the available keys. > ℹ️️ **Info**: Use `ssh-keygen` to show a fingerprint of an existing public > key file: `ssh-keygen -l -E md5 -f ~/.ssh/id_ed25519.pub` @@ -51,10 +50,12 @@ The functions `$SSHKeysImportFile` can read an `authorized_keys`-style file and import all the keys. The user given to the function can be overwritting from comments in the file. Create a file `keys.pub` with this content: - ssh-ed25519 AAAAC3Nza...3OcN8A user@client - ssh-rsa AAAAB3Nza...ozyts= worker@station - # user=example - ssh-rsa AAAAB3Nza...GXQVk= person@host +``` +ssh-ed25519 AAAAC3Nza...3OcN8A user@client +ssh-rsa AAAAB3Nza...ozyts= worker@station +# user=example +ssh-rsa AAAAB3Nza...GXQVk= person@host +``` Then import it with: diff --git a/doc/mode-button.md b/doc/mode-button.md index 367b7fa0..7feb19fa 100644 --- a/doc/mode-button.md +++ b/doc/mode-button.md @@ -4,7 +4,7 @@ Mode button with multiple presses [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -26,15 +26,17 @@ can configure the reset button to act the same, see Copy this code to terminal to check: - :if ([ :len [ /system/routerboard/mode-button/print as-value ] ] > 0) do={ - :put "Mode button is supported."; - } else={ - :if ([ :len [ /system/routerboard/reset-button/print as-value ] ] > 0) do={ - :put "Mode button is not supported, but reset button is."; - } else={ - :put "Neither mode button nor reset button is supported."; - } - } +``` +:if ([ :len [ /system/routerboard/mode-button/print as-value ] ] > 0) do={ + :put "Mode button is supported."; +} else={ + :if ([ :len [ /system/routerboard/reset-button/print as-value ] ] > 0) do={ + :put "Mode button is not supported, but reset button is."; + } else={ + :put "Neither mode button nor reset button is supported."; + } +} +``` Requirements and installation ----------------------------- diff --git a/doc/netwatch-dns.md b/doc/netwatch-dns.md index 23190b12..0d949182 100644 --- a/doc/netwatch-dns.md +++ b/doc/netwatch-dns.md @@ -4,7 +4,7 @@ Manage DNS and DoH servers from netwatch [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.16-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/netwatch-notify.d/notification-01-down.avif b/doc/netwatch-notify.d/notification-01-down.avif index 2257a0d3..894fb23f 100644 Binary files a/doc/netwatch-notify.d/notification-01-down.avif and b/doc/netwatch-notify.d/notification-01-down.avif differ diff --git a/doc/netwatch-notify.d/notification-02-up.avif b/doc/netwatch-notify.d/notification-02-up.avif index 4147cb77..9021a93b 100644 Binary files a/doc/netwatch-notify.d/notification-02-up.avif and b/doc/netwatch-notify.d/notification-02-up.avif differ diff --git a/doc/netwatch-notify.md b/doc/netwatch-notify.md index b2eae8da..81adfe9d 100644 --- a/doc/netwatch-notify.md +++ b/doc/netwatch-notify.md @@ -4,7 +4,7 @@ Notify on host up and down [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.15-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -47,7 +47,6 @@ The hosts to be checked have to be added to netwatch with specific comment: Also notification settings are required for [e-mail](mod/notification-email.md), -[gotify](mod/notification-gotify.md), [matrix](mod/notification-matrix.md), [ntfy](mod/notification-ntfy.md) and/or [telegram](mod/notification-telegram.md). diff --git a/doc/ospf-to-leds.md b/doc/ospf-to-leds.md index 1bb503b4..23248b5b 100644 --- a/doc/ospf-to-leds.md +++ b/doc/ospf-to-leds.md @@ -4,7 +4,7 @@ Visualize OSPF state via LEDs [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/packages-update.md b/doc/packages-update.md index e3942e0b..8b0d4a31 100644 --- a/doc/packages-update.md +++ b/doc/packages-update.md @@ -4,7 +4,7 @@ Manage system update [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -46,8 +46,8 @@ Configuration The configuration goes to `global-config-overlay`, this is the only parameter: -* `PackagesUpdateDeferReboot`: defer the reboot for night (between 3 AM and - 5 AM), use a numerical value in days suffixed with a `d` to defer further +* `PackagesUpdateDeferReboot`: defer the reboot for night (between 3 AM + and 5 AM) By modifying the scheduler's `start-time` you can force the reboot at different time. diff --git a/doc/ppp-on-up.md b/doc/ppp-on-up.md index 3459ea12..7902f3bb 100644 --- a/doc/ppp-on-up.md +++ b/doc/ppp-on-up.md @@ -4,7 +4,7 @@ Run scripts on ppp connection [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/sms-action.md b/doc/sms-action.md index 5a0e07df..5de7f0d7 100644 --- a/doc/sms-action.md +++ b/doc/sms-action.md @@ -4,7 +4,7 @@ Act on received SMS [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/sms-forward.d/notification.avif b/doc/sms-forward.d/notification.avif index 14764a3c..01eb7ba6 100644 Binary files a/doc/sms-forward.d/notification.avif and b/doc/sms-forward.d/notification.avif differ diff --git a/doc/sms-forward.md b/doc/sms-forward.md index c5a50489..8e7417b8 100644 --- a/doc/sms-forward.md +++ b/doc/sms-forward.md @@ -4,7 +4,7 @@ Forward received SMS [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) @@ -56,7 +56,6 @@ The configuration goes to `global-config-overlay`, this is the only parameter: Notification settings are required for [e-mail](mod/notification-email.md), -[gotify](mod/notification-gotify.md), [matrix](mod/notification-matrix.md), [ntfy](mod/notification-ntfy.md) and/or [telegram](mod/notification-telegram.md). diff --git a/doc/super-mario-theme.md b/doc/super-mario-theme.md index a3f6277d..2ffb25b3 100644 --- a/doc/super-mario-theme.md +++ b/doc/super-mario-theme.md @@ -4,7 +4,7 @@ Play Super Mario theme [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/telegram-chat.md b/doc/telegram-chat.md index c6f565ad..1e6f70f0 100644 --- a/doc/telegram-chat.md +++ b/doc/telegram-chat.md @@ -4,7 +4,7 @@ Chat with your router and send commands via Telegram bot [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.15-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/unattended-lte-firmware-upgrade.md b/doc/unattended-lte-firmware-upgrade.md index 1df34c0e..e9a888c3 100644 --- a/doc/unattended-lte-firmware-upgrade.md +++ b/doc/unattended-lte-firmware-upgrade.md @@ -4,7 +4,7 @@ Install LTE firmware upgrade [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/update-gre-address.md b/doc/update-gre-address.md index dd047c23..7e101c4a 100644 --- a/doc/update-gre-address.md +++ b/doc/update-gre-address.md @@ -4,7 +4,7 @@ Update GRE configuration with dynamic addresses [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/doc/update-tunnelbroker.md b/doc/update-tunnelbroker.md index 7c2ca35b..126d470b 100644 --- a/doc/update-tunnelbroker.md +++ b/doc/update-tunnelbroker.md @@ -4,7 +4,7 @@ Update tunnelbroker configuration [![GitHub stars](https://img.shields.io/github/stars/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=red)](https://github.com/eworm-de/routeros-scripts/stargazers) [![GitHub forks](https://img.shields.io/github/forks/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=green)](https://github.com/eworm-de/routeros-scripts/network) [![GitHub watchers](https://img.shields.io/github/watchers/eworm-de/routeros-scripts?logo=GitHub&style=flat&color=blue)](https://github.com/eworm-de/routeros-scripts/watchers) -[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.17-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.14-yellow?style=flat)](https://mikrotik.com/download/changelogs/) [![Telegram group @routeros_scripts](https://img.shields.io/badge/Telegram-%40routeros__scripts-%2326A5E4?logo=telegram&style=flat)](https://t.me/routeros_scripts) [![donate with PayPal](https://img.shields.io/badge/Like_it%3F-Donate!-orange?logo=githubsponsors&logoColor=orange&style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A4ZXBD6YS2W8J) diff --git a/firmware-upgrade-reboot.rsc b/firmware-upgrade-reboot.rsc index 93a264fc..e3d62def 100644 --- a/firmware-upgrade-reboot.rsc +++ b/firmware-upgrade-reboot.rsc @@ -1,18 +1,18 @@ #!rsc by RouterOS # RouterOS script: firmware-upgrade-reboot -# Copyright (c) 2022-2026 Christian Hesse +# Copyright (c) 2022-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # install firmware upgrade, and reboot # https://rsc.eworm.de/doc/firmware-upgrade-reboot.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global LogPrint; @@ -55,6 +55,6 @@ $LogPrint info $ScriptName ("Firmware upgrade successful, rebooting."); /system/reboot; -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/fw-addr-lists.d/allow b/fw-addr-lists.d/allow index 8c4ca3c7..8b59ed7c 100644 --- a/fw-addr-lists.d/allow +++ b/fw-addr-lists.d/allow @@ -1,3 +1,3 @@ # an ip address list for use with fw-addr-lists script -# https://rsc.eworm.de/doc/fw-addr-lists.md -rsc.eworm.de +# https://git.eworm.de/cgit/routeros-scripts/about/doc/fw-addr-lists.md +git.eworm.de diff --git a/fw-addr-lists.d/block b/fw-addr-lists.d/block index 86a6c626..5e9fef29 100644 --- a/fw-addr-lists.d/block +++ b/fw-addr-lists.d/block @@ -1,5 +1,5 @@ # an ip address list for use with fw-addr-lists script -# https://rsc.eworm.de/doc/fw-addr-lists.md +# https://git.eworm.de/cgit/routeros-scripts/about/doc/fw-addr-lists.md # example.net 93.184.216.34 diff --git a/fw-addr-lists.rsc b/fw-addr-lists.rsc index a9b3daf4..d41dc04e 100644 --- a/fw-addr-lists.rsc +++ b/fw-addr-lists.rsc @@ -1,18 +1,18 @@ #!rsc by RouterOS # RouterOS script: fw-addr-lists -# Copyright (c) 2023-2026 Christian Hesse +# Copyright (c) 2023-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.16 # # download, import and update firewall address-lists # https://rsc.eworm.de/doc/fw-addr-lists.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global FwAddrLists; @@ -22,12 +22,8 @@ :global EitherOr; :global FetchHuge; :global HumanReadableNum; - :global IfThenElse; :global LogPrint; :global LogPrintOnce; - :global LogPrintVerbose; - :global NetMask4; - :global NetMask6; :global ScriptLock; :global WaitFullyConnected; @@ -40,23 +36,12 @@ } } - :local GetBranch do={ - :global EitherOr; - :return [ :pick [ :convert transform=md5 to=hex [ :pick $1 0 [ $EitherOr [ :find $1 "/" ] [ :len $1 ] ] ] ] 0 2 ]; - } - :if ([ $ScriptLock $ScriptName ] = false) do={ :set ExitOK true; :error false; } $WaitFullyConnected; - :if ([ :len [ /log/find where topics=({"script"; "warning"}) \ - message=("\$LogPrintOnce: The message is already in log, scripting subsystem may have crashed before!") ] ] > 0) do={ - $LogPrintOnce warning $ScriptName ("Scripting subsystem may have crashed, possibly caused by us. Delaying!"); - :delay 5m; - } - :local ListComment ("managed by " . $ScriptName); :foreach FwListName,FwList in=$FwAddrLists do={ @@ -74,7 +59,7 @@ :if ([ :len ($List->"cert") ] > 0) do={ :set CheckCertificate true; - :if ([ $CertificateAvailable ($List->"cert") "fetch" ] = false) do={ + :if ([ $CertificateAvailable ($List->"cert") ] = false) do={ $LogPrint warning $ScriptName ("Downloading required certificate (" . $FwListName . \ " / " . $List->"url" . ") failed, trying anyway."); } @@ -106,7 +91,7 @@ :foreach Line in=[ :deserialize $Data delimiter="\n" from=dsv options=dsv.plain ] do={ :set Line ($Line->0); :local Address; - :if ([ :pick $Line 0 1 ] = "{" && [ :pick $Line ([ :len $Line ] - 1) ] = "}") do={ + :if ([ :pick $Line 0 1 ] = "{") do={ :do { :set Address [ :tostr ([ :deserialize from=json $Line ]->"cidr") ]; } on-error={ } @@ -114,37 +99,17 @@ :set Address ([ :pick $Line 0 [ $FindDelim $Line ] ] . ($List->"cidr")); } :do { - :local Branch; :if ($Address ~ "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}(/[0-9]{1,2})?\$") do={ - :local Net $Address; - :local CIDR 32; - :local Slash [ :find $Address "/" ]; - :if ([ :typeof $Slash ] = "num") do={ - :set Net [ :toip [ :pick $Address 0 $Slash ] ] - :set CIDR [ :pick $Address ($Slash + 1) [ :len $Address ] ]; - :set Address [ :tostr (([ :toip $Net ] & [ $NetMask4 $CIDR ]) . [ $IfThenElse ($CIDR < 32) ("/" . $CIDR) ]) ]; - } - :set Branch [ $GetBranch $Address ]; - :set ($IPv4Addresses->$Branch->$Address) $TimeOut; + :set ($IPv4Addresses->$Address) $TimeOut; :error true; } :if ($Address ~ "^[0-9a-zA-Z]*:[0-9a-zA-Z:\\.]+(/[0-9]{1,3})?\$") do={ - :local Net $Address; - :local CIDR 128; - :local Slash [ :find $Address "/" ]; - :if ([ :typeof $Slash ] = "num") do={ - :set Net [ :toip6 [ :pick $Address 0 $Slash ] ] - :set CIDR [ :pick $Address ($Slash + 1) [ :len $Address ] ]; - } - :set Address (([ :toip6 $Net ] & [ $NetMask6 $CIDR ]) . "/" . $CIDR); - :set Branch [ $GetBranch $Address ]; - :set ($IPv6Addresses->$Branch->$Address) $TimeOut; + :set ($IPv6Addresses->$Address) $TimeOut; :error true; } :if ($Address ~ "^[\\.a-zA-Z0-9-]+\\.[a-zA-Z]{2,}\$") do={ - :set Branch [ $GetBranch $Address ]; - :set ($IPv4Addresses->$Branch->$Address) $TimeOut; - :set ($IPv6Addresses->$Branch->$Address) $TimeOut; + :set ($IPv4Addresses->$Address) $TimeOut; + :set ($IPv6Addresses->$Address) $TimeOut; :error true; } } on-error={ } @@ -154,18 +119,16 @@ :foreach Entry in=[ /ip/firewall/address-list/find where \ list=$FwListName comment=$ListComment ] do={ :local Address [ /ip/firewall/address-list/get $Entry address ]; - :local Branch [ $GetBranch $Address ]; - :local TimeOut ($IPv4Addresses->$Branch->$Address); - :if ([ :typeof $TimeOut ] = "time") do={ - $LogPrintVerbose debug $ScriptName ("Renewing IPv4 address " . $Address . \ - " in list '" . $FwListName . "' with " . $TimeOut . "."); - /ip/firewall/address-list/set $Entry timeout=$TimeOut; - :set ($IPv4Addresses->$Branch->$Address); + :if ([ :typeof ($IPv4Addresses->$Address) ] = "time") do={ + $LogPrint debug $ScriptName ("Renewing IPv4 address in list '" . $FwListName . \ + "' with " . ($IPv4Addresses->$Address) . ": " . $Address); + /ip/firewall/address-list/set $Entry timeout=($IPv4Addresses->$Address); + :set ($IPv4Addresses->$Address); :set CntRenew ($CntRenew + 1); } else={ :if ($Failure = false) do={ - $LogPrintVerbose debug $ScriptName ("Removing IPv4 address " . $Address . \ - " from list '" . $FwListName . "."); + $LogPrint debug $ScriptName ("Removing IPv4 address from list '" . $FwListName . \ + "': " . $Address); /ip/firewall/address-list/remove $Entry; :set CntRemove ($CntRemove + 1); } @@ -175,53 +138,47 @@ :foreach Entry in=[ /ipv6/firewall/address-list/find where \ list=$FwListName comment=$ListComment ] do={ :local Address [ /ipv6/firewall/address-list/get $Entry address ]; - :local Branch [ $GetBranch $Address ]; - :local TimeOut ($IPv6Addresses->$Branch->$Address); - :if ([ :typeof $TimeOut ] = "time") do={ - $LogPrintVerbose debug $ScriptName ("Renewing IPv6 address " . $Address . \ - " in list '" . $FwListName . "' with " . $TimeOut . "."); - /ipv6/firewall/address-list/set $Entry timeout=$TimeOut; - :set ($IPv6Addresses->$Branch->$Address); + :if ([ :typeof ($IPv6Addresses->$Address) ] = "time") do={ + $LogPrint debug $ScriptName ("Renewing IPv6 address in list '" . $FwListName . \ + "' with " . ($IPv6Addresses->$Address) . ": " . $Address); + /ipv6/firewall/address-list/set $Entry timeout=($IPv6Addresses->$Address); + :set ($IPv6Addresses->$Address); :set CntRenew ($CntRenew + 1); } else={ :if ($Failure = false) do={ - $LogPrintVerbose debug $ScriptName ("Removing IPv6 address " . $Address . \ - " from list '" . $FwListName ."."); + $LogPrint debug $ScriptName ("Removing IPv6 address from list '" . $FwListName . \ + "': " . $Address); /ipv6/firewall/address-list/remove $Entry; :set CntRemove ($CntRemove + 1); } } } - :foreach BranchName,Branch in=$IPv4Addresses do={ - $LogPrintVerbose debug $ScriptName ("Handling branch: " . $BranchName); - :foreach Address,Timeout in=$Branch do={ - $LogPrintVerbose debug $ScriptName ("Adding IPv4 address " . $Address . \ - " to list '" . $FwListName . "' with " . $Timeout . "."); - :onerror Err { - /ip/firewall/address-list/add list=$FwListName comment=$ListComment \ - address=$Address timeout=$Timeout; - :set CntAdd ($CntAdd + 1); - } do={ - $LogPrint warning $ScriptName ("Failed to add IPv4 address " . $Address . \ - " to list '" . $FwListName . "': " . $Err); - } + :foreach Address,Timeout in=$IPv4Addresses do={ + $LogPrint debug $ScriptName ("Adding IPv4 address to list '" . $FwListName . \ + "' with " . $Timeout . ": " . $Address); + :do { + /ip/firewall/address-list/add list=$FwListName comment=$ListComment \ + address=$Address timeout=$Timeout; + :set ($IPv4Addresses->$Address); + :set CntAdd ($CntAdd + 1); + } on-error={ + $LogPrint warning $ScriptName ("Failed to add IPv4 address to list '" . $FwListName . \ + "': " . $Address); } } - :foreach BranchName,Branch in=$IPv6Addresses do={ - $LogPrintVerbose debug $ScriptName ("Handling branch: " . $BranchName); - :foreach Address,Timeout in=$Branch do={ - $LogPrintVerbose debug $ScriptName ("Adding IPv6 address " . $Address . \ - " to list '" . $FwListName . "' with " . $Timeout . "."); - :onerror Err { - /ipv6/firewall/address-list/add list=$FwListName comment=$ListComment \ - address=$Address timeout=$Timeout; - :set CntAdd ($CntAdd + 1); - } do={ - $LogPrint warning $ScriptName ("Failed to add IPv6 address " . $Address . \ - " to list '" . $FwListName . "': " . $Err); - } + :foreach Address,Timeout in=$IPv6Addresses do={ + $LogPrint debug $ScriptName ("Adding IPv6 address to list '" . $FwListName . \ + "' with " . $Timeout . ": " . $Address); + :do { + /ipv6/firewall/address-list/add list=$FwListName comment=$ListComment \ + address=$Address timeout=$Timeout; + :set ($IPv6Addresses->$Address); + :set CntAdd ($CntAdd + 1); + } on-error={ + $LogPrint warning $ScriptName ("Failed to add IPv6 address to list '" . $FwListName . \ + "': " . $Address); } } @@ -231,6 +188,6 @@ " - renewed: " . [ $HumanReadableNum $CntRenew 1000 ] . \ " - removed: " . [ $HumanReadableNum $CntRemove 1000 ]); } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/general/clipboard.js b/general/clipboard.js deleted file mode 100644 index cbcfa4ad..00000000 --- a/general/clipboard.js +++ /dev/null @@ -1,8 +0,0 @@ -/* copy code to clipboard */ -function CopyToClipboard(element) { - element.style.filter = 'invert(1)'; - navigator.clipboard.writeText(element.firstElementChild.textContent); - setTimeout(function() { - element.style.filter = 'invert(0)'; - }, 100); -} diff --git a/general/eworm-meadow.avif b/general/eworm-meadow.avif deleted file mode 100644 index f592d59b..00000000 Binary files a/general/eworm-meadow.avif and /dev/null differ diff --git a/general/style.css b/general/style.css deleted file mode 100644 index c3e86901..00000000 --- a/general/style.css +++ /dev/null @@ -1,108 +0,0 @@ -/* stylesheet for RouterOS Scripts */ -body { - background-color: transparent; - font-family: fira-sans, sans-serif; - font-size: 10pt; - line-height: 1.6; -} -h2 { - border-bottom: 1px solid #ccc; - color: #000; -} -a { - text-decoration: none; -} -a:hover { - text-decoration: underline; -} -blockquote { - border-left: 4px solid #ccc; - padding: 0 10px; - color: #555; -} -code { - margin: 0 2px; - padding: 2px 5px; - border: 1px solid #ccc; - background-color: #f8f8f8; - border-radius: 3px; -} -div.notification { - position: relative; - float: none; - width: 600px; - border: 3px outset #6c5d53; - /* border-radius: 5px; */ - padding: 10px; - background-color: #e6e6e6; -} -div.content { - padding-left: 60px; -} -hr { - clear: both; -} -img.logo { - float: left; - /* border-radius: 50%; */ -} -p.foot { - color: #777; - text-align: center; -} -p.heading { - font-size: 120%; - margin: 0px; - font-weight: bold; - text-decoration: underline; -} -p.hint { - display: none; -} -pre { - font-family: fira-mono, monospace; - white-space: pre-wrap; -} -pre.code { - background-color: #f8f8f8; - border: 1px solid #ccc; - overflow: auto; - padding: 6px 10px; - border-radius: 3px; -} -pre code { - margin: 0; - padding: 0; - border: 0; -} -pre.code::before { - content: "📋 Copy!"; - float: right; - border: 1px solid #ccc; - border-radius: 3px; -} -span.link { - color: #863600; -} -td.head { - line-height: 1.2; - padding: 0 2em; -} -td.head .top { - font-size: 250%; - font-weight: bold; -} -td.head .bottom { - font-size: 125%; - color: #555; -} -@media only screen and (orientation: landscape) { - body { - margin-left: 10vw; - margin-right: 10vw; - } - div.notification { - float: right; - margin: 10px; - } -} diff --git a/global-config-overlay.rsc b/global-config-overlay.rsc index 5bfc3031..9afacebd 100644 --- a/global-config-overlay.rsc +++ b/global-config-overlay.rsc @@ -1,12 +1,12 @@ # Overlay for global configuration by RouterOS Scripts -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # # global configuration, custom overlay # https://rsc.eworm.de/#editing-configuration # Copy relevant configuration from global-config, paste and modify it here. -# https://rsc.eworm.de/main/global-config.rsc +# https://rsc.eworm.de/global-config.rsc # End of global-config-overlay diff --git a/global-config.rsc b/global-config.rsc index 25254123..df26ef97 100644 --- a/global-config.rsc +++ b/global-config.rsc @@ -1,17 +1,11 @@ #!rsc by RouterOS # RouterOS script: global-config -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # # global configuration # https://rsc.eworm.de/ -# Warning: Do *NOT* copy this line to overlay! -:global GlobalConfigReady false; -# || ... but -# \||/ start -# \/ here! - # Set this to 'true' to disable news and change notifications. :global NoNewsAndChangesNotification false; @@ -39,8 +33,6 @@ :global TelegramChatId ""; #:global TelegramTokenId "123456:ABCDEF-GHI"; #:global TelegramChatId "12345678"; -# Use this to send notifications to a specific topic in group. -:global TelegramThreadId ""; # Using telegram-chat you have to define trusted chat ids (not group ids!) # or user names. Groups allow to chat with devices simultaneously. #:global TelegramChatIdsTrusted { @@ -64,17 +56,11 @@ # install the module: # $ScriptInstallUpdate mod/notification-ntfy :global NtfyServer "ntfy.sh"; -:global NtfyServerUser ""; -:global NtfyServerPass ""; -:global NtfyServerToken ""; +:global NtfyServerUser []; +:global NtfyServerPass []; +:global NtfyServerToken []; :global NtfyTopic ""; -# You can send Gotify notifications. Configure these settings and -# install the module: -# $ScriptInstallUpdate mod/notification-gotify -:global GotifyServer ""; -:global GotifyToken ""; - # It is possible to override e-mail, Telegram, Matrix and Ntfy setting # for every script. This is done in arrays, where 'Override' is appended # to the variable name, like this: @@ -104,7 +90,6 @@ :global BackupPartitionCopyBeforeFeatureUpdate false; # This defines the settings for firewall address-lists (fw-addr-lists). -# Warning: Mind your device's resources - memory and processing! :global FwAddrLists { # "allow"={ # { url="https://rsc.eworm.de/main/fw-addr-lists.d/allow"; @@ -113,9 +98,10 @@ "block"={ # { url="https://rsc.eworm.de/main/fw-addr-lists.d/block"; # cert="ISRG Root X2" }; - { url="https://raw.githubusercontent.com/stamparm/ipsum/refs/heads/master/levels/4.txt"; -# # higher level (decrease the numerical value) for more addresses, and vice versa - cert="USERTrust RSA Certification Authority" }; + { url="https://feodotracker.abuse.ch/downloads/ipblocklist_recommended.txt"; + cert="GlobalSign" }; + { url="https://sslbl.abuse.ch/blacklist/sslipblacklist.txt"; + cert="GlobalSign" }; { url="https://www.dshield.org/block.txt"; cidr="/24"; cert="ISRG Root X1" }; { url="https://lists.blocklist.de/lists/strongips.txt"; @@ -133,17 +119,17 @@ :global FwAddrListTimeOut 1d; # This defines what log messages to filter or include by topic or message -# text. Regular expressions are supported. An empty string has a special -# meaning not to filter or include anything. +# text. Regular expressions are supported. Do *NOT* set an empty string, +# that will filter or include everything! # These are filters, so excluding messages from forwarding. :global LogForwardFilter "(debug|info|packet|raw)"; -:global LogForwardFilterMessage ""; +:global LogForwardFilterMessage []; #:global LogForwardFilterMessage "message text"; #:global LogForwardFilterMessage "(message text|another text|...)"; # ... and another setting with reverse logic. This includes messages even # if filtered above. -:global LogForwardInclude ""; -:global LogForwardIncludeMessage ""; +:global LogForwardInclude []; +:global LogForwardIncludeMessage []; #:global LogForwardInclude "account"; #:global LogForwardIncludeMessage "message text"; @@ -270,21 +256,14 @@ "cert2-cn"="4n0th3r-s3cr3t"; }; -# /\ Warning: Do *NOT* copy -# /\7\ the code below to overlay! -# /_()_\ Things *will* break! -# # load custom settings from overlay and snippets -:foreach Script in=([ /system/script/find where name~"^global-config\\.d/." ], \ - [ /system/script/find where name="global-config-overlay" ], \ - [ /system/script/find where name~"^global-config-overlay\\.d/." ]) do={ - :onerror Err { +# Warning: Do *NOT* copy this code to overlay! +:foreach Script in=([ /system/script/find where name="global-config-overlay" ], \ + [ /system/script/find where name~"^global-config-overlay.d/" ]) do={ + :do { /system/script/run $Script; - } do={ + } on-error={ :log error ("Loading configuration from overlay or snippet " . \ - [ /system/script/get $Script name ] . " failed: " . $Err); + [ /system/script/get $Script name ] . " failed!"); } } - -# signal we are ready -:set GlobalConfigReady true; diff --git a/global-functions.rsc b/global-functions.rsc index 5c70a463..8eb6712c 100644 --- a/global-functions.rsc +++ b/global-functions.rsc @@ -1,10 +1,10 @@ #!rsc by RouterOS # RouterOS script: global-functions -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # Michael Gisbers # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # requires device-mode, fetch, scheduler # # global functions @@ -12,10 +12,8 @@ :local ScriptName [ :jobname ]; -# Git commit id & info, expected configuration version -:global CommitId "unknown"; -:global CommitInfo "unknown"; -:global ExpectedConfigVersion 138; +# expected configuration version +:global ExpectedConfigVersion 132; # global variables not to be changed by user :global GlobalFunctionsReady false; @@ -38,8 +36,6 @@ :global ExitError; :global FetchHuge; :global FetchUserAgentStr; -:global FileExists; -:global FileGet; :global FormatLine; :global FormatMultiLines; :global GetMacVendor; @@ -57,12 +53,9 @@ :global IsTimeSync; :global LogPrint; :global LogPrintOnce; -:global LogPrintVerbose; :global MAX; :global MIN; :global MkDir; -:global NetMask4; -:global NetMask6; :global NotificationFunctions; :global ParseDate; :global ParseKeyValueStore; @@ -70,8 +63,6 @@ :global ProtocolStrip; :global RandomDelay; :global RequiredRouterOS; -:global RmDir; -:global RmFile; :global ScriptFromTerminal; :global ScriptInstallUpdate; :global ScriptLock; @@ -106,15 +97,11 @@ # check and download required certificate :set CertificateAvailable do={ :local CommonName [ :tostr $1 ]; - :local UseFor [ :tostr $2 ]; :global CertificateDownload; - :global EitherOr; :global LogPrint; :global ParseKeyValueStore; - :set UseFor [ $EitherOr $UseFor "undefined" ]; - :if ([ /system/resource/get free-hdd-space ] < 8388608 && \ [ /certificate/settings/get crl-download ] = true && \ [ /certificate/settings/get crl-store ] = "system") do={ @@ -127,14 +114,6 @@ :return false; } - :local CertSettings [ /certificate/settings/get ]; - :if ((($CertSettings->"builtin-trust-anchors") = "trusted" || \ - ($CertSettings->"builtin-trust-store") ~ $UseFor || \ - ($CertSettings->"builtin-trust-store") = "all") && \ - [[ :parse (":return [ :len [ /certificate/builtin/find where common-name=\"" . $CommonName . "\" ] ]") ]] > 0) do={ - :return true; - } - :if ([ :len [ /certificate/find where common-name=$CommonName ] ] = 0) do={ $LogPrint info $0 ("Certificate with CommonName '" . $CommonName . "' not available."); :if ([ $CertificateDownload $CommonName ] = false) do={ @@ -142,11 +121,6 @@ } } - :if ([ :len [ /certificate/find where common-name=$CommonName ] ] > 1) do={ - $LogPrint info $0 ("There are " . $CertCount . " Certificates with CommonName '" . $CommonName . "'. Should be ok."); - :return true; - } - :local CertVal [ /certificate/get [ find where common-name=$CommonName ] ]; :while (($CertVal->"akid") != "" && ($CertVal->"akid") != ($CertVal->"skid")) do={ :if ([ :len [ /certificate/find where skid=($CertVal->"akid") ] ] = 0) do={ @@ -168,11 +142,11 @@ :global ScriptUpdatesBaseUrl; :global ScriptUpdatesUrlSuffix; + :global CertificateAvailable; :global CertificateNameByCN; :global CleanName; :global FetchUserAgentStr; :global LogPrint; - :global RmFile; :global WaitForFile; $LogPrint info $0 ("Downloading and importing certificate with " . \ @@ -187,8 +161,8 @@ $LogPrint warning $0 ("Failed downloading certificate with CommonName '" . $CommonName . \ "' from repository! Trying fallback to mkcert.org..."); :do { - :if ([ :len [ /certificate/find where common-name="ISRG Root X1" ] ] = 0) do={ - $LogPrint error $0 ("Required certificate is not available."); + :if ([ $CertificateAvailable "ISRG Root X1" ] = false) do={ + $LogPrint error $0 ("Downloading required certificate failed."); :return false; } /tool/fetch check-certificate=yes-without-crl http-header-field=({ [ $FetchUserAgentStr $0 ] }) \ @@ -196,7 +170,7 @@ dst-path=$FileName as-value; $WaitForFile $FileName; :if ([ /file/get $FileName size ] = 0) do={ - $RmFile $FileName; + /file/remove $FileName; :error false; } } on-error={ @@ -207,7 +181,7 @@ /certificate/import file-name=$FileName passphrase="" as-value; :delay 1s; - $RmFile $FileName; + /file/remove [ find where name=$FileName ]; :if ([ :len [ /certificate/find where common-name=$CommonName ] ] = 0) do={ /certificate/remove [ find where name~("^" . $FileName . "_[0-9]+\$") ]; @@ -223,33 +197,19 @@ # name a certificate by its common-name :set CertificateNameByCN do={ - :local Match [ :tostr $1 ]; + :local CommonName [ :tostr $1 ]; :global CleanName; - :global LogPrint; - :local Cert ([ /certificate/find where (common-name=$Match or fingerprint=$Match or name=$Match) ]->0); - :if ([ :len $Cert ] = 0) do={ - $LogPrint warning $0 ("No matching certificate found."); - :return false; - } - :local CommonName [ /certificate/get $Cert common-name ]; + :local Cert [ /certificate/find where common-name=$CommonName ]; /certificate/set $Cert name=[ $CleanName $CommonName ]; - :return true; } # multiply given character(s) :set CharacterMultiply do={ - :local Str [ :tostr $1 ]; - :local Num [ :tonum $2 ]; - - :if ($Num = 0) do={ - :return ""; - } - :local Return ""; - :for I from=1 to=$Num do={ - :set Return ($Return . $Str); + :for I from=1 to=$2 do={ + :set Return ($Return . $1); } :return $Return; } @@ -321,8 +281,6 @@ # get readable device info :set DeviceInfo do={ - :global CommitId; - :global CommitInfo; :global ExpectedConfigVersion; :global Identity; @@ -344,19 +302,16 @@ ([ $FormatLine "Location" ($Snmp->"location") ] . "\n") ] . \ [ $IfThenElse ([ :len ($Snmp->"contact") ] > 0) \ ([ $FormatLine "Contact" ($Snmp->"contact") ] . "\n") ] . \ - "Hardware:\n" . \ - [ $FormatLine " Board" ($Resource->"board-name") ] . "\n" . \ - [ $FormatLine " Arch" ($Resource->"architecture-name") ] . "\n" . \ + [ $FormatLine "Board name" ($Resource->"board-name") ] . "\n" . \ + [ $FormatLine "Architecture" ($Resource->"architecture-name") ] . "\n" . \ [ $IfThenElse ($RouterBoard->"routerboard" = true) \ - ([ $FormatLine " Model" ($RouterBoard->"model") ] . \ + ([ $FormatLine "Model" ($RouterBoard->"model") ] . \ [ $IfThenElse ([ :len ($RouterBoard->"revision") ] > 0) \ (" " . $RouterBoard->"revision") ] . "\n" . \ - [ $FormatLine " Serial" ($RouterBoard->"serial-number") ] . "\n") ] . \ - [ $IfThenElse ([ :len ($License->"nlevel") ] > 0) \ - ([ $FormatLine " License" ("level " . ($License->"nlevel")) ] . "\n") ] . \ - "RouterOS:\n" . \ + [ $FormatLine "Serial number" ($RouterBoard->"serial-number") ] . "\n") ] . \ [ $IfThenElse ([ :len ($License->"level") ] > 0) \ - ([ $FormatLine " License" ("level " . ($License->"level")) ] . "\n") ] . \ + ([ $FormatLine "License" ($License->"level") ] . "\n") ] . \ + "RouterOS:\n" . \ [ $FormatLine " Channel" ($Update->"channel") ] . "\n" . \ [ $FormatLine " Installed" ($Update->"installed-version") ] . "\n" . \ [ $IfThenElse ([ :typeof ($Update->"latest-version") ] != "nothing" && \ @@ -366,8 +321,6 @@ $RouterBoard->"current-firmware" != $RouterBoard->"upgrade-firmware") \ ([ $FormatLine " Firmware" ($RouterBoard->"current-firmware") ] . "\n") ] . \ "RouterOS-Scripts:\n" . \ - [ $IfThenElse ($CommitId != "unknown") \ - ([ $FormatLine " Commit" ($CommitInfo . "/" . [ :pick $CommitId 0 8 ]) ] . "\n") ] . \ [ $FormatLine " Version" $ExpectedConfigVersion ]); } @@ -385,10 +338,8 @@ :global CertificateAvailable; :global CleanFilePath; - :global FileExists; :global LogPrint; :global MkDir; - :global RmFile; :global WaitForFile; :if ([ :len $PkgName ] = 0) do={ :return false; } @@ -406,12 +357,12 @@ :return false; } - :if ([ $FileExists $PkgDest "package" ] = true) do={ + :if ([ :len [ /file/find where name=$PkgDest type="package" ] ] > 0) do={ $LogPrint info $0 ("Package file " . $PkgName . " already exists."); :return true; } - :if ([ $CertificateAvailable "ISRG Root X1" "fetch" ] = false) do={ + :if ([ $CertificateAvailable "ISRG Root X1" ] = false) do={ $LogPrint error $0 ("Downloading required certificate failed."); :return false; } @@ -419,22 +370,25 @@ :local Url ("https://upgrade.mikrotik.com/routeros/" . $PkgVer . "/" . $PkgFile); $LogPrint info $0 ("Downloading package file '" . $PkgName . "'..."); $LogPrint debug $0 ("... from url: " . $Url); + :local Retry 3; + :while ($Retry > 0) do={ + :do { + /tool/fetch check-certificate=yes-without-crl $Url dst-path=$PkgDest; + $WaitForFile $PkgDest; - :onerror Err { - /tool/fetch check-certificate=yes-without-crl $Url dst-path=$PkgDest; - $WaitForFile $PkgDest; - } do={ - $LogPrint warning $0 ("Downloading package file '" . $PkgName . "' failed: " . $Err); - :return false; + :if ([ /file/get [ find where name=$PkgDest ] type ] = "package") do={ + :return true; + } + } on-error={ + $LogPrint debug $0 ("Downloading package file failed."); + } + + /file/remove [ find where name=$PkgDest ]; + :set Retry ($Retry - 1); } - :if ([ $FileExists $PkgDest "package" ] = false) do={ - $LogPrint warning $0 ("Downloaded file is not a package, removing."); - $RmFile $PkgDest; - :return false; - } - - :return true; + $LogPrint warning $0 ("Downloading package file '" . $PkgName . "' failed."); + :return false; } # return either first (if "true") or second @@ -477,15 +431,13 @@ :set ExitError do={ :local ExitOK [ :tostr $1 ]; :local Name [ :tostr $2 ]; - :local Error [ :tostr $3 ]; :global IfThenElse; - :global LogPrint; + :global LogPrint; :if ($ExitOK = "false") do={ $LogPrint error $Name ([ $IfThenElse ([ :pick $Name 0 1 ] = "\$") \ - "Function" "Script" ] . " '" . $Name . "' exited with error" . \ - [ $IfThenElse (!($Error ~ "^(|true|false)\$")) (": " . $Error) "." ]); + "Function" "Script" ] . " '" . $Name . "' exited with error."); } } @@ -501,8 +453,6 @@ :global IfThenElse; :global LogPrint; :global MkDir; - :global RmDir; - :global RmFile; :global WaitForFile; :set CheckCert [ $IfThenElse ($CheckCert = "false") "no" "yes-without-crl" ]; @@ -514,22 +464,18 @@ } :local FileName ($DirName . "/" . [ $CleanName $0 ] . "-" . [ $GetRandom20CharAlNum ]); - :onerror Err { + :do { /tool/fetch check-certificate=$CheckCert $Url dst-path=$FileName \ http-header-field=({ [ $FetchUserAgentStr $ScriptName ] }) as-value; - } do={ + } on-error={ :if ([ $WaitForFile $FileName 500ms ] = true) do={ - $RmFile $FileName; + /file/remove $FileName; } - $LogPrint debug $0 ("Failed downloading from " . $Url . " - " . $Err); - $RmDir $DirName; - :return false; - } - - :if ([ $WaitForFile $FileName 5s ] = false) do={ - $LogPrint debug $0 ("The file downloaded from " . $Url . " did not show up."); + $LogPrint debug $0 ("Failed downloading from: " . $Url); + /file/remove $DirName; :return false; } + $WaitForFile $FileName; :local FileSize [ /file/get $FileName size ]; :local Return ""; @@ -542,7 +488,7 @@ :delay 100ms; } } - $RmDir $DirName; + /file/remove $DirName; :return $Return; } @@ -550,57 +496,10 @@ :set FetchUserAgentStr do={ :local Caller [ :tostr $1 ]; - :global CommitId; - :global CommitInfo; - - :global IfThenElse; - :local Resource [ /system/resource/get ]; - :return ("User-Agent: Mikrotik/" . $Resource->"version" . " " . $Resource->"architecture-name" . \ - " " . $Caller . "/Fetch (https://rsc.eworm.de/" . [ $IfThenElse ($CommitId != "unknown") \ - ("; " . $CommitInfo . "/" . [ :pick $CommitId 0 8 ]) ] . ")"); -} - -# check for existence of file, optionally with type -:set FileExists do={ - :local FileName [ :tostr $1 ]; - :local Type [ :tostr $2 ]; - - :global FileGet; - - :local FileVal [ $FileGet $FileName ]; - :if ($FileVal = false) do={ - :return false; - } - - :if ([ :len ($FileVal->"size") ] = 0) do={ - :return false; - } - - :if ([ :len $Type ] = 0 || $FileVal->"type" = $Type) do={ - :return true; - } - - :return false; -} - -# get file properties in array, or false on error -:set FileGet do={ - :local FileName [ :tostr $1 ]; - - :global WaitForFile; - - :if ([ $WaitForFile $FileName 0s ] = false) do={ - :return false; - } - - :local FileVal false; - :do { - :set FileVal [ /file/get $FileName ]; - } on-error={ } - - :return $FileVal; + :return ("User-Agent: Mikrotik/" . $Resource->"version" . " " . \ + $Resource->"architecture-name" . " " . $Caller . "/Fetch (https://rsc.eworm.de/)"); } # format a line for output @@ -657,7 +556,7 @@ } :do { - :if ([ $CertificateAvailable "GTS Root R4" "fetch" ] = false) do={ + :if ([ $CertificateAvailable "GTS Root R4" ] = false) do={ $LogPrint warning $0 ("Downloading required certificate failed."); :error false; } @@ -665,12 +564,12 @@ ("https://api.macvendors.com/" . [ :pick $Mac 0 8 ]) output=user as-value ]->"data"); :return $Vendor; } on-error={ - :onerror Err { + :do { /tool/fetch check-certificate=yes-without-crl ("https://api.macvendors.com/") \ output=none as-value; $LogPrint debug $0 ("The mac vendor is not known in database."); - } do={ - $LogPrint warning $0 ("Failed getting mac vendor: " . $Err); + } on-error={ + $LogPrint warning $0 ("Failed getting mac vendor."); } :return "unknown vendor"; } @@ -934,9 +833,6 @@ :return true; } -# The function $LogPrintVerbose is declared, but has no code, intentionally. -# https://rsc.eworm.de/DEBUG.md#verbose-output - # get max value :set MAX do={ :if ($1 > $2) do={ :return $1; } @@ -954,9 +850,7 @@ :local Path [ :tostr $1 ]; :global CleanFilePath; - :global FileGet; :global LogPrint; - :global RmDir; :global WaitForFile; :local MkTmpfs do={ @@ -973,12 +867,12 @@ } $LogPrint info $0 ("Creating disk of type tmpfs."); - $RmDir "tmpfs"; - :onerror Err { + /file/remove [ find where name="tmpfs" type="directory" ]; + :do { /disk/add slot=tmpfs type=tmpfs tmpfs-max-size=([ /system/resource/get total-memory ] / 3); $WaitForFile "tmpfs"; - } do={ - $LogPrint warning $0 ("Creating disk of type tmpfs failed: " . $Err); + } on-error={ + $LogPrint warning $0 ("Creating disk of type tmpfs failed!"); :return false; } :return true; @@ -990,11 +884,7 @@ :return true; } - $LogPrint debug $0 ("Making directory: " . $Path); - - :local PathVal [ $FileGet $Path ]; - :if ($PathVal->"type" = "directory") do={ - $LogPrint debug $0 ("... which already exists."); + :if ([ :len [ /file/find where name=$Path type="directory" ] ] = 1) do={ :return true; } @@ -1004,54 +894,19 @@ } } - :onerror Err { - /file/add type="directory" name=$Path; - $WaitForFile $Path; - } do={ - $LogPrint warning $0 ("Making directory '" . $Path . "' failed: " . $Err); + :do { + :local File ($Path . "/file"); + /file/add name=$File; + $WaitForFile $File; + /file/remove $File; + } on-error={ + $LogPrint warning $0 ("Making directory '" . $Path . "' failed!"); :return false; } :return true; } -# return an IPv4 netmask for CIDR -:set NetMask4 do={ - :local CIDR [ :tonum $1 ]; - - :return ((255.255.255.255 << (32 - $CIDR)) & 255.255.255.255); -} - -# return an IPv6 netmask for CIDR -:set NetMask6 do={ - :local FuncName $0; - :local CIDR [ :tostr $1 ]; - - :global IfThenElse; - :global MAX; - :global MIN; - - :global NetMask6Cache; - - :if ([ :typeof ($NetMask6Cache->$CIDR) ] = "ip6") do={ - :return ($NetMask6Cache->$CIDR); - } - - :if ([ :typeof $NetMask6Cache ] = "nothing") do={ - :set NetMask6Cache ({}); - } - - :local Mask ""; - :for I from=0 to=7 do={ - :set Mask ($Mask . \ - [ :convert from=num to=hex (0xffff - (0xffff >> [ :tonum [ $MIN [ $MAX ($CIDR - (16 * $I)) 0 ] 16 ] ])) ] . \ - [ $IfThenElse ($I < 7) ":" ]); - } - :set Mask [ :toip6 $Mask ]; - :set ($NetMask6Cache->$CIDR) $Mask; - :return $Mask; -} - # prepare NotificationFunctions array :if ([ :typeof $NotificationFunctions ] != "array") do={ :set NotificationFunctions ({}); @@ -1151,64 +1006,6 @@ :return true; } -# remove directory -:set RmDir do={ - :local DirName [ :tostr $1 ]; - - :global FileGet; - :global LogPrint; - - $LogPrint debug $0 ("Removing directory: ". $DirName); - - :local DirVal [ $FileGet $DirName ]; - :if ($DirVal = false) do={ - $LogPrint debug $0 ("... which does not exist."); - :return true; - } - - :if ($DirVal->"type" != "directory") do={ - $LogPrint error $0 ("Directory '" . $DirName . "' is not a directory."); - :return false; - } - - :onerror Err { - /file/remove $DirName; - } do={ - $LogPrint error $0 ("Removing directory '" . $DirName . "' failed: " . $Err); - :return false; - } - :return true; -} - -# remove file -:set RmFile do={ - :local FileName [ :tostr $1 ]; - - :global FileGet; - :global LogPrint; - - $LogPrint debug $0 ("Removing file: ". $FileName); - - :local FileVal [ $FileGet $FileName ]; - :if ($FileVal = false) do={ - $LogPrint debug $0 ("... which does not exist."); - :return true; - } - - :if ($FileVal->"type" = "directory" || $FileVal->"type" = "disk") do={ - $LogPrint error $0 ("File '" . $FileName . "' is not a file."); - :return false; - } - - :onerror Err { - /file/remove $FileName; - } do={ - $LogPrint error $0 ("Removing file '" . $FileName . "' failed: " . $Err); - :return false; - } - :return true; -} - # check if script is run from terminal :set ScriptFromTerminal do={ :local Script [ :tostr $1 ]; @@ -1236,15 +1033,11 @@ } # install new scripts, update existing scripts -:set ScriptInstallUpdate do={ :onerror Err { +:set ScriptInstallUpdate do={ :do { :local Scripts [ :toarray $1 ]; :local NewComment [ :tostr $2 ]; - :global CommitId; - :global CommitInfo; :global ExpectedConfigVersion; - :global GlobalConfigReady; - :global GlobalFunctionsReady; :global Identity; :global IDonate; :global NoNewsAndChangesNotification; @@ -1265,7 +1058,7 @@ :global SymbolForNotification; :global ValidateSyntax; - :if ([ $CertificateAvailable "ISRG Root X2" "fetch" ] = false) do={ + :if ([ $CertificateAvailable "ISRG Root X2" ] = false) do={ $LogPrint warning $0 ("Downloading certificate failed, trying without."); } @@ -1276,19 +1069,11 @@ } } - :local CommitIdBefore $CommitId; :local ExpectedConfigVersionBefore $ExpectedConfigVersion; - :local ReloadGlobal false; + :local ReloadGlobalFunctions false; + :local ReloadGlobalConfig false; :local DeviceMode [ /system/device-mode/get ]; - :local CheckSums ({}); - :do { - :local Url ($ScriptUpdatesBaseUrl . "checksums.json" . $ScriptUpdatesUrlSuffix); - $LogPrint debug $0 ("Fetching checksums from url: " . $Url); - :set CheckSums [ :deserialize from=json ([ /tool/fetch check-certificate=yes-without-crl \ - http-header-field=({ [ $FetchUserAgentStr $0 ] }) $Url output=user as-value ]->"data") ]; - } on-error={ } - :foreach Script in=[ /system/script/find where source~"^#!rsc by RouterOS\r?\n" ] do={ :local ScriptVal [ /system/script/get $Script ]; :local ScriptInfo [ $ParseKeyValueStore ($ScriptVal->"comment") ]; @@ -1302,26 +1087,8 @@ } } - :do { - :if ($ScriptInfo->"ignore" = true) do={ - $LogPrint debug $0 ("Ignoring script '" . $ScriptVal->"name" . "', as requested."); - :error true; - } - - :local CheckSum ($CheckSums->($ScriptVal->"name")); - :if ([ :len ($ScriptInfo->"base-url") ] = 0 && [ :len ($ScriptInfo->"url-suffix") ] = 0 && \ - [ :convert transform=md5 to=hex [ :tolf ($ScriptVal->"source") ] ] = $CheckSum) do={ - $LogPrint debug $0 ("Checksum for script '" . $ScriptVal->"name" . "' matches, ignoring."); - :error true; - } - - :if ([ :len ($ScriptInfo->"certificate") ] > 0) do={ - :if ([ $CertificateAvailable ($ScriptInfo->"certificate") "fetch" ] = false) do={ - $LogPrint warning $0 ("Downloading certificate failed, trying without."); - } - } - - :onerror Err { + :if (!($ScriptInfo->"ignore" = true)) do={ + :do { :local BaseUrl [ $EitherOr ($ScriptInfo->"base-url") $ScriptUpdatesBaseUrl ]; :local UrlSuffix [ $EitherOr ($ScriptInfo->"url-suffix") $ScriptUpdatesUrlSuffix ]; :local Url ($BaseUrl . $ScriptVal->"name" . ".rsc" . $UrlSuffix); @@ -1331,25 +1098,18 @@ :if ($Result->"status" = "finished") do={ :set SourceNew [ :tolf ($Result->"data") ]; } - } do={ - $LogPrint warning $0 ("Failed fetching script '" . $ScriptVal->"name" . "': " . $Err); - :if ($Err != "Fetch failed with status 404") do={ - :error false; - } - + } on-error={ :if ($ScriptVal->"source" = "#!rsc by RouterOS\n") do={ - $LogPrint warning $0 ("Removing dummy. Typo on installation?"); + $LogPrint warning $0 ("Failed fetching script '" . $ScriptVal->"name" . \ + "', removing dummy. Typo on installation?"); /system/script/remove $Script; - :error false; + } else={ + $LogPrint warning $0 ("Failed fetching script '" . $ScriptVal->"name" . "'!"); } - :if ([ :len ($ScriptInfo->"base-url") ] = 0 && [ :len ($ScriptInfo->"url-suffix") ] = 0 && \ - [ :len $CheckSum ] = 0) do={ - $LogPrintOnce warning $0 \ - ("Added the script manually? Skip updates with 'ignore=true' in comment."); - } - :error false; } + } + :do { :if ([ :len $SourceNew ] = 0) do={ $LogPrint debug $0 ("No update for script '" . $ScriptVal->"name" . "'."); :error false; @@ -1395,30 +1155,32 @@ $LogPrint info $0 ("Updating script: " . $ScriptVal->"name"); /system/script/set owner=($ScriptVal->"name") \ source=[ $IfThenElse ($ScriptUpdatesCRLF = true) $SourceCRLF $SourceNew ] $Script; - :if ($ScriptVal->"name" = "global-config" || \ - $ScriptVal->"name" = "global-functions" || \ - $ScriptVal->"name" ~ ("^mod/.")) do={ - :set ReloadGlobal true; + :if ($ScriptVal->"name" = "global-config") do={ + :set ReloadGlobalConfig true; + } + :if ($ScriptVal->"name" = "global-functions" || $ScriptVal->"name" ~ ("^mod/.")) do={ + :set ReloadGlobalFunctions true; } } on-error={ } } - :if ($ReloadGlobal = true) do={ - $LogPrint info $0 ("Reloading global configuration and functions."); - :set GlobalConfigReady false; - :set GlobalFunctionsReady false; - :delay 1s; - - :onerror Err { - /system/script/run global-config; + :if ($ReloadGlobalFunctions = true) do={ + $LogPrint info $0 ("Reloading global functions."); + :do { /system/script/run global-functions; - } do={ - $LogPrint error $0 ("Reloading global configuration and functions failed! " . $Err); + } on-error={ + $LogPrint error $0 ("Reloading global functions failed!"); } } - :if ($CommitId != "unknown" && $CommitIdBefore != $CommitId) do={ - $LogPrint info $0 ("Updated to commit: " . $CommitInfo . "/" . [ :pick $CommitId 0 8 ]); + :if ($ReloadGlobalConfig = true) do={ + $LogPrint info $0 ("Reloading global configuration."); + :do { + /system/script/run global-config; + } on-error={ + $LogPrint error $0 ("Reloading global configuration failed!" . \ + " Syntax error or missing overlay?"); + } } :if ($ExpectedConfigVersionBefore > $ExpectedConfigVersion) do={ @@ -1432,7 +1194,7 @@ :global GlobalConfigMigration; :local ChangeLogCode; - :onerror Err { + :do { :local Url ($ScriptUpdatesBaseUrl . "news-and-changes.rsc" . $ScriptUpdatesUrlSuffix); $LogPrint debug $0 ("Fetching news, changes and migration: " . $Url); :local Result [ /tool/fetch check-certificate=yes-without-crl \ @@ -1440,16 +1202,16 @@ :if ($Result->"status" = "finished") do={ :set ChangeLogCode ($Result->"data"); } - } do={ - $LogPrint warning $0 ("Failed fetching news, changes and migration: " . $Err); + } on-error={ + $LogPrint warning $0 ("Failed fetching news, changes and migration!"); } :if ([ :len $ChangeLogCode ] > 0) do={ :if ([ $ValidateSyntax $ChangeLogCode ] = true) do={ - :onerror Err { + :do { [ :parse $ChangeLogCode ]; - } do={ - $LogPrint warning $0 ("The changelog failed to run: " . $Err); + } on-error={ + $LogPrint warning $0 ("The changelog failed to run!"); } } else={ $LogPrint warning $0 ("The changelog failed syntax validation!"); @@ -1471,10 +1233,10 @@ } $LogPrint info $0 ("Applying migration for change " . $I . ": " . $Migration); - :onerror Err { + :do { [ :parse $Migration ]; - } do={ - $LogPrint warning $0 ("Migration code for change " . $I . " failed to run: " . $Err); + } on-error={ + $LogPrint warning $0 ("Migration code for change " . $I . " failed to run!"); } } on-error={ } } @@ -1516,14 +1278,14 @@ :set GlobalConfigChanges; :set GlobalConfigMigration; } -} do={ - :global ExitError; $ExitError false $0 $Err; +} on-error={ + :global ExitError; $ExitError false $0; } } # lock script against multiple invocation :set ScriptLock do={ - :local Script [ :tostr $1 ]; - :local WaitMax [ :totime $2 ]; + :local Script [ :tostr $1 ]; + :local WaitMax ([ :tonum $3 ] * 10); :global GetRandom20CharAlNum; :global IfThenElse; @@ -1612,10 +1374,6 @@ :set ($ScriptLockOrder->$Script) ({}); } - :if ([ :typeof $WaitMax ] = "nil" ) do={ - :set WaitMax 0s; - } - :if ([ :len [ /system/script/find where name=$Script ] ] = 0) do={ $LogPrint error $0 ("A script named '" . $Script . "' does not exist!"); :error false; @@ -1635,13 +1393,12 @@ :local MyTicket [ $GetRandom20CharAlNum 6 ]; $AddTicket $Script $MyTicket; - :local WaitInterval ($WaitMax / 20); - :local WaitTime $WaitMax; - :while ($WaitTime > 0 && \ + :local WaitCount 0; + :while ($WaitMax > $WaitCount && \ ([ $IsFirstTicket $Script $MyTicket ] = false || \ [ $TicketCount $Script ] < [ $JobCount $Script ])) do={ - :set WaitTime ($WaitTime - $WaitInterval); - :delay $WaitInterval; + :set WaitCount ($WaitCount + 1); + :delay 100ms; } :if ([ $IsFirstTicket $Script $MyTicket ] = true && \ @@ -1653,17 +1410,17 @@ $RemoveTicket $Script $MyTicket; $LogPrint debug $0 ("Script '" . $Script . "' started more than once" . \ - [ $IfThenElse ($WaitTime < $WaitMax) " and timed out waiting for lock" "" ] . "..."); + [ $IfThenElse ($WaitCount > 0) " and timed out waiting for lock" "" ] . "..."); :return false; } # send notification via NotificationFunctions - expects at least two string arguments -:set SendNotification do={ :onerror Err { +:set SendNotification do={ :do { :global SendNotification2; $SendNotification2 ({ origin=$0; subject=$1; message=$2; link=$3; silent=$4 }); -} do={ - :global ExitError; $ExitError false $0 $Err; +} on-error={ + :global ExitError; $ExitError false $0; } } # send notification via NotificationFunctions - expects one array argument @@ -1683,12 +1440,9 @@ :set SymbolByUnicodeName do={ :local Name [ :tostr $1 ]; - :global EitherOr; :global LogPrintOnce; - :global SymbolsExtra; - - :local Symbols ({ + :local Symbols { "abacus"="\F0\9F\A7\AE"; "alarm-clock"="\E2\8F\B0"; "arrow-down"="\E2\AC\87"; @@ -1715,7 +1469,6 @@ "mobile-phone"="\F0\9F\93\B1"; "pushpin"="\F0\9F\93\8C"; "scissors"="\E2\9C\82"; - "scroll"="\F0\9F\93\9C"; "smiley-partying-face"="\F0\9F\A5\B3"; "smiley-smiling-face"="\E2\98\BA"; "smiley-winking-face-with-tongue"="\F0\9F\98\9C"; @@ -1724,21 +1477,14 @@ "star"="\E2\AD\90"; "warning-sign"="\E2\9A\A0"; "white-heavy-check-mark"="\E2\9C\85" - }, $SymbolsExtra); - - :local Magic [ :pick [ /system/clock/get date ] 4 10 ]; - :local Special { - "information-04-01"="\F0\9F\9A\BB"; - "large-orange-circle-04-01"="\F0\9F\8D\8A"; - "large-orange-circle-10-31"="\F0\9F\8E\83"; - "large-red-circle-04-01"="\F0\9F\8D\92" }; + } :if ([ :len ($Symbols->$Name) ] = 0) do={ $LogPrintOnce warning $0 ("No symbol available for name '" . $Name . "'!"); :return ""; } - :return ([ $EitherOr ($Special->($Name . $Magic)) ($Symbols->$Name) ] . "\EF\B8\8F"); + :return (($Symbols->$Name) . "\EF\B8\8F"); } # return symbol for notification @@ -1793,12 +1539,9 @@ :set ValidateSyntax do={ :local Code [ :tostr $1 ]; - :global LogPrint; - - :onerror Err { + :do { [ :parse (":local Validate do={\n" . $Code . "\n}") ]; - } do={ - $LogPrint debug $0 ("Valdation failed: " . $Err); + } on-error={ :return false; } :return true; @@ -1865,25 +1608,17 @@ :global MAX; :set FileName [ $CleanFilePath $FileName ]; - :local Delay ([ $MAX [ $EitherOr $WaitTime 2s ] 100ms ] / 9); + :local I 1; + :local Delay ([ $MAX [ $EitherOr $WaitTime 2s ] 100ms ] / 10); - :do { - :retry { - /file/get $FileName; - :return true; - } delay=$Delay max=10; - } on-error={ } - - :while ([ :len [ /file/find where name=$FileName ] ] > 0) do={ - :do { - /file/get $FileName; - :return true; - } on-error={ } + :while ([ :len [ /file/find where name=$FileName ] ] = 0) do={ + :if ($I >= 10) do={ + :return false; + } :delay $Delay; - :set Delay ($Delay * 3 / 2); + :set I ($I + 1); } - - :return false; + :return true; } # wait to be fully connected (default route is reachable, time is sync, DNS resolves) @@ -1907,28 +1642,19 @@ } # load modules -:foreach Script in=[ /system/script/find where name ~ "^(global-functions\\.d|mod)/." ] do={ +:foreach Script in=[ /system/script/find where name ~ "^mod/." ] do={ :local ScriptVal [ /system/script/get $Script ]; :if ([ $ValidateSyntax ($ScriptVal->"source") ] = true) do={ - :onerror Err { + :do { /system/script/run $Script; - } do={ - $LogPrint error $0 ("Module '" . $ScriptVal->"name" . "' failed to run: " . $Err); + } on-error={ + $LogPrint error $0 ("Module '" . $ScriptVal->"name" . "' failed to run."); } } else={ $LogPrint error $0 ("Module '" . $ScriptVal->"name" . "' failed syntax validation, skipping."); } } -# add (and fix) global scripts scheduler -:local OnEvent "/system/script { run global-config; run global-functions; }"; -:if ([ :len [ /system/scheduler/find where name="global-scripts" ] ] = 0) do={ - /system/scheduler/add name="global-scripts" start-time=startup; -} -:if ([ /system/scheduler/get "global-scripts" on-event ] != $OnEvent) do={ - /system/scheduler/set "global-scripts" on-event=$OnEvent; -} - # Log success :local Resource [ /system/resource/get ]; $LogPrintOnce info $ScriptName ("Loaded on " . $Resource->"board-name" . \ diff --git a/global-wait.rsc b/global-wait.rsc index 5b5f5e12..bc984622 100644 --- a/global-wait.rsc +++ b/global-wait.rsc @@ -1,13 +1,12 @@ #!rsc by RouterOS # RouterOS script: global-wait -# Copyright (c) 2020-2026 Christian Hesse +# Copyright (c) 2020-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # wait for global-functions to finish # https://rsc.eworm.de/doc/global-wait.md -:global GlobalConfigReady; :global GlobalFunctionsReady; -:while ($GlobalConfigReady != true || $GlobalFunctionsReady != true) do={ :delay 500ms; } +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } diff --git a/gps-track.rsc b/gps-track.rsc index dae7d521..5e35f8da 100644 --- a/gps-track.rsc +++ b/gps-track.rsc @@ -1,19 +1,19 @@ #!rsc by RouterOS # RouterOS script: gps-track -# Copyright (c) 2018-2026 Christian Hesse +# Copyright (c) 2018-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # requires device-mode, fetch # # track gps data by sending json data to http server # https://rsc.eworm.de/doc/gps-track.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global GpsTrackUrl; @@ -34,7 +34,7 @@ :local Gps [ /system/gps/monitor once as-value ]; :if ($Gps->"valid" = true) do={ - :onerror Err { + :do { /tool/fetch check-certificate=yes-without-crl output=none http-method=post \ http-header-field=({ [ $FetchUserAgentStr $ScriptName ]; "Content-Type: application/json" }) \ http-data=[ :serialize to=json { "identity"=$Identity; \ @@ -42,12 +42,12 @@ $LogPrint debug $ScriptName ("Sending GPS data in " . $CoordinateFormat . " format: " . \ "lat: " . ($Gps->"latitude") . " " . \ "lon: " . ($Gps->"longitude")); - } do={ - $LogPrint warning $ScriptName ("Failed sending GPS data: " . $Err); + } on-error={ + $LogPrint warning $ScriptName ("Failed sending GPS data!"); } } else={ $LogPrint debug $ScriptName ("GPS data not valid."); } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/hotspot-to-wpa-cleanup.capsman.rsc b/hotspot-to-wpa-cleanup.capsman.rsc index 99ff0029..c21ec3ea 100644 --- a/hotspot-to-wpa-cleanup.capsman.rsc +++ b/hotspot-to-wpa-cleanup.capsman.rsc @@ -1,10 +1,10 @@ #!rsc by RouterOS # RouterOS script: hotspot-to-wpa-cleanup.capsman -# Copyright (c) 2021-2026 Christian Hesse +# Copyright (c) 2021-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # # provides: lease-script, order=80 -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # requires device-mode, hotspot # # manage and clean up private WPA passphrase after hotspot login @@ -12,11 +12,11 @@ # # !! Do not edit this file, it is generated from template! +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global EitherOr; @@ -75,6 +75,6 @@ /ip/dhcp-server/lease/remove $Lease; } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/hotspot-to-wpa-cleanup.template.rsc b/hotspot-to-wpa-cleanup.template.rsc index 113c1bb2..1bd877e9 100644 --- a/hotspot-to-wpa-cleanup.template.rsc +++ b/hotspot-to-wpa-cleanup.template.rsc @@ -1,10 +1,10 @@ #!rsc by RouterOS # RouterOS script: hotspot-to-wpa-cleanup%TEMPL% -# Copyright (c) 2021-2026 Christian Hesse +# Copyright (c) 2021-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # # provides: lease-script, order=80 -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # requires device-mode, hotspot # # manage and clean up private WPA passphrase after hotspot login @@ -13,11 +13,11 @@ # !! This is just a template to generate the real script! # !! Pattern '%TEMPL%' is replaced, paths are filtered. +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global EitherOr; @@ -82,6 +82,6 @@ /ip/dhcp-server/lease/remove $Lease; } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/hotspot-to-wpa-cleanup.wifi.rsc b/hotspot-to-wpa-cleanup.wifi.rsc index 1a7ef364..8e362048 100644 --- a/hotspot-to-wpa-cleanup.wifi.rsc +++ b/hotspot-to-wpa-cleanup.wifi.rsc @@ -1,10 +1,10 @@ #!rsc by RouterOS # RouterOS script: hotspot-to-wpa-cleanup.wifi -# Copyright (c) 2021-2026 Christian Hesse +# Copyright (c) 2021-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # # provides: lease-script, order=80 -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # requires device-mode, hotspot # # manage and clean up private WPA passphrase after hotspot login @@ -12,11 +12,11 @@ # # !! Do not edit this file, it is generated from template! +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global EitherOr; @@ -75,6 +75,6 @@ /ip/dhcp-server/lease/remove $Lease; } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/hotspot-to-wpa.capsman.rsc b/hotspot-to-wpa.capsman.rsc index 0751f8e5..de9f9d9a 100644 --- a/hotspot-to-wpa.capsman.rsc +++ b/hotspot-to-wpa.capsman.rsc @@ -1,9 +1,9 @@ #!rsc by RouterOS # RouterOS script: hotspot-to-wpa.capsman -# Copyright (c) 2019-2026 Christian Hesse +# Copyright (c) 2019-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # requires device-mode, hotspot # # add private WPA passphrase after hotspot login @@ -11,11 +11,11 @@ # # !! Do not edit this file, it is generated from template! +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global EitherOr; @@ -100,6 +100,6 @@ :delay 2s; /caps-man/access-list/set $Entry action=accept; -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/hotspot-to-wpa.template.rsc b/hotspot-to-wpa.template.rsc index ba044a09..003b12e2 100644 --- a/hotspot-to-wpa.template.rsc +++ b/hotspot-to-wpa.template.rsc @@ -1,9 +1,9 @@ #!rsc by RouterOS # RouterOS script: hotspot-to-wpa%TEMPL% -# Copyright (c) 2019-2026 Christian Hesse +# Copyright (c) 2019-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # requires device-mode, hotspot # # add private WPA passphrase after hotspot login @@ -12,11 +12,11 @@ # !! This is just a template to generate the real script! # !! Pattern '%TEMPL%' is replaced, paths are filtered. +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global EitherOr; @@ -120,6 +120,6 @@ :delay 2s; /caps-man/access-list/set $Entry action=accept; /interface/wifi/access-list/set $Entry action=accept; -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/hotspot-to-wpa.wifi.rsc b/hotspot-to-wpa.wifi.rsc index 569d7827..0d6a7b96 100644 --- a/hotspot-to-wpa.wifi.rsc +++ b/hotspot-to-wpa.wifi.rsc @@ -1,9 +1,9 @@ #!rsc by RouterOS # RouterOS script: hotspot-to-wpa.wifi -# Copyright (c) 2019-2026 Christian Hesse +# Copyright (c) 2019-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # requires device-mode, hotspot # # add private WPA passphrase after hotspot login @@ -11,11 +11,11 @@ # # !! Do not edit this file, it is generated from template! +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global EitherOr; @@ -97,6 +97,6 @@ :delay 2s; /interface/wifi/access-list/set $Entry action=accept; -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/ip-addr-bridge.rsc b/ip-addr-bridge.rsc index 0f2bf8ab..68ff4a41 100644 --- a/ip-addr-bridge.rsc +++ b/ip-addr-bridge.rsc @@ -1,6 +1,6 @@ #!rsc by RouterOS # RouterOS script: ip-addr-bridge -# Copyright (c) 2018-2026 Christian Hesse +# Copyright (c) 2018-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # # enable or disable ip addresses based on bridge port state diff --git a/ipsec-to-dns.rsc b/ipsec-to-dns.rsc index 02391fe8..91f6b45e 100644 --- a/ipsec-to-dns.rsc +++ b/ipsec-to-dns.rsc @@ -1,19 +1,19 @@ #!rsc by RouterOS # RouterOS script: ipsec-to-dns -# Copyright (c) 2021-2026 Christian Hesse +# Copyright (c) 2021-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # requires device-mode, ipsec # # and add/remove/update DNS entries from IPSec mode-config # https://rsc.eworm.de/doc/ipsec-to-dns.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global Domain; @@ -79,6 +79,6 @@ /ip/dns/static/add name=$Fqdn address=($PeerVal->"dynamic-address") ttl=$Ttl comment=$Comment place-before=$PlaceBefore; } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/ipv6-update.rsc b/ipv6-update.rsc index a4da6516..7eb625b2 100644 --- a/ipv6-update.rsc +++ b/ipv6-update.rsc @@ -1,18 +1,18 @@ #!rsc by RouterOS # RouterOS script: ipv6-update -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # update firewall and dns settings on IPv6 prefix change # https://rsc.eworm.de/doc/ipv6-update.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global LogPrint; @@ -20,9 +20,7 @@ :global ScriptLock; :local NaAddress $"na-address"; - :local NaValid $"na-valid"; :local PdPrefix $"pd-prefix"; - :local PdValid $"pd-valid"; :if ([ $ScriptLock $ScriptName ] = false) do={ :set ExitOK true; @@ -35,18 +33,12 @@ :error false; } - :if ([ :typeof $PdPrefix ] = "nothing" || [ :typeof $PdValid ] = "nothing") do={ + :if ([ :typeof $PdPrefix ] = "nothing") do={ $LogPrint error $ScriptName ("This script is supposed to run from ipv6 dhcp-client."); :set ExitOK true; :error false; } - :if ($PdValid != 1) do={ - $LogPrint info $ScriptName ("The prefix " . $PdPrefix . " is no longer valid. Ignoring."); - :set ExitOK true; - :error false; - } - :local Pool [ /ipv6/pool/get [ find where prefix=$PdPrefix ] name ]; :if ([ :len [ /ipv6/firewall/address-list/find where comment=("ipv6-pool-" . $Pool) ] ] = 0) do={ /ipv6/firewall/address-list/add list=("ipv6-pool-" . $Pool) address=:: comment=("ipv6-pool-" . $Pool) dynamic=yes; @@ -102,6 +94,6 @@ } } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/lease-script.rsc b/lease-script.rsc index 1b7935b8..b6ceac96 100644 --- a/lease-script.rsc +++ b/lease-script.rsc @@ -1,18 +1,18 @@ #!rsc by RouterOS # RouterOS script: lease-script -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # run scripts on DHCP lease # https://rsc.eworm.de/doc/lease-script.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global Grep; @@ -53,13 +53,13 @@ } :foreach Order,Script in=$RunOrder do={ - :onerror Err { + :do { $LogPrint debug $ScriptName ("Running script with order " . $Order . ": " . $Script); /system/script/run $Script; - } do={ - $LogPrint warning $ScriptName ("Running script '" . $Script . "' failed: " . $Err); + } on-error={ + $LogPrint warning $ScriptName ("Running script '" . $Script . "' failed!"); } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/leds-day-mode.rsc b/leds-day-mode.rsc index d2341bfd..7344fde7 100644 --- a/leds-day-mode.rsc +++ b/leds-day-mode.rsc @@ -1,6 +1,6 @@ #!rsc by RouterOS # RouterOS script: leds-day-mode -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # # enable LEDs diff --git a/leds-night-mode.rsc b/leds-night-mode.rsc index 87094fad..8bd028e7 100644 --- a/leds-night-mode.rsc +++ b/leds-night-mode.rsc @@ -1,6 +1,6 @@ #!rsc by RouterOS # RouterOS script: leds-night-mode -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # # disable LEDs diff --git a/leds-toggle-mode.rsc b/leds-toggle-mode.rsc index b6118513..b55e3514 100644 --- a/leds-toggle-mode.rsc +++ b/leds-toggle-mode.rsc @@ -1,6 +1,6 @@ #!rsc by RouterOS # RouterOS script: leds-toggle-mode -# Copyright (c) 2018-2026 Christian Hesse +# Copyright (c) 2018-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # # toggle LEDs mode diff --git a/log-forward.rsc b/log-forward.rsc index 26a23761..379fa54e 100644 --- a/log-forward.rsc +++ b/log-forward.rsc @@ -1,18 +1,18 @@ #!rsc by RouterOS # RouterOS script: log-forward -# Copyright (c) 2020-2026 Christian Hesse +# Copyright (c) 2020-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # forward log messages via notification # https://rsc.eworm.de/doc/log-forward.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global Identity; @@ -57,11 +57,6 @@ :local MessageVal; :local MessageDups ({}); - :set LogForwardFilter [ $EitherOr $LogForwardFilter [] ]; - :set LogForwardFilterMessage [ $EitherOr $LogForwardFilterMessage [] ]; - :set LogForwardInclude [ $EitherOr $LogForwardInclude [] ]; - :set LogForwardIncludeMessage [ $EitherOr $LogForwardIncludeMessage [] ]; - :local LogForwardFilterLogForwardingCached [ $EitherOr [ $LogForwardFilterLogForwarding ] ("\$^") ]; :foreach Message in=[ /log/find where (!(message="") and \ !(message~$LogForwardFilterLogForwardingCached) and \ @@ -95,7 +90,7 @@ :set LogForwardRateLimit ($LogForwardRateLimit + 10); $SendNotification2 ({ origin=$ScriptName; \ - subject=([ $SymbolForNotification ("memo" . [ $IfThenElse ($Warning = true) ",warning-sign" ]) ] . \ + subject=([ $SymbolForNotification [ $IfThenElse ($Warning = true) "warning-sign" "memo" ] ] . \ "Log Forwarding"); \ message=("The log on " . $Identity . " contains " . [ $IfThenElse ($Count = 1) "this message" \ ("these " . $Count . " messages") ] . " after " . [ /system/resource/get uptime ] . " uptime." . \ @@ -108,6 +103,6 @@ :local LogAll [ /log/find ]; :set LogForwardLast ($LogAll->([ :len $LogAll ] - 1) ); -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/logo.avif b/logo.avif index 956fea8a..399a2f5a 100644 Binary files a/logo.avif and b/logo.avif differ diff --git a/logo.png b/logo.png index 7bec10e5..d97b75dc 100644 Binary files a/logo.png and b/logo.png differ diff --git a/mod/bridge-port-to.rsc b/mod/bridge-port-to.rsc index b14926bb..f00e10b1 100644 --- a/mod/bridge-port-to.rsc +++ b/mod/bridge-port-to.rsc @@ -1,16 +1,16 @@ #!rsc by RouterOS # RouterOS script: mod/bridge-port-to -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # reset bridge ports to default bridge # https://rsc.eworm.de/doc/mod/bridge-port-to.md :global BridgePortTo; -:set BridgePortTo do={ :onerror Err { +:set BridgePortTo do={ :do { :local BridgePortTo [ :tostr $1 ]; :global IfThenElse; @@ -65,6 +65,6 @@ $LogPrint info $0 ("Re-enabling interfaces..."); /interface/ethernet/enable $InterfaceReEnable; } -} do={ - :global ExitError; $ExitError false $0 $Err; +} on-error={ + :global ExitError; $ExitError false $0; } } diff --git a/mod/bridge-port-vlan.rsc b/mod/bridge-port-vlan.rsc index 3d9567a9..62e71e38 100644 --- a/mod/bridge-port-vlan.rsc +++ b/mod/bridge-port-vlan.rsc @@ -1,16 +1,16 @@ #!rsc by RouterOS # RouterOS script: mod/bridge-port-vlan -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # manage VLANs on bridge ports # https://rsc.eworm.de/doc/mod/bridge-port-vlan.md :global BridgePortVlan; -:global BridgePortVlan do={ :onerror Err { +:global BridgePortVlan do={ :do { :local ConfigTo [ :tostr $1 ]; :global IfThenElse; @@ -74,6 +74,6 @@ $LogPrint info $0 ("Re-enabling interfaces..."); /interface/ethernet/enable $InterfaceReEnable; } -} do={ - :global ExitError; $ExitError false $0 $Err; +} on-error={ + :global ExitError; $ExitError false $0; } } diff --git a/mod/inspectvar.rsc b/mod/inspectvar.rsc index d8c0bc79..0f05da72 100644 --- a/mod/inspectvar.rsc +++ b/mod/inspectvar.rsc @@ -1,9 +1,9 @@ #!rsc by RouterOS # RouterOS script: mod/inspectvar -# Copyright (c) 2020-2026 Christian Hesse +# Copyright (c) 2020-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # inspect variables # https://rsc.eworm.de/doc/mod/inspectvar.md @@ -12,12 +12,12 @@ :global InspectVarReturn; # inspect variable and print on terminal -:set InspectVar do={ :onerror Err { +:set InspectVar do={ :do { :global InspectVarReturn; :put [ :tocrlf [ $InspectVarReturn $1 ] ]; -} do={ - :global ExitError; $ExitError false $0 $Err; +} on-error={ + :global ExitError; $ExitError false $0; } } # inspect variable and return formatted string @@ -25,7 +25,6 @@ :local Input $1; :local Level (0 + [ :tonum $2 ]); - :global CharacterReplace; :global IfThenElse; :global InspectVarReturn; @@ -34,13 +33,14 @@ :local Value [ :tostr $2 ]; :local Level [ :tonum $3 ]; - :global CharacterMultiply; - - :return ([ $CharacterMultiply " " ($Level * 2) ] . "-" . $Prefix . "-> " . $Value); + :local Indent ""; + :for I from=1 to=$Level step=1 do={ + :set Indent ($Indent . " "); + } + :return ($Indent . "-" . $Prefix . "-> " . $Value); } :local TypeOf [ :typeof $Input ]; - :local Len [ :len $Input ]; :local Return [ $IndentReturn "type" $TypeOf $Level ]; :if ($TypeOf = "array") do={ @@ -50,16 +50,6 @@ [ $InspectVarReturn $Value ($Level + 2) ]); } } else={ - :if ($TypeOf = "str") do={ - :set $Return ($Return . "\n" . \ - [ $IndentReturn "len" $Len $Level ]); - :if ([ :typeof [ :find $Input ("\r") ] ] = "num") do={ - :set Input [ $CharacterReplace $Input ("\r") "" ]; - } - :if ([ :typeof [ :find $Input ("\n") ] ] = "num") do={ - :set Input [ $CharacterReplace $Input ("\n") " " ]; - } - } :if ($TypeOf != "nothing") do={ :set $Return ($Return . "\n" . \ [ $IndentReturn "value" [ $IfThenElse ([ :len $Input ] > 80) \ diff --git a/mod/ipcalc.rsc b/mod/ipcalc.rsc index a485468e..fbed74b5 100644 --- a/mod/ipcalc.rsc +++ b/mod/ipcalc.rsc @@ -1,9 +1,9 @@ #!rsc by RouterOS # RouterOS script: mod/ipcalc -# Copyright (c) 2020-2026 Christian Hesse +# Copyright (c) 2020-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # ip address calculation # https://rsc.eworm.de/doc/mod/ipcalc.md @@ -12,7 +12,7 @@ :global IPCalcReturn; # print netmask, network, min host, max host and broadcast -:set IPCalc do={ :onerror Err { +:set IPCalc do={ :do { :local Input [ :tostr $1 ]; :global FormatLine; @@ -27,41 +27,27 @@ [ $FormatLine "HostMin" ($Values->"hostmin") ] . "\n" . \ [ $FormatLine "HostMax" ($Values->"hostmax") ] . "\n" . \ [ $FormatLine "Broadcast" ($Values->"broadcast") ]) ]; -} do={ - :global ExitError; $ExitError false $0 $Err; +} on-error={ + :global ExitError; $ExitError false $0; } } # calculate and return netmask, network, min host, max host and broadcast :set IPCalcReturn do={ :local Input [ :tostr $1 ]; - - :global NetMask4; - :global NetMask6; - - :local Address [ :pick $Input 0 [ :find $Input "/" ] ]; + :local Address [ :toip [ :pick $Input 0 [ :find $Input "/" ] ] ]; :local Bits [ :tonum [ :pick $Input ([ :find $Input "/" ] + 1) [ :len $Input ] ] ]; - :local Mask; - :local One; - :if ([ :typeof [ :toip $Address ] ] = "ip") do={ - :set Address [ :toip $Address ]; - :set Mask [ $NetMask4 $Bits ]; - :set One 0.0.0.1; - } else={ - :set Address [ :toip6 $Address ]; - :set Mask [ $NetMask6 $Bits ]; - :set One ::1; - } + :local Mask ((255.255.255.255 << (32 - $Bits)) & 255.255.255.255); - :local Return ({ + :local Return { "address"=$Address; "netmask"=$Mask; "networkaddress"=($Address & $Mask); "networkbits"=$Bits; "network"=(($Address & $Mask) . "/" . $Bits); - "hostmin"=(($Address & $Mask) | $One); - "hostmax"=(($Address | ~$Mask) ^ $One); + "hostmin"=(($Address & $Mask) | 0.0.0.1); + "hostmax"=(($Address | ~$Mask) ^ 0.0.0.1); "broadcast"=($Address | ~$Mask); - }); + } :return $Return; } diff --git a/mod/notification-email.rsc b/mod/notification-email.rsc index 1ca76f62..404e74db 100644 --- a/mod/notification-email.rsc +++ b/mod/notification-email.rsc @@ -1,9 +1,9 @@ #!rsc by RouterOS # RouterOS script: mod/notification-email -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # requires device-mode, email, scheduler # # send notifications via e-mail @@ -35,16 +35,14 @@ } # flush e-mail queue -:set FlushEmailQueue do={ :onerror Err { +:set FlushEmailQueue do={ :do { :global EmailQueue; :global EitherOr; :global EMailGenerateFrom; - :global FileExists; :global IsDNSResolving; :global IsTimeSync; :global LogPrint; - :global RmFile; :local AllDone true; :local QueueLen [ :len $EmailQueue ]; @@ -91,48 +89,40 @@ :foreach Id,Message in=$EmailQueue do={ :if ([ :typeof $Message ] = "array" ) do={ + :local Attach ({}); :while ([ /tool/e-mail/get last-status ] = "in-progress") do={ :delay 1s; } - :onerror Err { - :local Attach ({}); - :foreach File in=[ :toarray [ $EitherOr ($Message->"attach") "" ] ] do={ - :if ([ $FileExists $File ] = true) do={ - :set Attach ($Attach, $File); - } else={ - $LogPrint warning $0 ("File '" . $File . "' does not exist, can not attach."); - } + :foreach File in=[ :toarray [ $EitherOr ($Message->"attach") "" ] ] do={ + :if ([ :len [ /file/find where name=$File ] ] = 1) do={ + :set Attach ($Attach, $File); + } else={ + $LogPrint warning $0 ("File '" . $File . "' does not exist, can not attach."); } - :do { - /tool/e-mail/send from=[ $EMailGenerateFrom ] to=($Message->"to") \ - cc=($Message->"cc") subject=($Message->"subject") \ - body=($Message->"body") file=$Attach; - } on-error={ } - :local Wait true; - :do { - :delay 1s; - :local Status [ /tool/e-mail/get last-status ]; - :if ($Status = "succeeded") do={ - :set ($EmailQueue->$Id); - :set Wait false; - :if (($Message->"remove-attach") = true) do={ - :foreach File in=$Attach do={ - $RmFile $File; - } + } + /tool/e-mail/send from=[ $EMailGenerateFrom ] to=($Message->"to") cc=($Message->"cc") \ + subject=($Message->"subject") body=($Message->"body") file=$Attach; + :local Wait true; + :do { + :delay 1s; + :local Status [ /tool/e-mail/get last-status ]; + :if ($Status = "succeeded") do={ + :set ($EmailQueue->$Id); + :set Wait false; + :if (($Message->"remove-attach") = true) do={ + :foreach File in=$Attach do={ + /file/remove $File; } } - :if ($Status = "failed") do={ - :set AllDone false; - :set Wait false; - } - } while=($Wait = true); - } do={ - $LogPrint warning $0 ("Sending queued mail failed: " . $Err); - :set AllDone false; - } + } + :if ($Status = "failed") do={ + :set AllDone false; + :set Wait false; + } + } while=($Wait = true); } } :if ($AllDone = true && $QueueLen = [ :len $EmailQueue ]) do={ - /system/scheduler/remove [ find where name="_FlushEmailQueue" ]; + /system/scheduler/remove $Scheduler; :set EmailQueue; :return true; } @@ -145,8 +135,8 @@ /system/scheduler/set interval=(($SchedVal->"run-count") . "m") \ comment="Waiting for retry..." $Scheduler; -} do={ - :global ExitError; $ExitError false $0 $Err; +} on-error={ + :global ExitError; $ExitError false $0; } } # generate filter for log-forward @@ -186,7 +176,6 @@ :global IfThenElse; :global NotificationEMailSignature; :global NotificationEMailSubject; - :global SymbolForNotification; :local To [ $EitherOr ($EmailGeneralToOverride->($Notification->"origin")) $EmailGeneralTo ]; :local Cc [ $EitherOr ($EmailGeneralCcOverride->($Notification->"origin")) $EmailGeneralCc ]; @@ -199,23 +188,13 @@ :if ([ :typeof $EmailQueue ] = "nothing") do={ :set EmailQueue ({}); } - :local Truncated false; - :local Body ($Notification->"message"); - :if ([ :len $Body ] > 62000) do={ - :set Body ([ :pick $Body 0 62000 ] . "..."); - :set Truncated true; - } :local Signature [ $EitherOr [ $NotificationEMailSignature ] [ /system/note/get note ] ]; - :set Body ($Body . "\n" . \ - [ $IfThenElse ([ :len ($Notification->"link") ] > 0) \ - ("\n" . [ $SymbolForNotification "link" ] . ($Notification->"link")) ] . \ - [ $IfThenElse ($Truncated = true) ("\n" . [ $SymbolForNotification "scissors" ] . \ - "The message was too long and has been truncated!") ] . \ - [ $IfThenElse ([ :len $Signature ] > 0) ("\n-- \n" . $Signature) "" ]); :set ($EmailQueue->[ :len $EmailQueue ]) { to=$To; cc=$Cc; subject=[ $NotificationEMailSubject ($Notification->"subject") ]; - body=$Body; \ + body=(($Notification->"message") . \ + [ $IfThenElse ([ :len ($Notification->"link") ] > 0) ("\n\n" . ($Notification->"link")) "" ] . \ + [ $IfThenElse ([ :len $Signature ] > 0) ("\n-- \n" . $Signature) "" ]); \ attach=($Notification->"attach"); remove-attach=($Notification->"remove-attach") }; :if ([ :len [ /system/scheduler/find where name="_FlushEmailQueue" ] ] = 0) do={ /system/scheduler/add name="_FlushEmailQueue" interval=1s start-time=startup \ @@ -269,12 +248,12 @@ } # send notification via e-mail - expects at least two string arguments -:set SendEMail do={ :onerror Err { +:set SendEMail do={ :do { :global SendEMail2; $SendEMail2 ({ origin=$0; subject=$1; message=$2; link=$3 }); -} do={ - :global ExitError; $ExitError false $0 $Err; +} on-error={ + :global ExitError; $ExitError false $0; } } # send notification via e-mail - expects one array argument diff --git a/mod/notification-gotify.rsc b/mod/notification-gotify.rsc deleted file mode 100644 index 677d993c..00000000 --- a/mod/notification-gotify.rsc +++ /dev/null @@ -1,139 +0,0 @@ -#!rsc by RouterOS -# RouterOS script: mod/notification-gotify -# Copyright (c) 2013-2026 Christian Hesse -# Leonardo David Monteiro -# https://rsc.eworm.de/COPYING.md -# -# requires RouterOS, version=7.17 -# requires device-mode, fetch, scheduler -# -# send notifications via Gotify (gotify.net) -# https://rsc.eworm.de/doc/mod/notification-gotify.md - -:global FlushGotifyQueue; -:global NotificationFunctions; -:global PurgeGotifyQueue; -:global SendGotify; -:global SendGotify2; - -# flush Gotify queue -:set FlushGotifyQueue do={ :onerror Err { - :global GotifyQueue; - - :global IsFullyConnected; - :global LogPrint; - - :if ([ $IsFullyConnected ] = false) do={ - $LogPrint debug $0 ("System is not fully connected, not flushing."); - :return false; - } - - :local AllDone true; - :local QueueLen [ :len $GotifyQueue ]; - - :if ([ :len [ /system/scheduler/find where name="_FlushGotifyQueue" ] ] > 0 && $QueueLen = 0) do={ - $LogPrint warning $0 ("Flushing Gotify messages from scheduler, but queue is empty."); - } - - :foreach Id,Message in=$GotifyQueue do={ - :if ([ :typeof $Message ] = "array" ) do={ - :onerror Err { - /tool/fetch check-certificate=yes-without-crl output=none http-method=post \ - http-header-field=($Message->"headers") http-data=[ :serialize to=json ($Message->"message") ] \ - ($Message->"url") as-value; - :set ($GotifyQueue->$Id); - } do={ - $LogPrint debug $0 ("Sending queued Gotify message failed: " . $Err); - :set AllDone false; - } - } - } - - :if ($AllDone = true && $QueueLen = [ :len $GotifyQueue ]) do={ - /system/scheduler/remove [ find where name="_FlushGotifyQueue" ]; - :set GotifyQueue; - } -} do={ - :global ExitError; $ExitError false $0 $Err; -} } - -# send notification via Gotify - expects one array argument -:set ($NotificationFunctions->"gotify") do={ - :local Notification $1; - - :global Identity; - :global IdentityExtra; - :global GotifyQueue; - :global GotifyServer; - :global GotifyServerOverride; - :global GotifyToken; - :global GotifyTokenOverride; - - :global EitherOr; - :global FetchUserAgentStr; - :global IfThenElse; - :global LogPrint; - :global SymbolForNotification; - - :local Server [ $EitherOr ($GotifyServerOverride->($Notification->"origin")) $GotifyServer ]; - :local Token [ $EitherOr ($GotifyTokenOverride->($Notification->"origin")) $GotifyToken ]; - - :if ([ :len $Token ] = 0) do={ - :return false; - } - - :local Url ("https://" . $Server . "/message"); - :local Headers ({ [ $FetchUserAgentStr ($Notification->"origin") ]; \ - ("X-Gotify-Key: " . $Token); "Content-Type: application/json" }); - :local Message ({ - "title"=("[" . $IdentityExtra . $Identity . "] " . ($Notification->"subject")); \ - "message"=(($Notification->"message") . "\n" . [ $IfThenElse ([ :len ($Notification->"link") ] > 0) \ - ("\n" . [ $SymbolForNotification "link" ] . ($Notification->"link")) ]); \ - "priority"=[ :tonum [ $IfThenElse ($Notification->"silent") 2 5 ] ] }); - - :onerror Err { - /tool/fetch check-certificate=yes-without-crl output=none http-method=post \ - http-header-field=$Headers http-data=[ :serialize to=json $Message ] $Url as-value; - } do={ - $LogPrint info $0 ("Failed sending Gotify notification: " . $Err . " - Queuing..."); - - :if ([ :typeof $GotifyQueue ] = "nothing") do={ - :set GotifyQueue ({}); - } - :set ($Message->"message") (($Notification->"message") . "\n" . \ - [ $SymbolForNotification "alarm-clock" ] . "This message was queued since " . \ - [ /system/clock/get date ] . " " . [ /system/clock/get time ] . " and may be obsolete."); - :set ($GotifyQueue->[ :len $GotifyQueue ]) \ - { url=$Url; headers=$Headers; message=$Message }; - :if ([ :len [ /system/scheduler/find where name="_FlushGotifyQueue" ] ] = 0) do={ - /system/scheduler/add name="_FlushGotifyQueue" interval=1m start-time=startup \ - on-event=(":global FlushGotifyQueue; \$FlushGotifyQueue;"); - } - } -} - -# purge the Gotify queue -:set PurgeGotifyQueue do={ - :global GotifyQueue; - - /system/scheduler/remove [ find where name="_FlushGotifyQueue" ]; - :set GotifyQueue; -} - -# send notification via Gotify - expects at least two string arguments -:set SendGotify do={ :onerror Err { - :global SendGotify2; - - $SendGotify2 ({ origin=$0; subject=$1; message=$2; link=$3; silent=$4 }); -} do={ - :global ExitError; $ExitError false $0 $Err; -} } - -# send notification via Gotify - expects one array argument -:set SendGotify2 do={ - :local Notification $1; - - :global NotificationFunctions; - - ($NotificationFunctions->"gotify") ("\$NotificationFunctions->\"gotify\"") $Notification; -} diff --git a/mod/notification-matrix.rsc b/mod/notification-matrix.rsc index b78b1132..9b2b641c 100644 --- a/mod/notification-matrix.rsc +++ b/mod/notification-matrix.rsc @@ -1,10 +1,10 @@ #!rsc by RouterOS # RouterOS script: mod/notification-matrix -# Copyright (c) 2013-2026 Michael Gisbers +# Copyright (c) 2013-2025 Michael Gisbers # Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # requires device-mode, fetch, scheduler # # send notifications via Matrix @@ -19,7 +19,7 @@ :global SetupMatrixJoinRoom; # flush Matrix queue -:set FlushMatrixQueue do={ :onerror Err { +:set FlushMatrixQueue do={ :do { :global MatrixQueue; :global IsFullyConnected; @@ -39,7 +39,7 @@ :foreach Id,Message in=$MatrixQueue do={ :if ([ :typeof $Message ] = "array" ) do={ - :onerror Err { + :do { /tool/fetch check-certificate=yes-without-crl output=none \ http-header-field=($Message->"headers") http-method=post \ http-data=[ :serialize to=json { "msgtype"="m.text"; "body"=($Message->"plain"); @@ -47,8 +47,8 @@ ("https://" . $Message->"homeserver" . "/_matrix/client/r0/rooms/" . $Message->"room" . \ "/send/m.room.message?access_token=" . $Message->"accesstoken") as-value; :set ($MatrixQueue->$Id); - } do={ - $LogPrint debug $0 ("Sending queued Matrix message failed: " . $Err); + } on-error={ + $LogPrint debug $0 ("Sending queued Matrix message failed."); :set AllDone false; } } @@ -58,8 +58,8 @@ /system/scheduler/remove [ find where name="_FlushMatrixQueue" ]; :set MatrixQueue; } -} do={ - :global ExitError; $ExitError false $0 $Err; +} on-error={ + :global ExitError; $ExitError false $0; } } # send notification via Matrix - expects one array argument @@ -129,15 +129,15 @@ [ $PrepareText $Label ] . ""); } - :onerror Err { + :do { /tool/fetch check-certificate=yes-without-crl output=none \ http-header-field=$Headers http-method=post \ http-data=[ :serialize to=json { "msgtype"="m.text"; "body"=$Plain; "format"="org.matrix.custom.html"; "formatted_body"=$Formatted } ] \ ("https://" . $HomeServer . "/_matrix/client/r0/rooms/" . $Room . \ "/send/m.room.message?access_token=" . $AccessToken) as-value; - } do={ - $LogPrint info $0 ("Failed sending Matrix notification: " . $Err . " - Queuing..."); + } on-error={ + $LogPrint info $0 ("Failed sending Matrix notification! Queuing..."); :if ([ :typeof $MatrixQueue ] = "nothing") do={ :set MatrixQueue ({}); @@ -167,12 +167,12 @@ } # send notification via Matrix - expects at least two string arguments -:set SendMatrix do={ :onerror Err { +:set SendMatrix do={ :do { :global SendMatrix2; $SendMatrix2 ({ origin=$0; subject=$1; message=$2; link=$3 }); -} do={ - :global ExitError; $ExitError false $0 $Err; +} on-error={ + :global ExitError; $ExitError false $0; } } # send notification via Matrix - expects one array argument @@ -196,14 +196,14 @@ :global MatrixHomeServer; :local Domain [ :pick $User ([ :find $User ":" ] + 1) [ :len $User] ]; - :onerror Err { + :do { :local Data ([ /tool/fetch check-certificate=yes-without-crl output=user \ http-header-field=({ [ $FetchUserAgentStr $0 ] }) \ ("https://" . $Domain . "/.well-known/matrix/client") as-value ]->"data"); :set MatrixHomeServer ([ :deserialize from=json value=$Data ]->"m.homeserver"->"base_url"); $LogPrint debug $0 ("Home server is: " . $MatrixHomeServer); - } do={ - $LogPrint error $0 ("Failed getting home server: " . $Err); + } on-error={ + $LogPrint error $0 ("Failed getting home server!"); :return false; } @@ -211,27 +211,27 @@ :set MatrixHomeServer [ :pick $MatrixHomeServer 8 [ :len $MatrixHomeServer ] ]; } - :onerror Err { + :do { :local Data ([ /tool/fetch check-certificate=yes-without-crl output=user \ http-header-field=({ [ $FetchUserAgentStr $0 ] }) http-method=post \ http-data=[ :serialize to=json { "type"="m.login.password"; "user"=$User; "password"=$Pass } ] \ ("https://" . $MatrixHomeServer . "/_matrix/client/r0/login") as-value ]->"data"); :set MatrixAccessToken ([ :deserialize from=json value=$Data ]->"access_token"); $LogPrint debug $0 ("Access token is: " . $MatrixAccessToken); - } do={ - $LogPrint error $0 ("Failed logging in (and getting access token): " . $Err); + } on-error={ + $LogPrint error $0 ("Failed logging in (and getting access token)!"); :return false; } - :onerror Err { + :do { /system/script/remove [ find where name="global-config-overlay.d/mod/notification-matrix" ]; /system/script/add name="global-config-overlay.d/mod/notification-matrix" source=( \ "# configuration snippet: mod/notification-matrix\n\n" . \ ":global MatrixHomeServer \"" . $MatrixHomeServer . "\";\n" . \ ":global MatrixAccessToken \"" . $MatrixAccessToken . "\";\n"); $LogPrint info $0 ("Added configuration snippet. Now create and join a room, please!"); - } do={ - $LogPrint error $0 ("Failed adding configuration snippet: " . $Err); + } on-error={ + $LogPrint error $0 ("Failed adding configuration snippet!"); :return false; } } @@ -248,24 +248,24 @@ :global MatrixHomeServer; :global MatrixRoom; - :onerror Err { + :do { /tool/fetch check-certificate=yes-without-crl output=none \ http-header-field=({ [ $FetchUserAgentStr $0 ] }) http-method=post http-data="" \ ("https://" . $MatrixHomeServer . "/_matrix/client/r0/rooms/" . [ $UrlEncode $MatrixRoom ] . \ "/join?access_token=" . [ $UrlEncode $MatrixAccessToken ]) as-value; $LogPrint debug $0 ("Joined the room."); - } do={ - $LogPrint error $0 ("Failed joining the room: " . $Err); + } on-error={ + $LogPrint error $0 ("Failed joining the room!"); :return false; } - :onerror Err { + :do { :local Snippet [ /system/script/find where name="global-config-overlay.d/mod/notification-matrix" ]; /system/script/set $Snippet source=([ get $Snippet source ] . \ ":global MatrixRoom \"" . $MatrixRoom . "\";\n"); $LogPrint info $0 ("Appended configuration to configuration snippet. Please review!"); - } do={ - $LogPrint error $0 ("Failed appending configuration to snippet: " . $Err); + } on-error={ + $LogPrint error $0 ("Failed appending configuration to snippet!"); :return false; } } diff --git a/mod/notification-ntfy.rsc b/mod/notification-ntfy.rsc index ac1792d4..212fde2e 100644 --- a/mod/notification-ntfy.rsc +++ b/mod/notification-ntfy.rsc @@ -1,9 +1,9 @@ #!rsc by RouterOS # RouterOS script: mod/notification-ntfy -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # requires device-mode, fetch, scheduler # # send notifications via Ntfy (ntfy.sh) @@ -16,8 +16,9 @@ :global SendNtfy2; # flush ntfy queue -:set FlushNtfyQueue do={ :onerror Err { +:set FlushNtfyQueue do={ :do { :global NtfyQueue; + :global NtfyMessageIDs; :global IsFullyConnected; :global LogPrint; @@ -36,13 +37,13 @@ :foreach Id,Message in=$NtfyQueue do={ :if ([ :typeof $Message ] = "array" ) do={ - :onerror Err { + :do { /tool/fetch check-certificate=yes-without-crl output=none http-method=post \ http-header-field=($Message->"headers") http-data=($Message->"text") \ ($Message->"url") as-value; :set ($NtfyQueue->$Id); - } do={ - $LogPrint debug $0 ("Sending queued Ntfy message failed: " . $Err); + } on-error={ + $LogPrint debug $0 ("Sending queued Ntfy message failed."); :set AllDone false; } } @@ -52,8 +53,8 @@ /system/scheduler/remove [ find where name="_FlushNtfyQueue" ]; :set NtfyQueue; } -} do={ - :global ExitError; $ExitError false $0 $Err; +} on-error={ + :global ExitError; $ExitError false $0; } } # send notification via ntfy - expects one array argument @@ -107,17 +108,17 @@ :set Text ($Text . "\n" . [ $SymbolForNotification "link" ] . ($Notification->"link")); } - :onerror Err { + :do { :if ($Server = "ntfy.sh") do={ - :if ([ $CertificateAvailable "ISRG Root X1" "fetch" ] = false) do={ + :if ([ $CertificateAvailable "ISRG Root X1" ] = false) do={ $LogPrint warning $0 ("Downloading required certificate failed."); :error false; } } /tool/fetch check-certificate=yes-without-crl output=none http-method=post \ http-header-field=$Headers http-data=$Text $Url as-value; - } do={ - $LogPrint info $0 ("Failed sending ntfy notification: " . $Err . " - Queuing..."); + } on-error={ + $LogPrint info $0 ("Failed sending ntfy notification! Queuing..."); :if ([ :typeof $NtfyQueue ] = "nothing") do={ :set NtfyQueue ({}); @@ -143,12 +144,12 @@ } # send notification via ntfy - expects at least two string arguments -:set SendNtfy do={ :onerror Err { +:set SendNtfy do={ :do { :global SendNtfy2; $SendNtfy2 ({ origin=$0; subject=$1; message=$2; link=$3; silent=$4 }); -} do={ - :global ExitError; $ExitError false $0 $Err; +} on-error={ + :global ExitError; $ExitError false $0; } } # send notification via ntfy - expects one array argument diff --git a/mod/notification-telegram.rsc b/mod/notification-telegram.rsc index 9e9ae57e..c3ef2dd3 100644 --- a/mod/notification-telegram.rsc +++ b/mod/notification-telegram.rsc @@ -1,40 +1,34 @@ #!rsc by RouterOS # RouterOS script: mod/notification-telegram -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # requires device-mode, fetch, scheduler # # send notifications via Telegram # https://rsc.eworm.de/doc/mod/notification-telegram.md :global FlushTelegramQueue; -:global GetTelegramChatId; :global NotificationFunctions; :global PurgeTelegramQueue; :global SendTelegram; :global SendTelegram2; # flush telegram queue -:set FlushTelegramQueue do={ :onerror Err { +:set FlushTelegramQueue do={ :do { :global TelegramQueue; :global TelegramMessageIDs; - :global CertificateAvailable; :global IsFullyConnected; :global LogPrint; + :global UrlEncode; :if ([ $IsFullyConnected ] = false) do={ $LogPrint debug $0 ("System is not fully connected, not flushing."); :return false; } - :if ([ $CertificateAvailable "Go Daddy Root Certificate Authority - G2" "fetch" ] = false) do={ - $LogPrint warning $0 ("Downloading required certificate failed."); - :return false; - } - :local AllDone true; :local QueueLen [ :len $TelegramQueue ]; @@ -44,14 +38,16 @@ :foreach Id,Message in=$TelegramQueue do={ :if ([ :typeof $Message ] = "array" ) do={ - :onerror Err { + :do { :local Data ([ /tool/fetch check-certificate=yes-without-crl output=user http-method=post \ ("https://api.telegram.org/bot" . ($Message->"tokenid") . "/sendMessage") \ - http-data=($Message->"http-data") as-value ]->"data"); + http-data=("chat_id=" . ($Message->"chatid") . "&disable_notification=" . ($Message->"silent") . \ + "&reply_to_message_id=" . ($Message->"replyto") . "&disable_web_page_preview=true" . \ + "&parse_mode=MarkdownV2&text=" . [ $UrlEncode ($Message->"text") ]) as-value ]->"data"); :set ($TelegramQueue->$Id); :set ($TelegramMessageIDs->[ :tostr ([ :deserialize from=json value=$Data ]->"result"->"message_id") ]) 1; - } do={ - $LogPrint debug $0 ("Sending queued Telegram message failed: " . $Err); + } on-error={ + $LogPrint debug $0 ("Sending queued Telegram message failed."); :set AllDone false; } } @@ -61,49 +57,10 @@ /system/scheduler/remove [ find where name="_FlushTelegramQueue" ]; :set TelegramQueue; } -} do={ - :global ExitError; $ExitError false $0 $Err; +} on-error={ + :global ExitError; $ExitError false $0; } } -# get the chat id -:set GetTelegramChatId do={ :onerror Err { - :global TelegramTokenId; - - :global CertificateAvailable; - :global LogPrint; - - :if ([ $CertificateAvailable "Go Daddy Root Certificate Authority - G2" "fetch" ] = false) do={ - $LogPrint warning $0 ("Downloading required certificate failed."); - :return false; - } - - :local Data; - :onerror Err { - :set Data ([ /tool/fetch check-certificate=yes-without-crl output=user \ - ("https://api.telegram.org/bot" . $TelegramTokenId . "/getUpdates?offset=0" . \ - "&allowed_updates=%5B%22message%22%5D") as-value ]->"data"); - } do={ - $LogPrint warning $0 ("Fetching data failed: " . $Err); - :return false; - } - - :local JSON [ :deserialize from=json value=$Data ]; - :local Count [ :len ($JSON->"result") ]; - - :if ($Count = 0) do={ - $LogPrint info $0 ("No message received."); - :return false; - } - - :local Message ($JSON->"result"->($Count - 1)->"message"); - $LogPrint info $0 ("The chat id is: " . ($Message->"chat"->"id")); - :if (($Message->"is_topic_message") = true) do={ - $LogPrint info $0 ("The thread id is: " . ($Message->"message_thread_id")); - } -} do={ - :global ExitError; $ExitError false $0 $Err; -} } - # send notification via telegram - expects one array argument :set ($NotificationFunctions->"telegram") do={ :local Notification $1; @@ -114,8 +71,6 @@ :global TelegramChatIdOverride; :global TelegramMessageIDs; :global TelegramQueue; - :global TelegramThreadId; - :global TelegramThreadIdOverride; :global TelegramTokenId; :global TelegramTokenIdOverride; @@ -156,9 +111,6 @@ :local ChatId [ $EitherOr ($Notification->"chatid") \ [ $EitherOr ($TelegramChatIdOverride->($Notification->"origin")) $TelegramChatId ] ]; - :local ThreadId [ $EitherOr ($Notification->"threadid") \ - [ $EitherOr ($TelegramThreadIdOverride->($Notification->"origin")) \ - [ $IfThenElse ([ :len ($TelegramChatIdOverride->($Notification->"origin")) ] = 0) $TelegramThreadId ] ] ]; :local TokenId [ $EitherOr ($TelegramTokenIdOverride->($Notification->"origin")) $TelegramTokenId ]; :if ([ :len $TokenId ] = 0 || [ :len $ChatId ] = 0) do={ @@ -193,20 +145,19 @@ (($LenSum - [ :len $Text ]) * 100 / $LenSum) . "%_!") "plain" "_" ]); } - :local HTTPData ("chat_id=" . $ChatId . "&disable_notification=" . ($Notification->"silent") . \ - "&reply_to_message_id=" . ($Notification->"replyto") . "&message_thread_id=" . $ThreadId . \ - "&disable_web_page_preview=true&parse_mode=MarkdownV2"); - :onerror Err { - :if ([ $CertificateAvailable "Go Daddy Root Certificate Authority - G2" "fetch" ] = false) do={ + :do { + :if ([ $CertificateAvailable "Go Daddy Root Certificate Authority - G2" ] = false) do={ $LogPrint warning $0 ("Downloading required certificate failed."); :error false; } :local Data ([ /tool/fetch check-certificate=yes-without-crl output=user http-method=post \ ("https://api.telegram.org/bot" . $TokenId . "/sendMessage") \ - http-data=($HTTPData . "&text=" . [ $UrlEncode $Text ]) as-value ]->"data"); + http-data=("chat_id=" . $ChatId . "&disable_notification=" . ($Notification->"silent") . \ + "&reply_to_message_id=" . ($Notification->"replyto") . "&disable_web_page_preview=true" . \ + "&parse_mode=MarkdownV2&text=" . [ $UrlEncode $Text ]) as-value ]->"data"); :set ($TelegramMessageIDs->[ :tostr ([ :deserialize from=json value=$Data ]->"result"->"message_id") ]) 1; - } do={ - $LogPrint info $0 ("Failed sending Telegram notification: " . $Err . " - Queuing..."); + } on-error={ + $LogPrint info $0 ("Failed sending Telegram notification! Queuing..."); :if ([ :typeof $TelegramQueue ] = "nothing") do={ :set TelegramQueue ({}); @@ -214,8 +165,8 @@ :set Text ($Text . "\n" . [ $SymbolForNotification "alarm-clock" ] . \ [ $EscapeMD ("This message was queued since _" . [ /system/clock/get date ] . \ " " . [ /system/clock/get time ] . "_ and may be obsolete.") "plain" "_" ]); - :set ($TelegramQueue->[ :len $TelegramQueue ]) { tokenid=$TokenId; - http-data=($HTTPData . "&text=" . [ $UrlEncode $Text ]) }; + :set ($TelegramQueue->[ :len $TelegramQueue ]) { chatid=$ChatId; tokenid=$TokenId; + text=$Text; silent=($Notification->"silent"); replyto=($Notification->"replyto") }; :if ([ :len [ /system/scheduler/find where name="_FlushTelegramQueue" ] ] = 0) do={ /system/scheduler/add name="_FlushTelegramQueue" interval=1m start-time=startup \ on-event=(":global FlushTelegramQueue; \$FlushTelegramQueue;"); @@ -232,12 +183,12 @@ } # send notification via telegram - expects at least two string arguments -:set SendTelegram do={ :onerror Err { +:set SendTelegram do={ :do { :global SendTelegram2; $SendTelegram2 ({ origin=$0; subject=$1; message=$2; link=$3; silent=$4 }); -} do={ - :global ExitError; $ExitError false $0 $Err; +} on-error={ + :global ExitError; $ExitError false $0; } } # send notification via telegram - expects one array argument diff --git a/mod/scriptrunonce.rsc b/mod/scriptrunonce.rsc index 598c7602..e5368c45 100644 --- a/mod/scriptrunonce.rsc +++ b/mod/scriptrunonce.rsc @@ -1,9 +1,10 @@ #!rsc by RouterOS # RouterOS script: mod/scriptrunonece -# Copyright (c) 2020-2026 Christian Hesse +# Copyright (c) 2020-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 +# requires device-mode, fetch # # download script and run it once # https://rsc.eworm.de/doc/mod/scriptrunonce.md @@ -11,13 +12,12 @@ :global ScriptRunOnce; # fetch and run script(s) once -:set ScriptRunOnce do={ :onerror Err { +:set ScriptRunOnce do={ :do { :local Scripts [ :toarray $1 ]; :global ScriptRunOnceBaseUrl; :global ScriptRunOnceUrlSuffix; - :global FetchHuge; :global LogPrint; :global ValidateSyntax; @@ -30,27 +30,26 @@ :set Script ($ScriptRunOnceBaseUrl . $Script . ".rsc" . $ScriptRunOnceUrlSuffix); } - :local Source [ $FetchHuge $0 $Script true ]; - :if ($Source = false) do={ + :local Source; + :do { + :set Source ([ /tool/fetch check-certificate=yes-without-crl $Script output=user as-value ]->"data"); + } on-error={ $LogPrint warning $0 ("Failed fetching script '" . $Script . "'!"); - :return false; } - :if ([ $ValidateSyntax $Source ] = false) do={ - $LogPrint warning $0 ("The script '" . $Script . "' failed syntax validation!"); - :return false; + :if ([ :len $Source ] > 0) do={ + :if ([ $ValidateSyntax $Source ] = true) do={ + :do { + $LogPrint info $0 ("Running script '" . $Script . "' now."); + [ :parse $Source ]; + } on-error={ + $LogPrint warning $0 ("The script '" . $Script . "' failed to run!"); + } + } else={ + $LogPrint warning $0 ("The script '" . $Script . "' failed syntax validation!"); + } } - - :onerror Err { - $LogPrint info $0 ("Running script '" . $Script . "' now."); - [ :parse $Source ]; - } do={ - $LogPrint warning $0 ("The script '" . $Script . "' failed to run: " . $Err); - :return false; - } - - :return true; } -} do={ - :global ExitError; $ExitError false $0 $Err; +} on-error={ + :global ExitError; $ExitError false $0; } } diff --git a/mod/ssh-keys-import.rsc b/mod/ssh-keys-import.rsc index 16a02859..35aa7ec9 100644 --- a/mod/ssh-keys-import.rsc +++ b/mod/ssh-keys-import.rsc @@ -1,9 +1,9 @@ #!rsc by RouterOS # RouterOS script: mod/ssh-keys-import -# Copyright (c) 2020-2026 Christian Hesse +# Copyright (c) 2020-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.16 # # import ssh keys for public key authentication # https://rsc.eworm.de/doc/mod/ssh-keys-import.md @@ -12,14 +12,13 @@ :global SSHKeysImportFile; # import single key passed as string -:set SSHKeysImport do={ :onerror Err { +:set SSHKeysImport do={ :do { :local Key [ :tostr $1 ]; :local User [ :tostr $2 ]; :global GetRandom20CharAlNum; :global LogPrint; :global MkDir; - :global RmDir; :global WaitForFile; :if ([ :len $Key ] = 0 || [ :len $User ] = 0) do={ @@ -40,9 +39,7 @@ :local FingerPrintMD5 [ :convert from=base64 transform=md5 to=hex ($KeyVal->1) ]; - :local RegEx ("\\bmd5=" . $FingerPrintMD5 . "\\b"); - :if ([ :len [ /user/ssh-keys/find where user=$User \ - (key-owner~$RegEx or info~$RegEx) ] ] > 0) do={ + :if ([ :len [ /user/ssh-keys/find where user=$User key-owner~("\\bmd5=" . $FingerPrintMD5 . "\\b") ] ] > 0) do={ $LogPrint warning $0 ("The ssh public key (MD5:" . $FingerPrintMD5 . \ ") is already available for user '" . $User . "'."); :return false; @@ -57,27 +54,26 @@ /file/add name=$FileName contents=($Key . ", md5=" . $FingerPrintMD5); $WaitForFile $FileName; - :onerror Err { + :do { /user/ssh-keys/import public-key-file=$FileName user=$User; $LogPrint info $0 ("Imported ssh public key (" . $KeyVal->2 . ", " . $KeyVal->0 . ", " . \ "MD5:" . $FingerPrintMD5 . ") for user '" . $User . "'."); - $RmDir "tmpfs/ssh-keys-import"; - } do={ - $LogPrint warning $0 ("Failed importing key: " . $Err); - $RmDir "tmpfs/ssh-keys-import"; + /file/remove "tmpfs/ssh-keys-import"; + } on-error={ + $LogPrint warning $0 ("Failed importing key."); + /file/remove "tmpfs/ssh-keys-import"; :return false; } -} do={ - :global ExitError; $ExitError false $0 $Err; +} on-error={ + :global ExitError; $ExitError false $0; } } # import keys from a file -:set SSHKeysImportFile do={ :onerror Err { +:set SSHKeysImportFile do={ :do { :local FileName [ :tostr $1 ]; :local User [ :tostr $2 ]; :global EitherOr; - :global FileExists; :global LogPrint; :global ParseKeyValueStore; :global SSHKeysImport; @@ -87,7 +83,8 @@ :return false; } - :if ([ $FileExists $FileName ] = false) do={ + :local File [ /file/find where name=$FileName ]; + :if ([ :len $File ] = 0) do={ $LogPrint warning $0 ("File '" . $FileName . "' does not exist."); :return false; } @@ -96,7 +93,9 @@ :foreach KeyVal in=[ :deserialize $Keys delimiter=" " from=dsv options=dsv.plain ] do={ :local Continue false; :if ($KeyVal->0 = "ssh-ed25519" || $KeyVal->0 = "ssh-rsa") do={ - :if ([ $SSHKeysImport ($KeyVal->0 . " " . $KeyVal->1 . " " . $KeyVal->2) $User ] = false) do={ + :do { + $SSHKeysImport ($KeyVal->0 . " " . $KeyVal->1 . " " . $KeyVal->2) $User; + } on-error={ $LogPrint warning $0 ("Failed importing key for user '" . $User . "'."); } :set Continue true; @@ -109,6 +108,6 @@ $LogPrint warning $0 ("SSH key of type '" . $KeyVal->0 . "' is not supported."); } } -} do={ - :global ExitError; $ExitError false $0 $Err; +} on-error={ + :global ExitError; $ExitError false $0; } } diff --git a/mode-button.rsc b/mode-button.rsc index 81bdc05a..4cf5e754 100644 --- a/mode-button.rsc +++ b/mode-button.rsc @@ -1,19 +1,19 @@ #!rsc by RouterOS # RouterOS script: mode-button -# Copyright (c) 2018-2026 Christian Hesse +# Copyright (c) 2018-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # requires device-mode, scheduler # # act on multiple mode and reset button presses # https://rsc.eworm.de/doc/mode-button.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global ModeButton; @@ -26,7 +26,7 @@ :if ([ :len $Scheduler ] = 0) do={ $LogPrint info $ScriptName ("Creating scheduler _ModeButtonScheduler, counting presses..."); - :global ModeButtonScheduler do={ :onerror Err { + :global ModeButtonScheduler do={ :do { :local FuncName $0; :global ModeButton; @@ -69,11 +69,11 @@ :delay 200ms; } - :onerror Err { + :do { [ :parse $Code ]; - } do={ + } on-error={ $LogPrint warning $FuncName \ - ("The code for " . $Count . " mode-button presses failed with runtime error: " . $Err); + ("The code for " . $Count . " mode-button presses failed with runtime error!"); } } else={ $LogPrint warning $FuncName \ @@ -82,8 +82,8 @@ } else={ $LogPrint info $FuncName ("No action defined for " . $Count . " mode-button presses."); } - } do={ - :global ExitError; $ExitError false $0 $Err; + } on-error={ + :global ExitError; $ExitError false $0; } } /system/scheduler/add name="_ModeButtonScheduler" \ on-event=":global ModeButtonScheduler; \$ModeButtonScheduler;" interval=3s; @@ -91,6 +91,6 @@ $LogPrint debug $ScriptName ("Updating scheduler _ModeButtonScheduler..."); /system/scheduler/set $Scheduler start-time=[ /system/clock/get time ]; } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/netwatch-dns.rsc b/netwatch-dns.rsc index 4172d28e..467d6362 100644 --- a/netwatch-dns.rsc +++ b/netwatch-dns.rsc @@ -1,24 +1,25 @@ #!rsc by RouterOS # RouterOS script: netwatch-dns -# Copyright (c) 2022-2026 Christian Hesse +# Copyright (c) 2022-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.16 # requires device-mode, fetch # # monitor and manage dns/doh with netwatch # https://rsc.eworm.de/doc/netwatch-dns.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global CertificateAvailable; :global EitherOr; :global IsDNSResolving; + :global IsTimeSync; :global LogPrint; :global LogPrintOnce; :global ParseKeyValueStore; @@ -72,6 +73,13 @@ :local DohCurrent [ /ip/dns/get use-doh-server ]; :local DohServers ({}); + + :if ([ :len $DohCurrent ] > 0 && [ $IsDNSResolving ] = false && [ $IsTimeSync ] = false) do={ + $LogPrint info $ScriptName ("Time is not sync, disabling DoH: " . $DohCurrent); + /ip/dns/set use-doh-server=""; + :set DohCurrent ""; + } + :foreach Host in=[ /tool/netwatch/find where comment~"\\bdoh\\b" status="up" ] do={ :local HostVal [ /tool/netwatch/get $Host ]; :local HostInfo [ $ParseKeyValueStore ($HostVal->"comment") ]; @@ -86,8 +94,8 @@ :set ($HostInfo->"doh-url") ("https://" . [ $EitherOr $HostName ($HostVal->"host") ] . "/dns-query"); } - :if ($DohCurrent = $HostInfo->"doh-url" && [ $IsDNSResolving ] = true) do={ - $LogPrint debug $ScriptName ("Current DoH server is still up and resolving: " . $DohCurrent); + :if ($DohCurrent = $HostInfo->"doh-url") do={ + $LogPrint debug $ScriptName ("Current DoH server is still up: " . $DohCurrent); :set ExitOK true; :error true; } @@ -97,30 +105,28 @@ } :if ([ :len $DohCurrent ] > 0) do={ - $LogPrint info $ScriptName ("Current DoH server is down or not resolving, disabling: " . $DohCurrent); + $LogPrint info $ScriptName ("Current DoH server is down, disabling: " . $DohCurrent); /ip/dns/set use-doh-server=""; /ip/dns/cache/flush; } :foreach DohServer in=$DohServers do={ :if ([ :len ($DohServer->"doh-cert") ] > 0) do={ - :if ([ $CertificateAvailable ($DohServer->"doh-cert") "dns" ] = false) do={ + :if ([ $CertificateAvailable ($DohServer->"doh-cert") ] = false) do={ $LogPrint warning $ScriptName ("Downloading certificate failed, trying without."); } } :local Data false; - :onerror Err { - :retry { - :set Data ([ /tool/fetch check-certificate=yes-without-crl output=user \ - http-header-field=({ "accept: application/dns-message" }) \ - url=(($DohServer->"doh-url") . "?dns=" . [ :convert to=base64 ([ :rndstr length=2 ] . \ - "\01\00" . "\00\01" . "\00\00" . "\00\00" . "\00\00" . "\09doh-check\05eworm\02de\00" . \ - "\00\10" . "\00\01") ]) as-value ]->"data"); - } delay=1s max=3; - } do={ - $LogPrint warning $ScriptName ("Request to DoH server " . ($DohServer->"doh-url") . \ - " failed: " . $Err); + :do { + :set Data ([ /tool/fetch check-certificate=yes-without-crl output=user \ + http-header-field=({ "accept: application/dns-message" }) \ + url=(($DohServer->"doh-url") . "?dns=" . [ :convert to=base64 ([ :rndstr length=2 ] . \ + "\01\00" . "\00\01" . "\00\00" . "\00\00" . "\00\00" . "\09doh-check\05eworm\02de\00" . \ + "\00\10" . "\00\01") ]) as-value ]->"data"); + } on-error={ + $LogPrint warning $ScriptName ("Request to DoH server failed (network or certificate issue): " . \ + ($DohServer->"doh-url")); } :if ($Data != false) do={ @@ -139,6 +145,6 @@ } } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/netwatch-notify.rsc b/netwatch-notify.rsc index 46a10ee0..8b05c5e3 100644 --- a/netwatch-notify.rsc +++ b/netwatch-notify.rsc @@ -1,18 +1,18 @@ #!rsc by RouterOS # RouterOS script: netwatch-notify -# Copyright (c) 2020-2026 Christian Hesse +# Copyright (c) 2020-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.15 # # monitor netwatch and send notifications # https://rsc.eworm.de/doc/netwatch-notify.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global NetwatchNotify; @@ -38,10 +38,10 @@ :global ValidateSyntax; :if ([ $ValidateSyntax $Hook ] = true) do={ - onerror Err { + :do { [ :parse $Hook ]; - } do={ - $LogPrint warning $ScriptName ("The " . $State . "-hook for " . $Type . " '" . $Name . "' failed to run: " . $Err); + } on-error={ + $LogPrint warning $ScriptName ("The " . $State . "-hook for " . $Type . " '" . $Name . "' failed to run."); :return ("The hook failed to run."); } } else={ @@ -61,19 +61,15 @@ :global GetRandom20CharAlNum; :local FwAddrList ($ScriptName . "-" . [ $GetRandom20CharAlNum ]); - :if ([ :typeof [ :toip $Expected ] ] = "ip") do={ - /ip/firewall/address-list/add address=$Name list=$FwAddrList dynamic=yes timeout=30s; - :delay 20ms; - :if ([ :len [ /ip/firewall/address-list/find where list=$FwAddrList address=$Expected ] ] > 0) do={ - :return true; - } + /ip/firewall/address-list/add address=$Name list=$FwAddrList dynamic=yes timeout=1s; + :delay 20ms; + :if ([ :len [ /ip/firewall/address-list/find where list=$FwAddrList address=$Expected ] ] > 0) do={ + :return true; } - :if ([ :typeof [ :toip6 $Expected ] ] = "ip6") do={ - /ipv6/firewall/address-list/add address=$Name list=$FwAddrList dynamic=yes timeout=30s; - :delay 20ms; - :if ([ :len [ /ipv6/firewall/address-list/find where list=$FwAddrList address=$Expected ] ] > 0) do={ - :return true; - } + /ipv6/firewall/address-list/add address=$Name list=$FwAddrList dynamic=yes timeout=1s; + :delay 20ms; + :if ([ :len [ /ipv6/firewall/address-list/find where list=$FwAddrList address=$Expected ] ] > 0) do={ + :return true; } :return false; @@ -107,7 +103,7 @@ :if ([ :typeof ($HostInfo->"resolve") ] = "str") do={ :if ([ $IsDNSResolving ] = true) do={ - :onerror Err { + :do { :local Resolve [ :resolve type=[ $IfThenElse ([ :typeof ($HostVal->"host") ] = "ip") \ "ipv4" "ipv6" ] ($HostInfo->"resolve") ]; :if ($Resolve != $HostVal->"host") do={ @@ -121,13 +117,13 @@ :set ($HostVal->"status") "unknown"; } } - } do={ + } on-error={ :set ($Metric->"resolve-failcnt") ($Metric->"resolve-failcnt" + 1); :if ($Metric->"resolve-failcnt" = 3) do={ $LogPrint [ $IfThenElse ($HostInfo->"no-resolve-fail" != true) warning debug ] \ $ScriptName ("Resolving name '" . $HostInfo->"resolve" . [ $IfThenElse \ ($HostInfo->"resolve" != $HostInfo->"name") ("' for " . $Type . " '" . \ - $HostInfo->"name") "" ] . "' failed third time: " . $Err); + $HostInfo->"name") "" ] . "' failed."); } } } @@ -224,6 +220,6 @@ "since"=($Metric->"since") }; } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/news-and-changes.rsc b/news-and-changes.rsc index 53f3e7b6..c7e566ff 100644 --- a/news-and-changes.rsc +++ b/news-and-changes.rsc @@ -1,5 +1,5 @@ # News, changes and migration by RouterOS Scripts -# Copyright (c) 2019-2026 Christian Hesse +# Copyright (c) 2019-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md :global IDonate; @@ -57,12 +57,6 @@ 130="Dropped intermediate certificates, depending on just root certificates now."; 131="Enhanced certificate download to fallback to mkcert.org, so all (commonly trusted) root certificates are available now."; 132="Split off plugins from 'check-health', so the script works on all devices to monitor CPU and RAM. The supported plugins for sensors in hardware are installed automatically."; - 133="Updated the default configuration for 'fw-addr-lists', deprecated lists were removed, a collective list was added."; - 134="Enhanced 'mod/notification-telegram' and 'telegram-chat' to support topics in groups."; - 135="Introduced helper function '\$GetTelegramChatId' for 'mod/notification-telegram' which helps retrieve information."; - 136="Introduced script 'check-perpetual-license' to check for license state on CHR."; - 137="Added support to send notifications via Gotify (gotify.net)."; - 138="RouterOS 7.19 is suffering an issue with certificate store. Fixing trust state for all certificates..."; }; # Migration steps to be applied on script updates @@ -72,5 +66,4 @@ 104=":global CharacterReplace; :global ScriptInstallUpdate; :foreach Script in={ \"capsman-download-packages\"; \"capsman-rolling-upgrade\"; \"hotspot-to-wpa\"; \"hotspot-to-wpa-cleanup\" } do={ /system/script/set name=(\$Script . \".capsman\") [ find where name=\$Script ]; :foreach Scheduler in=[ /system/scheduler/find where on-event~(\$Script . \"([^-.]|\\\$)\") ] do={ /system/scheduler/set \$Scheduler on-event=[ \$CharacterReplace [ get \$Scheduler on-event ] \$Script (\$Script . \".capsman\") ]; }; }; /ip/hotspot/user/profile/set on-login=\"hotspot-to-wpa.capsman\" [ find where on-login=\"hotspot-to-wpa\" ]; \$ScriptInstallUpdate;"; 111=":local Rec [ /ip/dns/static/find where comment~\"^managed by dhcp-to-dns for \" ]; :if ([ :len \$Rec ] > 0) do={ /ip/dns/static/remove \$Rec; /system/script/run dhcp-to-dns; }"; 132=":if ([ :len [ /system/script/find where name=\"check-health\" ] ] > 0) do={ :local Code \":local Install \\\"check-health\\\"; :if ([ :len [ /system/health/find where type=\\\"\\\" name~\\\"-state\\\\\\\$\\\" ] ] > 0) do={ :set Install (\\\$Install . \\\",check-health.d/state\\\"); }; :if ([ :len [ /system/health/find where type=\\\"C\\\" ] ] > 0) do={ :set Install (\\\$Install . \\\",check-health.d/temperature\\\"); }; :if ([ :len [ /system/health/find where type=\\\"V\\\" ] ] > 0) do={ :set Install (\\\$Install . \\\",check-health.d/voltage\\\"); }; :global ScriptInstallUpdate; \\\$ScriptInstallUpdate \\\$Install;\"; :global ValidateSyntax; :if ([ \$ValidateSyntax \$Code ] = true) do={ :do { [ :parse \$Code ]; } on-error={ }; }; }"; - 138="/certificate/set trusted=yes [ find where trusted=yes ];"; }; diff --git a/ospf-to-leds.rsc b/ospf-to-leds.rsc index 73a70c8b..9d822c15 100644 --- a/ospf-to-leds.rsc +++ b/ospf-to-leds.rsc @@ -1,18 +1,18 @@ #!rsc by RouterOS # RouterOS script: ospf-to-leds -# Copyright (c) 2020-2026 Christian Hesse +# Copyright (c) 2020-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # visualize ospf instance state via leds # https://rsc.eworm.de/doc/ospf-to-leds.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global LogPrint; @@ -44,6 +44,6 @@ /system/leds/set type=off [ find where leds=$LED ]; } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/packages-update.rsc b/packages-update.rsc index 960e07ca..ff47b2a3 100644 --- a/packages-update.rsc +++ b/packages-update.rsc @@ -1,24 +1,20 @@ #!rsc by RouterOS # RouterOS script: packages-update -# Copyright (c) 2019-2026 Christian Hesse +# Copyright (c) 2019-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # requires device-mode, scheduler # # download packages and reboot for installation # https://rsc.eworm.de/doc/packages-update.md -:local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; - :local ScriptName [ :jobname ]; +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } - :global BackupRandomDelay; - :global PackagesUpdateDeferReboot; - :global PackagesUpdateBackupFailure; +:local ExitOK false; +:do { + :local ScriptName [ :jobname ]; :global DownloadPackage; :global Grep; @@ -28,33 +24,25 @@ :global ScriptLock; :global VersionToNum; + :global PackagesUpdateDeferReboot; + :global PackagesUpdateBackupFailure; + :local Schedule do={ :local ScriptName [ :tostr $1 ]; - :global PackagesUpdateDeferReboot; - :global GetRandomNumber; - :global IfThenElse; :global LogPrint; :global RebootForUpdate do={ /system/reboot; } - :if ([ :len [ /system/scheduler/find where name="_RebootForUpdate" ] ] > 0) do={ - $LogPrint warning $ScriptName ("Scheduler for reboot already exists."); - :return false; - } - - :local Interval [ $IfThenElse ([ :totime $PackagesUpdateDeferReboot ] >= 1d) \ - $PackagesUpdateDeferReboot 1d ]; :local StartTime [ :tostr [ :totime (10800 + [ $GetRandomNumber 7200 ]) ] ]; - /system/scheduler/add name="_RebootForUpdate" start-time=$StartTime interval=$Interval \ + /system/scheduler/add name="_RebootForUpdate" start-time=$StartTime interval=1d \ on-event=("/system/scheduler/remove \"_RebootForUpdate\"; " . \ ":global RebootForUpdate; \$RebootForUpdate;"); $LogPrint info $ScriptName ("Scheduled reboot for update at " . $StartTime . \ - " local time (" . [ /system/clock/get time-zone-name ] . ")" . \ - [ $IfThenElse ($Interval > 1d) (" deferred by " . $Interval) ] . "."); + " local time (" . [ /system/clock/get time-zone-name ] . ")."); :return true; } @@ -91,9 +79,7 @@ :set ($RunOrder->($Store->"order" . "-" . $ScriptVal->"name")) ($ScriptVal->"name"); } - :local BackupRandomDelayBefore $BackupRandomDelay; :foreach Order,Script in=$RunOrder do={ - :set BackupRandomDelay 0; :set PackagesUpdateBackupFailure false; :do { $LogPrint info $ScriptName ("Running backup script " . $Script . " before update."); @@ -101,7 +87,6 @@ } on-error={ :set PackagesUpdateBackupFailure true; } - :set BackupRandomDelay $BackupRandomDelayBefore; :if ($PackagesUpdateBackupFailure = true) do={ $LogPrint warning $ScriptName ("Running backup script " . $Script . " before update failed!"); @@ -141,7 +126,7 @@ } } - :foreach Package in=[ /system/package/find where !bundle !available ] do={ + :foreach Package in=[ /system/package/find where !bundle ] do={ :local PkgName [ /system/package/get $Package name ]; :if ([ $DownloadPackage $PkgName ($Update->"latest-version") ] = false) do={ $LogPrint error $ScriptName ("Download for package " . $PkgName . " failed, update aborted."); @@ -164,7 +149,7 @@ :error true; } } else={ - :if ($PackagesUpdateDeferReboot = true || [ :totime $PackagesUpdateDeferReboot ] >= 1d) do={ + :if ($PackagesUpdateDeferReboot = true) do={ $Schedule $ScriptName; :set ExitOK true; :error true; @@ -174,6 +159,6 @@ $LogPrint info $ScriptName ("Rebooting for update."); :delay 1s; /system/reboot; -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/ppp-on-up.rsc b/ppp-on-up.rsc index 231d3d2d..85e96896 100644 --- a/ppp-on-up.rsc +++ b/ppp-on-up.rsc @@ -1,18 +1,18 @@ #!rsc by RouterOS # RouterOS script: ppp-on-up -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # run scripts on ppp up # https://rsc.eworm.de/doc/ppp-on-up.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global LogPrint; @@ -39,6 +39,6 @@ $LogPrint warning $ScriptName ("Running script '" . $ScriptName . "' failed!"); } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/sms-action.rsc b/sms-action.rsc index 9750e967..34d21272 100644 --- a/sms-action.rsc +++ b/sms-action.rsc @@ -1,18 +1,18 @@ #!rsc by RouterOS # RouterOS script: sms-action -# Copyright (c) 2018-2026 Christian Hesse +# Copyright (c) 2018-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # run action on received SMS # https://rsc.eworm.de/doc/sms-action.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global SmsAction; @@ -36,6 +36,6 @@ } else={ $LogPrint warning $ScriptName ("The code for action '" . $Action . "' failed syntax validation!"); } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/sms-forward.rsc b/sms-forward.rsc index d4570ea1..654fd564 100644 --- a/sms-forward.rsc +++ b/sms-forward.rsc @@ -1,19 +1,19 @@ #!rsc by RouterOS # RouterOS script: sms-forward -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # Anatoly Bubenkov # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # forward SMS to e-mail # https://rsc.eworm.de/doc/sms-forward.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global Identity; @@ -61,25 +61,20 @@ :if ($Phone = $Settings->"allowed-number" && \ ($SmsVal->"message")~("^:cmd " . $Settings->"secret" . " script ")) do={ $LogPrint debug $ScriptName ("Removing SMS, which started a script."); - :onerror Err { - /tool/sms/inbox/remove $Sms; - :delay 50ms; - } do={ - $LogPrint warning $ScriptName ("Failed to remove message: " . $Err); - } + /tool/sms/inbox/remove $Sms; } else={ - :set Messages ($Messages . "\n\n" . [ $SymbolForNotification "incoming-envelope" ] . \ - "On " . $SmsVal->"timestamp" . " type " . $SmsVal->"type" . ":\n" . $SmsVal->"message"); + :set Messages ($Messages . "\n\nOn " . $SmsVal->"timestamp" . \ + " type " . $SmsVal->"type" . ":\n" . $SmsVal->"message"); :foreach Hook in=$SmsForwardHooks do={ :if ($Phone~($Hook->"allowed-number") && ($SmsVal->"message")~($Hook->"match")) do={ :if ([ $ValidateSyntax ($Hook->"command") ] = true) do={ $LogPrint info $ScriptName ("Running hook '" . $Hook->"match" . "': " . $Hook->"command"); - :onerror Err { + :do { :local Command [ :parse ($Hook->"command") ]; $Command Phone=$Phone Message=($SmsVal->"message"); :set Messages ($Messages . "\n\nRan hook '" . $Hook->"match" . "':\n" . $Hook->"command"); - } do={ - $LogPrint warning $ScriptName ("The code for hook '" . $Hook->"match" . "' failed to run: " . $Err); + } on-error={ + $LogPrint warning $ScriptName ("The code for hook '" . $Hook->"match" . "' failed to run!"); } } else={ $LogPrint warning $ScriptName ("The code for hook '" . $Hook->"match" . "' failed syntax validation!"); @@ -97,15 +92,10 @@ message=("Received " . [ $IfThenElse ($Count = 1) "this message" ("these " . $Count . " messages") ] . \ " by " . $Identity . " from " . $Phone . ":" . $Messages) }); :foreach Sms in=$Delete do={ - :onerror Err { - /tool/sms/inbox/remove $Sms; - :delay 50ms; - } do={ - $LogPrint warning $ScriptName ("Failed to remove message: " . $Err); - } + /tool/sms/inbox/remove $Sms; } } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/super-mario-theme.rsc b/super-mario-theme.rsc index 318f1d9c..726c5267 100644 --- a/super-mario-theme.rsc +++ b/super-mario-theme.rsc @@ -1,6 +1,6 @@ #!rsc by RouterOS # RouterOS script: super-mario-theme -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # # play Super Mario theme diff --git a/telegram-chat.rsc b/telegram-chat.rsc index 53ab6c66..8f29d8c0 100644 --- a/telegram-chat.rsc +++ b/telegram-chat.rsc @@ -1,19 +1,19 @@ #!rsc by RouterOS # RouterOS script: telegram-chat -# Copyright (c) 2023-2026 Christian Hesse +# Copyright (c) 2023-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.15 # requires device-mode, fetch # # use Telegram to chat with your Router and send commands # https://rsc.eworm.de/doc/telegram-chat.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global Identity; @@ -30,16 +30,13 @@ :global CertificateAvailable; :global EitherOr; :global EscapeForRegEx; - :global FileExists; :global GetRandom20CharAlNum; :global IfThenElse; :global LogPrint; - :global LogPrintVerbose; :global MAX; :global MIN; :global MkDir; :global RandomDelay; - :global RmDir; :global ScriptLock; :global SendTelegram2; :global SymbolForNotification; @@ -61,7 +58,7 @@ :set TelegramRandomDelay 0; } - :if ([ $CertificateAvailable "Go Daddy Root Certificate Authority - G2" "fetch" ] = false) do={ + :if ([ $CertificateAvailable "Go Daddy Root Certificate Authority - G2" ] = false) do={ $LogPrint warning $ScriptName ("Downloading required certificate failed."); :set ExitOK true; :error false; @@ -72,14 +69,14 @@ :local Data false; :for I from=1 to=4 do={ :if ($Data = false) do={ - :onerror Err { + :do { :set Data ([ /tool/fetch check-certificate=yes-without-crl output=user \ ("https://api.telegram.org/bot" . $TelegramTokenId . "/getUpdates?offset=" . \ $TelegramChatOffset->0 . "&allowed_updates=%5B%22message%22%5D") as-value ]->"data"); :set TelegramRandomDelay [ $MAX 0 ($TelegramRandomDelay - 1) ]; - } do={ + } on-error={ :if ($I < 4) do={ - $LogPrint debug $ScriptName ("Fetch failed, " . $I . ". try: " . $Err); + $LogPrint debug $ScriptName ("Fetch failed, " . $I . ". try."); :set TelegramRandomDelay [ $MIN 15 ($TelegramRandomDelay + 5) ]; :delay (($I * $I) . "s"); } @@ -98,22 +95,17 @@ :local Uptime [ /system/resource/get uptime ]; :foreach Update in=($JSON->"result") do={ :set UpdateID ($Update->"update_id"); - $LogPrintVerbose debug $ScriptName ("Update " . $UpdateID . ": " . [ :serialize to=json $Update ]); - :local Message ($Update->"message"); - :local IsAnyReply ([ :typeof ($Message->"reply_to_message") ] = "array"); + :local IsReply [ :len ($Message->"reply_to_message") ]; :local IsMyReply ($TelegramMessageIDs->[ :tostr ($Message->"reply_to_message"->"message_id") ]); :if (($IsMyReply = 1 || $TelegramChatOffset->0 > 0 || $Uptime > 5m) && $UpdateID >= $TelegramChatOffset->2) do={ :local Trusted false; :local Chat ($Message->"chat"); :local From ($Message->"from"); :local Command ($Message->"text"); - :local ThreadId [ $IfThenElse ($Message->"is_topic_message") ($Message->"message_thread_id") "" ]; :foreach IdsTrusted in=($TelegramChatId, $TelegramChatIdsTrusted) do={ - :if ($From->"id" = $IdsTrusted || \ - $From->"username" = $IdsTrusted || \ - $Chat->"id" = $IdsTrusted) do={ + :if ($From->"id" = $IdsTrusted || $From->"username" = $IdsTrusted) do={ :set Trusted true; } } @@ -122,11 +114,9 @@ :local Done false; :if ($Command = "?") do={ $LogPrint info $ScriptName ("Sending notice for update " . $UpdateID . "."); - $SendTelegram2 ({ origin=$ScriptName; chatid=($Chat->"id"); silent=true; \ - replyto=($Message->"message_id"); threadid=$ThreadId; \ + $SendTelegram2 ({ origin=$ScriptName; chatid=($Chat->"id"); silent=true; replyto=($Message->"message_id"); \ subject=([ $SymbolForNotification "speech-balloon" ] . "Telegram Chat"); \ - message=([ $IfThenElse ([ :len ($From->"first_name") ] > 0) ("Hello " . ($From->"first_name") . "!\n\n") ] . \ - "Online" . [ $IfThenElse $TelegramChatActive " (and active!)" ] . ", awaiting your commands!") }); + message=("Online" . [ $IfThenElse $TelegramChatActive " (and active!)" ] . ", awaiting your commands!") }); :set Done true; } :if ($Done = false && [ :pick $Command 0 1 ] = "!") do={ @@ -139,8 +129,7 @@ " from update " . $UpdateID . "!"); :set Done true; } - :if ($Done = false && ($IsMyReply = 1 || ($IsAnyReply = false && \ - $TelegramChatActive = true)) && [ :len $Command ] > 0) do={ + :if ($Done = false && ($IsMyReply = 1 || ($IsReply = 0 && $TelegramChatActive = true)) && [ :len $Command ] > 0) do={ :if ([ $ValidateSyntax $Command ] = true) do={ :local State ""; :local File ("tmpfs/telegram-chat/" . [ $GetRandom20CharAlNum 6 ]); @@ -155,22 +144,20 @@ :if ([ $WaitForFile ($File . ".done") [ $EitherOr $TelegramChatRunTime 20s ] ] = false) do={ :set State ([ $SymbolForNotification "warning-sign" ] . "The command did not finish, still running in background.\n\n"); } - :if ([ $FileExists ($File . ".failed") ] = true) do={ + :if ([ :len [ /file/find where name=($File . ".failed") ] ] > 0) do={ :set State ([ $SymbolForNotification "cross-mark" ] . "The command failed with an error!\n\n"); } :local Content ([ /file/read chunk-size=32768 file=$File as-value ]->"data"); - $SendTelegram2 ({ origin=$ScriptName; chatid=($Chat->"id"); silent=true; \ - replyto=($Message->"message_id"); threadid=$ThreadId; \ + $SendTelegram2 ({ origin=$ScriptName; chatid=($Chat->"id"); silent=true; replyto=($Message->"message_id"); \ subject=([ $SymbolForNotification "speech-balloon" ] . "Telegram Chat"); \ message=([ $SymbolForNotification "gear" ] . "Command:\n" . $Command . "\n\n" . \ $State . [ $IfThenElse ([ :len $Content ] > 0) \ ([ $SymbolForNotification "memo" ] . "Output:\n" . $Content) \ ([ $SymbolForNotification "memo" ] . "No output.") ]) }); - $RmDir "tmpfs/telegram-chat"; + /file/remove "tmpfs/telegram-chat"; } else={ $LogPrint info $ScriptName ("The command from update " . $UpdateID . " failed syntax validation!"); - $SendTelegram2 ({ origin=$ScriptName; chatid=($Chat->"id"); silent=false; \ - replyto=($Message->"message_id"); threadid=$ThreadId; \ + $SendTelegram2 ({ origin=$ScriptName; chatid=($Chat->"id"); silent=false; replyto=($Message->"message_id"); \ subject=([ $SymbolForNotification "speech-balloon" ] . "Telegram Chat"); \ message=([ $SymbolForNotification "gear" ] . "Command:\n" . $Command . "\n\n" . \ [ $SymbolForNotification "cross-mark" ] . "The command failed syntax validation!") }); @@ -182,8 +169,7 @@ " (ID " . $From->"id" . ") in update " . $UpdateID . "!"); :if ($Command ~ ("^! *" . [ $EscapeForRegEx $Identity ] . "\$")) do={ $LogPrint warning $ScriptName $MessageText; - $SendTelegram2 ({ origin=$ScriptName; chatid=($Chat->"id"); silent=false; \ - replyto=($Message->"message_id"); threadid=$ThreadId; \ + $SendTelegram2 ({ origin=$ScriptName; chatid=($Chat->"id"); silent=false; replyto=($Message->"message_id"); \ subject=([ $SymbolForNotification "speech-balloon" ] . "Telegram Chat"); \ message=("You are not trusted.") }); } else={ @@ -196,6 +182,6 @@ } :set TelegramChatOffset ([ :pick $TelegramChatOffset 1 3 ], \ [ $IfThenElse ($UpdateID >= $TelegramChatOffset->2) ($UpdateID + 1) ($TelegramChatOffset->2) ]); -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/unattended-lte-firmware-upgrade.rsc b/unattended-lte-firmware-upgrade.rsc index 16d6f47d..74495d1a 100644 --- a/unattended-lte-firmware-upgrade.rsc +++ b/unattended-lte-firmware-upgrade.rsc @@ -1,9 +1,9 @@ #!rsc by RouterOS # RouterOS script: unattended-lte-firmware-upgrade -# Copyright (c) 2018-2026 Christian Hesse +# Copyright (c) 2018-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # requires device-mode, scheduler # # schedule unattended lte firmware upgrade @@ -12,10 +12,10 @@ :foreach Interface in=[ /interface/lte/find where running ] do={ :local Firmware; :local IntName [ /interface/lte/get $Interface name ]; - :onerror Err { + :do { :set Firmware [ /interface/lte/firmware-upgrade $Interface as-value ]; - } do={ - :log debug ("Could not get latest LTE firmware version for interface " . $IntName . ": " . $Err); + } on-error={ + :log debug ("Could not get latest LTE firmware version for interface " . $IntName . "."); } :if ([ :typeof $Firmware ] = "array") do={ @@ -27,7 +27,7 @@ :set LTEFirmwareUpgrade; /system/scheduler/remove ($1 . "-firmware-upgrade"); - :onerror Err { + :do { /interface/lte/firmware-upgrade $1 upgrade=yes; :log info ("LTE firmware upgrade on '" . $1 . "' finished, waiting for reset."); :delay 240s; @@ -36,8 +36,8 @@ ($Firmware->"installed") != ($Firmware->"latest")) do={ :log warning ("LTE firmware versions still differ. Upgrade failed anyway?"); } - } do={ - :log error ("LTE firmware upgrade on '" . $1 . "' failed: " . $Err); + } on-error={ + :log error ("LTE firmware upgrade on '" . $1 . "' failed."); } } diff --git a/update-gre-address.rsc b/update-gre-address.rsc index 15cfc143..6b169a00 100644 --- a/update-gre-address.rsc +++ b/update-gre-address.rsc @@ -1,19 +1,19 @@ #!rsc by RouterOS # RouterOS script: update-gre-address -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # # update gre interface remote address with dynamic address from # ipsec remote peer # https://rsc.eworm.de/doc/update-gre-address.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global CharacterReplace; @@ -41,6 +41,6 @@ } } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; } diff --git a/update-tunnelbroker.rsc b/update-tunnelbroker.rsc index f9eaf247..a58589b8 100644 --- a/update-tunnelbroker.rsc +++ b/update-tunnelbroker.rsc @@ -1,21 +1,21 @@ #!rsc by RouterOS # RouterOS script: update-tunnelbroker -# Copyright (c) 2013-2026 Christian Hesse +# Copyright (c) 2013-2025 Christian Hesse # Michael Gisbers # https://rsc.eworm.de/COPYING.md # # provides: ppp-on-up -# requires RouterOS, version=7.17 +# requires RouterOS, version=7.14 # requires device-mode, fetch # # update local address of tunnelbroker interface # https://rsc.eworm.de/doc/update-tunnelbroker.md +:global GlobalFunctionsReady; +:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } + :local ExitOK false; -:onerror Err { - :global GlobalConfigReady; :global GlobalFunctionsReady; - :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ - do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; +:do { :local ScriptName [ :jobname ]; :global CertificateAvailable; @@ -28,7 +28,7 @@ :error false; } - :if ([ $CertificateAvailable "Starfield Root Certificate Authority - G2" "fetch" ] = false) do={ + :if ([ $CertificateAvailable "Starfield Root Certificate Authority - G2" ] = false) do={ $LogPrint error $ScriptName ("Downloading required certificate failed."); :set ExitOK true; :error false; @@ -41,12 +41,12 @@ :for I from=2 to=0 do={ :if ($Data = false) do={ - :onerror Err { + :do { :set Data ([ /tool/fetch check-certificate=yes-without-crl \ ("https://ipv4.tunnelbroker.net/nic/update?hostname=" . $Comment->"id") \ user=($Comment->"user") password=($Comment->"pass") output=user as-value ]->"data"); - } do={ - $LogPrint debug $ScriptName ("Failed downloading: " . $Err . " - " . $I . " retries pending."); + } on-error={ + $LogPrint debug $ScriptName ("Failed downloading, " . $I . " retries pending."); :delay 2s; } } @@ -69,6 +69,6 @@ /interface/6to4/set $Interface local-address=$PublicAddress; } } -} do={ - :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} on-error={ + :global ExitError; $ExitError $ExitOK [ :jobname ]; }