mirror of
https://git.eworm.de/cgit/routeros-scripts
synced 2025-07-15 04:24:29 +02:00
Compare commits
39 commits
change-138
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
89175e511f | ||
|
b068f86995 | ||
|
d46574b4fe | ||
|
c3010af4ed | ||
|
1307b8587e | ||
|
6415849850 | ||
|
95f8af6234 | ||
|
de2a90d841 | ||
|
e2d3f0f073 | ||
|
595b4aea9d | ||
|
0de6d006ae | ||
|
1f4bf9ee63 | ||
|
c3d3d61f92 | ||
|
6130c94cc1 | ||
|
15fd522d3d | ||
|
5b15c82bb1 | ||
|
30b80e903d | ||
|
80aed200fd | ||
|
2d81984aed | ||
|
e3284ca770 | ||
|
daee05dbd7 | ||
|
43bac7c33c | ||
|
a2f837be59 | ||
|
8353a8547f | ||
|
cb984a5e52 | ||
|
0e00a228d6 | ||
|
e08bb2192d | ||
|
fb8e616846 | ||
|
d993495e44 | ||
|
1e4f168735 | ||
|
b70e6e7984 | ||
|
4bc3bf40e6 | ||
|
d69b399572 | ||
|
bf684a7197 | ||
|
d59c4aee26 | ||
|
3d3b270748 | ||
|
6a49c483b6 | ||
|
c50acd697a | ||
|
4bd7d44cd2 |
21 changed files with 190 additions and 87 deletions
|
@ -35,6 +35,7 @@ Add yourself to the list,
|
|||
[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)
|
||||
|
|
|
@ -18,9 +18,12 @@ Run the complete base installation:
|
|||
|
||||
{
|
||||
:local BaseUrl "https://git.eworm.de/cgit/routeros-scripts/plain/";
|
||||
:local CertCommonName "ISRG Root X2";
|
||||
:local CertFileName "ISRG-Root-X2.pem";
|
||||
:local CertFingerprint "69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470";
|
||||
|
||||
:if (!(([ /certificate/settings/get ]->"builtin-trust-anchors") = "trusted" && \
|
||||
[[ :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;
|
||||
|
@ -29,6 +32,7 @@ Run the complete base installation:
|
|||
:error "Something is wrong with your certificates!";
|
||||
};
|
||||
:delay 1s;
|
||||
};
|
||||
:put "Renaming global-config-overlay, if exists...";
|
||||
/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={
|
||||
|
@ -41,10 +45,12 @@ Run the complete base installation:
|
|||
:put "Scheduling to load configuration and functions...";
|
||||
/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; }";
|
||||
:if ([ :len [ /certificate/find where fingerprint=$CertFingerprint ] ] > 0) do={
|
||||
:put "Renaming certificate by its common-name...";
|
||||
:global CertificateNameByCN;
|
||||
$CertificateNameByCN $CertFingerprint;
|
||||
};
|
||||
};
|
||||
|
||||
Then continue setup with
|
||||
[scheduled automatic updates](README.md#scheduled-automatic-updates) or
|
||||
|
|
12
README.md
12
README.md
|
@ -72,7 +72,15 @@ including demonstation 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. If you intend to download the scripts from a
|
||||
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;`
|
||||
|
||||
If you intend to download the scripts from a
|
||||
different location (for example from github.com) install the corresponding
|
||||
certificate chain.
|
||||
|
||||
|
@ -106,6 +114,8 @@ 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!
|
||||
|
|
|
@ -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 where mac-address=$Mac;
|
||||
/caps-man/access-list/print without-paging where mac-address=$Mac;
|
||||
:local Remove [ :tonum [ /terminal/ask prompt="\nNumeric id to remove, any key to skip!" ] ];
|
||||
|
||||
:if ([ :typeof $Remove ] = "num") do={
|
||||
|
|
|
@ -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 where mac-address=$Mac;
|
||||
/interface/wireless/access-list/print without-paging where mac-address=$Mac;
|
||||
:local Remove [ :tonum [ /terminal/ask prompt="\nNumeric id to remove, any key to skip!" ] ];
|
||||
|
||||
:if ([ :typeof $Remove ] = "num") do={
|
||||
|
|
|
@ -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 where mac-address=$Mac;
|
||||
/interface/wifi/access-list/print where mac-address=$Mac;
|
||||
/interface/wireless/access-list/print where mac-address=$Mac;
|
||||
/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;
|
||||
:local Remove [ :tonum [ /terminal/ask prompt="\nNumeric id to remove, any key to skip!" ] ];
|
||||
|
||||
:if ([ :typeof $Remove ] = "num") do={
|
||||
|
|
|
@ -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 where mac-address=$Mac;
|
||||
/interface/wifi/access-list/print without-paging where mac-address=$Mac;
|
||||
:local Remove [ :tonum [ /terminal/ask prompt="\nNumeric id to remove, any key to skip!" ] ];
|
||||
|
||||
:if ([ :typeof $Remove ] = "num") do={
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
:global CleanName;
|
||||
:global DeviceInfo;
|
||||
:global FileExists;
|
||||
:global FormatLine;
|
||||
:global LogPrint;
|
||||
:global MkDir;
|
||||
|
@ -124,17 +125,19 @@
|
|||
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={
|
||||
: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;
|
||||
: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;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
:global CleanFilePath;
|
||||
:global DownloadPackage;
|
||||
:global FileGet;
|
||||
:global LogPrint;
|
||||
:global MkDir;
|
||||
:global RmFile;
|
||||
|
@ -42,7 +43,7 @@
|
|||
:error false;
|
||||
}
|
||||
|
||||
:if ([ :len [ /file/find where name=$PackagePath type="directory" ] ] = 0) do={
|
||||
:if ([ $FileGet $PackagePath ] = false) do={
|
||||
:if ([ $MkDir $PackagePath ] = false) do={
|
||||
$LogPrint warning $ScriptName ("Creating directory at CAPsMAN package path (" . \
|
||||
$PackagePath . ") failed!");
|
||||
|
@ -53,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={
|
||||
|
@ -66,7 +67,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
: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={
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
:global CleanFilePath;
|
||||
:global DownloadPackage;
|
||||
:global FileGet;
|
||||
:global LogPrint;
|
||||
:global MkDir;
|
||||
:global RmFile;
|
||||
|
@ -44,7 +45,7 @@
|
|||
:error false;
|
||||
}
|
||||
|
||||
:if ([ :len [ /file/find where name=$PackagePath type="directory" ] ] = 0) do={
|
||||
:if ([ $FileGet $PackagePath ] = false) do={
|
||||
:if ([ $MkDir $PackagePath ] = false) do={
|
||||
$LogPrint warning $ScriptName ("Creating directory at CAPsMAN package path (" . \
|
||||
$PackagePath . ") failed!");
|
||||
|
@ -55,7 +56,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={
|
||||
|
@ -68,7 +69,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
: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={
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
:global CleanFilePath;
|
||||
:global DownloadPackage;
|
||||
:global FileGet;
|
||||
:global LogPrint;
|
||||
:global MkDir;
|
||||
:global RmFile;
|
||||
|
@ -42,7 +43,7 @@
|
|||
:error false;
|
||||
}
|
||||
|
||||
:if ([ :len [ /file/find where name=$PackagePath type="directory" ] ] = 0) do={
|
||||
:if ([ $FileGet $PackagePath ] = false) do={
|
||||
:if ([ $MkDir $PackagePath ] = false) do={
|
||||
$LogPrint warning $ScriptName ("Creating directory at CAPsMAN package path (" . \
|
||||
$PackagePath . ") failed!");
|
||||
|
@ -53,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={
|
||||
|
@ -66,7 +67,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
: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" };
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
:global EscapeForRegEx;
|
||||
:global FetchUserAgentStr;
|
||||
:global LogPrint;
|
||||
:global RebootForUpdate;
|
||||
:global ScriptFromTerminal;
|
||||
:global ScriptLock;
|
||||
:global SendNotification2;
|
||||
|
@ -62,10 +63,15 @@
|
|||
$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;
|
||||
}
|
||||
}
|
||||
|
||||
$LogPrint debug $ScriptName ("Checking for updates...");
|
||||
/system/package/update/check-for-updates without-paging as-value;
|
||||
|
|
|
@ -33,6 +33,9 @@ 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.
|
||||
|
||||
Requirements and installation
|
||||
-----------------------------
|
||||
|
|
|
@ -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)
|
||||
* `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
|
||||
|
||||
By modifying the scheduler's `start-time` you can force the reboot at
|
||||
different time.
|
||||
|
|
|
@ -48,6 +48,12 @@
|
|||
}
|
||||
$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={
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
:global ExitError;
|
||||
:global FetchHuge;
|
||||
:global FetchUserAgentStr;
|
||||
:global FileExists;
|
||||
:global FileGet;
|
||||
:global FormatLine;
|
||||
:global FormatMultiLines;
|
||||
:global GetMacVendor;
|
||||
|
@ -119,6 +121,11 @@
|
|||
:return false;
|
||||
}
|
||||
|
||||
:if (([ /certificate/settings/get ]->"builtin-trust-anchors") = "trusted" && \
|
||||
[[ :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={
|
||||
|
@ -358,6 +365,7 @@
|
|||
|
||||
:global CertificateAvailable;
|
||||
:global CleanFilePath;
|
||||
:global FileExists;
|
||||
:global LogPrint;
|
||||
:global MkDir;
|
||||
:global RmFile;
|
||||
|
@ -378,7 +386,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;
|
||||
}
|
||||
|
@ -400,7 +408,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;
|
||||
|
@ -524,6 +532,47 @@
|
|||
$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 ];
|
||||
|
||||
: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;
|
||||
}
|
||||
|
||||
# format a line for output
|
||||
:set FormatLine do={
|
||||
:local Key [ :tostr $1 ];
|
||||
|
@ -875,6 +924,7 @@
|
|||
:local Path [ :tostr $1 ];
|
||||
|
||||
:global CleanFilePath;
|
||||
:global FileGet;
|
||||
:global LogPrint;
|
||||
:global RmDir;
|
||||
:global WaitForFile;
|
||||
|
@ -912,7 +962,8 @@
|
|||
|
||||
$LogPrint debug $0 ("Making directory: " . $Path);
|
||||
|
||||
:if ([ :len [ /file/find where name=$Path type="directory" ] ] = 1) do={
|
||||
:local PathVal [ $FileGet $Path ];
|
||||
:if ($PathVal->"type" = "directory") do={
|
||||
$LogPrint debug $0 ("... which already exists.");
|
||||
:return true;
|
||||
}
|
||||
|
@ -1037,25 +1088,26 @@
|
|||
:set RmDir do={
|
||||
:local DirName [ :tostr $1 ];
|
||||
|
||||
:global FileGet;
|
||||
:global LogPrint;
|
||||
|
||||
$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 [ $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 $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;
|
||||
|
@ -1065,25 +1117,26 @@
|
|||
:set RmFile do={
|
||||
:local FileName [ :tostr $1 ];
|
||||
|
||||
:global FileGet;
|
||||
:global LogPrint;
|
||||
|
||||
$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 [ $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 $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;
|
||||
|
@ -1212,7 +1265,7 @@
|
|||
:set SourceNew [ :tolf ($Result->"data") ];
|
||||
}
|
||||
} do={
|
||||
$LogPrint warning $0 ("Failed fetching script '" . $ScriptVal->"name" . . "': " . $Err);
|
||||
$LogPrint warning $0 ("Failed fetching script '" . $ScriptVal->"name" . "': " . $Err);
|
||||
:if ($ScriptVal->"source" = "#!rsc by RouterOS\n") do={
|
||||
$LogPrint warning $0 ("Removing dummy. Typo on installation?");
|
||||
/system/script/remove $Script;
|
||||
|
@ -1724,15 +1777,16 @@
|
|||
:global MAX;
|
||||
|
||||
:set FileName [ $CleanFilePath $FileName ];
|
||||
:local I 1;
|
||||
:local Delay ([ $MAX [ $EitherOr $WaitTime 2s ] 100ms ] / 10);
|
||||
:local Delay ([ $MAX [ $EitherOr $WaitTime 2s ] 100ms ] / 9);
|
||||
|
||||
:while ([ :len [ /file/find where name=$FileName ] ] = 0) do={
|
||||
:if ($I >= 10) do={
|
||||
:return false;
|
||||
:do {
|
||||
:retry {
|
||||
:if ([ :len [ /file/find where name=$FileName ] ] = 0) do={
|
||||
:error false;
|
||||
}
|
||||
:delay $Delay;
|
||||
:set I ($I + 1);
|
||||
} delay=$Delay max=10;
|
||||
} on-error={
|
||||
:return false;
|
||||
}
|
||||
|
||||
:while ([ :len [ /file/find where name=$FileName ] ] > 0) do={
|
||||
|
|
|
@ -40,9 +40,11 @@
|
|||
|
||||
:global EitherOr;
|
||||
:global EMailGenerateFrom;
|
||||
:global FileExists;
|
||||
:global IsDNSResolving;
|
||||
:global IsTimeSync;
|
||||
:global LogPrint;
|
||||
:global RmFile;
|
||||
|
||||
:local AllDone true;
|
||||
:local QueueLen [ :len $EmailQueue ];
|
||||
|
@ -93,7 +95,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.");
|
||||
|
@ -110,7 +112,7 @@
|
|||
:set Wait false;
|
||||
:if (($Message->"remove-attach") = true) do={
|
||||
:foreach File in=$Attach do={
|
||||
/file/remove $File;
|
||||
$RmFile $File;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -119,11 +119,13 @@
|
|||
|
||||
: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);
|
||||
|
|
|
@ -31,19 +31,25 @@
|
|||
:local Schedule do={
|
||||
:local ScriptName [ :tostr $1 ];
|
||||
|
||||
:global PackagesUpdateDeferReboot;
|
||||
|
||||
:global GetRandomNumber;
|
||||
:global IfThenElse;
|
||||
:global LogPrint;
|
||||
|
||||
:global RebootForUpdate do={
|
||||
/system/reboot;
|
||||
}
|
||||
|
||||
:local Interval [ $IfThenElse ([ :totime $PackagesUpdateDeferReboot ] >= 1d) \
|
||||
$PackagesUpdateDeferReboot 1d ];
|
||||
:local StartTime [ :tostr [ :totime (10800 + [ $GetRandomNumber 7200 ]) ] ];
|
||||
/system/scheduler/add name="_RebootForUpdate" start-time=$StartTime interval=1d \
|
||||
/system/scheduler/add name="_RebootForUpdate" start-time=$StartTime interval=$Interval \
|
||||
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 ] . ").");
|
||||
" local time (" . [ /system/clock/get time-zone-name ] . ")" . \
|
||||
[ $IfThenElse ($Interval > 1d) (" deferred by " . $Interval) ] . ".");
|
||||
:return true;
|
||||
}
|
||||
|
||||
|
@ -153,7 +159,7 @@
|
|||
:error true;
|
||||
}
|
||||
} else={
|
||||
:if ($PackagesUpdateDeferReboot = true) do={
|
||||
:if ($PackagesUpdateDeferReboot = true || [ :totime $PackagesUpdateDeferReboot ] >= 1d) do={
|
||||
$Schedule $ScriptName;
|
||||
:set ExitOK true;
|
||||
:error true;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
:global CertificateAvailable;
|
||||
:global EitherOr;
|
||||
:global EscapeForRegEx;
|
||||
:global FileExists;
|
||||
:global GetRandom20CharAlNum;
|
||||
:global IfThenElse;
|
||||
:global LogPrint;
|
||||
|
@ -100,7 +101,7 @@
|
|||
$LogPrintVerbose debug $ScriptName ("Update " . $UpdateID . ": " . [ :serialize to=json $Update ]);
|
||||
|
||||
:local Message ($Update->"message");
|
||||
:local IsReply ([ :typeof ($Message->"reply_to_message") ] = "string");
|
||||
:local IsAnyReply ([ :typeof ($Message->"reply_to_message") ] = "array");
|
||||
: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;
|
||||
|
@ -138,7 +139,7 @@
|
|||
" from update " . $UpdateID . "!");
|
||||
:set Done true;
|
||||
}
|
||||
:if ($Done = false && ($IsMyReply = 1 || ($IsReply = false && \
|
||||
:if ($Done = false && ($IsMyReply = 1 || ($IsAnyReply = false && \
|
||||
$TelegramChatActive = true)) && [ :len $Command ] > 0) do={
|
||||
:if ([ $ValidateSyntax $Command ] = true) do={
|
||||
:local State "";
|
||||
|
@ -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");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue