From e14e94162a88fb1990ce727cd933e0b4dfd15133 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 30 May 2025 20:42:25 +0200 Subject: [PATCH 01/14] global-functions: $MkDir: work around restrictions in new file handling --- global-functions.rsc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/global-functions.rsc b/global-functions.rsc index 759b2744..89fff7c3 100644 --- a/global-functions.rsc +++ b/global-functions.rsc @@ -917,7 +917,9 @@ $LogPrint debug $0 ("Making directory: " . $Path); - :if ([ :len [ /file/find where name=$Path type="directory" ] ] = 1) do={ + :local PathVal; + :do { :set PathVal [ /file/get $Path ]; } on-error={ } + :if ($PathVal->"type"="directory") do={ $LogPrint debug $0 ("... which already exists."); :return true; } From b930137999e57872c95000f195480115039a5283 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 30 May 2025 21:38:26 +0200 Subject: [PATCH 02/14] global-functions: $RmDir: work around restrictions in new file handling --- global-functions.rsc | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/global-functions.rsc b/global-functions.rsc index 89fff7c3..ac73f85c 100644 --- a/global-functions.rsc +++ b/global-functions.rsc @@ -1048,21 +1048,23 @@ $LogPrint debug $0 ("Removing directory: ". $DirName); - :if ([ :len [ /file/find where name=$DirName type!=directory ] ] > 0) do={ - $LogPrint error $0 ("Directory '" . $DirName . "' is not a directory."); - :return false; - } - - :local Dir [ /file/find where name=$DirName type=directory ]; - :if ([ :len $Dir ] = 0) do={ + :local DirVal; + :do { + :set DirVal [ /file/get $DirName ]; + } on-error={ $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 $Dir; + /file/remove $DirName; } do={ - $LogPrint error $0 ("Removing directory '" . $DirName . "' (" . $Dir . ") failed: " . $Err); + $LogPrint error $0 ("Removing directory '" . $DirName . "' failed: " . $Err); :return false; } :return true; From ab84670c8ecee4ee3c0a004938e62e55980f7737 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 30 May 2025 21:41:34 +0200 Subject: [PATCH 03/14] global-functions: $RmFile: work around restrictions in new file handling --- global-functions.rsc | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/global-functions.rsc b/global-functions.rsc index ac73f85c..d3fe6ede 100644 --- a/global-functions.rsc +++ b/global-functions.rsc @@ -1078,21 +1078,23 @@ $LogPrint debug $0 ("Removing file: ". $FileName); - :if ([ :len [ /file/find where name=$FileName (type=directory or type=disk) ] ] > 0) do={ - $LogPrint error $0 ("File '" . $FileName . "' is not a file."); - :return false; - } - - :local File [ /file/find where name=$FileName !(type=directory or type=disk) ]; - :if ([ :len $File ] = 0) do={ + :local FileVal; + :do { + :set FileVal [ /file/get $FileName ]; + } on-error={ $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 $File; + /file/remove $FileName; } do={ - $LogPrint error $0 ("Removing file '" . $FileName . "' (" . $File . ") failed: " . $Err); + $LogPrint error $0 ("Removing file '" . $FileName . "' failed: " . $Err); :return false; } :return true; From 94a87ff83203674dd83991ada58eeb32150e5ca0 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 30 May 2025 20:48:05 +0200 Subject: [PATCH 04/14] global-functions: $WaitForFile: drop the workaround --- global-functions.rsc | 9 --------- 1 file changed, 9 deletions(-) diff --git a/global-functions.rsc b/global-functions.rsc index d3fe6ede..7ffc8799 100644 --- a/global-functions.rsc +++ b/global-functions.rsc @@ -1746,15 +1746,6 @@ :set I ($I + 1); } - :while ([ :len [ /file/find where name=$FileName ] ] > 0) do={ - :do { - /file/get $FileName; - :return true; - } on-error={ } - :delay $Delay; - :set Delay ($Delay * 3 / 2); - } - :return false; } From 117abedc0cc783f1dc117c6e5939beb321de1f22 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 30 May 2025 21:25:20 +0200 Subject: [PATCH 05/14] global-functions: $WaitForFile: use :retry for simplification --- global-functions.rsc | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/global-functions.rsc b/global-functions.rsc index 7ffc8799..50f3e054 100644 --- a/global-functions.rsc +++ b/global-functions.rsc @@ -1735,16 +1735,14 @@ :global MAX; :set FileName [ $CleanFilePath $FileName ]; - :local I 1; :local Delay ([ $MAX [ $EitherOr $WaitTime 2s ] 100ms ] / 10); - :while ([ :len [ /file/find where name=$FileName ] ] = 0) do={ - :if ($I >= 10) do={ - :return false; - } - :delay $Delay; - :set I ($I + 1); - } + :do { + :retry { + /file/get $FileName; + :return true; + } delay=$Delay max=10; + } on-error={ } :return false; } From c1bb4f095e7f01533248b181b1ec92f73f59fd0c Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 30 May 2025 20:34:07 +0200 Subject: [PATCH 06/14] global-functions: introduce $FileExists --- global-functions.rsc | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/global-functions.rsc b/global-functions.rsc index 50f3e054..e693567a 100644 --- a/global-functions.rsc +++ b/global-functions.rsc @@ -38,6 +38,7 @@ :global ExitError; :global FetchHuge; :global FetchUserAgentStr; +:global FileExists; :global FormatLine; :global FormatMultiLines; :global GetMacVendor; @@ -529,6 +530,29 @@ $Resource->"architecture-name" . " " . $Caller . "/Fetch (https://rsc.eworm.de/)"); } +# check for existence of file, optionally with type +:set FileExists do={ + :local FileName [ :tostr $1 ]; + :local Type [ :tostr $2 ]; + + :local FileVal; + :do { + :set FileVal [ /file/get $FileName ]; + } on-error={ + :return false; + } + + :if ([ :len ($FileVal->"size") ] = 0) do={ + :return false; + } + + :if ([ :len $Type ] = 0 || $FileVal->"type" = $Type) do={ + :return true; + } + + :return false; +} + # format a line for output :set FormatLine do={ :local Key [ :tostr $1 ]; From 0ef506a862649fea4e883e2b920e3f21e230367a Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 30 May 2025 20:44:49 +0200 Subject: [PATCH 07/14] global-functions: $DownloadPackage: use $FileExists --- global-functions.rsc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/global-functions.rsc b/global-functions.rsc index e693567a..bf905506 100644 --- a/global-functions.rsc +++ b/global-functions.rsc @@ -364,6 +364,7 @@ :global CertificateAvailable; :global CleanFilePath; + :global FileExists; :global LogPrint; :global MkDir; :global RmFile; @@ -384,7 +385,7 @@ :return false; } - :if ([ :len [ /file/find where name=$PkgDest type="package" ] ] > 0) do={ + :if ([ $FileExists $PkgDest "package" ] = true) do={ $LogPrint info $0 ("Package file " . $PkgName . " already exists."); :return true; } @@ -406,7 +407,7 @@ :return false; } - :if ([ /file/get [ find where name=$PkgDest ] type ] != "package") do={ + :if ([ $FileExists $PkgDest "package" ] = false) do={ $LogPrint warning $0 ("Downloaded file is not a package, removing."); $RmFile $PkgDest; :return false; From 2ef3a0bdf174e96c0f6194d233ca8c565b39ce19 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 30 May 2025 22:39:18 +0200 Subject: [PATCH 08/14] backup-email: use :retry and $FileExists --- backup-email.rsc | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/backup-email.rsc b/backup-email.rsc index 632d2e60..cff6fd83 100644 --- a/backup-email.rsc +++ b/backup-email.rsc @@ -27,6 +27,7 @@ :global CleanName; :global DeviceInfo; + :global FileExists; :global FormatLine; :global LogPrint; :global MkDir; @@ -124,16 +125,16 @@ attach=$Attach; remove-attach=true }); # wait for the mail to be sent - :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 { + :retry { + :if ([ $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; } } do={ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; From 3ea41799373e70eef587d6a890e50f424a611828 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 30 May 2025 23:07:31 +0200 Subject: [PATCH 09/14] backup-email: also remove the directory --- backup-email.rsc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backup-email.rsc b/backup-email.rsc index cff6fd83..4abc9610 100644 --- a/backup-email.rsc +++ b/backup-email.rsc @@ -32,6 +32,7 @@ :global LogPrint; :global MkDir; :global RandomDelay; + :global RmDir; :global ScriptFromTerminal; :global ScriptLock; :global SendEMail2; @@ -136,6 +137,7 @@ $LogPrint warning $ScriptName ("Files are still available, sending e-mail failed."); :set PackagesUpdateBackupFailure true; } + $RmDir $DirName; } do={ :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; } From adc1b668c1d1c183e82d2e81670bf729efe26abc Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 30 May 2025 22:46:03 +0200 Subject: [PATCH 10/14] mod/notification-email: use $FileExists --- mod/notification-email.rsc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mod/notification-email.rsc b/mod/notification-email.rsc index 52937668..75e11b9d 100644 --- a/mod/notification-email.rsc +++ b/mod/notification-email.rsc @@ -40,6 +40,7 @@ :global EitherOr; :global EMailGenerateFrom; + :global FileExists; :global IsDNSResolving; :global IsTimeSync; :global LogPrint; @@ -93,7 +94,7 @@ :onerror Err { :local Attach ({}); :foreach File in=[ :toarray [ $EitherOr ($Message->"attach") "" ] ] do={ - :if ([ :len [ /file/find where name=$File ] ] = 1) do={ + :if ([ $FileExists $File ] = true) do={ :set Attach ($Attach, $File); } else={ $LogPrint warning $0 ("File '" . $File . "' does not exist, can not attach."); From ae431134b3df18d73b59e86ac831c24308ea4d7d Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 30 May 2025 22:46:16 +0200 Subject: [PATCH 11/14] mod/notification-email: use $RmFile --- mod/notification-email.rsc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mod/notification-email.rsc b/mod/notification-email.rsc index 75e11b9d..ad9762a3 100644 --- a/mod/notification-email.rsc +++ b/mod/notification-email.rsc @@ -44,6 +44,7 @@ :global IsDNSResolving; :global IsTimeSync; :global LogPrint; + :global RmFile; :local AllDone true; :local QueueLen [ :len $EmailQueue ]; @@ -111,7 +112,7 @@ :set Wait false; :if (($Message->"remove-attach") = true) do={ :foreach File in=$Attach do={ - /file/remove $File; + $RmFile $File; } } } From 8e6b39b1e90ec69b1cfc433d6af8d8fc02979c0d Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 30 May 2025 22:48:57 +0200 Subject: [PATCH 12/14] mod/ssh-keys-import: use $FileExists --- mod/ssh-keys-import.rsc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mod/ssh-keys-import.rsc b/mod/ssh-keys-import.rsc index 94675255..7bdc95da 100644 --- a/mod/ssh-keys-import.rsc +++ b/mod/ssh-keys-import.rsc @@ -75,6 +75,7 @@ :local User [ :tostr $2 ]; :global EitherOr; + :global FileExists; :global LogPrint; :global ParseKeyValueStore; :global SSHKeysImport; @@ -84,8 +85,7 @@ :return false; } - :local File [ /file/find where name=$FileName ]; - :if ([ :len $File ] = 0) do={ + :if ([ $FileExists $FileName ] = true) do={ $LogPrint warning $0 ("File '" . $FileName . "' does not exist."); :return false; } From 733e2f695e93f7ee3c0bec12ad16892041a72877 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 30 May 2025 22:41:03 +0200 Subject: [PATCH 13/14] telegram-chat: use $FileExists --- telegram-chat.rsc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/telegram-chat.rsc b/telegram-chat.rsc index fdd08838..7f7b7a79 100644 --- a/telegram-chat.rsc +++ b/telegram-chat.rsc @@ -30,6 +30,7 @@ :global CertificateAvailable; :global EitherOr; :global EscapeForRegEx; + :global FileExists; :global GetRandom20CharAlNum; :global IfThenElse; :global LogPrint; @@ -154,7 +155,7 @@ :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 ([ :len [ /file/find where name=($File . ".failed") ] ] > 0) do={ + :if ([ $FileExists ($File . ".failed") ] = true) 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"); From d3c802c7911ba94f23dcc063e5d01d1ec45860bc Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Fri, 30 May 2025 23:22:59 +0200 Subject: [PATCH 14/14] capsman-download-packages: adopt new functionality from file menu --- capsman-download-packages.capsman.rsc | 12 +++++++----- capsman-download-packages.template.rsc | 12 +++++++----- capsman-download-packages.wifi.rsc | 12 +++++++----- doc/capsman-download-packages.md | 2 +- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/capsman-download-packages.capsman.rsc b/capsman-download-packages.capsman.rsc index cab1e4c3..5ccf1fed 100644 --- a/capsman-download-packages.capsman.rsc +++ b/capsman-download-packages.capsman.rsc @@ -4,7 +4,7 @@ # Michael Gisbers # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.15 +# requires RouterOS, version=7.18 # # download and cleanup packages for CAP installation from CAPsMAN # https://rsc.eworm.de/doc/capsman-download-packages.md @@ -42,7 +42,9 @@ :error false; } - :if ([ :len [ /file/find where name=$PackagePath type="directory" ] ] = 0) do={ + :do { + /file/get $PackagePath; + } on-error={ :if ([ $MkDir $PackagePath ] = false) do={ $LogPrint warning $ScriptName ("Creating directory at CAPsMAN package path (" . \ $PackagePath . ") failed!"); @@ -53,8 +55,8 @@ "). Please place your packages!"); } - :foreach Package in=[ /file/find where type=package \ - package-version!=$InstalledVersion name~("^" . $PackagePath) ] do={ + :foreach Package in=[ /file/find recursive where path=$PackagePath \ + type="package" package-version!=$InstalledVersion ] do={ :local File [ /file/get $Package ]; :if ($File->"package-architecture" = "mips") do={ :set ($File->"package-architecture") "mipsbe"; @@ -66,7 +68,7 @@ } } - :if ([ :len [ /file/find where type=package name~("^" . $PackagePath) ] ] = 0) do={ + :if ([ :len [ /file/find recursive where path=$PackagePath type="package" ] ] = 0) do={ $LogPrint info $ScriptName ("No packages available, downloading default set."); :foreach Arch in={ "arm"; "mipsbe" } do={ :foreach Package in={ "routeros"; "wireless" } do={ diff --git a/capsman-download-packages.template.rsc b/capsman-download-packages.template.rsc index ea411201..22700452 100644 --- a/capsman-download-packages.template.rsc +++ b/capsman-download-packages.template.rsc @@ -4,7 +4,7 @@ # Michael Gisbers # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.15 +# requires RouterOS, version=7.18 # # download and cleanup packages for CAP installation from CAPsMAN # https://rsc.eworm.de/doc/capsman-download-packages.md @@ -44,7 +44,9 @@ :error false; } - :if ([ :len [ /file/find where name=$PackagePath type="directory" ] ] = 0) do={ + :do { + /file/get $PackagePath; + } on-error={ :if ([ $MkDir $PackagePath ] = false) do={ $LogPrint warning $ScriptName ("Creating directory at CAPsMAN package path (" . \ $PackagePath . ") failed!"); @@ -55,8 +57,8 @@ "). Please place your packages!"); } - :foreach Package in=[ /file/find where type=package \ - package-version!=$InstalledVersion name~("^" . $PackagePath) ] do={ + :foreach Package in=[ /file/find recursive where path=$PackagePath \ + type="package" package-version!=$InstalledVersion ] do={ :local File [ /file/get $Package ]; :if ($File->"package-architecture" = "mips") do={ :set ($File->"package-architecture") "mipsbe"; @@ -68,7 +70,7 @@ } } - :if ([ :len [ /file/find where type=package name~("^" . $PackagePath) ] ] = 0) do={ + :if ([ :len [ /file/find recursive where path=$PackagePath type="package" ] ] = 0) do={ $LogPrint info $ScriptName ("No packages available, downloading default set."); # NOT /interface/wifi/ # :foreach Arch in={ "arm"; "mipsbe" } do={ diff --git a/capsman-download-packages.wifi.rsc b/capsman-download-packages.wifi.rsc index a8103569..f6384a95 100644 --- a/capsman-download-packages.wifi.rsc +++ b/capsman-download-packages.wifi.rsc @@ -4,7 +4,7 @@ # Michael Gisbers # https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.15 +# requires RouterOS, version=7.18 # # download and cleanup packages for CAP installation from CAPsMAN # https://rsc.eworm.de/doc/capsman-download-packages.md @@ -42,7 +42,9 @@ :error false; } - :if ([ :len [ /file/find where name=$PackagePath type="directory" ] ] = 0) do={ + :do { + /file/get $PackagePath; + } on-error={ :if ([ $MkDir $PackagePath ] = false) do={ $LogPrint warning $ScriptName ("Creating directory at CAPsMAN package path (" . \ $PackagePath . ") failed!"); @@ -53,8 +55,8 @@ "). Please place your packages!"); } - :foreach Package in=[ /file/find where type=package \ - package-version!=$InstalledVersion name~("^" . $PackagePath) ] do={ + :foreach Package in=[ /file/find recursive where path=$PackagePath \ + type="package" package-version!=$InstalledVersion ] do={ :local File [ /file/get $Package ]; :if ($File->"package-architecture" = "mips") do={ :set ($File->"package-architecture") "mipsbe"; @@ -66,7 +68,7 @@ } } - :if ([ :len [ /file/find where type=package name~("^" . $PackagePath) ] ] = 0) do={ + :if ([ :len [ /file/find recursive where path=$PackagePath type="package" ] ] = 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" }; diff --git a/doc/capsman-download-packages.md b/doc/capsman-download-packages.md index 57222272..4daad494 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.15-yellow?style=flat)](https://mikrotik.com/download/changelogs/) +[![required RouterOS version](https://img.shields.io/badge/RouterOS-7.18-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)