From b8e068d63bf8af6eec1a0f330cbc0503ffa39a6b Mon Sep 17 00:00:00 2001 From: vados-dev Date: Mon, 2 Mar 2026 23:20:10 +0300 Subject: [PATCH] Backup for MikroMaster sucessfully creatd at Mar 02 23:20:10. --- .../20260302/20260302232004-Binary.backup | Bin 0 -> 289700 bytes .../20260302/20260302232004-Config.rsc | 3971 +++++++++++++++++ .../20260302/20260302232004-Diff-Config.rsc | 4 + 3 files changed, 3975 insertions(+) create mode 100644 MikroMaster/20260302/20260302232004-Binary.backup create mode 100644 MikroMaster/20260302/20260302232004-Config.rsc create mode 100644 MikroMaster/history/20260302/20260302232004-Diff-Config.rsc diff --git a/MikroMaster/20260302/20260302232004-Binary.backup b/MikroMaster/20260302/20260302232004-Binary.backup new file mode 100644 index 0000000000000000000000000000000000000000..811742c99fd1dce01c8ccad0e793fa5deb0fd40a GIT binary patch literal 289700 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 50) do={\r\ + \n # after 50 * 0.1s delays, it's been 5 seconds, which should \ + be long enough\r\ + \n :set errorMsg \"New folder could not be created at \$newFold\ + er\";\r\ + \n :log error \"mkdir: \$errorMsg\"\r\ + \n :error \$errorMsg\r\ + \n }\r\ + \n :delay 0.1s;\r\ + \n :set count (\$count + 1);\r\ + \n }\r\ + \n\r\ + \n :return \$newFolder;\r\ + \n}\r\ + \n\r\ + \n:log info \"Created function \\\$mkdir\"\r\ + \n" +add comment="Certificates CloudFlare, Quad9 " dont-require-permissions=no \ + name=Update-Certificates owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + \_CloudFlare\r\ + \n/tool/fetch mode=https url=https://cacerts.digicert.com/DigiCertGlobalRo\ + otCA.crt.pem;\r\ + \n/certificate/import file-name=DigiCertGlobalRootCA.crt.pem passphrase=\"\ + \";\r\ + \n/tool/ fetch mode=https url=https://cacerts.digicert.com/DigiCertGlobalG\ + 2TLSRSASHA2562020CA1-1.crt.pem;\r\ + \n/certificate/import file-name=DigiCertGlobalG2TLSRSASHA2562020CA1-1.crt.\ + pem passphrase=\"\";\r\ + \n# Quad9\r\ + \n/tool/fetch mode=https url=\"https://cacerts.digicert.com/DigiCertGlobal\ + G3TLSECCSHA3842020CA1-1.crt.pem\"\r\ + \n/certificate/import file-name=DigiCertGlobalG3TLSECCSHA3842020CA1-1.crt.\ + pem passphrase=\"\";\r\ + \n\r\ + \n#:global AmScriptsUrl;\r\ + \n#google\r\ + \n#:local CertName \"GTS-Root-R1.pem\";\r\ + \n#/tool/fetch mode=https url=(\$AmScriptsUrl . \"certs/\" . \$CertName);\ + \r\ + \n#/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n#:set CertName \"GTS-Root-R4.pem\";\r\ + \n#/tool/fetch mode=https url=(\$AmScriptsUrl . \"certs/\" . \$CertName);\ + \r\ + \n#/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n#:set CertName \"GTS-Root-RX.pem\";\r\ + \n#/tool/fetch mode=https url=(\$AmScriptsUrl . \"certs/\" . \$CertName);\ + \r\ + \n#/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n#internet\r\ + \n#:set CertName \"ISRG-Root-X1.pem\";\r\ + \n#/tool/fetch mode=https url=(\$AmScriptsUrl . \"certs/\" . \$CertName);\ + \r\ + \n#/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n#:set CertName \"ISRG-Root-X2.pem\";\r\ + \n#/tool/fetch mode=https url=(\$AmScriptsUrl . \"certs/\" . \$CertName);\ + \r\ + \n#/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n#:set CertName \"Starfield-Root-Certificate-Authority-G2.pem\";\r\ + \n#/tool/fetch mode=https url=(\$AmScriptsUrl . \"certs/\" . \$CertName);\ + \r\ + \n#/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n\r\ + \n#/ip/dns/set allow-remote-requests=yes doh-max-concurrent-queries=100 do\ + h-max-server-connections=20 use-doh-server=https://security.cloudflare-dns\ + .com/dns-query verify-doh-cert=yes;\r\ + \n#/ip/dns/static remove [find where address=1.1.1.1];\r\ + \n#/ip/dns/static add address=1.1.1.1 name=security.cloudflare-dns.com com\ + ment=\"cloudflare-dns IPv4 1\";\r\ + \n#/ip/dns/ static remove [find where address=1.0.0.1];\r\ + \n#/ip/dns/static add address=1.0.0.1 name=security.cloudflare-dns.com com\ + ment=\"cloudflare-dns IPv4 2\"\r\ + \n#/ip dns static add address=2606:4700:4700::1111 name=security.cloudflar\ + e-dns.com type=AAAA\r\ + \n#/ip dns static add address=2606:4700:4700::1001 name=security.cloudflar\ + e-dns.com type=AAAA\r\ + \n#/ip/dns set servers=\"1.0.0.1, 8.8.4.4\";\r\ + \n#/ip/dns set servers=\"\";" +add dont-require-permissions=no name=script1 owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="/\ + tool/netwatch/add comment=\"doh-fallback, doh-url=https://security.cloudfl\ + are-dns.com/dns-query, doh-cert=DigiCert Global Root CA, notify, name=Clou\ + dFlare-doh IPv4 1\" host=1.1.1.1;\r\ + \n/tool/netwatch/add comment=\"doh, doh-url=https://security.cloudflare-dn\ + s.com/dns-query, doh-cert=DigiCert Global Root CA, notify, name=CloudFlare\ + -doh IPv4 2\" host=1.0.0.1;\r\ + \n/tool/netwatch/add comment=\"doh-fallback, dns-fallback, doh-url=https:/\ + /dns.google/dns-query, doh-cert=DigiCert Global Root G2, notify, name=Goog\ + le-doh IPv4 1\" host=8.8.8.8;\r\ + \n/tool/netwatch/add comment=\"doh-fallback, dns-fallback, doh-url=https:/\ + /dns.google/dns-query, doh-cert=DigiCert Global Root G2, notify, name=Goog\ + le-doh IPv4 2\" host=8.8.4.4;\r\ + \n/tool/netwatch/add comment=\"doh-fallback, dns-fallback, doh-url=https:/\ + /dns.quad9.net/dns-query, doh-cert=DigiCert Global Root G3, notify, name=C\ + uad9-doh IPv4 1\" host=9.9.9.9;\r\ + \n/tool/netwatch/add comment=\"doh-fallback, dns-fallback, doh-url=https:/\ + /dns.quad9.net/dns-query, doh-cert=DigiCert Global Root G3, notify, name=C\ + uad9-doh IPv4 2\" host=149.112.112.112;\r\ + \n\r\ + \n/tool/netwatch/add comment=\"dns, notify, name=ns1.unet.ws\" host=91.192\ + .189.2;" +add dont-require-permissions=no name=script2 owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + \r\ + \n\r\ + \n:global InspectVar;\r\ + \n#:global RouterBoard;\r\ + \n#:do {:set RouterBoard [[ :parse \"/system/routerboard/get\" ]]} on-erro\ + r={}\r\ + \n#:global Resources;\r\ + \n#:do {:set Resources [[ :parse \"/system/resource/get\" ]]} on-error={}\ + \r\ + \n\r\ + \n#:global Updates;\r\ + \n#:do {:set Updates [[ :parse \"/system/package/update/get\" ]]} on-error\ + ={}\r\ + \n\r\ + \n#:global PkgUpdStatus \"undefined\";\r\ + \n#:local Update [/system/package/update/get];\r\ + \n#:retry command={:set PkgUpdStatus (\$Update->\"status\")} delay=200ms m\ + ax=5 on-error={};\r\ + \n\r\ + \n#:log warning [\$InspectVar \$RouterBoard];\r\ + \n#:put [\$InspectVar \$RouterBoard];\r\ + \n\r\ + \n#:retry command={/system/package/update check-for-updates without-paging\ + \_as-value} delay=300ms max=5 on-error={};\r\ + \n\r\ + \n#:global arrDeviceInfo ({});\r\ + \n#:local arrDeviceInfo ({\"section\":{\"key\":\"\"; \"value\":\"\";};});\ + \r\ + \n#:set (\$arrDeviceInfo->\"RouterBoard\") [[ :parse \"/system/routerboard\ + /get\" ]];\r\ + \n#:retry command={:set (\$arrDeviceInfo->\"Updates\") [[ :parse \"/system\ + /package/update/get\" ]]} delay=500ms max=5 on-error={:log error (\"Error\ + \")};\r\ + \n# [:toarray {\"section\"={\"key\"=\"\"; \"value\"=\"\";} }];\r\ + \n# [:toarray \"\"];\r\ + \n:local arrDeviceInfo ({});\r\ + \n\r\ + \n:set (\$arrDeviceInfo->\"devUpdates\") {\"channel\"; \"stable\";};\r\ + \n#:do {:set (arrDeviceInfo->\"Updates\") [[ :parse \"/system/package/upda\ + te/get\" ]]} on-error={:log error (\$error)}\r\ + \n\$InspectVar \$arrDeviceInfo;\r\ + \n" +add dont-require-permissions=no name=AM-setup owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + \_RouterOS Setup Script: AM-setup\r\ + \n# \r\ + \n# Copyright (c) 2005-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# requires RouterOS, version=7.19\r\ + \n# requires device-mode, fetch\r\ + \n\r\ + \n## Additional commands:\r\ + \n#\r\ + \n# For scripts:\r\ + \n#:if ([ :len [ /system/script/find where name=\$ScriptName ]] = 0 ) do={\ + \r\ + \n# :local ScriptName [ :jobname ];\r\ + \n# :global GlobalScriptsUrl \"https://ros.vados.ru/\";\r\ + \n# /system/script/add name=\$ScriptName owner=\$ScriptName source=([ /too\ + l/fetch check-certificate=yes-without-crl (\$GlobalScriptsUrl . \$ScriptNa\ + me . \".rsc\") output=user as-value ]->\"data\");\r\ + \n#}\r\ + \n# For run from terminal:\r\ + \n# /system/script/add name=AM-setup owner=AM-Setup source=([ /tool/fetch \ + check-certificate=yes-without-crl \"https://ros.vados.ru/AM-setup.rsc\" ou\ + tput=user as-value ]->\"data\");\r\ + \n#\r\ + \n# /system/script/set source=[ :tocrlf [ get \$ScriptName source ] ] \$Sc\ + riptName;\r\ + \n:local ScriptName [ :jobname ];\r\ + \n\r\ + \n:local RemoveThisScript false;\r\ + \n\r\ + \n:global GlobalScriptsUrl \"https://ros.vados.ru/\";\r\ + \n\r\ + \n{\r\ + \n :local ScriptName;\r\ + \n :local RemoveThisScript;\r\ + \n :global GlobalScriptsUrl;\r\ + \n :local AllDone;\r\ + \n :local CertCommonName \"Root YE\";\r\ + \n :local CertFileName \"Root-YE.pem\";\r\ + \n :local CertFingerprint \"e14ffcad5b0025731006caa43a121a22d8e9700f4fb9c\ + f852f02a708aa5d5666\";\r\ + \n\r\ + \n :local CertSettings [ /certificate/settings/get ];\r\ + \n :if (!(((\$CertSettings->\"builtin-trust-anchors\") = \"trusted\" || \ + \\\r\ + \n (\$CertSettings->\"builtin-trust-store\") ~ \"fetch\" || \\\r\ + \n (\$CertSettings->\"builtin-trust-store\") = \"all\") && \\\r\ + \n [ :len [ /certificate/builtin/find where common-name=\$CertComm\ + onName ] ] > 0)) do={\r\ + \n :put \"Importing certificate...\";\r\ + \n:log warning (\"\\n\\\$GlobalScriptsUrl = \" . \$GlobalScriptsUrl);\r\ + \n /tool/fetch (\$GlobalScriptsUrl . \"certs/\" . \$CertFileName) dst-p\ + ath=\$CertFileName as-value;\r\ + \n :delay 1s;\r\ + \n /certificate/import file-name=\$CertFileName passphrase=\"\";\r\ + \n :if ([ :len [ /certificate/find where fingerprint=\$CertFingerprint \ + ] ] != 1) do={\r\ + \n :error \"Something is wrong with your certificates!\";\r\ + \n };\r\ + \n :delay 1s;\r\ + \n };\r\ + \n :put \"Renaming AM-GlobalConfig, if exists...\";\r\ + \n :local ConfOldName (\"AM-GlobalConfig-\" . [ /system/clock/get date ] \ + . [ /system/clock/get time ] . \".rsc\");\r\ + \n /system/script/set name=\$ConfOldName [ find where name=\"AM-GlobalCon\ + fig\" ];\r\ + \n :foreach Script in={ \"AM-GlobalConfig\"; \"AM-GlobalFunc\" } do={\r\ + \n :put \"Installing \$Script...\";\r\ + \n /system/script/remove [ find where name=\$Script ];\r\ + \n /system/script/add name=\$Script owner=\$Script source=([ /tool/fetc\ + h check-certificate=yes-without-crl url=(\$GlobalScriptsUrl . \$Script . \ + \".rsc\") output=user as-value ]->\"data\");\r\ + \n };\r\ + \n\r\ + \n :if ([ :len [ /certificate/find where fingerprint=\$CertFingerprint ] \ + ] > 0) do={\r\ + \n :put \"Renaming certificate by its common-name...\";\r\ + \n :global CertificateNameByCN;\r\ + \n \$CertificateNameByCN \$CertFingerprint;\r\ + \n };\r\ + \n\r\ + \n :put \"Add Schedulers...\";\r\ + \n :delay 1;\r\ + \n :put \"Add Global scheduler...\";\r\ + \n :local OnEvent \"/system/script { run AM-GlobalConfig; run AM-GlobalFu\ + nc; }\";\r\ + \n :local Comment \"Setup Global Environment for scripts\";\r\ + \n :if ([ :len [ /system/scheduler/find where name=\"AM-SetGlobalEnv\" ] \ + ] = 0) do={\r\ + \n /system/scheduler/add name=\"AM-SetGlobalEnv\" comment=\$Comment on-\ + event=\$OnEvent start-time=startup;\r\ + \n }\r\ + \n :if ([ /system/scheduler/get \"AM-SetGlobalEnv\" comment ] != \$Commen\ + t) do={\r\ + \n /system/scheduler/set \"AM-SetGlobalEnv\" comment=\$Comment;\r\ + \n }\r\ + \n :if ([ /system/scheduler/get \"AM-SetGlobalEnv\" on-event ] != \$OnEve\ + nt) do={\r\ + \n /system/scheduler/set \"AM-SetGlobalEnv\" on-event=\$OnEvent;\r\ + \n }\r\ + \n :delay 1;\r\ + \n :put \"Add Update Script scheduler\";\r\ + \n :set OnEvent \":global ScriptInstallUpdate; \\\$ScriptInstallUpdate;\"\ + ;\r\ + \n :set Comment \"Every Day Check For Update Scripts\";\r\ + \n :if ([ :len [ /system/scheduler/find where name=\"AM-ScriptInstallUpda\ + te\" ] ] = 0) do={\r\ + \n /system/scheduler/add name=\"AM-ScriptInstallUpdate\" comment=\$Commen\ + t start-time=startup interval=1d on-event=\$OnEvent;\r\ + \n }\r\ + \n\r\ + \n :delay 1;\r\ + \n :put \"Loading configuration and functions...\";\r\ + \n :do { \r\ + \n /system/script { run AM-GlobalConfig; run AM-GlobalFunc; };\r\ + \n :global ScriptInstallUpdate; \$ScriptInstallUpdate;\r\ + \n :set AllDone true;\r\ + \n } on-error={\r\ + \n :set AllDone false;\r\ + \n :local ErrorMsg \"Loading configuration and functions error!\";\r\ + \n :log error (\$ScriptName . \$ErrorMsg . :error);\r\ + \n :error \$ErrorMsg;\r\ + \n }\r\ + \n\r\ + \n :delay 5s;\r\ + \n :if (\$AllDone = true && \$RemoveThisScript = true) do={\r\ + \n :put \"Add Scheduler for remove this script...\";\r\ + \n :set OnEvent \":delay 30s; /system/script/remove [ find where name=\$S\ + criptName ]; :delay5s; /system/scheduler/remove [ find where name=\\\"_Rem\ + oveSetup\\\" ];\";\r\ + \n :set Comment \"_RemoveSetup tmp scheduler for remove setup script.\";\ + \r\ + \n /system/scheduler/add name=\"_RemoveSetup\" comment=\$Comment start-ti\ + me=startup interval=30s on-event=\$OnEvent;\r\ + \n :log warning (\$ScriptName . \"\\nI've done everything, and now I'm ti\ + red... I'm leaving. ))\\nThere will be an error below, this is normal.\");\ + \r\ + \n }\r\ + \n};\r\ + \n" +add dont-require-permissions=no name=fetchCustom owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="\ + \r\ + \n#root.mnuc.backuper\r\ + \n:global GlobalScriptsUrl \"https://ros.vados.ru/\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \".bak/mikro_bak_rsa@10\ + .30.30.81.pub\") dst-path=\"/mikro_bak_rsa@10.30.30.81.pub\";\r\ + \n#/usb1/mikro_bak_rsa.pub" +add comment="Global Config Script" dont-require-permissions=no name=\ + AM-GlobalConfig owner=AM-GlobalConfig policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + !rsc by Vados\r\ + \n# RouterOS script: AM-GlobalConfig\r\ + \n# Script comment: Global Config Script\r\ + \n# Copyright (c) 2007-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# Warning: Dont touch this line!\r\ + \n:global GlobalConfReady false;\r\ + \n# \\/ start edit\r\ + \n#\r\ + \n# Global Url For Amster scripts to fetch\r\ + \n# most be defined in Amster-Init-Script\r\ + \n:global GlobalScriptsUrl \"https://ros.vados.ru/\";\r\ + \n:global ScriptsUrlSuffix \"\";\r\ + \n:global CheckSumsVerify true;\r\ + \n\r\ + \n:global ScriptUpdatesCRLF true;\r\ + \n:global CommentsInScripts true;\r\ + \n\r\ + \n# Debug output:\r\ + \n:global PrintDebug true; #false;\r\ + \n\r\ + \n# Debug output for specific script:\r\ + \n:set (\$PrintDebugOverride->\"AM-GlobalFunc\") true;\r\ + \n\r\ + \n# Debug logs\r\ + \n# Other actions (disk, email, remote or support) can be used as well.\r\ + \n# I do not recommend using echo - use debug output instead (https://rsc.\ + eworm.de/main/DEBUG.html#debug-output).\r\ + \n#/system/logging/add topics=script,debug action=memory;\r\ + \n\r\ + \n:global MikrotikUpgradeUrl \"https://upgrade.mikrotik.com/routeros\";\r\ + \n:global Domain \"WORKGROUP\";\r\ + \n\r\ + \n:global EmailGeneralTo \"vados@vados.ru\"; #:global EmailGeneralCc \"\";\ + \r\ + \n\r\ + \n# \$ScriptInstallUpdate mod/notification-telegram\r\ + \n:global TelegramTokenId \"8390868324:AAG3_d1hfVR2M6pGAgDK6ZvhOe4J97nyopw\ + \";\r\ + \n:global TelegramChatId \"-1003631309063\"; #\"454403445\";\r\ + \n# Use this to send notifications to a specific topic in group.\r\ + \n#:global TelegramThreadId \"30\";\r\ + \n# Using telegram-chat you have to define trusted chat ids (not group ids\ + !)\r\ + \n# or user names. Groups allow to chat with devices simultaneously.\r\ + \n:global TelegramChatIdsTrusted {\r\ + \n \"454403445\"\r\ + \n \"-1003631309063\"\r\ + \n \"-5124482807\"\r\ + \n \"1087968824\";\r\ + \n};\r\ + \n# \"-5294757340\";\r\ + \n\r\ + \n:global TelegramChatGroups \"(all)\";\r\ + \n#:global TelegramChatGroups \"(all|home|office)\";\r\ + \n\r\ + \n:global NotificationFunctions {\r\ + \n \"email\"\r\ + \n \"telegram\";\r\ + \n};\r\ + \n# Toggle this to disable symbols in notifications.\r\ + \n:global NotificationsWithSymbols true;\r\ + \n:global TerminalColorOutput true;\r\ + \n\r\ + \n:global DetectIpAddrDefault \"https://ipv4.mikrotik.ovh/\";\r\ + \n:global DetectIpAddrFallback \"https://api.ipify.org/\";\r\ + \n\r\ + \n## Update channel. Possible values: stable, long-term, testing, developm\ + ent\r\ + \n:global updateChannel \"stable\";\r\ + \n\r\ + \n# Script BackupAndUpdate mode, possible values: backup,\r\ + \n# updateOnce - Update once as \"osnotify\" and back \"osnotify\" mode (i\ + n terminal run :set OSUpdateMode updateOnce; \$OSUpdateMode;). \r\ + \n# osupdate - Update if available and creates backups before/after update\ + \_(ignores `forceBackup`)\r\ + \n# Set `forceBackup` to true to always create backups, even\ + \_without updates\r\ + \n# osnotify - Set `forceBackup` to always create backups on every run\r\ + \n:global DevInfoIncludeIP true;\r\ + \n:global BackupAndUpdateMode \"osnotify\"\r\ + \n\r\ + \n:global forceBackup true;\r\ + \n:global BackupPassword \"Peskar55\";\r\ + \n\r\ + \n# SFTP Backup Variables\r\ + \n:global BackupRandomDelay 0;\r\ + \n:global BackupUploadUrl \"sftp://amster.vados.ru/upload/\";\r\ + \n:global BackupUploadUser \$Identity;\r\ + \n:global BackupUploadPass \"root.mnuc.backuper\";\r\ + \n\r\ + \n:global BackupSendBinary true;\r\ + \n:global BackupSendExport true;\r\ + \n:global BackupSendGlobalConfig true;\r\ + \n:global BackupSendScripts true;\r\ + \n\r\ + \n# Remove local file after uploading if no errors\r\ + \n:global BackupRmLocal true;\r\ + \n\r\ + \n# Local Backups Root Directory \r\ + \n:global BackupLocalRoot \"tmpfs\";\r\ + \n\r\ + \n# Encrypt Backup\r\ + \n:global BackupEncrypt true;\r\ + \n\r\ + \n# Sensitive information in Backups\r\ + \n:global BackupSens true;\r\ + \n\r\ + \n# User Export\r\ + \n:global BackupUser true;\r\ + \n\r\ + \n# License Export (not for CHR, will silently skip)\r\ + \n:global BackupLicense false;\r\ + \n\r\ + \n# SSH Keys\r\ + \n:global BackupSshKeys true;\r\ + \n\r\ + \n# Certificate Export\r\ + \n:global BackupCerts true;\r\ + \n\r\ + \n# Certificate Password\r\ + \n:global BackupCertsPasswd \"\";\r\ + \n\r\ + \n# User-Manager Export\r\ + \n:global BackupUserMan false;\r\ + \n\r\ + \n# The Dude Export\r\ + \n:global BackupDude false;\r\ + \n\r\ + \n# User Files to export, comma-separated string or array of strings\r\ + \n# User Files are not removed on backup\r\ + \n# Any directory paths will be removed (/ -> _) on remote file\r\ + \n# Nonpresent files are silently skipped\r\ + \n:global BackupUserList \"autosupout.rif,autosupout.old.rif\";\r\ + \n\r\ + \n# load functions and any custom scripts\r\ + \n# [ /system/script/find where name=\"global-config-ov\ + erlay\" ], \\\r\ + \n# [ /system/script/find where name~\"^global-config-o\ + verlay\\\\.d/.\" ]\r\ + \n#\r\ + \n#:foreach Script in=([ /system/script/find where name=\"Amster-TGglobalV\ + ars\" ], [ /system/script/find where name=\"Amster-TGglobalFunc\" ]) do={\ + \r\ + \n# :onerror Err {\r\ + \n# /system/script/run \$Script;\r\ + \n# } do={\r\ + \n# :log error (\"Loading configuration from configs and functions\"\ + \_. [ /system/script/get \$Script name ] . \" failed: \" . \$Err);\r\ + \n# }\r\ + \n#}\r\ + \n#:log info \"\\ndevMode = \$devMode\";\r\ + \n#:log info \"\\ndevRunning = \$devRunning\";\r\ + \n:foreach Script in=[ /system/script/find where source~\"^#!rsc by Vados \ + GlobalRUN\\r\?\\n\" ] do={\r\ + \n :onerror Err {\r\ + \n /system/script/run \$Script;\r\ + \n } do={\r\ + \n :log error (\"Run script \" . [ /system/script/get \$Script name \ + ] . \" width marker \\\" GlobalRUN\\\" failed: \" . \$Err);\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n# signal we are ready\r\ + \n:set GlobalConfReady true;\r\ + \n:while (\$GlobalConfReady != true) do={:delay 500ms};\r\ + \n" +add comment="Global functions" dont-require-permissions=no name=AM-GlobalFunc \ + owner=AM-GlobalFunc policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + !rsc by Vados\r\ + \n# RouterOS script: AM-GglobalFunc\r\ + \n# Script comment: Global functions\r\ + \n#\r\ + \n#\r\ + \n# requires RouterOS, version=7.21\r\ + \n# requires device-mode, fetch, scheduler\r\ + \n:local ExitOK false;\r\ + \n:local ScriptName [ :jobname ];\r\ + \n#:global checkRunJob \$SriptName;\r\ + \n#:global fixCRLF;\r\ + \n#:if (\$fixCRLF != false) do={\r\ + \n#:foreach fixScript in=([ /system/script/find where name~\"*\" ]) do={/s\ + ystem/script/set source=[ :tocrlf [ get \$fixScript source ] ] \$fixScript\ + }\r\ + \n#:if (\$fixCRLF != \"LF\") do={ /system/script/set source=[ :tocrlf [ g\ + et \$fixScript source ] ] \$fixScript};};\r\ + \n#}\r\ + \n:global GlobalFuncReady false;\r\ + \n\r\ + \n# The variables are received right here.\r\ + \n:global GlobalConfVersion 138;\r\ + \n\r\ + \n:global Identity [/system/identity/get name];\r\ + \n:global IdentityShort [:pick \$Identity 0 18];\r\ + \n\r\ + \n:global devBoardName [/system/resource/get board-name];\r\ + \n:global devMode [/system/device-mode/get mode];\r\ + \n:global devCurArch [/system/resource/get architecture-name];\r\ + \n:global devCurVersion [/system/resource/get version];\r\ + \n\r\ + \n# Variables defined in AM-GlobalConfig.rsc\r\ + \n:global TerminalColorOutput;\r\ + \n:global CommentsInScripts;\r\ + \n:global DetectIpAddrDefault;\r\ + \n:global DetectIpAddrFallback;\r\ + \n:global updateChannel;\r\ + \n:global Domain;\r\ + \n:global EmailGeneralTo;\r\ + \n:global BackupAndUpdateMode;\r\ + \n\r\ + \n# Single functions, without nested functions.\r\ + \n:global GlobalEnvRemove;\r\ + \n:global MiniDateTimeStamp;\r\ + \n\r\ + \n# Include globals \$PrintDebug and \$PrintDebugOverride\r\ + \n:global LogPrint;\r\ + \n\r\ + \n# DeviceInfo and Updates\r\ + \n:global IsCheckUpdates;\r\ + \n:global WaitCheckUpdates;\r\ + \n:global GetPubIp;\r\ + \n\r\ + \n:global GetArrDeviceInfo;\r\ + \n:global WaitArrDeviceInfo;\r\ + \n\r\ + \n:global devModel;\r\ + \n:global devRunningMode;\r\ + \n\r\ + \n:global devRbRevision;\r\ + \n:global devRbSerialNumber;\r\ + \n:global devRbVerAvail;\r\ + \n\r\ + \n:global runningChannelVersion;\r\ + \n:global runningChannel;\r\ + \n:global runningVersion;\r\ + \n\r\ + \n:global devBuildTime;\r\ + \n#:global ROsVerAvail;\r\ + \n:global PkgUpdStatus;\r\ + \n:global currentUpdateChannel;\r\ + \n\r\ + \n:global ScriptInstallUpdate;\r\ + \n\r\ + \n:global DeviceInfo;\r\ + \n\r\ + \n:global OldMode;\r\ + \n\r\ + \n:global ParseKeyValueStore;\r\ + \n:global RandomDelay;\r\ + \n:global GetRandomNumber;\r\ + \n:global EscapeForRegEx;\r\ + \n:global ExitError;\r\ + \n:global CleanFilePath;\r\ + \n:global CleanName;\r\ + \n:global CharacterReplace;\r\ + \n:global CharacterMultiply;\r\ + \n:global EitherOr;\r\ + \n:global FormatLine;\r\ + \n:global GetRandom20CharAlNum;\r\ + \n:global Grep;\r\ + \n:global IfThenElse;\r\ + \n:global MAX;\r\ + \n:global MIN;\r\ + \n:global HumanReadableNum;\r\ + \n\r\ + \n:global IsFullyConnected;\r\ + \n:global IsDNSResolving;\r\ + \n:global IsTimeSync;\r\ + \n:global IsTimeSyncCached;\r\ + \n:global IsTimeSyncResetNtp;\r\ + \n\r\ + \n:global WaitDNSResolving;\r\ + \n:global WaitFullyConnected;\r\ + \n:global WaitTimeSync;\r\ + \n:global MkDir;\r\ + \n:global RmDir;\r\ + \n:global RmFile;\r\ + \n:global FileGet;\r\ + \n:global Unix2Dos;\r\ + \n:global UrlEncode;\r\ + \n:global WaitForFile;\r\ + \n:global ScriptLock;\r\ + \n:global SendTelegram;\r\ + \n:global NotificationFunctions;\r\ + \n:global SendNotification;\r\ + \n:global SendNotification2;\r\ + \n:global SymbolForNotification;\r\ + \n:global SymbolByUnicodeName;\r\ + \n:global ValidateSyntax;\r\ + \n:global CheckSumsVerify;\r\ + \n:global GlobalConfChanges;\r\ + \n:global GlobalConfMigration;\r\ + \n:global VersionToNum;\r\ + \n:global RequiredRouterOS;\r\ + \n:global FetchLargeFiles;\r\ + \n:global FetchUserAgentStr;\r\ + \n:global CertificateAvailable;\r\ + \n:global CertificateDownload;\r\ + \n:global CertificateNameByCN;\r\ + \n:global CharacterMultiply;\r\ + \n\r\ + \n:global InspectVar;\r\ + \n:global InspectVarRet;\r\ + \n:global ParseCustom;\r\ + \n\r\ + \n:set IsCheckUpdates do={\r\ + \n :local isInfo [:tobool \$1];\r\ + \n :global LogPrint;\r\ + \n :global updateChannel;\r\ + \n :global PkgUpdStatus;\r\ + \n \$LogPrint debug \$0 (\"\\\$isInfo = \" . \$isInfo); \r\ + \n :local CurrentChannel [ /system/package/update/get channel ];\r\ + \n :if (\$CurrentChannel != \$updateChannel) do={\r\ + \n :retry command={/system/package/update set channel=\$updateChannel} \ + \_delay=300ms max=5 on-error={};\r\ + \n \$LogPrint debug \$0 (\"Set updates channel to: \$updateChannel\");\ + \r\ + \n }\r\ + \n \r\ + \n :local Update [ /system/package/update/get ];\r\ + \n :local Channel (\$Update->\"channel\");\r\ + \n \$LogPrint debug \$0 (\"Update Channel: \" . \$Channel . \".\");\r\ + \n \r\ + \n :local StatusPkg \"undefined\";\r\ + \n \$LogPrint debug \$0 (\"Checking for updates...\");\r\ + \n :retry command={:set \$StatusPkg ([/system/package/update/check-for-up\ + dates without-paging as-value]->\"status\")} \\\r\ + \n delay=300ms max=5 on-error={};\r\ + \n \$LogPrint debug \$0 (\"\\\$StatusPkg = \" . \$StatusPkg);\r\ + \n :if (\$StatusPkg = \"New version is available\") do={ :set PkgUpdStatu\ + s true; } else={ :set PkgUpdStatus false; }\r\ + \n \$LogPrint debug \$0 (\"\\\$PkgUpdStatus = \" . \$PkgUpdStatus);\r\ + \n :if (\$isInfo != false || \$PkgUpdStatus = true) do={\r\ + \n \$LogPrint debug \$0 (\"\\\$PkgUpdStatus = \" . \$PkgUpdStatus);\r\ + \n :if ([:len \$arrDeviceInfo] = 0) do={\r\ + \n :global arrDeviceInfo ({});\r\ + \n :local arrDeviceInfo ({\"section\":{\"key\":\"\"; \"value\":\"\";};}\ + );\r\ + \n }\r\ + \n # else={:local arrDeviceInfo ({})}\r\ + \n :retry command={:set (\$arrDeviceInfo->\"devUpdates\") [[ :parse \"/\ + system/package/update/get\" ]]} delay=500ms max=5 on-error={:log error (\"\ + Error\")};\r\ + \n #:set (\$arrDeviceInfo->\"devUpdates\") {\"devCurrentChannel\"; \$Cu\ + rrentChannel;};\r\ + \n #:set (\$arrDeviceInfo->\"devUpdates\") {\"devCurrentVersion\"; (\$U\ + pdate->\"installed-version\");};\r\ + \n #:set (\$arrDeviceInfo->\"devUpdates\") {\"devCurrentChannelVersion\ + \"; [/system/resource/get version];};\r\ + \n #:set (\$arrDeviceInfo->\"devUpdates\") {\"devUpdateChannel\"; [\$up\ + dateChannel];};\r\ + \n #:set (\$arrDeviceInfo->\"devUpdates\") {\"devUpdateVersion\"; (\$Up\ + date->\"latest-version\");};\r\ + \n } else={\r\ + \n :return \$PkgUpdStatus;\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set WaitArrDeviceInfo do={\r\ + \n :global GetArrDeviceInfo;\r\ + \n :while ([ \$GetArrDeviceInfo ] = false) do={\r\ + \n :delay 1s;\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set GetArrDeviceInfo do={\r\ + \n :global LogPrint;\r\ + \n\r\ + \n :global devBoardName;\r\ + \n :global devModel;\r\ + \n \r\ + \n :global arrDeviceInfo [:toarray {\"section\"={\"key\"=\"\"; \"value\"\ + =\"\";} }];\r\ + \n #:do {:set (\$arrDeviceInfo->\"Updates\") [[ :parse \"/system/package\ + /update/get\" ]]} on-error={}\r\ + \n :global devRbRevision;\r\ + \n :global devRbSerialNumber;\r\ + \n :global devRbCurrentFw;\r\ + \n :global devRbUpgradeFw;\r\ + \n \r\ + \n :global devRunning;\r\ + \n :global devCurArch;\r\ + \n :global ROsVerCurrent;\r\ + \n :global ROsChannelCurrent;\r\ + \n :global ROsVerAvail;\r\ + \n\r\ + \n :global ParseCustom;\r\ + \n :global runningChannelVersion;\r\ + \n :global runningChannel;\r\ + \n :global runningVersion;\r\ + \n :global devBuildTime;\r\ + \n :global GetPubIp;\r\ + \n \r\ + \n :local License [/system/license/get];\r\ + \n :local Resource [/system/resource/get];\r\ + \n :set devBuildTime (\$Resource->\"build-time\");\r\ + \n :set runningChannelVersion (\$Resource->\"version\");\r\ + \n :set runningChannel [\$ParseCustom \$runningChannelVersion \"(\" \")\ + \" 1];\r\ + \n :set runningVersion [\$ParseCustom \$runningChannelVersion \" \"];\r\ + \n \r\ + \n :do {\r\ + \n :if ([:pick \$devBoardName 0 3] != \"CHR\" or [:pick \$devBoardName 0\ + \_3] != \"x86\") do={\r\ + \n :local RouterBoard;\r\ + \n :do {:set RouterBoard [[ :parse \"/system/routerboard/get\" ]]} on\ + -error={}\r\ + \n :set devModel (\$RouterBoard->\"model\");\r\ + \n :set devRbRevision (\$RouterBoard->\"revision\");\r\ + \n :set devRbSerialNumber (\$RouterBoard->\"serial-number\");\r\ + \n #:set devRbCurrentFw (\$RouterBoard->\"current-firmware\");\r\ + \n #:set devRbUpgradeFw (\$RouterBoard->\"upgrade-firmware\");\r\ + \n :if (\$devCurArch = \"mipsbe\" || \$devCurArch = \"arm\") do={\r\ + \n :global devRunning [ /system/device-mode/get mode ];\r\ + \n } else={\r\ + \n :global devRunning [/system/device-mode/get running];}\r\ + \n } else={\r\ + \n :set devModel \$devBoardName;\r\ + \n \r\ + \n :set devRbRevision false;\r\ + \n :set devRbSerialNumber false;\r\ + \n# :set devRbCurrentFw false;\r\ + \n# :set devRbUpgradeFw false;\r\ + \n #:set devCurrentFw \$runningVersion;#:set devUpgradeFw \$ROsVerAvail\ + ;\r\ + \n :set devRunning [/system/device-mode/get running];\r\ + \n }\r\ + \n } on-error={\r\ + \n \$LogPrint error \$0 (\"Error in Function getDevice!\");\r\ + \n :return false;\r\ + \n }\r\ + \n:return true;\r\ + \n}\r\ + \n\r\ + \n:set DeviceInfo do={\r\ + \n :global WaitArrDeviceInfo;\r\ + \n # \$WaitDeviceInfo;\r\ + \n :global devBoardName;\r\ + \n :global devCurArch;\r\ + \n :global devModel;\r\ + \n :global devRunning;\r\ + \n :global devRbRevision;\r\ + \n :global devRbSerialNumber;\r\ + \n :global PiblicIpAddress;\r\ + \n\r\ + \n :global GlobalConfVersion;\r\ + \n :global Identity;\r\ + \n :global IfThenElse;\r\ + \n :global FormatLine;\r\ + \n :local Return;\r\ + \n :local License [/system/license/get];\r\ + \n :local Resource [/system/resource/get];\r\ + \n :local Snmp [ /snmp/get ];\r\ + \n :local Update [ /system/package/update/get ];\r\ + \n \r\ + \n :set Return ([ \$FormatLine \"Hostname:\" \$Identity ] . \"\\n\" . \\\ + \r\ + \n [ \$IfThenElse ([ :len (\$Snmp->\"location\") ] > 0) \\\r\ + \n ([ \$FormatLine \"Location:\" (\$Snmp->\"location\") ] . \"\\n\") \ + ] . \\\r\ + \n [ \$IfThenElse ([ :len (\$Snmp->\"contact\") ] > 0) \\\r\ + \n ([ \$FormatLine \"Contact:\" (\$Snmp->\"contact\") ] . \"\\n\") ] \ + . \\\r\ + \n \"Hardware:\\n\" . \\\r\ + \n [ \$FormatLine \" Board:\" . \$devBoardName ] . \"\\n\" . \\\r\ + \n [ \$FormatLine \" Arch:\" . \$devCurArch ] . \"\\n\" . \\\r\ + \n [ \$FormatLine \" Model:\" \$devModel ] . \\\r\ + \n [ \$IfThenElse ([ :len \$devRbRevision ] > 0) \\\r\ + \n (\" \" . \$devRbRevision) ] . \"\\n\" . \\\r\ + \n [ \$IfThenElse ([ :len \$devRbSerialNumber ] > 0) \\\r\ + \n ([ \$FormatLine \" Serial:\" . \$devRbSerialNumber ] . \"\\n\"\ + ) ] . \\\r\ + \n [ \$IfThenElse ([ :len (\$License->\"nlevel\") ] > 0) \\\r\ + \n ([ \$FormatLine \" License:\" (\"level \" . (\$License->\"nleve\ + l\")) ] . \"\\n\") ] . \"RouterOS:\\n\" . \\\r\ + \n [ \$IfThenElse ([ :len (\$License->\"level\") ] > 0) \\\r\ + \n ([ \$FormatLine \" License:\" (\"level \" . (\$License->\"level\ + \")) ] . \"\\n\") ] . \\\r\ + \n [ \$FormatLine \"Running Channel\" \$runningChannel ] . \"\\n\" . \\\ + \r\ + \n [ \$FormatLine \" Installed:\" (\$Update->\"installed-version\") \ + ] . \"\\n\" . \\\r\ + \n [ \$IfThenElse ([ :typeof (\$Update->\"latest-version\") ] != \"noth\ + ing\" && \\\r\ + \n \$Update->\"installed-version\" != \$Update->\"latest-version\")\ + \_\\\r\ + \n ([ \$FormatLine \" Available\" (\$Update->\"latest-version\") ]\ + \_. \"\\n\") ] . \\\r\ + \n [ \$IfThenElse (\$RouterBoard->\"routerboard\" = true && \\\r\ + \n \$RouterBoard->\"current-firmware\" != \$RouterBoard->\"upgrade-\ + firmware\") \\\r\ + \n ([ \$FormatLine \" Firmware\" (\$RouterBoard->\"current-firmwar\ + e\") ] . \"\\n\") ] . \\ \r\ + \n \"RouterOS-Scripts:\\n\" . \\\r\ + \n [ \$FormatLine \" Commit\" [ \$CommitBrief ] ] . \"\\n\" . \\\r\ + \n [ \$FormatLine \" Version\" \$GlobalConfVersion ]);\r\ + \n}\r\ + \n\r\ + \n:if ([ :typeof \$NotificationFunctions ] != \"array\") do={:set Notifica\ + tionFunctions ({})}\r\ + \n:set GetRandom20CharAlNum do={\r\ + \n :global EitherOr;\r\ + \n :return [ :rndstr length=[ \$EitherOr [ :tonum \$1 ] 20 ] from=\"ABCDE\ + FGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\" ];\r\ + \n}\r\ + \n\r\ + \n:global checkRunJob;\r\ + \n:set checkRunJob do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :global ScriptLock; \r\ + \n :if ([ \$ScriptLock \$Script ] = false) do={:return false}\r\ + \n :foreach Job in=[ /system/script/job/find where script=\$Script ] do={\ + :set Job [ /system/script/job/get \$Job ];\r\ + \n :while ([ :typeof (\$Job->\"parent\") ] = \"id\") do={:set Job [ /sy\ + stem/script/job/get [ find where .id=(\$Job->\"parent\") ] ]}\r\ + \n :if ((\$Job->\"type\") = \"login\") do={:return true};}; :return fa\ + lse; \r\ + \n}\r\ + \n\r\ + \n:set InspectVar do={\r\ + \n :global InspectVarRet;\r\ + \n :put [ :tocrlf [ \$InspectVarRet \$1 ] ];\r\ + \n}\r\ + \n\r\ + \n:set InspectVarRet do={\r\ + \n :local Input \$1;\r\ + \n :local Level (0 + [ :tonum \$2 ]);\r\ + \n :global CharacterReplace;\r\ + \n :global IfThenElse;\r\ + \n :global InspectVarRet;\r\ + \n :local IndentReturn do={\r\ + \n :local Prefix [ :tostr \$1 ];\r\ + \n :local Value [ :tostr \$2 ];\r\ + \n :local Level [ :tonum \$3 ];\r\ + \n :global CharacterMultiply;\r\ + \n :return ([ \$CharacterMultiply \" \" (\$Level * 2) ] . \"-\" . \$Pre\ + fix . \"-> \" . \$Value);\r\ + \n }\r\ + \n :local TypeOf [ :typeof \$Input ];\r\ + \n :local Len [ :len \$Input ];\r\ + \n :local Return [ \$IndentReturn \"type\" \$TypeOf \$Level ];\r\ + \n :if (\$TypeOf = \"array\") do={\r\ + \n :foreach Key,Value in=\$Input do={\r\ + \n :set \$Return (\$Return . \"\\n\" . \\\r\ + \n [ \$IndentReturn \"key\" \$Key (\$Level + 1) ] . \"\\n\" . \\\r\ + \n [ \$InspectVarRet \$Value (\$Level + 2) ]);\r\ + \n }\r\ + \n } else={\r\ + \n :if (\$TypeOf = \"str\") do={\r\ + \n :set \$Return (\$Return . \"\\n\" . \\\r\ + \n [ \$IndentReturn \"len\" \$Len \$Level ]);\r\ + \n :if ([ :typeof [ :find \$Input (\"\\r\") ] ] = \"num\") do={\r\ + \n :set Input [ \$CharacterReplace \$Input (\"\\r\") \"\" ];\r\ + \n }\r\ + \n :if ([ :typeof [ :find \$Input (\"\\n\") ] ] = \"num\") do={\r\ + \n :set Input [ \$CharacterReplace \$Input (\"\\n\") \" \" ];\r\ + \n }\r\ + \n }\r\ + \n :if (\$TypeOf != \"nothing\") do={\r\ + \n :set \$Return (\$Return . \"\\n\" . \\\r\ + \n [ \$IndentReturn \"value\" [ \$IfThenElse ([ :len \$Input ] > 80)\ + \_\\\r\ + \n ([ :pick \$Input 0 77 ] . \"...\") \$Input ] \$Level ]);\r\ + \n }\r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n# !!! The function is not ready !!!\r\ + \n:global FetchHttpInfo do={\r\ + \n :local Mac [ :tostr \$1 ];\r\ + \n :global CertificateAvailable;\r\ + \n :global IsMacLocallyAdministered;\r\ + \n :global LogPrint;\r\ + \n :local Url \"https://api.macvendors.com/\";\r\ + \n :if ([ \$IsMacLocallyAdministered \$Mac ] = true) do={:return \"locall\ + y administered\";}\r\ + \n :do {\r\ + \n :if ([ \$CertificateAvailable \"GTS Root R4\" \"fetch\" ] = false) d\ + o={\r\ + \n \$LogPrint warning \$0 (\"Downloading required certificate failed.\ + \");\r\ + \n :error false;\r\ + \n }\r\ + \n :local Vendor ([ /tool/fetch \r\ + \n (\$Url . [ :pick \$Mac 0 8 ]) output=user as-value ]->\"data\");\r\ + \n :return \$Vendor;\r\ + \n } on-error={\r\ + \n :onerror Err {\r\ + \n /tool/fetch check-certificate=yes-without-crl (\$Url) output=none \ + as-value;\r\ + \n \$LogPrint debug \$0 (\"The mac vendor is not known in database.\"\ + );\r\ + \n } do={ \$LogPrint warning \$0 (\"Failed getting mac vendor: \" . \$E\ + rr); }\r\ + \n :return \"unknown vendor\";\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set GetPubIp do={\r\ + \n :global DetectIpAddrDefault;\r\ + \n :global DetectIpAddrFallback;\r\ + \n :global LogPrint;\r\ + \n \r\ + \n :local PubIpAddr false;\r\ + \n :local Url \$DetectIpAddrDefault;\r\ + \n\r\ + \n# :retry command={abc} delay=1 max=2 on-error={:put \"got error\"} \r\ + \n :do {\r\ + \n \$LogPrint debug \$0 (\"Trying to detect public IP using default s\ + ervice: \" . \$Url . \"...\");\r\ + \n :retry command={:set PubIpAddr ([ /tool/fetch http-method=\"get\"\ + \_check-certificate=yes-without-crl \$Url output=user as-value ]->\"data\"\ + )} \\\r\ + \n delay=50ms max=5 on-error={\$LogPrint error [ :jobname ] (\"Fail\ + ed to detect public IP using default service: \" . \$Url . \".\")}\r\ + \n #:error \"Failed to detect public IP using default service: \$Url\ + .\"};\r\ + \n } on-error={\r\ + \n \$LogPrint error \$0 (\"Failed to detect public IP using default s\ + ervice: \" . \$Url . \".\");\r\ + \n :set Url \$DetectIpAddrFallBack;\r\ + \n \$LogPrint debug \$0 (\"Trying to detect public IP using fallback \ + service: \" . \$Url . \"...\");\r\ + \n :retry command={:set PubIpAddr ([ /tool/fetch http-method=\"get\"\ + \_check-certificate=yes-without-crl \$Url output=user as-value ]->\"data\"\ + )} \\\r\ + \n delay=200ms max=5 on-error={\$LogPrint error [ :jobname ] (\"Fai\ + led to detect public IP using fallback service: \" . \$Url . \".\")}\r\ + \n };\r\ + \n :if (\$PubIpAddr = false) do={\r\ + \n :set PubIpAddr \"not-detected\";\r\ + \n } else={\r\ + \n :set PubIpAddr [ :pick \$PubIpAddr 0 15];\r\ + \n }\r\ + \n :return \$PubIpAddr;\r\ + \n}\r\ + \n\r\ + \n:set FormatLine do={\r\ + \n :local Key [ :tostr \$1 ];\r\ + \n :local Value [ :tostr \$2 ];\r\ + \n :local Indent [ :tonum \$3 ];\r\ + \n :local Spaces;\r\ + \n :local Return \"\";\r\ + \n :global CharacterMultiply;\r\ + \n :global EitherOr;\r\ + \n :set Indent [ \$EitherOr \$Indent 16 ];\r\ + \n :local Spaces [ \$CharacterMultiply \" \" \$Indent ];\r\ + \n :if ([ :len \$Key ] > 0) do={ :set Return (\$Key . \":\")}\r\ + \n :if ([ :len \$Key ] > (\$Indent - 2)) do={:set Return (\$Return . \"\\\ + n\" . [ :pick \$Spaces 0 \$Indent ] . \$Value);\r\ + \n } else={:set Return (\$Return . [ :pick \$Spaces 0 (\$Indent - [ :len \ + \$Return ]) ] . \$Value)}\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set ParseCustom do={\r\ + \n :local Str [ :tostr \$1 ];\r\ + \n :local Start [:find [ \$Str ] [:tostr \$2]];\r\ + \n :local End [ :tostr \$3 ];\r\ + \n :local Num [ :tonum \$4 ];\r\ + \n :local Return;\r\ + \n :if ([:len \$Num] = 0) do={:set Num \"0\"}\r\ + \n :local rest [:pick \$Str (\$Start+\$Num) [:len \$Str]]; \r\ + \n :if ([:len \$End ] = 0) do={:set Return [:pick \$Str \$Num \$Start]} e\ + lse={\r\ + \n :set End [:find \$rest \$End];\r\ + \n :set Return [:pick \$rest 0 \$End];\r\ + \n }\r\ + \n:return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set LogPrint do={\r\ + \n :local Severity [ :tostr \$1 ];\r\ + \n :local Name [ :tostr \$2 ];\r\ + \n :local Message [ :tostr \$3 ];\r\ + \n :global PrintDebug;\r\ + \n :global PrintDebugOverride;\r\ + \n :global EitherOr;\r\ + \n :local Debug [ \$EitherOr (\$PrintDebugOverride->\$Name) \$PrintDebug \ + ];\r\ + \n :local PrintSeverity do={\r\ + \n :global TerminalColorOutput;\r\ + \n :if (\$TerminalColorOutput != true) do={:return \$1}\r\ + \n :local Color { debug=96; info=97; warning=93; error=91 };\r\ + \n :return (\"\\1B[\" . \$Color->\$1 . \"m\" . \$1 . \"\\1B[0m\");\r\ + \n}\r\ + \n :local Log ([ \$EitherOr \$Name \"\" ] . \": \" . \$Message);\ + \r\ + \n :if (\$Severity ~ (\"^(custom|debug|error|info)\\\$\")) do={\r\ + \n :if (\$Severity = \"debug\") do={:log debug \$Log}\r\ + \n :if (\$Severity = \"error\") do={:log error \$Log}\r\ + \n :if (\$Severity = \"info\" ) do={:log info \$Log}\r\ + \n } else={:log warning \$Log; :set Severity \"warning\"}\r\ + \n :if (\$Severity != \"debug\" || \$Debug = true) do={:put ([ \$PrintSev\ + erity \$Severity ] . \": \" . \$Message)}\r\ + \n}\r\ + \n\r\ + \n:set CertificateAvailable do={\r\ + \n :local CommonName [ :tostr \$1 ];\r\ + \n :local UseFor [ :tostr \$2 ];\r\ + \n :global CertificateDownload;\r\ + \n :global EitherOr;\r\ + \n :global LogPrint;\r\ + \n :global ParseKeyValueStore;\r\ + \n :set UseFor [ \$EitherOr \$UseFor \"undefined\" ];\r\ + \n :if ([ /system/resource/get free-hdd-space ] < 8388608 && \\\r\ + \n [ /certificate/settings/get crl-download ] = true && \\\r\ + \n [ /certificate/settings/get crl-store ] = \"system\") do={\r\ + \n \$LogPrint warning \$0 (\"This system has low free flash space but \ + \" . \\\r\ + \n \"is configured to download certificate CRLs to system!\");\r\ + \n }\r\ + \n :if ([ :len \$CommonName ] = 0) do={\r\ + \n \$LogPrint warning \$0 (\"No CommonName given!\");\r\ + \n :return false;\r\ + \n }\r\ + \n :local CertSettings [ /certificate/settings/get ];\r\ + \n :if (((\$CertSettings->\"builtin-trust-anchors\") = \"trusted\" || \\\ + \r\ + \n (\$CertSettings->\"builtin-trust-store\") ~ \$UseFor || \\\r\ + \n (\$CertSettings->\"builtin-trust-store\") = \"all\") && \\\r\ + \n [ :len [ /certificate/builtin/find where common-name=\$CommonName\ + \_] ] > 0) do={\r\ + \n :return true;\r\ + \n }\r\ + \n :if ([ :len [ /certificate/find where common-name=\$CommonName ] ] = 0\ + ) do={\r\ + \n \$LogPrint info \$0 (\"Certificate with CommonName '\" . \$CommonNam\ + e . \"' not available.\");\r\ + \n :if ([ \$CertificateDownload \$CommonName ] = false) do={:return fal\ + se}\r\ + \n }\r\ + \n :if ([ :len [ /certificate/find where common-name=\$CommonName ] ] > 1\ + ) do={\r\ + \n \$LogPrint info \$0 (\"There are \" . \$CertCount . \" Certificates \ + with CommonName '\" . \$CommonName . \"'. Should be ok.\");\r\ + \n :return true;\r\ + \n }\r\ + \n :local CertVal [ /certificate/get [ find where common-name=\$CommonNam\ + e ] ];\r\ + \n :while ((\$CertVal->\"akid\") != \"\" && (\$CertVal->\"akid\") != (\$C\ + ertVal->\"skid\")) do={\r\ + \n :if ([ :len [ /certificate/find where skid=(\$CertVal->\"akid\") ] ]\ + \_= 0) do={\r\ + \n :local IssuerCN ([ \$ParseKeyValueStore (\$CertVal->\"issuer\") ]-\ + >\"CN\");\r\ + \n \$LogPrint info \$0 (\"Certificate chain for '\" . \$CommonName . \ + \"' is incomplete, missing '\" . \$IssuerCN . \"'.\");\r\ + \n :if ([ \$CertificateDownload \$IssuerCN ] = false) do={:return fal\ + se}\r\ + \n }\r\ + \n :set CertVal [ /certificate/get [ find where skid=(\$CertVal->\"akid\ + \") ] ];\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set CertificateDownload do={\r\ + \n :local CommonName [ :tostr \$1 ];\r\ + \n :global GlobalScriptsUrl;\r\ + \n :global GlobalScriptsUrlSuffix;\r\ + \n :global CertificateNameByCN;\r\ + \n :global CleanName;\r\ + \n :global FetchUserAgentStr;\r\ + \n :global LogPrint;\r\ + \n :global RmFile;\r\ + \n :global WaitForFile;\r\ + \n \r\ + \n \$LogPrint info \$0 (\"Downloading and importing certificate with Comm\ + onName '\" . \$CommonName . \"'.\");\r\ + \n \r\ + \n :local FileName ([ \$CleanName \$CommonName ] . \".pem\");\r\ + \n :do {\r\ + \n /tool/fetch check-certificate=yes-without-crl http-header-field=({ [\ + \_\$FetchUserAgentStr \$0 ] }) \\\r\ + \n (\$GlobalScriptsUrl . \"certs/\" . \$FileName . \$GlobalScriptsUrl\ + Suffix) dst-path=\$FileName as-value;\r\ + \n \$WaitForFile \$FileName;\r\ + \n } on-error={\r\ + \n \$LogPrint warning \$0 (\"Failed downloading certificate with Common\ + Name '\" . \$CommonName . \\\r\ + \n \"' from repository! Trying fallback to mkcert.org...\");\r\ + \n :do {\r\ + \n :if ([ :len [ /certificate/find where common-name=\"ISRG Root X1\"\ + \_] ] = 0) do={\r\ + \n \$LogPrint error \$0 (\"Required certificate is not available.\"\ + );\r\ + \n :return false;\r\ + \n }\r\ + \n /tool/fetch check-certificate=yes-without-crl http-header-field=({\ + \_[ \$FetchUserAgentStr \$0 ] }) \\\r\ + \n \"https://mkcert.org/generate/\" http-data=[ :serialize to=json \ + ({ \$CommonName }) ] \\\r\ + \n dst-path=\$FileName as-value;\r\ + \n \$WaitForFile \$FileName;\r\ + \n :if ([ /file/get \$FileName size ] = 0) do={\r\ + \n \$RmFile \$FileName;\r\ + \n :error false;\r\ + \n }\r\ + \n } on-error={\r\ + \n \$LogPrint warning \$0 (\"Failed downloading certificate with Comm\ + onName '\" . \$CommonName . \"'!\");\r\ + \n :return false;\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n /certificate/import file-name=\$FileName passphrase=\"\" as-value;\r\ + \n :delay 1s;\r\ + \n \$RmFile \$FileName;\r\ + \n\r\ + \n :if ([ :len [ /certificate/find where common-name=\$CommonName ] ] = 0\ + ) do={\r\ + \n /certificate/remove [ find where name~(\"^\" . \$FileName . \"_[0-9]\ + +\\\$\") ];\r\ + \n \$LogPrint warning \$0 (\"Certificate with CommonName '\" . \$Common\ + Name . \"' still unavailable!\");\r\ + \n :return false;\r\ + \n }\r\ + \n :foreach Cert in=[ /certificate/find where name~(\"^\" . \$FileName . \ + \"_[0-9]+\\\$\") ] do={\r\ + \n \$CertificateNameByCN [ /certificate/get \$Cert common-name ];\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set CertificateNameByCN do={\r\ + \n :local Match [ :tostr \$1 ];\r\ + \n :global CleanName;\r\ + \n :global LogPrint;\r\ + \n :local Cert ([ /certificate/find where (common-name=\$Match or fingerp\ + rint=\$Match or name=\$Match) ]->0);\r\ + \n :if ([ :len \$Cert ] = 0) do={\r\ + \n \$LogPrint warning \$0 (\"No matching certificate found.\");\r\ + \n :return false;\r\ + \n }\r\ + \n :local CommonName [ /certificate/get \$Cert common-name ];\r\ + \n /certificate/set \$Cert name=[ \$CleanName \$CommonName ];\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set CharacterMultiply do={\r\ + \n :local Str [ :tostr \$1 ];\r\ + \n :local Num [ :tonum \$2 ];\r\ + \n :if (\$Num = 0) do={:return \"\"}\r\ + \n :local Return \"\";\r\ + \n :for I from=1 to=\$Num do={:set Return (\$Return . \$Str)}\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set ScriptInstallUpdate do={ :onerror Err {\r\ + \n :local Scripts [ :toarray \$1 ];\r\ + \n :local NewComment [ :tostr \$2 ];\r\ + \n :global InitSetup;\r\ + \n\r\ + \n :global ScriptUpdatesCRLF;\r\ + \n :global GlobalConfVersion;\r\ + \n :global Identity;\r\ + \n :global CertificateAvailable;\r\ + \n :global CheckSumsVerify;\r\ + \n :global GlobalScriptsUrl;\r\ + \n :global GlobalScriptsUrlSuffix;\r\ + \n :global EitherOr;\r\ + \n :global FetchUserAgentStr;\r\ + \n :global Grep;\r\ + \n :global IfThenElse;\r\ + \n :global LogPrint;\r\ + \n :global ParseKeyValueStore;\r\ + \n :global RequiredRouterOS;\r\ + \n :global SendNotification2;\r\ + \n :global SymbolForNotification;\r\ + \n :global ValidateSyntax;\r\ + \n :global CommentsInScripts;\r\ + \n\r\ + \n :if ([ \$CertificateAvailable \"Root YE\" \"fetch\" ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"Downloading certificate failed, trying wit\ + hout.\");\r\ + \n }\r\ + \n\r\ + \n :foreach Script in=\$Scripts do={\r\ + \n :if ([ :len [ /system/script/find where name=\$Script ] ] = 0) do={\ + \r\ + \n \$LogPrint info \$0 (\"Adding new script: \" . \$Script);\r\ + \n /system/script/add name=\$Script owner=\$Script source=\"#!rsc by \ + Vados\\n\" comment=\$NewComment;\r\ + \n }\r\ + \n }\r\ + \n \r\ + \n :local GlobalConfVersionBefore \$GlobalConfVersion;\r\ + \n :local ReloadGlobal false;\r\ + \n :local DeviceMode [ /system/device-mode/get ];\r\ + \n \r\ + \n :if (\$CheckSumsVerify = true) do={\r\ + \n :local CheckSums ({});\r\ + \n :do {\r\ + \n :local Url (\$GlobalScriptsUrl . \"checksums.json\" . \$GlobalScrip\ + tsUrlSuffix);\r\ + \n \$LogPrint debug \$0 (\"Fetching checksums from url: \" . \$Url);\ + \r\ + \n :set CheckSums [ :deserialize from=json ([ /tool/fetch check-certi\ + ficate=yes-without-crl \\\r\ + \n http-header-field=({ [ \$FetchUserAgentStr \$0 ] }) \$Url output\ + =user as-value ]->\"data\") ];\r\ + \n } on-error={ \$LogPrint warning \$0 (\"Err = \" . \$Err); }\r\ + \n }\r\ + \n\r\ + \n :foreach Script in=[ /system/script/find where source~\"^#!rsc by Vado\ + s\" ] do={\r\ + \n :local ScriptVal [ /system/script/get \$Script ];\r\ + \n :local ScriptInfo [ \$ParseKeyValueStore (\$ScriptVal->\"comment\") \ + ];\r\ + \n :local SourceNew;\r\ + \n\r\ + \n :foreach Scheduler in=[ /system/scheduler/find where on-event~(\"\\\ + \\b\" . \$ScriptVal->\"name\" . \"\\\\b\") ] do={\r\ + \n :local SchedulerVal [ /system/scheduler/get \$Scheduler ];\r\ + \n :if (\$ScriptVal->\"policy\" != \$SchedulerVal->\"policy\") do={\r\ + \n \$LogPrint warning \$0 (\"Policies differ for script '\" . \$Scr\ + iptVal->\"name\" . \"' and its scheduler '\" . \$SchedulerVal->\"name\" . \ + \"'!\");\r\ + \n }\r\ + \n }\r\ + \n :do {\r\ + \n :if (\$ScriptInfo->\"ignore\" = true) do={\r\ + \n \$LogPrint debug \$0 (\"Ignoring script '\" . \$ScriptVal->\"nam\ + e\" . \"', as requested.\");\r\ + \n :error true;\r\ + \n }\r\ + \n :if (\$CheckSumsVerify = true) do={\r\ + \n :local CheckSum (\$CheckSums->(\$ScriptVal->\"name\"));\r\ + \n :if ([ :len (\$ScriptInfo->\"base-url\") ] = 0 && [ :len (\$Scri\ + ptInfo->\"url-suffix\") ] = 0 && \\\r\ + \n [ :convert transform=md5 to=hex [ :tolf (\$ScriptVal->\"sou\ + rce\") ] ] = \$CheckSum) do={\r\ + \n \$LogPrint debug \$0 (\"Checksum for script '\" . \$ScriptVal-\ + >\"name\" . \"' matches, ignoring.\");\r\ + \n :error true;\r\ + \n }\r\ + \n }\r\ + \n :if ([ :len (\$ScriptInfo->\"certificate\") ] > 0) do={\r\ + \n :if ([ \$CertificateAvailable (\$ScriptInfo->\"certificate\") \"\ + fetch\" ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"Downloading certificate failed, tryi\ + ng without.\");\r\ + \n }\r\ + \n }\r\ + \n :onerror Err {\r\ + \n :local BaseUrl [ \$EitherOr (\$ScriptInfo->\"base-url\") \$Globa\ + lScriptsUrl ];\r\ + \n :local UrlSuffix [ \$EitherOr (\$ScriptInfo->\"url-suffix\") \$G\ + lobalScriptsUrlSuffix ];\r\ + \n :local Url (\$BaseUrl . \$ScriptVal->\"name\" . \".rsc\" . \$Url\ + Suffix);\r\ + \n \$LogPrint warning \$0 (\"Fetching script '\" . (\$ScriptVal->\"\ + name\") . \"' from url: \" . \$Url);\r\ + \n :local Result [ /tool/fetch check-certificate=yes-without-crl \\\ + \r\ + \n http-header-field=({ [ \$FetchUserAgentStr \$0 ] }) \$Url outp\ + ut=user as-value ];\r\ + \n :if (\$Result->\"status\" = \"finished\") do={\r\ + \n :set SourceNew [ :tolf (\$Result->\"data\") ];\r\ + \n } \r\ + \n } do={\r\ + \n \$LogPrint warning \$0 (\"Failed fetching script '\" . \$ScriptV\ + al->\"name\" . \"': \" . \$Err);\r\ + \n :if (\$Err != \"Fetch failed with status 404\") do={\r\ + \n :error false;\r\ + \n }\r\ + \n :if (\$ScriptVal->\"source\" = \"#!rsc by Vados\") do={\r\ + \n \$LogPrint warning \$0 (\"Removing dummy. Typo on installation\ + \?\");\r\ + \n /system/script/remove \$Script;\r\ + \n :error false;\r\ + \n }\r\ + \n :if (\$CheckSumsVerify = true) do={\r\ + \n :if ([ :len (\$ScriptInfo->\"base-url\") ] = 0 && [ :len (\$Sc\ + riptInfo->\"url-suffix\") ] = 0 && \\\r\ + \n [ :len \$CheckSum ] = 0) do={\r\ + \n \$LogPrint warning \$0 (\"Added the script manually\? Skip u\ + pdates with 'ignore=true' in comment.\");\r\ + \n }\r\ + \n }\r\ + \n :error false;\r\ + \n }\r\ + \n\r\ + \n :if ([ :len \$SourceNew ] = 0) do={\r\ + \n \$LogPrint debug \$0 (\"No update for script '\" . (\$ScriptVal-\ + >\"name\") . \"'.\");\r\ + \n :error false;\r\ + \n }\r\ + \n\r\ + \n :local SourceCRLF [ :tocrlf \$SourceNew ];\r\ + \n :if (\$InitSetup != true && ((\$ScriptVal->\"name\") != \"AM-Globa\ + lConfig\" || (\$ScriptVal->\"name\") != \"AM-GlobalFunc\")) do={\r\ + \n :if (\$SourceNew = (\$ScriptVal->\"source\") || \$SourceCRLF = (\ + \$ScriptVal->\"source\")) do={\r\ + \n \$LogPrint debug \$0 (\"Script '\" . (\$ScriptVal->\"name\") \ + . \"' source did not change. End of lines set to CRLF.\");\r\ + \n if (\$ScriptUpdatesCRLF = false) do={\r\ + \n :put [ :tolf \$SourceNew ];\r\ + \n \$LogPrint debug \$0 (\"Script '\" . (\$ScriptVal->\"name\"\ + ) . \"' source update end of lines to LF.\");\r\ + \n }\r\ + \n :error false;\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :if ([ :pick \$SourceNew 0 14 ] != \"#!rsc by Vados\") do={\r\ + \n \$LogPrint warning \$0 (\"Looks like new script '\" . \$ScriptVa\ + l->\"name\" . \"' is not valid (missing shebang = '\$shebang') Ignoring!\"\ + );\r\ + \n :error false;\r\ + \n }\r\ + \n\r\ + \n :if (\$CommentsInScripts = true) do={\r\ + \n :local CommentLine [ \$Grep \$SourceNew (\"\\23 Script comment:\ + \_\") ];\r\ + \n :if ([ :len \$CommentLine ] = 0) do={\r\ + \n \$LogPrint debug \$0 (\"The search in new script '\" . (\$Scr\ + iptVal->\"name\") . \"' for comment in script body, is not found result Ig\ + noring!\");\r\ + \n :error false;\r\ + \n } else={\r\ + \n :if ([ :len (\$ScriptVal->\"comment\")] = 0 || [ :len (\$Scri\ + ptVal->\"comment\")] != [ :pick \$CommentLine ([ :find \$CommentLine \":\"\ + ] + 2) [ :len \$CommentLine] ]) do={\r\ + \n \$LogPrint debug \$0 (\"Exsiting comment for script '\" . (\ + \$ScriptVal->\"name\") . \"' is '\" . (\$ScriptVal->\"comment\") . \"'.\")\ + ;\r\ + \n :set (\$ScriptVal->\"comment\") [ :pick \$CommentLine ([ :f\ + ind \$CommentLine \":\"] + 2) [ :len \$CommentLine] ];\r\ + \n \$LogPrint debug \$0 (\"New comment (\" . (\$ScriptVal->\"c\ + omment\") . \") for script '\" . (\$ScriptVal->\"name\") . \"' has been ad\ + ded!\");\r\ + \n } else={\r\ + \n \$LogPrint debug \$0 (\"Comment for script '\" . (\$ScriptV\ + al->\"name\") . \"' did not change.\");\r\ + \n :error false;\r\ + \n }\r\ + \n } \r\ + \n }\r\ + \n\r\ + \n :local RequiredROS ([ \$ParseKeyValueStore [ \$Grep \$SourceNew (\ + \"\\23 requires RouterOS, \") ] ]->version);\r\ + \n :if ([ \$RequiredRouterOS \$0 [ \$EitherOr \$RequiredROS \"0.0\" ]\ + \_false ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"The script '\" . (\$ScriptVal->\"name\ + \") . \"' requires RouterOS \" . \\\r\ + \n \$RequiredROS . \", which is not met by your installation. I\ + gnoring!\");\r\ + \n :error false;\r\ + \n }\r\ + \n :local RequiredDM [ \$ParseKeyValueStore [ \$Grep \$SourceNew (\"\ + \\23 requires device-mode, \") ] ];\r\ + \n :local MissingDM ({});\r\ + \n :foreach Feature,Value in=\$RequiredDM do={\r\ + \n :if ([ :typeof (\$DeviceMode->\$Feature) ] = \"bool\" && (\$Devi\ + ceMode->\$Feature) = false) do={\r\ + \n :set MissingDM (\$MissingDM, \$Feature);\r\ + \n }\r\ + \n }\r\ + \n :if ([ :len \$MissingDM ] > 0) do={\r\ + \n \$LogPrint warning \$0 (\"The script '\" . (\$ScriptVal->\"name\ + \") . \"' requires disabled \" . \\\r\ + \n \"device-mode features (\" . [ :tostr \$MissingDM ] . \"). I\ + gnoring!\");\r\ + \n :error false;\r\ + \n }\r\ + \n\r\ + \n :if ([ \$ValidateSyntax \$SourceNew ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"Syntax validation for script '\" . (\$\ + ScriptVal->\"name\") . \"' failed! Ignoring!\");\r\ + \n :error false;\r\ + \n }\r\ + \n \r\ + \n :log info (\"Updating script: \" . (\$ScriptVal->\"name\") . \" Sc\ + ript comment: \" . (\$ScriptVal->\"comment\"));\r\ + \n\r\ + \n /system/script/set owner=(\$ScriptVal->\"name\") comment=(\$Script\ + Val->\"comment\") \\\r\ + \n source=[ \$IfThenElse (\$ScriptUpdatesCRLF = true) \$SourceCRL\ + F \$SourceNew ] \$Script;\r\ + \n :if (\$ScriptVal->\"name\" = \"AM-GlobalConfig\" || \\\r\ + \n \$ScriptVal->\"name\" = \"AM-GlobalFunc\" || \\\r\ + \n \$ScriptVal->\"name\" ~ (\"^(AM-GlobalFunc\\\\.d|mod)/.\")) d\ + o={\r\ + \n :set ReloadGlobal true;\r\ + \n }\r\ + \n } on-error={ }\r\ + \n }\r\ + \n :if (\$ReloadGlobal = true) do={\r\ + \n \$LogPrint info \$0 (\"Reloading global configuration and functions.\ + \");\r\ + \n :onerror Err {\r\ + \n :global InitSetup (a);\r\ + \n /system/script {run AM-GlobalConfig; run AM-GlobalFunc;};\r\ + \n } do={\$LogPrint error \$0 (\"Reloading global configuration and fun\ + ctions failed! \" . \$Err)}\r\ + \n }\r\ + \n :if (\$GlobalConfVersionBefore > \$GlobalConfVersion) do={\r\ + \n \$LogPrint warning \$0 (\"The configuration version decreased from \ + \" . \\\r\ + \n \$GlobalConfVersionBefore . \" to \" . \$GlobalConfVersion . \\\r\ + \n \". Installed an older version\?\");\r\ + \n }\r\ + \n :if (\$GlobalConfVersionBefore < \$GlobalConfVersion) do={\r\ + \n :global GlobalConfChanges;\r\ + \n :global GlobalConfMigration;\r\ + \n :local ChangeLogCode;\r\ + \n :if ([ :len \$ChangeLogCode ] > 0) do={\r\ + \n :if ([ \$ValidateSyntax \$ChangeLogCode ] = true) do={\r\ + \n :onerror Err {\r\ + \n [ :parse \$ChangeLogCode ];\r\ + \n } do={\$LogPrint warning \$0 (\"The changelog failed to run: \" \ + . \$Err)}\r\ + \n } else={\$LogPrint warning \$0 (\"The changelog failed syntax vali\ + dation!\")}\r\ + \n }\r\ + \n :if ([ :len \$GlobalConfMigration ] > 0) do={\r\ + \n :for I from=(\$GlobalConfVersionBefore + 1) to=\$GlobalConfVersion\ + \_do={\r\ + \n :local Migration (\$GlobalConfMigration->[ :tostr \$I ]);\r\ + \n :do {\r\ + \n :if ([ :typeof \$Migration ] != \"str\") do={\r\ + \n \$LogPrint debug \$0 (\"Migration code for change \" . \$I .\ + \_\" is not available.\");\r\ + \n :error false;\r\ + \n }\r\ + \n :if ([ \$ValidateSyntax \$Migration ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"Migration code for change \" . \$I\ + \_. \" failed syntax validation!\");\r\ + \n :error false}\r\ + \n \$LogPrint info \$0 (\"Applying migration for change \" . \$I \ + . \": \" . \$Migration);\r\ + \n :onerror Err {\r\ + \n [ :parse \$Migration ];\r\ + \n } do={\$LogPrint warning \$0 (\"Migration code for change \" .\ + \_\$I . \" failed to run: \" . \$Err)}\r\ + \n } on-error={ }\r\ + \n }\r\ + \n }\r\ + \n :local NotificationMessage (\"The configuration version on \" . \$Id\ + entity . \" increased \" . \\\r\ + \n \"to \" . \$GlobalConfVersion . \", current configuration may nee\ + d modification. \" . \\\r\ + \n \"Please review and update global-config-overlay, then re-run glo\ + bal-config.\");\r\ + \n \$LogPrint info \$0 (\$NotificationMessage);\r\ + \n :if ([ :len \$GlobalConfChanges ] > 0) do={\r\ + \n :set NotificationMessage (\$NotificationMessage . \"\\n\\nChanges:\ + \");\r\ + \n :for I from=(\$GlobalConfVersionBefore + 1) to=\$GlobalConfVersion\ + \_do={\r\ + \n :local Change (\$GlobalConfChanges->[ :tostr \$I ]);\r\ + \n :set NotificationMessage (\$NotificationMessage . \"\\n \" . \\\ + \r\ + \n [ \$SymbolForNotification \"pushpin\" \"*\" ] . \$Change);\r\ + \n \$LogPrint info \$0 (\"Change \" . \$I . \": \" . \$Change);\r\ + \n }\r\ + \n } else={:set NotificationMessage (\$NotificationMessage . \"\\n\\nNe\ + ws and changes are not available.\")}\r\ + \n\r\ + \n :set GlobalConfChanges;\r\ + \n :set GlobalConfMigration;\r\ + \n }\r\ + \n} do={:global ExitOnError; \$ExitOnError \$0 \$Err}\r\ + \n}\r\ + \n\r\ + \n:set FetchUserAgentStr do={\r\ + \n :local Caller [ :tostr \$1 ];\r\ + \n :global IfThenElse;\r\ + \n :local Resource [ /system/resource/get ];\r\ + \n :return (\"User-Agent: Mikrotik/\" . \$Resource->\"version\" . \" \" .\ + \_\$Resource->\"architecture-name\" . \\\r\ + \n \" \" . \$Caller . \"/Fetch (https://amster.vados.ru/; main/3419/3ee\ + 19780)\");\r\ + \n}\r\ + \n\r\ + \n:set Grep do={\r\ + \n :local Input ([ :tostr \$1 ] . \"\\n\");\r\ + \n :local Pattern [ :tostr \$2 ];\r\ + \n :if ([ :typeof [ :find \$Input \$Pattern ] ] = \"nil\") do={:return []\ + }\r\ + \n :do {\r\ + \n :local Line [ :pick \$Input 0 [ :find \$Input \"\\n\" ] ];\r\ + \n :if ([ :typeof [ :find \$Line \$Pattern ] ] = \"num\") do={:return \ + \$Line}\r\ + \n :set Input [ :pick \$Input ([ :find \$Input \"\\n\" ] + 1) [ :len \$\ + Input ] ];\r\ + \n } while=([ :len \$Input ] > 0);\r\ + \n :return [];\r\ + \n}\r\ + \n\r\ + \n:set HumanReadableNum do={\r\ + \n :local Input [ :tonum \$1 ];\r\ + \n :local Base [ :tonum \$2 ];\r\ + \n :global EitherOr;\r\ + \n :global IfThenElse;\r\ + \n :local Prefix \"kMGTPE\";\r\ + \n :local Pow 1;\r\ + \n :set Base [ \$EitherOr \$Base 1024 ];\r\ + \n :local Bin [ \$IfThenElse (\$Base = 1024) \"i\" \"\" ];\r\ + \n :if (\$Input < \$Base) do={:return \$Input}\r\ + \n :for I from=0 to=[ :len \$Prefix ] do={\r\ + \n :set Pow (\$Pow * \$Base);\r\ + \n :if (\$Input / \$Base < \$Pow) do={\r\ + \n :set Prefix [ :pick \$Prefix \$I ];\r\ + \n :local Tmp1 (\$Input * 100 / \$Pow);\r\ + \n :local Tmp2 (\$Tmp1 / 100);\r\ + \n :if (\$Tmp2 >= 100) do={:return (\$Tmp2 . \$Prefix . \$Bin)}\r\ + \n :return (\$Tmp2 . \".\" . \\\r\ + \n [ :pick \$Tmp1 [ :len \$Tmp2 ] ([ :len \$Tmp1 ] - [ :len \$Tmp\ + 2 ] + 1) ] . \\\r\ + \n \$Prefix . \$Bin);\r\ + \n }\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set CleanName do={\r\ + \n :local Input [ :tostr \$1 ];\r\ + \n :local Return \"\";\r\ + \n :for I from=0 to=([ :len \$Input ] - 1) do={\r\ + \n :local Char [ :pick \$Input \$I ];\r\ + \n :if ([ :typeof [ find \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr\ + stuvwxyz0123456789\" \$Char ] ] = \"nil\") do={\r\ + \n :do {:if ([ :len \$Return ] = 0) do={:error true};\r\ + \n :if ([ :pick \$Return ([ :len \$Return ] - 1) ] = \"-\") do={:er\ + ror true}; :set Char \"-\"} on-error={:set Char \"\"}; \r\ + \n };\r\ + \n :set Return (\$Return . \$Char)};\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set GetRandomNumber do={\r\ + \n :global EitherOr;\r\ + \n :return [ :rndnum from=0 to=[ \$EitherOr [ :tonum \$1 ] 4294967295 ] ]\ + \r\ + \n}\r\ + \n\r\ + \n:set RandomDelay do={\r\ + \n :local Time [ :tonum \$1 ];\r\ + \n :local Unit [ :tostr \$2 ];\r\ + \n :global EitherOr;\r\ + \n :global GetRandomNumber;\r\ + \n :global MAX;\r\ + \n :if (\$Time = 0) do={:return false}\r\ + \n :delay ([ \$MAX 10 [ \$GetRandomNumber ([ :tonsec [ :totime (\$Time . \ + [ \$EitherOr \$Unit \"s\" ]) ] ] / 1000000) ] ] . \"ms\");\r\ + \n}\r\ + \n\r\ + \n:set EscapeForRegEx do={\r\ + \n :local Input [ :tostr \$1 ];\r\ + \n :if ([ :len \$Input ] = 0) do={:return \"\"}\r\ + \n :local Return \"\";\r\ + \n :local Chars (\"^.[]\\\$()|*+\?{}\\\\\");\r\ + \n :for I from=0 to=([ :len \$Input ] - 1) do={\r\ + \n :local Char [ :pick \$Input \$I ];\r\ + \n :if ([ :find \$Chars \$Char ]) do={:set Char (\"\\\\\" . \$Char)}\r\ + \n :set Return (\$Return . \$Char);\r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n:set ExitError do={\r\ + \n :local ExitOK [ :tostr \$1 ];\r\ + \n :local Name [ :tostr \$2 ];\r\ + \n :local Error [ :tostr \$3 ];\r\ + \n :global IfThenElse;\r\ + \n :global LogPrint;\r\ + \n :if (\$ExitOK = \"false\") do={\r\ + \n \$LogPrint error \$Name ([ \$IfThenElse ([ :pick \$Name 0 1 ] = \"\\\ + \$\") \\\r\ + \n \"Function\" \"Script\" ] . \" '\" . \$Name . \"' exited with er\ + ror\" . \\\r\ + \n [ \$IfThenElse (!(\$Error ~ \"^(|true|false)\\\$\")) (\": \" . \ + \$Error) \".\" ]);\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set MiniDateTimeStamp do={\r\ + \n /system/clock;\r\ + \n :local vdate [get date];\r\ + \n :local vtime [get time];\r\ + \n :local vdoff [:toarray \"0,4,5,7,8,10\"];\r\ + \n :local MM [:pick \$vdate (\$vdoff->2) (\$vdoff->3)];\r\ + \n :local M [:tonum \$MM];\r\ + \n :if (\$vdate ~ \".../../....\") do={\r\ + \n :set vdoff [:toarray \"7,11,1,3,4,6\"];\r\ + \n :set M ([:find \"xxanebarprayunulugepctovecANEBARPRAYUNULUGE\ + PCTOVEC\" [:pick \$vdate (\$vdoff->2) (\$vdoff->3)] -1] / 2);\r\ + \n :if (\$M>12) do={:set M (\$M - 12)}\r\ + \n :set MM [:pick (100 + \$M) 1 3];\r\ + \n }\r\ + \n :local yyyy [:pick \$vdate (\$vdoff->0) (\$vdoff->1)];\r\ + \n :local dd [:pick \$vdate (\$vdoff->4) (\$vdoff->5)];\r\ + \n :local HH [:pick \$vtime 0 2];\r\ + \n :local mm [:pick \$vtime 3 5];\r\ + \n :local ss [:pick \$vtime 6 8];\r\ + \n :return ([\$yyyy] . [\$MM] . [\$dd] . [\$HH] . [\$mm] . [\$ss]);\r\ + \n}\r\ + \n\r\ + \n:set WaitForFile do={\r\ + \n :local FileName [ :tostr \$1 ];\r\ + \n :local WaitTime [ :totime \$2 ];\r\ + \n :global CleanFilePath;\r\ + \n :global EitherOr;\r\ + \n :global MAX;\r\ + \n :set FileName [ \$CleanFilePath \$FileName ];\r\ + \n :local Delay ([ \$MAX [ \$EitherOr \$WaitTime 2s ] 100ms ] / 9);\r\ + \n :do {\r\ + \n :retry {\r\ + \n /file/get \$FileName;\r\ + \n :return true;\r\ + \n } delay=\$Delay max=10;\r\ + \n } on-error={ }\r\ + \n :while ([ :len [ /file/find where name=\$FileName ] ] > 0) do={\r\ + \n :do {\r\ + \n /file/get \$FileName;\r\ + \n :return true;\r\ + \n } on-error={ }\r\ + \n :delay \$Delay;\r\ + \n :set Delay (\$Delay * 3 / 2);\r\ + \n }\r\ + \n :return false;\r\ + \n}\r\ + \n\r\ + \n:set FileGet do={\r\ + \n :local FileName [ :tostr \$1 ];\r\ + \n :global WaitForFile;\r\ + \n :if ([ \$WaitForFile \$FileName 0s ] = false) do={:return false}\r\ + \n :local FileVal false;\r\ + \n :do {:set FileVal [ /file/get \$FileName ];\r\ + \n } on-error={ }\r\ + \n :return \$FileVal;\r\ + \n}\r\ + \n\r\ + \n:set RmDir do={\r\ + \n :local DirName [ :tostr \$1 ];\r\ + \n :global FileGet;\r\ + \n :global LogPrint;\r\ + \n \$LogPrint debug \$0 (\"Removing directory: \". \$DirName);\r\ + \n :local DirVal [ \$FileGet \$DirName ];\r\ + \n :if (\$DirVal = false) do={\$LogPrint debug \$0 (\"... which does not \ + exist.\"); :return true};\r\ + \n :if (\$DirVal->\"type\" != \"directory\") do={\$LogPrint error \$0 (\"\ + Directory '\" . \$DirName . \"' is not a directory.\"); :return false};\r\ + \n :onerror Err {/file/remove \$DirName} do={\$LogPrint error \$0 (\"Remo\ + ving directory '\" . \$DirName . \"' failed: \" . \$Err); :return false};\ + \r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set RmFile do={\r\ + \n :local FileName [ :tostr \$1 ];\r\ + \n :global FileGet;\r\ + \n :global LogPrint;\r\ + \n \$LogPrint debug \$0 (\"Removing file: \". \$FileName);\r\ + \n :local FileVal [ \$FileGet \$FileName ];\r\ + \n :if (\$FileVal = false) do={\$LogPrint debug \$0 (\"... which does not\ + \_exist.\"); :return true}\r\ + \n :if (\$FileVal->\"type\" = \"directory\" || \$FileVal->\"type\" = \"di\ + sk\") do={\r\ + \n \$LogPrint error \$0 (\"File '\" . \$FileName . \"' is not a file.\"\ + ); :return false}\r\ + \n :onerror Err {\r\ + \n /file/remove \$FileName;\r\ + \n } do={\$LogPrint error \$0 (\"Removing file '\" . \$FileName . \"' fai\ + led: \" . \$Err); :return false}\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set MkDir do={\r\ + \n :local Path [ :tostr \$1 ];\r\ + \n :global CleanFilePath;\r\ + \n :global FileGet;\r\ + \n :global RmDir;\r\ + \n :global WaitForFile;\r\ + \n :global LogPrint;\r\ + \n :local MkTmpfs do={\r\ + \n :global WaitForFile;\r\ + \n :local TmpFs [ /disk/find where slot=tmpfs type=tmpfs ];\r\ + \n :if ([ :len \$TmpFs ] = 1) do={\r\ + \n :if ([ /disk/get \$TmpFs disabled ] = true) do={\r\ + \n \$LogPrint info \$0 (\"The tmpfs is disabled, enabling.\");\r\ + \n /disk/enable \$TmpFs;\r\ + \n }\r\ + \n :return true;\r\ + \n }\r\ + \n \$LogPrint info \$0 (\"Creating disk of type tmpfs.\");\r\ + \n \$RmDir \"tmpfs\";\r\ + \n :onerror Err {\r\ + \n /disk/add slot=tmpfs type=tmpfs tmpfs-max-size=([ /system/resource\ + /get total-memory ] / 3);\r\ + \n \$WaitForFile \"tmpfs\";\r\ + \n } do={\r\ + \n \$LogPrint warning \$0 (\"Creating disk of type tmpfs failed: \" .\ + \_\$Err);\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n }\r\ + \n :set Path [ \$CleanFilePath \$Path ];\r\ + \n :if (\$Path = \"\") do={\r\ + \n :return true;\r\ + \n }\r\ + \n \$LogPrint debug \$0 (\"Making directory: \" . \$Path);\r\ + \n :local PathVal [ \$FileGet \$Path ];\r\ + \n :if (\$PathVal->\"type\" = \"directory\") do={\r\ + \n \$LogPrint debug \$0 (\"... which already exists.\");\r\ + \n :return true;\r\ + \n }\r\ + \n :if ([ :pick \$Path 0 5 ] = \"tmpfs\") do={\r\ + \n :if ([ \$MkTmpfs ] = false) do={\r\ + \n :return false;\r\ + \n }\r\ + \n }\r\ + \n :onerror Err {\r\ + \n /file/add type=\"directory\" name=\$Path;\r\ + \n \$WaitForFile \$Path;\r\ + \n } do={\r\ + \n \$LogPrint warning \$0 (\"Making directory '\" . \$Path . \"' failed\ + : \" . \$Err);\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n:set MAX do={:if (\$1 > \$2) do={:return \$1}\r\ + \n :return \$2;\r\ + \n}\r\ + \n:set MIN do={:if (\$1 < \$2) do={:return \$1}\r\ + \n :return \$2;\r\ + \n}\r\ + \n\r\ + \n:set CharacterMultiply do={\r\ + \n :local Str [ :tostr \$1 ];\r\ + \n :local Num [ :tonum \$2 ];\r\ + \n :if (\$Num = 0) do={:return \"\"}\r\ + \n :local Return \"\";\r\ + \n :for I from=1 to=\$Num do={:set Return (\$Return . \$Str)}\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n:set CharacterReplace do={\r\ + \n :local String [ :tostr \$1 ];\r\ + \n :local ReplaceFrom [ :tostr \$2 ];\r\ + \n :local ReplaceWith [ :tostr \$3 ];\r\ + \n :local Return \"\";\r\ + \n :if (\$ReplaceFrom = \"\") do={:return \$String}\r\ + \n :while ([ :typeof [ :find \$String \$ReplaceFrom ] ] != \"nil\") do={\ + \r\ + \n :local Pos [ :find \$String \$ReplaceFrom ];\r\ + \n :set Return (\$Return . [ :pick \$String 0 \$Pos ] . \$ReplaceWith);\ + \r\ + \n :set String [ :pick \$String (\$Pos + [ :len \$ReplaceFrom ]) [ :len\ + \_\$String ] ];\r\ + \n }\r\ + \n :return (\$Return . \$String);\r\ + \n}\r\ + \n\r\ + \n:set CleanFilePath do={\r\ + \n :local Path [ :tostr \$1 ];\r\ + \n :global CharacterReplace;\r\ + \n :while (\$Path ~ \"//\") do={:set \$Path [ \$CharacterReplace \$Path \ + \"//\" \"/\" ]};\r\ + \n :if ([ :pick \$Path 0 ] = \"/\") do={:set Path [ :pick \$Path 1 [ :len\ + \_\$Path ] ]};\r\ + \n :if ([ :pick \$Path ([ :len \$Path ] - 1) ] = \"/\") do={:set Path [ :\ + pick \$Path 0 ([ :len \$Path ] - 1) ]};\r\ + \n :return \$Path;\r\ + \n}\r\ + \n\r\ + \n:set IfThenElse do={\r\ + \n :if ([ :tostr \$1 ] = \"true\" || [ :tobool \$1 ] = true) do={:return \ + \$2};\r\ + \n :return \$3;\r\ + \n}\r\ + \n\r\ + \n:set EitherOr do={\r\ + \n :global IfThenElse;\r\ + \n :if ([ :typeof \$1 ] = \"num\") do={:return [ \$IfThenElse (\$1 != 0) \ + \$1 \$2 ]}\r\ + \n :if ([ :typeof \$1 ] = \"time\") do={:return [ \$IfThenElse (\$1 > 0s)\ + \_\$1 \$2 ]}\r\ + \n# this works for boolean values, literal ones with parentheses\r\ + \n :return [ \$IfThenElse ([ :len [ :tostr \$1 ] ] > 0) \$1 \$2 ];\r\ + \n}\r\ + \n\r\ + \n:set ParseKeyValueStore do={\r\ + \n :local Source \$1;\r\ + \n :if ([ :pick \$Source 0 1 ] = \"{\") do={\r\ + \n :do {\r\ + \n :return [ :deserialize from=json \$Source ];\r\ + \n } on-error={ }\r\ + \n } \r\ + \n :if ([ :typeof \$Source ] != \"array\") do={:set Source [ :tostr \$1 ]\ + }\r\ + \n :local Result ({});\r\ + \n :foreach KeyValue in=[ :toarray \$Source ] do={\r\ + \n :if ([ :find \$KeyValue \"=\" ]) do={\r\ + \n :local Key [ :pick \$KeyValue 0 [ :find \$KeyValue \"=\" ] ];\r\ + \n :local Value [ :pick \$KeyValue ([ :find \$KeyValue \"=\" ] + 1) [\ + \_:len \$KeyValue ] ];\r\ + \n :if (\$Value=\"true\") do={:set Value true}\r\ + \n :if (\$Value=\"false\") do={:set Value false}\r\ + \n :set (\$Result->\$Key) \$Value;\r\ + \n } else={:set (\$Result->\$KeyValue) true}\r\ + \n }\r\ + \n :return \$Result;\r\ + \n}\r\ + \n:set RequiredRouterOS do={\r\ + \n :local Caller [ :tostr \$1 ];\r\ + \n :local Required [ :tostr \$2 ];\r\ + \n :local Warn [ :tostr \$3 ];\r\ + \n :global IfThenElse;\r\ + \n :global LogPrint;\r\ + \n :global VersionToNum;\r\ + \n :if (!(\$Required ~ \"^\\\\d+\\\\.\\\\d+((alpha|beta|rc|\\\\.)\\\\d+|)\ + \\\$\")) do={\r\ + \n \$LogPrint error \$0 (\"No valid RouterOS version: \" . \$Required);\ + \r\ + \n :return false;\r\ + \n }\r\ + \n :if ([ \$VersionToNum \$Required ] > [ \$VersionToNum [ /system/packag\ + e/update/get installed-version ] ]) do={\r\ + \n :if (\$Warn = \"true\") do={\r\ + \n \$LogPrint warning \$0 (\"This \" . [ \$IfThenElse ([ :pick \$Call\ + er 0 ] = (\"\\\$\")) \"function\" \"script\" ] . \\\r\ + \n \" '\" . \$Caller . \"' (at least specific functionality) requir\ + es RouterOS \" . \$Required . \". Please update!\");\r\ + \n }\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n:set VersionToNum do={\r\ + \n :local Input [ :tostr \$1 ];\r\ + \n :local Multi 0x1000000;\r\ + \n :local Return 0;\r\ + \n :global CharacterReplace;\r\ + \n :set Input [ \$CharacterReplace \$Input \".\" \",\" ];\r\ + \n :foreach I in={ \"zero\"; \"alpha\"; \"beta\"; \"rc\" } do={\r\ + \n :set Input [ \$CharacterReplace \$Input \$I (\",\" . \$I . \",\") ];\ + \r\ + \n }\r\ + \n :foreach Value in=([ :toarray \$Input ], 0) do={\r\ + \n :local Num [ :tonum \$Value ];\r\ + \n :if (\$Multi = 0x100) do={\r\ + \n :if ([ :typeof \$Num ] = \"num\") do={\r\ + \n :set Return (\$Return + 0xff00);\r\ + \n :set Multi (\$Multi / 0x100);\r\ + \n } else={\r\ + \n :if (\$Value = \"zero\") do={ }\r\ + \n :if (\$Value = \"alpha\") do={ :set Return (\$Return + 0x3f00); \ + }\r\ + \n :if (\$Value = \"beta\") do={ :set Return (\$Return + 0x5f00); }\ + \r\ + \n :if (\$Value = \"rc\") do={ :set Return (\$Return + 0x7f00); }\r\ + \n }\r\ + \n }\r\ + \n :if ([ :typeof \$Num ] = \"num\") do={ :set Return (\$Return + (\$Va\ + lue * \$Multi)); }\r\ + \n :set Multi (\$Multi / 0x100);\r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n:set ScriptLock do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :local WaitMax [ :totime \$2 ];\r\ + \n :global GetRandom20CharAlNum;\r\ + \n :global IfThenElse;\r\ + \n :global LogPrint;\r\ + \n :global ScriptLockOrder;\r\ + \n :if ([ :typeof \$ScriptLockOrder ] = \"nothing\") do={\r\ + \n :set ScriptLockOrder ({});\r\ + \n }\r\ + \n :if ([ :typeof (\$ScriptLockOrder->\$Script) ] = \"nothing\") do={\r\ + \n :set (\$ScriptLockOrder->\$Script) ({});\r\ + \n }\r\ + \n :local JobCount do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :return [ :len [ /system/script/job/find where script=\$Script ] ];\ + \r\ + \n }\r\ + \n :local TicketCount do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :local Count 0;\r\ + \n :foreach Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ + \n :if ([ :typeof \$Ticket ] != \"nothing\") do={:set Count (\$Count \ + + 1)}\r\ + \n }\r\ + \n :return \$Count;\r\ + \n }\r\ + \n :local IsFirstTicket do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :local Check [ :tostr \$2 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :foreach Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ + \n :if (\$Ticket = \$Check) do={:return true}\r\ + \n :if ([ :typeof \$Ticket ] != \"nothing\" && \$Ticket != \$Check) d\ + o={:return false}\r\ + \n }\r\ + \n :return false;\r\ + \n }\r\ + \n :local AddTicket do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :local Add [ :tostr \$2 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :while (true) do={\r\ + \n :local Pos [ :len (\$ScriptLockOrder->\$Script) ];\r\ + \n :set (\$ScriptLockOrder->\$Script->\$Pos) \$Add;\r\ + \n :delay 10ms;\r\ + \n :if ((\$ScriptLockOrder->\$Script->\$Pos) = \$Add) do={:return tru\ + e}\r\ + \n }\r\ + \n }\r\ + \n :local RemoveTicket do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :local Remove [ :tostr \$2 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :foreach Id,Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ + \n :while ((\$ScriptLockOrder->\$Script->\$Id) = \$Remove) do={\r\ + \n :set (\$ScriptLockOrder->\$Script->\$Id);\r\ + \n :delay 10ms;\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n :local CleanupTickets do={\r\ + \n :local Script [ :tostr \$1 ];\r\ + \n :global ScriptLockOrder;\r\ + \n :foreach Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ + \n :if ([ :typeof \$Ticket ] != \"nothing\") do={:return false}\r\ + \n }\r\ + \n :set (\$ScriptLockOrder->\$Script) ({});\r\ + \n }\r\ + \n :if ([ :typeof \$WaitMax ] = \"nil\" ) do={:set WaitMax 0s}\r\ + \n :if ([ :len [ /system/script/find where name=\$Script ] ] = 0) do={\r\ + \n \$LogPrint error \$0 (\"A script named '\" . \$Script . \"' does not\ + \_exist!\");\r\ + \n :error false;\r\ + \n }\r\ + \n :if ([ \$JobCount \$Script ] = 0) do={\r\ + \n \$LogPrint error \$0 (\"No script '\" . \$Script . \"' is running!\"\ + );\r\ + \n :error false;\r\ + \n }\r\ + \n :if ([ \$TicketCount \$Script ] >= [ \$JobCount \$Script ]) do={\r\ + \n \$LogPrint error \$0 (\"More tickets than running scripts '\" . \$Sc\ + ript . \"', resetting!\");\r\ + \n :set (\$ScriptLockOrder->\$Script) ({});\r\ + \n /system/script/job/remove [ find where script=\$Script ];\r\ + \n }\r\ + \n :local MyTicket [ \$GetRandom20CharAlNum 6 ];\r\ + \n \$AddTicket \$Script \$MyTicket;\r\ + \n :local WaitInterval (\$WaitMax / 20);\r\ + \n :local WaitTime \$WaitMax;\r\ + \n :while (\$WaitTime > 0 && \\\r\ + \n ([ \$IsFirstTicket \$Script \$MyTicket ] = false || \\\r\ + \n [ \$TicketCount \$Script ] < [ \$JobCount \$Script ])) do={\r\ + \n :set WaitTime (\$WaitTime - \$WaitInterval);\r\ + \n :delay \$WaitInterval;\r\ + \n }\r\ + \n :if ([ \$IsFirstTicket \$Script \$MyTicket ] = true && \\\r\ + \n [ \$TicketCount \$Script ] = [ \$JobCount \$Script ]) do={\r\ + \n \$RemoveTicket \$Script \$MyTicket;\r\ + \n \$CleanupTickets \$Script;\r\ + \n :return true;\r\ + \n }\r\ + \n \$RemoveTicket \$Script \$MyTicket;\r\ + \n \$LogPrint debug \$0 (\"Script '\" . \$Script . \"' started more than \ + once\" . \\\r\ + \n [ \$IfThenElse (\$WaitTime < \$WaitMax) \" and timed out waiting for\ + \_lock\" \"\" ] . \"...\");\r\ + \n :return false;\r\ + \n}\r\ + \n:set SendNotification do={ :onerror Err {\r\ + \n :global SendNotification2;\r\ + \n \$SendNotification2 ({ origin=\$0; subject=\$1; message=\$2; link=\$3;\ + \_silent=\$4 });\r\ + \n} do={:global ExitOnError; \$ExitOnError \$0 \$Err}\r\ + \n}\r\ + \n:set SendNotification2 do={\r\ + \n :local Notification \$1;\r\ + \n :global NotificationFunctions;\r\ + \n :foreach FunctionName,Discard in=\$NotificationFunctions do={\r\ + \n (\$NotificationFunctions->\$FunctionName) (\"\\\$NotificationFunctio\ + ns->\\\"\" . \$FunctionName . \"\\\"\") \$Notification;\r\ + \n }\r\ + \n}\r\ + \n:set SymbolByUnicodeName do={\r\ + \n :local Name [ :tostr \$1 ];\r\ + \n :global EitherOr;\r\ + \n :global LogPrint;\r\ + \n :global SymbolsExtra;\r\ + \n :local Symbols ({\r\ + \n \"abacus\"=\"\\F0\\9F\\A7\\AE\";\r\ + \n \"alarm-clock\"=\"\\E2\\8F\\B0\";\r\ + \n \"arrow-down\"=\"\\E2\\AC\\87\";\r\ + \n \"arrow-up\"=\"\\E2\\AC\\86\";\r\ + \n \"calendar\"=\"\\F0\\9F\\93\\85\";\r\ + \n \"card-file-box\"=\"\\F0\\9F\\97\\83\";\r\ + \n \"chart-decreasing\"=\"\\F0\\9F\\93\\89\";\r\ + \n \"chart-increasing\"=\"\\F0\\9F\\93\\88\";\r\ + \n \"cloud\"=\"\\E2\\98\\81\";\r\ + \n \"cross-mark\"=\"\\E2\\9D\\8C\";\r\ + \n \"earth\"=\"\\F0\\9F\\8C\\8D\";\r\ + \n \"fire\"=\"\\F0\\9F\\94\\A5\";\r\ + \n \"floppy-disk\"=\"\\F0\\9F\\92\\BE\";\r\ + \n \"gear\"=\"\\E2\\9A\\99\";\r\ + \n \"heart\"=\"\\E2\\99\\A5\";\r\ + \n \"high-voltage-sign\"=\"\\E2\\9A\\A1\";\r\ + \n \"incoming-envelope\"=\"\\F0\\9F\\93\\A8\";\r\ + \n \"information\"=\"\\E2\\84\\B9\";\r\ + \n \"large-orange-circle\"=\"\\F0\\9F\\9F\\A0\";\r\ + \n \"large-red-circle\"=\"\\F0\\9F\\94\\B4\";\r\ + \n \"link\"=\"\\F0\\9F\\94\\97\";\r\ + \n \"lock-with-ink-pen\"=\"\\F0\\9F\\94\\8F\";\r\ + \n \"memo\"=\"\\F0\\9F\\93\\9D\";\r\ + \n \"mobile-phone\"=\"\\F0\\9F\\93\\B1\";\r\ + \n \"pushpin\"=\"\\F0\\9F\\93\\8C\";\r\ + \n \"scissors\"=\"\\E2\\9C\\82\";\r\ + \n \"scroll\"=\"\\F0\\9F\\93\\9C\";\r\ + \n \"smiley-partying-face\"=\"\\F0\\9F\\A5\\B3\";\r\ + \n \"smiley-smiling-face\"=\"\\E2\\98\\BA\";\r\ + \n \"smiley-winking-face-with-tongue\"=\"\\F0\\9F\\98\\9C\";\r\ + \n \"sparkles\"=\"\\E2\\9C\\A8\";\r\ + \n \"speech-balloon\"=\"\\F0\\9F\\92\\AC\";\r\ + \n \"star\"=\"\\E2\\AD\\90\";\r\ + \n \"warning-sign\"=\"\\E2\\9A\\A0\";\r\ + \n \"white-heavy-check-mark\"=\"\\E2\\9C\\85\"\r\ + \n }, \$SymbolsExtra);\r\ + \n :local Magic [ :pick [ /system/clock/get date ] 4 10 ];\r\ + \n :local Special {\r\ + \n \"information-04-01\"=\"\\F0\\9F\\9A\\BB\";\r\ + \n \"large-orange-circle-04-01\"=\"\\F0\\9F\\8D\\8A\";\r\ + \n \"large-orange-circle-10-31\"=\"\\F0\\9F\\8E\\83\";\r\ + \n \"large-red-circle-04-01\"=\"\\F0\\9F\\8D\\92\" };\r\ + \n :if ([ :len (\$Symbols->\$Name) ] = 0) do={\r\ + \n \$LogPrint warning \$0 (\"No symbol available for name '\" . \$Name \ + . \"'!\");\r\ + \n :return \"\";\r\ + \n }\r\ + \n :return ([ \$EitherOr (\$Special->(\$Name . \$Magic)) (\$Symbols->\$Na\ + me) ] . \"\\EF\\B8\\8F\");\r\ + \n}\r\ + \n:set SymbolForNotification do={\r\ + \n :global NotificationsWithSymbols;\r\ + \n :global SymbolByUnicodeName;\r\ + \n :global IfThenElse;\r\ + \n :if (\$NotificationsWithSymbols != true) do={:return [ \$IfThenElse ([\ + \_:len \$2 ] > 0) ([ :tostr \$2 ] . \" \") \"\" ]}\r\ + \n :local Return \"\";\r\ + \n :foreach Symbol in=[ :toarray \$1 ] do={:set Return (\$Return . [ \$Sy\ + mbolByUnicodeName \$Symbol ])}\r\ + \n :return (\$Return . \" \");\r\ + \n}\r\ + \n:set Unix2Dos do={:return [ :tocrlf [ :tostr \$1 ] ]}\r\ + \n:set UrlEncode do={\r\ + \n :local Input [ :tostr \$1 ];\r\ + \n :if ([ :len \$Input ] = 0) do={:return \"\"}\r\ + \n :local Return \"\";\r\ + \n :local Chars (\"\\n\\r !\\\"#\\\$%&'()*+,:;<=>\?@[\\\\]^`{|}~\");\r\ + \n :local Subs { \"%0A\"; \"%0D\"; \"%20\"; \"%21\"; \"%22\"; \"%23\"; \"\ + %24\"; \"%25\"; \"%26\"; \"%27\";\r\ + \n \"%28\"; \"%29\"; \"%2A\"; \"%2B\"; \"%2C\"; \"%3A\"; \"%3B\"; \ + \"%3C\"; \"%3D\"; \"%3E\"; \"%3F\";\r\ + \n \"%40\"; \"%5B\"; \"%5C\"; \"%5D\"; \"%5E\"; \"%60\"; \"%7B\"; \ + \"%7C\"; \"%7D\"; \"%7E\" };\r\ + \n :for I from=0 to=([ :len \$Input ] - 1) do={\r\ + \n :local Char [ :pick \$Input \$I ];\r\ + \n :local Replace [ :find \$Chars \$Char ];\r\ + \n :if ([ :typeof \$Replace ] = \"num\") do={:set Char (\$Subs->\$Repla\ + ce)}\r\ + \n :set Return (\$Return . \$Char);\r\ + \n }\r\ + \n :return \$Return;\r\ + \n}\r\ + \n:set ValidateSyntax do={\r\ + \n :local Code [ :tostr \$1 ];\r\ + \n :global LogPrint;\r\ + \n :onerror Err {\r\ + \n [ :parse (\":local Validate do={\\n\" . \$Code . \"\\n}\") ];\r\ + \n } do={\r\ + \n \$LogPrint debug \$0 (\"Valdation failed: \" . \$Err);\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\r\ + \n:set IsDNSResolving do={\r\ + \n :do {:resolve \"api.telegram.org\"} on-error={:return false}\r\ + \n :return true;\r\ + \n}\r\ + \n:set IsFullyConnected do={\r\ + \n :global IsDNSResolving;\r\ + \n :global IsTimeSync;\r\ + \n :if ([ \$IsDNSResolving ] = false) do={:return false};\r\ + \n :if ([ \$IsTimeSync ] = false) do={:return false};\r\ + \n :return true;\r\ + \n}\r\ + \n:set IsTimeSync do={\r\ + \n :global IsTimeSyncCached;\r\ + \n :global IsTimeSyncResetNtp;\r\ + \n :if (\$IsTimeSyncCached = true) do={:return true}\r\ + \n :if ([ /system/ntp/client/get enabled ] = true) do={\r\ + \n :if ([ /system/ntp/client/get status ] = \"synchronized\") do={\r\ + \n :set IsTimeSyncCached true;\r\ + \n :return true;\r\ + \n }\r\ + \n :local Uptime [ /system/resource/get uptime ];\r\ + \n :if ([ :typeof \$IsTimeSyncResetNtp ] = \"nothing\") do={\r\ + \n :set IsTimeSyncResetNtp \$Uptime;\r\ + \n }\r\ + \n :if (\$Uptime - \$IsTimeSyncResetNtp < 3m) do={:return false}\r\ + \n :log warning \"\$0 The ntp client is configured, but did not sync.\"\ + ;\r\ + \n :set IsTimeSyncResetNtp \$Uptime;\r\ + \n /system/ntp/client/set enabled=no;\r\ + \n :delay 20ms;\r\ + \n /system/ntp/client/set enabled=yes;\r\ + \n :return false;\r\ + \n }\r\ + \n :if ([ /system/license/get ]->\"level\" = \"free\" || \\\r\ + \n [ /system/resource/get ]->\"board-name\" = \"x86\") do={\r\ + \n :log debug \"\$0 No ntp client configured, relying on RTC for CHR fr\ + ee license and x86.\";\r\ + \n :return true;\r\ + \n }\r\ + \n :if ([ /ip/cloud/get update-time ] = true) do={\r\ + \n :if ([ :typeof [ /ip/cloud/get public-address ] ] = \"ip\") do={\r\ + \n :set IsTimeSyncCached true;\r\ + \n :return true;\r\ + \n }\r\ + \n :return false;\r\ + \n }\r\ + \n :log debug \"\$0 No time source configured! Returning gracefully...\";\ + \r\ + \n :return true;\r\ + \n}\r\ + \n\r\ + \n# read parts of a large file\r\ + \n:set FetchLargeFiles do={\r\ + \n :local ScriptName [:tostr \$1];\r\ + \n :local fetchUrl [:tostr \$2];\r\ + \n :local CheckCert [:tostr \$3];\r\ + \n :local fetchMode [:tostr \$4];\r\ + \n :local fetchMethod [:tostr \$5];\r\ + \n :local FetchString \"undefined\";\r\ + \n \r\ + \n :global CleanName;\r\ + \n :global FetchUserAgentStr;\r\ + \n :global GetRandom20CharAlNum;\r\ + \n :global IfThenElse;\r\ + \n :global LogPrint;\r\ + \n :global MkDir;\r\ + \n :global RmDir;\r\ + \n :global RmFile;\r\ + \n :global WaitForFile;\r\ + \n\r\ + \n :set CheckCert [ \$IfThenElse (\$CheckCert = \"false\") \"no\" \"yes-w\ + ithout-crl\" ];\r\ + \n #:set fetchMode [ \$IfThenElse (\$fetchMode != \"false\") [:tostr (\"m\ + ode=\" . \$fetchMode)] ];\r\ + \n #:set fetchMethod [\$IfThenElse (\$fetchMethod != \"false\") [:tostr (\ + \"http-method=\\\"\" . \$fetchMethod . \"\\\"\") ]];\r\ + \n \r\ + \n :local DirName (\"tmpfs/\" . [ \$CleanName \$ScriptName ]);\r\ + \n :if ([ \$MkDir \$DirName ] = false) do={\r\ + \n \$LogPrint error \$0 (\"Failed creating directory!\");\r\ + \n :return false;\r\ + \n }\r\ + \n :local FileName (\$DirName . \"/\" . [ \$CleanName \$0 ] . \"-\" . [ \ + \$GetRandom20CharAlNum ]);\r\ + \n #/tool/fetch check-certificate=\$CheckCert \$Url dst-path=\$FileName h\ + ttp-header-field=({ [ \$FetchUserAgentStr \$ScriptName ] }) as-value;\r\ + \n #:log warning (\"\\\$fUrl =\" . \$2 . ({[ \$fMode ]}));\r\ + \n :onerror Err {\r\ + \n :set FetchString (\"/tool/fetch \" . \\\r\ + \n [\$IfThenElse ([\$fetchMethod] != \"false\") (\"http-method=\\\"\"\ + \_. \$fetchMethod . \"\\\" \")] . \\\r\ + \n \"check-certificate=\" . \$CheckCert . \" url=(\\\"\" . \$fetchUrl\ + \_. \"\\\") \" . \\\r\ + \n [\$IfThenElse ([\$fetchMode] != \"false\") (\"mode=\" . \$fetchMod\ + e . \" \")] . \\\r\ + \n http-header-field=({ [ \$FetchUserAgentStr \$ScriptName ] }) as-va\ + lue);\r\ + \n :log warning (\"\\\$FetchSring = \" . \$FetchString);\r\ + \n :put [\$FetchString];\r\ + \n #:put [/tool/fetch \$fetchMode check-certificate=\$CheckCert url=(\$\ + fetchUrl) dst-path=(\$FileName) http-header-field=({ [ \$FetchUserAgentStr\ + \_\$ScriptName ] }) as-value];\r\ + \n } do={\r\ + \n :if ([ \$WaitForFile \$FileName 500ms ] = true) do={\r\ + \n \$RmFile \$FileName;\r\ + \n }\r\ + \n \$LogPrint debug \$0 (\"Failed downloading from \" . \$fetchUrl . \"\ + \_- \" . \$Err);\r\ + \n \$RmDir \$DirName;\r\ + \n :return false;\r\ + \n }\r\ + \n :if ([ \$WaitForFile \$FileName 5s ] = false) do={\r\ + \n \$LogPrint debug \$0 (\"The file downloaded from \" . \$fetchUrl . \ + \" did not show up.\");\r\ + \n :return false;\r\ + \n }\r\ + \n :local FileSize [ /file/get \$FileName size ];\r\ + \n :local Return \"\";\r\ + \n :local VarSize 0;\r\ + \n :while (\$VarSize != \$FileSize) do={\r\ + \n :set Return (\$Return . ([ /file/read offset=\$VarSize chunk-size=32\ + 768 file=\$FileName as-value ]->\"data\"));\r\ + \n :set FileSize [ /file/get \$FileName size ];\r\ + \n :set VarSize [ :len \$Return ];\r\ + \n :if (\$VarSize > \$FileSize) do={\r\ + \n :delay 100ms;\r\ + \n }\r\ + \n }\r\ + \n \$RmDir \$DirName;\r\ + \n :return \$Return;\r\ + \n}\r\ + \n\r\ + \n# Global Environment clear. Use: \"\$GlobalEnvRemove True;\".\r\ + \n:set GlobalEnvRemove do={\r\ + \n :local doRmEnv [ :tostr \$1 ];\r\ + \n :global GlobalScriptsUrl;\r\ + \n :local ScriptsUrl;\r\ + \n :global LogPrint;\r\ + \n :if (\$doRmEnv != \"True\") do={\r\ + \n \$LogPrint error \"GlobalEnvRemove\" (\"This script is needed \\\"T\ + rue\\\" for confirm to remove global environment variables!\");\r\ + \n :return [];\r\ + \n :error true; \r\ + \n } else={\r\ + \n :set ScriptsUrl \$GlobalScriptsUrl;\r\ + \n :delay 5;\r\ + \n :foreach var in=[/system/script/environment print as-value] do={/sy\ + stem/script/environment remove (\$var->\".id\")}\r\ + \n :delay 5;\r\ + \n :global GlobalScriptsUrl \$ScriptsUrl;\r\ + \n \$LogPrint warning \"GlobalEnvRemove\" (\"Done!\");\r\ + \n :return [];\r\ + \n :error false;\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n# Add and fix global scheduler\r\ + \n:put \"Add or/and fix Global scheduler...\";\r\ + \n:local OnEvent \"/system/script { run AM-GlobalConfig; run AM-GlobalFunc\ + ; }\";\r\ + \n:local Comment \"Setup Global Environment for scripts\";\r\ + \n:if ([ :len [ /system/scheduler/find where name=\"AM-SetGlobalEnv\" ] ] \ + = 0) do={\r\ + \n /system/scheduler/add name=\"AM-SetGlobalEnv\" comment=\$Comment on-ev\ + ent=\$OnEvent start-time=startup;\r\ + \n}\r\ + \n:if ([ /system/scheduler/get \"AM-SetGlobalEnv\" comment ] != \$Comment)\ + \_do={\r\ + \n /system/scheduler/set \"AM-SetGlobalEnv\" comment=\$Comment;\r\ + \n}\r\ + \n:if ([ /system/scheduler/get \"AM-SetGlobalEnv\" on-event ] != \$OnEvent\ + ) do={\r\ + \n /system/scheduler/set \"AM-SetGlobalEnv\" on-event=\$OnEvent;\r\ + \n}\r\ + \n# Add Update Script scheduler\r\ + \n:put \"Add or/and fix Update Script scheduler\";\r\ + \n:set OnEvent \":global ScriptInstallUpdate; \\\$ScriptInstallUpdate;\";\ + \r\ + \n:set Comment \"Every Day Check For Update Scripts\";\r\ + \n:if ([ :len [ /system/scheduler/find where name=\"AM-ScriptInstallUpdate\ + \" ] ] = 0) do={\r\ + \n/system/scheduler/add name=\"AM-ScriptInstallUpdate\" comment=\$Comment \ + start-time=startup interval=1d on-event=\$OnEvent;\r\ + \n}\r\ + \n\r\ + \n#:local Resource [ /system/resource/get ];\r\ + \n#:log info (\$ScriptName . \" Loaded on \" . \$Resource->\"board-name\" \ + . \" with RouterOS \" . \$Resource->\"version\" . \" and Architecture \" .\ + \".\");\r\ + \n\r\ + \n:onerror Err {\r\ + \n :global GlobalConfReady;\r\ + \n :retry { :if (\$GlobalConfReady != true) do={ :error (\"Global configs\ + \_not ready.\"); }; } delay=100ms max=5;\r\ + \n\r\ + \n# signal we are ready\r\ + \n:set GlobalFuncReady true;\r\ + \n:set ExitOK true;\r\ + \n:log warning (\"This script \$ScriptName Loaded on \" . \$devBoardName .\ + \_\"\\nRouterOS: \" . \$devCurVersion . \"\\nArchitecture: \" . \$devCurAr\ + ch . \"\\nIdentity: \" . \$Identity);\r\ + \n} do={:global ExitOnError; \$ExitOnError \$0 \$Err;}\r\ + \n\r\ + \n#} do={:global ExitError; \$ExitError \$ExitOK [ :jobname ] \$Err}\r\ + \n# log the successful load of the script, or an error if it failed\r\ + \n#:if ([\$GlobalFuncReady] = true && [\$GlobalConfReady] = true) do={\r\ + \n" +add comment="Import ssh keys for public key authentication" \ + dont-require-permissions=no name=AM-SshKeysImport owner=AM-SshKeysImport \ + policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + source="#!rsc by Vados\r\ + \n# RouterOS script: AM-SshKeysImport\r\ + \n# Script comment: Import ssh keys for public key authentication\r\ + \n# Copyright (c) 2005-2026 Vados \r\ + \n#\r\ + \n# requires RouterOS, version=7.19\r\ + \n#\r\ + \n:local ExitOK false;\r\ + \n:onerror Err {\r\ + \n :global GlobalConfReady; :global GlobalFuncReady;\r\ + \n :retry { :if (\$GlobalConfReady != true || \$GlobalFuncReady != true) \ + \\\r\ + \n do={ :error (\"Global configs or functions not ready.\"); }; } del\ + ay=500ms max=50;\r\ + \n :local ScriptName [ :jobname ];\r\ + \n\r\ + \n:global SSHKeysImport;\r\ + \n:global SSHKeysImportFile;\r\ + \n\r\ + \n# import single key passed as string\r\ + \n:set SSHKeysImport do={ :onerror Err {\r\ + \n :local Key [ :tostr \$1 ];\r\ + \n :local User [ :tostr \$2 ];\r\ + \n :global GetRandom20CharAlNum;\r\ + \n :global LogPrint;\r\ + \n :global MkDir;\r\ + \n :global RmDir;\r\ + \n :global WaitForFile;\r\ + \n :if ([ :len \$Key ] = 0 || [ :len \$User ] = 0) do={\r\ + \n \$LogPrint warning \$0 (\"Missing argument(s), please pass key and u\ + ser!\");\r\ + \n :return false;\r\ + \n }\r\ + \n :if ([ :len [ /user/find where name=\$User ] ] = 0) do={\r\ + \n \$LogPrint warning \$0 (\"User '\" . \$User . \"' does not exist.\")\ + ;\r\ + \n :return false;\r\ + \n }\r\ + \n :local KeyVal ([ :deserialize \$Key delimiter=\" \" from=dsv options=d\ + sv.plain ]->0);\r\ + \n :if (!(\$KeyVal->0 = \"ssh-ed25519\" || \$KeyVal->0 = \"ssh-rsa\")) do\ + ={\r\ + \n \$LogPrint warning \$0 (\"SSH key of type '\" . \$KeyVal->0 . \"' is\ + \_not supported.\");\r\ + \n :return false;\r\ + \n }\r\ + \n :local FingerPrintMD5 [ :convert from=base64 transform=md5 to=hex (\$K\ + eyVal->1) ];\r\ + \n :local RegEx (\"\\\\bmd5=\" . \$FingerPrintMD5 . \"\\\\b\");\r\ + \n :if ([ :len [ /user/ssh-keys/find where user=\$User \\\r\ + \n (key-owner~\$RegEx or info~\$RegEx) ] ] > 0) do={\r\ + \n \$LogPrint warning \$0 (\"The ssh public key (MD5:\" . \$FingerPrint\ + MD5 . \\\r\ + \n \") is already available for user '\" . \$User . \"'.\");\r\ + \n :return false;\r\ + \n }\r\ + \n :if ([ \$MkDir \"tmpfs/ssh-keys-import\" ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"Creating directory 'tmpfs/ssh-keys-import'\ + \_failed!\");\r\ + \n :return false;\r\ + \n }\r\ + \n :local FileName (\"tmpfs/ssh-keys-import/key-\" . [ \$GetRandom20CharA\ + lNum 6 ] . \".pub\");\r\ + \n /file/add name=\$FileName contents=(\$Key . \", md5=\" . \$FingerPrint\ + MD5);\r\ + \n \$WaitForFile \$FileName;\r\ + \n :onerror Err {\r\ + \n /user/ssh-keys/import public-key-file=\$FileName user=\$User;\r\ + \n \$LogPrint info \$0 (\"Imported ssh public key (\" . \$KeyVal->2 . \ + \", \" . \$KeyVal->0 . \", \" . \\\r\ + \n \"MD5:\" . \$FingerPrintMD5 . \") for user '\" . \$User . \"'.\");\ + \r\ + \n \$RmDir \"tmpfs/ssh-keys-import\";\r\ + \n } do={\r\ + \n \$LogPrint warning \$0 (\"Failed importing key: \" . \$Err);\r\ + \n \$RmDir \"tmpfs/ssh-keys-import\";\r\ + \n :return false;\r\ + \n }\r\ + \n} do={\r\ + \n :global ExitOnError; \$ExitOnError \$0 \$Err;\r\ + \n} }\r\ + \n\r\ + \n# import keys from a file\r\ + \n:set SSHKeysImportFile do={ :onerror Err {\r\ + \n :local FileName [ :tostr \$1 ];\r\ + \n :local User [ :tostr \$2 ];\r\ + \n :global EitherOr;\r\ + \n :global FileExists;\r\ + \n :global LogPrint;\r\ + \n :global ParseKeyValueStore;\r\ + \n :global SSHKeysImport;\r\ + \n :if ([ :len \$FileName ] = 0 || [ :len \$User ] = 0) do={\r\ + \n \$LogPrint warning \$0 (\"Missing argument(s), please pass file name\ + \_and user!\");\r\ + \n :return false;\r\ + \n }\r\ + \n :if ([ \$FileExists \$FileName ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"File '\" . \$FileName . \"' does not exist\ + .\");\r\ + \n :return false;\r\ + \n }\r\ + \n :local Keys [ :tolf [ /file/get \$FileName contents ] ];\r\ + \n :foreach KeyVal in=[ :deserialize \$Keys delimiter=\" \" from=dsv opti\ + ons=dsv.plain ] do={\r\ + \n :local Continue false;\r\ + \n :if (\$KeyVal->0 = \"ssh-ed25519\" || \$KeyVal->0 = \"ssh-rsa\") do=\ + {\r\ + \n :if ([ \$SSHKeysImport (\$KeyVal->0 . \" \" . \$KeyVal->1 . \" \" \ + . \$KeyVal->2) \$User ] = false) do={\r\ + \n \$LogPrint warning \$0 (\"Failed importing key for user '\" . \$\ + User . \"'.\");\r\ + \n }\r\ + \n :set Continue true;\r\ + \n }\r\ + \n :if (\$Continue = false && \$KeyVal->0 = \"#\") do={\r\ + \n :set User [ \$EitherOr ([ \$ParseKeyValueStore (\$KeyVal->1) ]->\"\ + user\") \$User ];\r\ + \n :set Continue true;\r\ + \n }\r\ + \n :if (\$Continue = false && [ :len (\$KeyVal->0) ] > 0) do={\r\ + \n \$LogPrint warning \$0 (\"SSH key of type '\" . \$KeyVal->0 . \"' \ + is not supported.\");\r\ + \n }\r\ + \n }\r\ + \n} do={\r\ + \n :global ExitOnError; \$ExitOnError \$0 \$Err;\r\ + \n} }\r\ + \n} do={:global ExitError; \$ExitError \$ExitOK [ :jobname ] \$Err}\r\ + \n" +/system watchdog +set watchdog-timer=no +/tool e-mail +set certificate-verification=no from=MikroVados port=587 \ + server=smtp.mail.me.com tls=starttls user=vadossio@icloud.com +/tool mac-server +set allowed-interface-list=LAN +/tool mac-server mac-winbox +set allowed-interface-list=LAN +/tool netwatch +add comment="doh, doh-url=https://security.cloudflare-dns.com/dns-query, notif\ + y, name=CloudFlare-doh IPv4 1" disabled=yes down-script="" host=1.1.1.1 \ + http-codes="" test-script="" type=simple up-script="" +add check-certificate=no comment="doh-fallback, doh-url=https://security.cloud\ + flare-dns.com/dns-query, doh-cert=DigiCert Global Root CA, notify, name=Cl\ + oudFlare-doh IPv4" disabled=yes down-script="" host=1.0.0.1 http-codes="" \ + port=443 test-script="" type=simple up-script="" +add comment="dns-fallback, notify, name=Google-DNS IPv4" disabled=yes \ + down-script="" host=8.8.8.8 http-codes="" test-script="" type=simple \ + up-script="" +add comment="doh-fallback, doh-url=https://dns.google/dns-query, doh-cert=GTS \ + Root R1, notify, name=Google-DOH IPv4" disabled=yes down-script="" host=\ + 8.8.4.4 http-codes="" test-script="" type=simple up-script="" +add comment="dns, notify, name=Cuad9-DOH IPv4" disabled=yes down-script="" \ + host=9.9.9.9 http-codes="" test-script="" type=simple up-script="" +add comment="doh-fallback, doh-url=https://dns.quad9.net/dns-query, name=Cuad9\ + -DOH IPv4" disabled=yes down-script="" host=149.112.112.112 http-codes="" \ + test-script="" type=simple up-script="" +add comment="dns-fallback, notify, name=ns1.unet.ws" disabled=yes \ + down-script="" host=91.192.189.2 http-codes="" test-script="" type=simple \ + up-script="" +/tool sniffer +set filter-interface=Bridge-LAN filter-src-ip-address=10.30.30.50/32 +/user aaa +set accounting=no diff --git a/MikroMaster/history/20260302/20260302232004-Diff-Config.rsc b/MikroMaster/history/20260302/20260302232004-Diff-Config.rsc new file mode 100644 index 0000000..de79a82 --- /dev/null +++ b/MikroMaster/history/20260302/20260302232004-Diff-Config.rsc @@ -0,0 +1,4 @@ +1c1 +< # 2026-03-02 23:20:04 by RouterOS 7.21.2 +--- +> # 2026-03-02 23:00:03 by RouterOS 7.21.2 -- 2.52.0