From 4b704110f89cd403e381f524484e2e9a5ca78795 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Mon, 19 Jan 2026 15:38:00 +0100 Subject: [PATCH 01/12] fw-addr-lists: use :continue in loop --- fw-addr-lists.rsc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/fw-addr-lists.rsc b/fw-addr-lists.rsc index f5514ffc..371cec7f 100644 --- a/fw-addr-lists.rsc +++ b/fw-addr-lists.rsc @@ -111,7 +111,7 @@ } else={ :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; @@ -124,7 +124,7 @@ } :set Branch [ $GetBranch $Address ]; :set ($IPv4Addresses->$Branch->$Address) $TimeOut; - :error true; + :continue; } :if ($Address ~ "^[0-9a-zA-Z]*:[0-9a-zA-Z:\\.]+(/[0-9]{1,3})?\$") do={ :local Net $Address; @@ -137,15 +137,14 @@ :set Address (([ :toip6 $Net ] & [ $NetMask6 $CIDR ]) . "/" . $CIDR); :set Branch [ $GetBranch $Address ]; :set ($IPv6Addresses->$Branch->$Address) $TimeOut; - :error true; + :continue; } :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; - :error true; + :continue; } - } on-error={ } } } From 82e6e30b120a87da8a09dd09b32bb84bd5dd3fdb Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Mon, 19 Jan 2026 15:38:50 +0100 Subject: [PATCH 02/12] fw-addr-lists: fix indention --- fw-addr-lists.rsc | 62 +++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/fw-addr-lists.rsc b/fw-addr-lists.rsc index 371cec7f..55276138 100644 --- a/fw-addr-lists.rsc +++ b/fw-addr-lists.rsc @@ -112,39 +112,39 @@ :set Address ([ :pick $Line 0 [ $FindDelim $Line ] ] . ($List->"cidr")); } - :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; - :continue; + :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) ]) ]; } - :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; - :continue; - } - :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; - :continue; + :set Branch [ $GetBranch $Address ]; + :set ($IPv4Addresses->$Branch->$Address) $TimeOut; + :continue; + } + :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; + :continue; + } + :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; + :continue; + } } } From f752feb79c9e712630c863330d50fd6160d5fdb3 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Mon, 19 Jan 2026 16:08:37 +0100 Subject: [PATCH 03/12] global-functions: $ScriptInstallUpdate: use :continue in loop --- README.md | 4 ++-- global-functions.d/deprecated.rsc | 2 +- global-functions.rsc | 26 ++++++++++++-------------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 0a9f340a..2c87acec 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ 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.21-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.22-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) @@ -50,7 +50,7 @@ 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.21-yellow?style=flat) +> ![required RouterOS version](https://img.shields.io/badge/RouterOS-7.22-yellow?style=flat) > ℹ️ **Info**: The `main` branch is now RouterOS v7 only. If you are still > running RouterOS v6 switch to `routeros-v6` branch! diff --git a/global-functions.d/deprecated.rsc b/global-functions.d/deprecated.rsc index 0ba7d5df..b35f78c6 100644 --- a/global-functions.d/deprecated.rsc +++ b/global-functions.d/deprecated.rsc @@ -3,7 +3,7 @@ # Copyright (c) 2013-2026 Christian Hesse # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.21 +# requires RouterOS, version=7.22 # # deprecated global functions # https://rsc.eworm.de/ diff --git a/global-functions.rsc b/global-functions.rsc index 4fa58b04..22ce596e 100644 --- a/global-functions.rsc +++ b/global-functions.rsc @@ -4,7 +4,7 @@ # Michael Gisbers # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.21 +# requires RouterOS, version=7.22 # requires device-mode, fetch, scheduler # # global functions @@ -1295,17 +1295,16 @@ } } - :do { :if ($ScriptInfo->"ignore" = true) do={ $LogPrint debug $0 ("Ignoring script '" . $ScriptVal->"name" . "', as requested."); - :error true; + :continue; } :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; + :continue; } :if ([ :len ($ScriptInfo->"certificate") ] > 0) do={ @@ -1327,44 +1326,44 @@ } do={ $LogPrint warning $0 ("Failed fetching script '" . $ScriptVal->"name" . "': " . $Err); :if ($Err != "Fetch failed with status 404") do={ - :error false; + :continue; } :if ($ScriptVal->"source" = "#!rsc by RouterOS\n") do={ $LogPrint warning $0 ("Removing dummy. Typo on installation?"); /system/script/remove $Script; - :error false; + :continue; } :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; + :continue; } :if ([ :len $SourceNew ] = 0) do={ $LogPrint debug $0 ("No update for script '" . $ScriptVal->"name" . "'."); - :error false; + :continue; } :local SourceCRLF [ :tocrlf $SourceNew ]; :if ($SourceNew = $ScriptVal->"source" || $SourceCRLF = $ScriptVal->"source") do={ $LogPrint debug $0 ("Script '" . $ScriptVal->"name" . "' did not change."); - :error false; + :continue; } :if ([ :pick $SourceNew 0 18 ] != "#!rsc by RouterOS\n") do={ $LogPrint warning $0 ("Looks like new script '" . $ScriptVal->"name" . \ "' is not valid (missing shebang). Ignoring!"); - :error false; + :continue; } :local RequiredROS ([ $ParseKeyValueStore [ $Grep $SourceNew ("\23 requires RouterOS, ") ] ]->"version"); :if ([ $RequiredRouterOS $0 [ $EitherOr $RequiredROS "0.0" ] false ] = false) do={ $LogPrintOnce warning $0 ("The script '" . $ScriptVal->"name" . "' requires RouterOS " . \ $RequiredROS . ", which is not met by your installation. Ignoring!"); - :error false; + :continue; } :local RequiredDM [ $ParseKeyValueStore [ $Grep $SourceNew ("\23 requires device-mode, ") ] ]; @@ -1377,12 +1376,12 @@ :if ([ :len $MissingDM ] > 0) do={ $LogPrintOnce warning $0 ("The script '" . $ScriptVal->"name" . "' requires disabled " . \ "device-mode features (" . [ :tostr $MissingDM ] . "). Ignoring!"); - :error false; + :continue; } :if ([ $ValidateSyntax $SourceNew ] = false) do={ $LogPrint warning $0 ("Syntax validation for script '" . $ScriptVal->"name" . "' failed! Ignoring!"); - :error false; + :continue; } $LogPrint info $0 ("Updating script: " . $ScriptVal->"name"); @@ -1393,7 +1392,6 @@ $ScriptVal->"name" ~ ("^(global-functions\\.d|mod)/.")) do={ :set ReloadGlobal true; } - } on-error={ } } :if ($ReloadGlobal = true) do={ From ce1333ab902d6283d0f09f3b674c7ae50de19adc Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Mon, 19 Jan 2026 16:09:41 +0100 Subject: [PATCH 04/12] global-functions: $ScriptInstallUpdate: fix indention --- global-functions.rsc | 168 +++++++++++++++++++++---------------------- 1 file changed, 84 insertions(+), 84 deletions(-) diff --git a/global-functions.rsc b/global-functions.rsc index 22ce596e..0da2b427 100644 --- a/global-functions.rsc +++ b/global-functions.rsc @@ -1295,103 +1295,103 @@ } } - :if ($ScriptInfo->"ignore" = true) do={ - $LogPrint debug $0 ("Ignoring script '" . $ScriptVal->"name" . "', as requested."); + :if ($ScriptInfo->"ignore" = true) do={ + $LogPrint debug $0 ("Ignoring script '" . $ScriptVal->"name" . "', as requested."); + :continue; + } + + :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."); + :continue; + } + + :if ([ :len ($ScriptInfo->"certificate") ] > 0) do={ + :if ([ $CertificateAvailable ($ScriptInfo->"certificate") "fetch" ] = false) do={ + $LogPrint warning $0 ("Downloading certificate failed, trying without."); + } + } + + :onerror Err { + :local BaseUrl [ $EitherOr ($ScriptInfo->"base-url") $ScriptUpdatesBaseUrl ]; + :local UrlSuffix [ $EitherOr ($ScriptInfo->"url-suffix") $ScriptUpdatesUrlSuffix ]; + :local Url ($BaseUrl . $ScriptVal->"name" . ".rsc" . $UrlSuffix); + $LogPrint debug $0 ("Fetching script '" . $ScriptVal->"name" . "' from url: " . $Url); + :local Result [ /tool/fetch check-certificate=yes-without-crl \ + http-header-field=({ [ $FetchUserAgentStr $0 ] }) $Url output=user as-value ]; + :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={ :continue; } - :local CheckSum ($CheckSums->($ScriptVal->"name")); + :if ($ScriptVal->"source" = "#!rsc by RouterOS\n") do={ + $LogPrint warning $0 ("Removing dummy. Typo on installation?"); + /system/script/remove $Script; + :continue; + } :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."); - :continue; + [ :len $CheckSum ] = 0) do={ + $LogPrintOnce warning $0 \ + ("Added the script manually? Skip updates with 'ignore=true' in comment."); } + :continue; + } - :if ([ :len ($ScriptInfo->"certificate") ] > 0) do={ - :if ([ $CertificateAvailable ($ScriptInfo->"certificate") "fetch" ] = false) do={ - $LogPrint warning $0 ("Downloading certificate failed, trying without."); - } - } + :if ([ :len $SourceNew ] = 0) do={ + $LogPrint debug $0 ("No update for script '" . $ScriptVal->"name" . "'."); + :continue; + } - :onerror Err { - :local BaseUrl [ $EitherOr ($ScriptInfo->"base-url") $ScriptUpdatesBaseUrl ]; - :local UrlSuffix [ $EitherOr ($ScriptInfo->"url-suffix") $ScriptUpdatesUrlSuffix ]; - :local Url ($BaseUrl . $ScriptVal->"name" . ".rsc" . $UrlSuffix); - $LogPrint debug $0 ("Fetching script '" . $ScriptVal->"name" . "' from url: " . $Url); - :local Result [ /tool/fetch check-certificate=yes-without-crl \ - http-header-field=({ [ $FetchUserAgentStr $0 ] }) $Url output=user as-value ]; - :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={ - :continue; - } + :local SourceCRLF [ :tocrlf $SourceNew ]; + :if ($SourceNew = $ScriptVal->"source" || $SourceCRLF = $ScriptVal->"source") do={ + $LogPrint debug $0 ("Script '" . $ScriptVal->"name" . "' did not change."); + :continue; + } - :if ($ScriptVal->"source" = "#!rsc by RouterOS\n") do={ - $LogPrint warning $0 ("Removing dummy. Typo on installation?"); - /system/script/remove $Script; - :continue; - } - :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."); - } - :continue; - } + :if ([ :pick $SourceNew 0 18 ] != "#!rsc by RouterOS\n") do={ + $LogPrint warning $0 ("Looks like new script '" . $ScriptVal->"name" . \ + "' is not valid (missing shebang). Ignoring!"); + :continue; + } - :if ([ :len $SourceNew ] = 0) do={ - $LogPrint debug $0 ("No update for script '" . $ScriptVal->"name" . "'."); - :continue; - } + :local RequiredROS ([ $ParseKeyValueStore [ $Grep $SourceNew ("\23 requires RouterOS, ") ] ]->"version"); + :if ([ $RequiredRouterOS $0 [ $EitherOr $RequiredROS "0.0" ] false ] = false) do={ + $LogPrintOnce warning $0 ("The script '" . $ScriptVal->"name" . "' requires RouterOS " . \ + $RequiredROS . ", which is not met by your installation. Ignoring!"); + :continue; + } - :local SourceCRLF [ :tocrlf $SourceNew ]; - :if ($SourceNew = $ScriptVal->"source" || $SourceCRLF = $ScriptVal->"source") do={ - $LogPrint debug $0 ("Script '" . $ScriptVal->"name" . "' did not change."); - :continue; + :local RequiredDM [ $ParseKeyValueStore [ $Grep $SourceNew ("\23 requires device-mode, ") ] ]; + :local MissingDM ({}); + :foreach Feature,Value in=$RequiredDM do={ + :if ([ :typeof ($DeviceMode->$Feature) ] = "bool" && ($DeviceMode->$Feature) = false) do={ + :set MissingDM ($MissingDM, $Feature); } + } + :if ([ :len $MissingDM ] > 0) do={ + $LogPrintOnce warning $0 ("The script '" . $ScriptVal->"name" . "' requires disabled " . \ + "device-mode features (" . [ :tostr $MissingDM ] . "). Ignoring!"); + :continue; + } - :if ([ :pick $SourceNew 0 18 ] != "#!rsc by RouterOS\n") do={ - $LogPrint warning $0 ("Looks like new script '" . $ScriptVal->"name" . \ - "' is not valid (missing shebang). Ignoring!"); - :continue; - } + :if ([ $ValidateSyntax $SourceNew ] = false) do={ + $LogPrint warning $0 ("Syntax validation for script '" . $ScriptVal->"name" . "' failed! Ignoring!"); + :continue; + } - :local RequiredROS ([ $ParseKeyValueStore [ $Grep $SourceNew ("\23 requires RouterOS, ") ] ]->"version"); - :if ([ $RequiredRouterOS $0 [ $EitherOr $RequiredROS "0.0" ] false ] = false) do={ - $LogPrintOnce warning $0 ("The script '" . $ScriptVal->"name" . "' requires RouterOS " . \ - $RequiredROS . ", which is not met by your installation. Ignoring!"); - :continue; - } - - :local RequiredDM [ $ParseKeyValueStore [ $Grep $SourceNew ("\23 requires device-mode, ") ] ]; - :local MissingDM ({}); - :foreach Feature,Value in=$RequiredDM do={ - :if ([ :typeof ($DeviceMode->$Feature) ] = "bool" && ($DeviceMode->$Feature) = false) do={ - :set MissingDM ($MissingDM, $Feature); - } - } - :if ([ :len $MissingDM ] > 0) do={ - $LogPrintOnce warning $0 ("The script '" . $ScriptVal->"name" . "' requires disabled " . \ - "device-mode features (" . [ :tostr $MissingDM ] . "). Ignoring!"); - :continue; - } - - :if ([ $ValidateSyntax $SourceNew ] = false) do={ - $LogPrint warning $0 ("Syntax validation for script '" . $ScriptVal->"name" . "' failed! Ignoring!"); - :continue; - } - - $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" ~ ("^(global-functions\\.d|mod)/.")) do={ - :set ReloadGlobal true; - } + $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" ~ ("^(global-functions\\.d|mod)/.")) do={ + :set ReloadGlobal true; + } } :if ($ReloadGlobal = true) do={ From b372f10bdc5bcc2c68f14077293751c12a3f49e2 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Thu, 22 Jan 2026 10:52:47 +0100 Subject: [PATCH 05/12] netwatch-dns: use :continue in loop --- netwatch-dns.rsc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/netwatch-dns.rsc b/netwatch-dns.rsc index 930ab70e..7bfa4831 100644 --- a/netwatch-dns.rsc +++ b/netwatch-dns.rsc @@ -121,9 +121,9 @@ } do={ $LogPrint warning $ScriptName ("Request to DoH server " . ($DohServer->"doh-url") . \ " failed: " . $Err); + :continue; } - :if ($Data != false) do={ :if ([ :typeof [ :find $Data "doh-check-OK" ] ] = "num") do={ /ip/dns/set use-doh-server=($DohServer->"doh-url") verify-doh-cert=yes; :if ([ /certificate/settings/get crl-use ] = true) do={ @@ -136,7 +136,6 @@ $LogPrint warning $ScriptName ("Received unexpected response from DoH server: " . \ ($DohServer->"doh-url")); } - } } } do={ :global ExitOnError; $ExitOnError [ :jobname ] $Err; From e0a92529dcbc1866038edf95a115c2436c17865f Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Thu, 22 Jan 2026 10:56:45 +0100 Subject: [PATCH 06/12] netwatch-dns: fix indention --- netwatch-dns.rsc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/netwatch-dns.rsc b/netwatch-dns.rsc index 7bfa4831..bb4ac57d 100644 --- a/netwatch-dns.rsc +++ b/netwatch-dns.rsc @@ -124,18 +124,18 @@ :continue; } - :if ([ :typeof [ :find $Data "doh-check-OK" ] ] = "num") do={ - /ip/dns/set use-doh-server=($DohServer->"doh-url") verify-doh-cert=yes; - :if ([ /certificate/settings/get crl-use ] = true) do={ - $LogPrintOnce warning $ScriptName ("Configured to use CRL, that can cause severe issue!"); - } - /ip/dns/cache/flush; - $LogPrint info $ScriptName ("Setting DoH server: " . ($DohServer->"doh-url")); - :exit; - } else={ - $LogPrint warning $ScriptName ("Received unexpected response from DoH server: " . \ - ($DohServer->"doh-url")); + :if ([ :typeof [ :find $Data "doh-check-OK" ] ] = "num") do={ + /ip/dns/set use-doh-server=($DohServer->"doh-url") verify-doh-cert=yes; + :if ([ /certificate/settings/get crl-use ] = true) do={ + $LogPrintOnce warning $ScriptName ("Configured to use CRL, that can cause severe issue!"); } + /ip/dns/cache/flush; + $LogPrint info $ScriptName ("Setting DoH server: " . ($DohServer->"doh-url")); + :exit; + } else={ + $LogPrint warning $ScriptName ("Received unexpected response from DoH server: " . \ + ($DohServer->"doh-url")); + } } } do={ :global ExitOnError; $ExitOnError [ :jobname ] $Err; From e89f22e3b66dbc9ecafbf19542cefb1f248e26f6 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Thu, 22 Jan 2026 10:54:21 +0100 Subject: [PATCH 07/12] netwatch-dns: use :continue in loop --- netwatch-dns.rsc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/netwatch-dns.rsc b/netwatch-dns.rsc index bb4ac57d..9d42971d 100644 --- a/netwatch-dns.rsc +++ b/netwatch-dns.rsc @@ -124,7 +124,12 @@ :continue; } - :if ([ :typeof [ :find $Data "doh-check-OK" ] ] = "num") do={ + :if ([ :typeof [ :find $Data "doh-check-OK" ] ] != "num") do={ + $LogPrint warning $ScriptName ("Received unexpected response from DoH server: " . \ + ($DohServer->"doh-url")); + :continue; + } + /ip/dns/set use-doh-server=($DohServer->"doh-url") verify-doh-cert=yes; :if ([ /certificate/settings/get crl-use ] = true) do={ $LogPrintOnce warning $ScriptName ("Configured to use CRL, that can cause severe issue!"); @@ -132,10 +137,6 @@ /ip/dns/cache/flush; $LogPrint info $ScriptName ("Setting DoH server: " . ($DohServer->"doh-url")); :exit; - } else={ - $LogPrint warning $ScriptName ("Received unexpected response from DoH server: " . \ - ($DohServer->"doh-url")); - } } } do={ :global ExitOnError; $ExitOnError [ :jobname ] $Err; From 99c1d11b8b54f4bca54b3b68f4d556add688401a Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Thu, 22 Jan 2026 10:58:31 +0100 Subject: [PATCH 08/12] netwatch-dns: fix indention --- netwatch-dns.rsc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/netwatch-dns.rsc b/netwatch-dns.rsc index 9d42971d..2406dad5 100644 --- a/netwatch-dns.rsc +++ b/netwatch-dns.rsc @@ -130,13 +130,13 @@ :continue; } - /ip/dns/set use-doh-server=($DohServer->"doh-url") verify-doh-cert=yes; - :if ([ /certificate/settings/get crl-use ] = true) do={ - $LogPrintOnce warning $ScriptName ("Configured to use CRL, that can cause severe issue!"); - } - /ip/dns/cache/flush; - $LogPrint info $ScriptName ("Setting DoH server: " . ($DohServer->"doh-url")); - :exit; + /ip/dns/set use-doh-server=($DohServer->"doh-url") verify-doh-cert=yes; + :if ([ /certificate/settings/get crl-use ] = true) do={ + $LogPrintOnce warning $ScriptName ("Configured to use CRL, that can cause severe issue!"); + } + /ip/dns/cache/flush; + $LogPrint info $ScriptName ("Setting DoH server: " . ($DohServer->"doh-url")); + :exit; } } do={ :global ExitOnError; $ExitOnError [ :jobname ] $Err; From d815b67847fba73d04b75706284fba380f279421 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Thu, 15 Jan 2026 09:28:38 +0100 Subject: [PATCH 09/12] telegram-chat: use :continue in loop --- telegram-chat.rsc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/telegram-chat.rsc b/telegram-chat.rsc index 8e9efb7e..5d612da0 100644 --- a/telegram-chat.rsc +++ b/telegram-chat.rsc @@ -115,7 +115,6 @@ } :if ($Trusted = true) do={ - :local Done false; :if ($Command = "?") do={ $LogPrint info $ScriptName ("Sending notice for update " . $UpdateID . "."); $SendTelegram2 ({ origin=$ScriptName; chatid=($Chat->"id"); silent=true; \ @@ -123,9 +122,9 @@ 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!") }); - :set Done true; + :continue; } - :if ($Done = false && [ :pick $Command 0 1 ] = "!") do={ + :if ([ :pick $Command 0 1 ] = "!") do={ :if ($Command ~ ("^! *(" . [ $EscapeForRegEx $Identity ] . "|@" . $TelegramChatGroups . ")\$")) do={ :set TelegramChatActive true; } else={ @@ -133,9 +132,9 @@ } $LogPrint info $ScriptName ("Now " . [ $IfThenElse $TelegramChatActive "active" "passive" ] . \ " from update " . $UpdateID . "!"); - :set Done true; + :continue; } - :if ($Done = false && ($IsMyReply = 1 || ($IsAnyReply = false && \ + :if (($IsMyReply = 1 || ($IsAnyReply = false && \ $TelegramChatActive = true)) && [ :len $Command ] > 0) do={ :if ([ $ValidateSyntax $Command ] = true) do={ :local State ""; From 79d9b9ea5951b76cffa5f419b96a6760d2e03b6a Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Mon, 16 Mar 2026 11:12:35 +0100 Subject: [PATCH 10/12] dhcp-to-dns: use :continue in loop --- dhcp-to-dns.rsc | 1 + 1 file changed, 1 insertion(+) diff --git a/dhcp-to-dns.rsc b/dhcp-to-dns.rsc index 44bc9b82..52e7ed61 100644 --- a/dhcp-to-dns.rsc +++ b/dhcp-to-dns.rsc @@ -64,6 +64,7 @@ } } on-error={ $LogPrint debug $ScriptName ("A lease just vanished, ignoring."); + :continue; } :if ([ :len ($LeaseVal->"active-address") ] > 0) do={ From 83d04bfa903107271cd1bc1ddcb4288c8c41c217 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Mon, 16 Mar 2026 11:14:17 +0100 Subject: [PATCH 11/12] dhcp-to-dns: use another :continue in loop --- dhcp-to-dns.rsc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dhcp-to-dns.rsc b/dhcp-to-dns.rsc index 52e7ed61..992277ec 100644 --- a/dhcp-to-dns.rsc +++ b/dhcp-to-dns.rsc @@ -67,7 +67,11 @@ :continue; } - :if ([ :len ($LeaseVal->"active-address") ] > 0) do={ + :if ([ :len ($LeaseVal->"active-address") ] = 0) do={ + $LogPrint debug $ScriptName ("No address available... Ignoring."); + :continue; + } + :local Comment ($CommentPrefix . ", macaddress=" . $LeaseVal->"active-mac-address" . ", server=" . $LeaseVal->"server"); :local MacDash [ $CleanName ($LeaseVal->"active-mac-address") ]; :local HostName [ $CleanName [ $EitherOr ([ $ParseKeyValueStore ($LeaseVal->"comment") ]->"hostname") ($LeaseVal->"host-name") ] ]; @@ -119,9 +123,6 @@ :if ([ :len [ /ip/dns/static/find where name=$FullA type=A ] ] > 1) do={ $LogPrintOnce warning $ScriptName ("The name '" . $FullA . "' appeared in more than one A record!"); } - } else={ - $LogPrint debug $ScriptName ("No address available... Ignoring."); - } } } do={ :global ExitOnError; $ExitOnError [ :jobname ] $Err; From d942721f6d80e969f5a02a58ac3b42624fe8e7ff Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Mon, 16 Mar 2026 11:15:48 +0100 Subject: [PATCH 12/12] dhcp-to-dns: fix indention --- dhcp-to-dns.rsc | 90 ++++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/dhcp-to-dns.rsc b/dhcp-to-dns.rsc index 992277ec..d176b9f7 100644 --- a/dhcp-to-dns.rsc +++ b/dhcp-to-dns.rsc @@ -72,57 +72,57 @@ :continue; } - :local Comment ($CommentPrefix . ", macaddress=" . $LeaseVal->"active-mac-address" . ", server=" . $LeaseVal->"server"); - :local MacDash [ $CleanName ($LeaseVal->"active-mac-address") ]; - :local HostName [ $CleanName [ $EitherOr ([ $ParseKeyValueStore ($LeaseVal->"comment") ]->"hostname") ($LeaseVal->"host-name") ] ]; - :local Network [ /ip/dhcp-server/network/find where ($LeaseVal->"active-address") in address ]; - :local NetworkVal; - :if ([ :len $Network ] > 0) do={ - :set NetworkVal [ /ip/dhcp-server/network/get ($Network->0) ]; - } - :local NetworkInfo [ $ParseKeyValueStore ($NetworkVal->"comment") ]; - :local NetDomain ([ $IfThenElse ([ :len ($NetworkInfo->"name-extra") ] > 0) ($NetworkInfo->"name-extra" . ".") ] . \ - [ $EitherOr [ $EitherOr ($NetworkInfo->"domain") ($NetworkVal->"domain") ] $Domain ]); - :local FullA ($MacDash . "." . $NetDomain); - :local FullCN ($HostName . "." . $NetDomain); - :local MacInServer ($LeaseVal->"active-mac-address" . " in " . $LeaseVal->"server"); + :local Comment ($CommentPrefix . ", macaddress=" . $LeaseVal->"active-mac-address" . ", server=" . $LeaseVal->"server"); + :local MacDash [ $CleanName ($LeaseVal->"active-mac-address") ]; + :local HostName [ $CleanName [ $EitherOr ([ $ParseKeyValueStore ($LeaseVal->"comment") ]->"hostname") ($LeaseVal->"host-name") ] ]; + :local Network [ /ip/dhcp-server/network/find where ($LeaseVal->"active-address") in address ]; + :local NetworkVal; + :if ([ :len $Network ] > 0) do={ + :set NetworkVal [ /ip/dhcp-server/network/get ($Network->0) ]; + } + :local NetworkInfo [ $ParseKeyValueStore ($NetworkVal->"comment") ]; + :local NetDomain ([ $IfThenElse ([ :len ($NetworkInfo->"name-extra") ] > 0) ($NetworkInfo->"name-extra" . ".") ] . \ + [ $EitherOr [ $EitherOr ($NetworkInfo->"domain") ($NetworkVal->"domain") ] $Domain ]); + :local FullA ($MacDash . "." . $NetDomain); + :local FullCN ($HostName . "." . $NetDomain); + :local MacInServer ($LeaseVal->"active-mac-address" . " in " . $LeaseVal->"server"); - :local DnsRecord [ /ip/dns/static/find where comment=$Comment type=A ]; - :if ([ :len $DnsRecord ] > 0) do={ - :local DnsRecordVal [ /ip/dns/static/get $DnsRecord ]; - - :if ($DnsRecordVal->"address" = $LeaseVal->"active-address" && $DnsRecordVal->"name" = $FullA) do={ - $LogPrint debug $ScriptName ("The A record for " . $MacInServer . " (" . $FullA . ") does not need updating."); - } else={ - $LogPrint info $ScriptName ("Updating A record for " . $MacInServer . " (" . $FullA . " -> " . $LeaseVal->"active-address" . ")."); - /ip/dns/static/set address=($LeaseVal->"active-address") name=$FullA $DnsRecord; - } - - :local CName [ /ip/dns/static/find where comment=$Comment type=CNAME ]; - :if ([ :len $CName ] > 0) do={ - :local CNameVal [ /ip/dns/static/get $CName ]; - :if ($CNameVal->"name" != $FullCN || $CNameVal->"cname" != $FullA) do={ - $LogPrint info $ScriptName ("Deleting CNAME record with wrong data for " . $MacInServer . "."); - /ip/dns/static/remove $CName; - } - } - :if ([ :len $HostName ] > 0 && [ :len [ /ip/dns/static/find where name=$FullCN type=CNAME ] ] = 0) do={ - $LogPrint info $ScriptName ("Adding CNAME record for " . $MacInServer . " (" . $FullCN . " -> " . $FullA . ")."); - /ip/dns/static/add name=$FullCN type=CNAME cname=$FullA ttl=$Ttl comment=$Comment place-before=$PlaceBefore; - } + :local DnsRecord [ /ip/dns/static/find where comment=$Comment type=A ]; + :if ([ :len $DnsRecord ] > 0) do={ + :local DnsRecordVal [ /ip/dns/static/get $DnsRecord ]; + :if ($DnsRecordVal->"address" = $LeaseVal->"active-address" && $DnsRecordVal->"name" = $FullA) do={ + $LogPrint debug $ScriptName ("The A record for " . $MacInServer . " (" . $FullA . ") does not need updating."); } else={ - $LogPrint info $ScriptName ("Adding A record for " . $MacInServer . " (" . $FullA . " -> " . $LeaseVal->"active-address" . ")."); - /ip/dns/static/add name=$FullA type=A address=($LeaseVal->"active-address") ttl=$Ttl comment=$Comment place-before=$PlaceBefore; - :if ([ :len $HostName ] > 0 && [ :len [ /ip/dns/static/find where name=$FullCN type=CNAME ] ] = 0) do={ - $LogPrint info $ScriptName ("Adding CNAME record for " . $MacInServer . " (" . $FullCN . " -> " . $FullA . ")."); - /ip/dns/static/add name=$FullCN type=CNAME cname=$FullA ttl=$Ttl comment=$Comment place-before=$PlaceBefore; - } + $LogPrint info $ScriptName ("Updating A record for " . $MacInServer . " (" . $FullA . " -> " . $LeaseVal->"active-address" . ")."); + /ip/dns/static/set address=($LeaseVal->"active-address") name=$FullA $DnsRecord; } - :if ([ :len [ /ip/dns/static/find where name=$FullA type=A ] ] > 1) do={ - $LogPrintOnce warning $ScriptName ("The name '" . $FullA . "' appeared in more than one A record!"); + :local CName [ /ip/dns/static/find where comment=$Comment type=CNAME ]; + :if ([ :len $CName ] > 0) do={ + :local CNameVal [ /ip/dns/static/get $CName ]; + :if ($CNameVal->"name" != $FullCN || $CNameVal->"cname" != $FullA) do={ + $LogPrint info $ScriptName ("Deleting CNAME record with wrong data for " . $MacInServer . "."); + /ip/dns/static/remove $CName; + } } + :if ([ :len $HostName ] > 0 && [ :len [ /ip/dns/static/find where name=$FullCN type=CNAME ] ] = 0) do={ + $LogPrint info $ScriptName ("Adding CNAME record for " . $MacInServer . " (" . $FullCN . " -> " . $FullA . ")."); + /ip/dns/static/add name=$FullCN type=CNAME cname=$FullA ttl=$Ttl comment=$Comment place-before=$PlaceBefore; + } + + } else={ + $LogPrint info $ScriptName ("Adding A record for " . $MacInServer . " (" . $FullA . " -> " . $LeaseVal->"active-address" . ")."); + /ip/dns/static/add name=$FullA type=A address=($LeaseVal->"active-address") ttl=$Ttl comment=$Comment place-before=$PlaceBefore; + :if ([ :len $HostName ] > 0 && [ :len [ /ip/dns/static/find where name=$FullCN type=CNAME ] ] = 0) do={ + $LogPrint info $ScriptName ("Adding CNAME record for " . $MacInServer . " (" . $FullCN . " -> " . $FullA . ")."); + /ip/dns/static/add name=$FullCN type=CNAME cname=$FullA ttl=$Ttl comment=$Comment place-before=$PlaceBefore; + } + } + + :if ([ :len [ /ip/dns/static/find where name=$FullA type=A ] ] > 1) do={ + $LogPrintOnce warning $ScriptName ("The name '" . $FullA . "' appeared in more than one A record!"); + } } } do={ :global ExitOnError; $ExitOnError [ :jobname ] $Err;