From 14cf002082939ea57fe071b7b0574be887793f34 Mon Sep 17 00:00:00 2001 From: vados-dev <192440777+vados-dev@users.noreply.github.com> Date: Thu, 12 Mar 2026 06:43:26 +0300 Subject: [PATCH] Backup for MikroNUC sucessfully creatd at Mar 12 06:43:26. --- .../20260312/20260312064322-Binary.backup | Bin 0 -> 308276 bytes MikroNUC/20260312/20260312064322-Config.rsc | 2779 +++++++++++++++++ .../20260312/20260312064322-Diff-Config.rsc | 36 + 3 files changed, 2815 insertions(+) create mode 100644 MikroNUC/20260312/20260312064322-Binary.backup create mode 100644 MikroNUC/20260312/20260312064322-Config.rsc create mode 100644 MikroNUC/history/20260312/20260312064322-Diff-Config.rsc diff --git a/MikroNUC/20260312/20260312064322-Binary.backup b/MikroNUC/20260312/20260312064322-Binary.backup new file mode 100644 index 0000000000000000000000000000000000000000..0bf4fbaa77f9f0172bf2fb5d8090ec1a3869caef GIT binary patch literal 308276 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\"name\") ];\r\ + \n#[/system/script get \$expScript name];\r\ + \n:delay 2s;\r\ + \n\r\ + \n:set expSrc [/system/script print where name=\$expName];\r\ + \n/system/script print where name=\$expName;\r\ + \n#[:put [/system/script get \$expScript source]];\r\ + \n:put [\$expSrc];\r\ + \n:delay 2s;\r\ + \n:set FileName \$expName;\r\ + \n:set FilePath (\$DirPath . \$FileName);\r\ + \n\r\ + \n#:log warning \"\\n----------------------\\n\\\$expSrc = \$expSrc\\n____\ + ______________________________\";\r\ + \n:log info \"\\n\\\$FileName = '\$FileName'\";\r\ + \n:log info \"\\n\\\$FilePath = \$FilePath\";\r\ + \n#:log warning {/system/script/get source=[/system/script/get \$expScript\ + \_source];};\r\ + \n\r\ + \n#\$[/system script get [/system script find name=\"\$FileName\"] source]\ + \r\ + \n\r\ + \n#:local gettingScript \"\$FileName\";\r\ + \n#:execute script=\"[[:parse \\\"[:parse { :put (\"\$[/system script get \ + [/system script find name=\$FileName] source]\"); } \\\"]]\"; \\\r\ + \n\r\ + \n#:execute script={:put \"[:parse \\\"[:parse [/system/script get [/syste\ + m/script find name=\$gettingScript] source];\\\"]]\";} \\\r\ + \n# file=(\$FilePath . \".rsc\\00\");\r\ + \n:do {\r\ + \n:local fName (\$FilePath . \".rsc\");\r\ + \n#:delay 3s;\r\ + \n#/file add name=\$fName;\r\ + \n:put [:tostr [\$expSrc]];\r\ + \n/file set \$fName contents=[:put [\$expSrc]];\r\ + \n:delay 3s;\r\ + \n\$WaitForFile \$fName;\r\ + \n(\$FilePath . \".rsc\");\r\ + \n#:delay 2s;\r\ + \n\r\ + \n} on-error={\r\ + \n:log error \"\\nERROR \\\$FilePath = \$FilePath\";\r\ + \n}\r\ + \n#\$WaitForFile (\$FilePath . \".rsc\");\r\ + \n#:execute script={ :put [/system/script get [:put \$FileName] source]; }\ + ;\r\ + \n#/system/script export \$Sscript file=\$FilePath;\r\ + \n#/system/script/export [:put [/system/script/get \$expScript source]] fi\ + le=\$FilePath;\r\ + \n#:execute script={ :put [/system/script/get \$expScript source]; } \\\r\ + \n\r\ + \n#:log warning \"\\n\\\$expScript = \$expScript\";\r\ + \n# \\\r\ + \n# file=(\$FilePath . \".rsc\\00\");\r\ + \n#script={:put [/system/script/get \$FileName source];} file=(\$FilePath\ + \_. \".rsc\\00\");\r\ + \n#/system script export \$src file=(\$FilePath . \$FileName);\r\ + \n}\r\ + \n\r\ + \n:log warning \"\\nComplete!\";\r\ + \n\r\ + \n # :execute script={ :put [ /system/script/get Amster-GlobalConfig sou\ + rce ]; } \\\r\ + \n # file=(\$FilePath . \".conf\\00\");\r\ + \n # \$WaitForFile (\$FilePath . \".conf\");\r\ + \n # :onerror Err {\r\ + \n # /tool/fetch upload=yes url=(\$BackupUploadUrl . \"/\" . \$FileName\ + \_. \".conf\") \\\r\ + \n # user=\$BackupUploadUser password=\$BackupUploadPass src-path=(\ + \$FilePath . \".conf\");\r\ + \n # :set ConfigFile [ /file/get (\$FilePath . \".conf\") ];\r\ + \n # :set (\$ConfigFile->\"name\") (\$FileName . \".conf\");\r\ + \n " +add dont-require-permissions=no name=test1 owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="\ + \r\ + \n#:local runningVer [:find [/system/resource/get version] \"(\"];\r\ + \n\r\ + \n:local runningChannel;\r\ + \n:local runningVersion;\r\ + \n:local ParseCustom;\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\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:global runningChannel [\$ParseCustom [/system/resource/get version] \"(\ + \" \")\" 1];\r\ + \n:log warning [\$runningChannel];\r\ + \n:set runningVersion [\$ParseCustom [/system/resource/get version] \" \" \ + \")\" 2];\r\ + \n:log warning [\$runningVersion];\r\ + \n\r\ + \n\r\ + \n\r\ + \n# :if ([:len \$open] = 0) do={\r\ + \n# :log error \"\$SMP Could not extract installed OS channel from vers\ + ion string: `\$runningOsAndChannel`.\";\r\ + \n# :error \"\$SMP error, check logs\";\r\ + \n# }\r\ + \n# :local rest [:pick \$runningOsAndChannel (\$open+1) [:len \$runningOs\ + AndChannel]];\r\ + \n# :local close [:find \$rest \")\"];\r\ + \n# :local channel [:pick \$rest 0 \$close];\r\ + \n# :return \$channel;\r\ + \n#}" +add dont-require-permissions=no name=01-Amster-Init-Script owner=vados \ + policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + source="# Amster Initial Script\r\ + \n#\r\ + \n#:global GlobalEnvRemove true; /system/script {run Amster-GlobalEnvRemov\ + e; };\r\ + \n#:delay 1s;\r\ + \n:#global ReloadGlobal true; \r\ + \n\r\ + \n:global AmScriptsUrl \"https://ros.vados.ru/\";\r\ + \n:global defOwner \"vados\";\r\ + \n:global AmFirstRun;\r\ + \n\r\ + \n:set AmFirstRun do={\r\ + \n :global AmScriptsUrl;\r\ + \n :global defOwner;\r\ + \n #:global ParseKeyValueStore;\r\ + \n #:local AmUpdCRLF true;\r\ + \n #:local IfThenElse;\r\ + \n #:set IfThenElse do={:if ([ :tostr \$1 ] = \"true\" || [ :tobool \$1\ + \_] = true) do={:return \$2}; :return \$3}\r\ + \n #/certificate/settings/set builtin-trust-store=fetch;\r\ + \n #/tool/fetch \"\$scriptsUrl/certs/Root-YE.pem\" dst-path=\"root-ye.p\ + em\";\r\ + \n #/certificate/import file-name=\"root-ye.pem\" passphrase=\"\";\r\ + \n # For basic verification we rename the certificate and print it by f\ + ingerprint. Make sure exactly this one certificate (\"Root-YE\") is shown.\ + \r\ + \n #/certificate/set name=\"Root-YE\" [ find where common-name=\"Root Y\ + E\" ];\r\ + \n #/certificate/print proplist=name,fingerprint where fingerprint=\"e1\ + 4ffcad5b0025731006caa43a121a22d8e9700f4fb9cf852f02a708aa5d5666\";\r\ + \n #:log info \"\\nAmScriptsUrl = \$AmScriptsUrl\";\r\ + \n :local Scripts {\r\ + \n \"Amster-GlobalConfig\"\r\ + \n \"Amster-GlobalFunc\";\r\ + \n# \"Amster-SFTP-backup\"\r\ + \n# \"Amster-BkpEmail-and-upd\";\r\ + \n };\r\ + \n# /system/script/set owner=(\$ScriptVal->\"name\") \\\r\ + \n# source=[ \$IfThenElse (\$ScriptUpdatesCRLF = true) \$SourceCRLF \$S\ + ourceNew ] \$Script;\r\ + \n :foreach Script in=\$Scripts do={\r\ + \n :put \"Installing \$Script...\";\r\ + \n /system/script/remove [ find where name=\$Script ];\r\ + \n /system/script/add name=\$Script owner=\$defOwner source=([ /too\ + l/fetch (\"\$AmScriptsUrl\" . \$Script . \".rsc\") output=user as-value ]-\ + >\"data\");\r\ + \n /system/script/set source=[ :tocrlf [ get \$Script source ] ] \$\ + Script;\r\ + \n };\r\ + \n /system/script { run Amster-GlobalConfig; run Amster-GlobalFunc; }\r\ + \n}\r\ + \n:global AmUpdRun;\r\ + \n:set AmUpdRun do={\r\ + \n #:local UpdScript [ :tostr \$1 ];\r\ + \n #:global ParseKeyValueStore;\r\ + \n :global AmScriptsUrl;\r\ + \n :global defOwner;\r\ + \n :local Scripts {\r\ + \n# \"Amster-GlobalConfig\"\r\ + \n# \"Amster-GlobalFunc\"\r\ + \n# \"Amster-GlobalRemove\"\r\ + \n \"Amster-backup-SFTP\"\r\ + \n \"Amster-SFTP-backup\"\r\ + \n \"Amster-BkpEmail-and-upd\"\r\ + \n \"Amster-TG-Bot\"\r\ + \n \"Amster-TG-Notification\";\r\ + \n };\r\ + \n :foreach Script in=\$Scripts do={\r\ + \n :put \"updating \$Script...\";\r\ + \n /system/script/remove [ find where name=\$Script ];\r\ + \n /system/script/add name=\$Script owner=\$defOwner source=([ /too\ + l/fetch (\"\$AmScriptsUrl\" . \$Script . \".rsc\") output=user as-value ]-\ + >\"data\");\r\ + \n /system/script/set source=[ :tocrlf [ get \$Script source ] ] \$\ + Script;\r\ + \n };\r\ + \n# /system/script/add name=\$Script owner=\$AmOwner source=([ /tool/fe\ + tch check-certificate=yes-without-crl (\"\$AmScriptsUrl\" . \$Script . \".\ + rsc\") output=user as-value ]->\"data\"); };\r\ + \n}\r\ + \n\r\ + \n\$AmFirstRun;\r\ + \n#\$AmUpdRun;\r\ + \n\r\ + \n#\$setUpdExist;\r\ + \n#:global setUpdExist;\r\ + \n#:global ParseKeyValueStore;\r\ + \n#:set setUpdExist do={\r\ + \n#:do {\r\ + \n#:global ParseKeyValueStore;\r\ + \n# :foreach Script in=[ /system/script/find where source~\"^#!rsc by Vad\ + os\\r\?\\n#comment=*\" ] do={\r\ + \n# :local ScriptVal [ /system/script/get \$Script ];\r\ + \n# :local ScriptInfo [ \$ParseKeyValueStore (\$ScriptVal->\"#comment\"\ + ) ];\r\ + \n# :local scriptName (\$ScriptVal->\"name\");\r\ + \n#:log warning (\"\\n\\\$scriptName = \". \$scriptName);\r\ + \n#: log warning (\"\\n\\\$ScriptInfo = \". \$ScriptInfo);\r\ + \n# }\r\ + \n#} on-error={}\r\ + \n#}\r\ + \n#\$name;\$owner;\$policy;\$dont-require-permissions;\$last-started;\$run\ + -count;\$source;\$invalid;\$comment;\$.id;\$.nextid;\$.dead;\$.about;\r\ + \n#;(evl / (evl /docommand=;(evl / (evl /foreachcounter=\$Script;do=;(evl \ + / (evl /localname=\$ScriptVal;value=(evl (evl /system/script/getnumber=\$S\ + cript))) (evl /localname=\$ScriptInfo;value=(evl (<%% \$ParseKeyValueStore\ + \_(> \$ParseKeyValueStore);(-> \$ScriptVal comment)))) (evl /localname=\$s\ + criptName) (evl /setname=\$scriptName;value=(-> #\$ScriptVal name)) (evl /\ + log/errormessage=(. \r\ + \n# \$ ScriptInfo = \$ScriptInfo)));in=(evl (evl /system/script/findwhere\ + =\$name;\$owner;\$policy;\$dont-require-permissions;\$last-started;\$run-c\ + ount;\$source;\$invalid;\$comment;\$.id;\$.nextid;\$.dead;\$.about;(~ \$so\ + urce (. ^#!rsc by Vados \r\ + \n# \? \r\ + \n#));5))));on-error=;(evl /)))\r\ + \n" +add dont-require-permissions=no name="Download cAP's Packages" owner=vados \ + policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + source="# +------------------------------+\r\ + \n# | |\r\ + \n# | Mikrotik RouterOS Scripts |\r\ + \n# | _Download cAP's Packages_ |\r\ + \n# | |\r\ + \n# +------------------------------+\r\ + \n# https://github.com/sebastian13/mikrotik-routeros-scripts\r\ + \n#\r\ + \n\r\ + \n# Set a directory path providing the required space\r\ + \n# Add a microSD card https://wiki.mikrotik.com/wiki/Manual:System/Disks\ + \r\ + \n# or setup a RAM-Disk via '/disk/add type=tmpfs tmpfs-max-size=20M slot=\ + ram'\r\ + \n:local dir \"/tmpfs/capsman-packages\";\r\ + \n\r\ + \n\r\ + \n# Set Package Path if required, set policy to none if using 'upgrade-cap\ + s' script\r\ + \n/interface/wifi/capsman/set package-path=\$dir upgrade-policy=none;\r\ + \n/caps-man/manager/set package-path=\$dir upgrade-policy=none;\r\ + \n#require-same-version;\r\ + \n\r\ + \n:local installed [/system package get value-name=version [find where nam\ + e=\"routeros\"]]\r\ + \n\r\ + \n# Delete old downloads\r\ + \n# /file/remove [ find type=package name~\"capsman*\" ]\r\ + \n\r\ + \n# Starting from RouterOS version 7.13, drivers for older wireless and 60\ + GHz interfaces are\r\ + \n# part of the separate \"wireless\" package. The existing \"wifiwave2\" \ + package has been divided\r\ + \n# into distinct packages: \"wifi-qcom\" and \"wifi-qcom-ac\".\r\ + \n# RouterOS >=7.12 is required to upgrade to 7.13.\r\ + \n# https://forum.mikrotik.com/viewtopic.php\?t=202423\r\ + \n\r\ + \n:foreach architecture in={ \"arm\";\r\ + \n# \"arm64\";\r\ + \n \"x86_64\";\r\ + \n \"mipsbe\"} do={\r\ + \n :foreach package in={ \"routeros\";\r\ + \n# \"wifi-qcom-ac\";\r\ + \n# \"wifi-qcom\";\r\ + \n \"wireless\"} do={ :do {\r\ + \n :put \"\"\r\ + \n :put \"Download \$package \$installed for \$architecture\"\r\ + \n /tool fetch mode=https \\\r\ + \n url=\"https://download.mikrotik.com/routeros/\$installed/\$packa\ + ge-\$installed-\$architecture.npk\" \\\r\ + \n dst-path=\"\$dir/\$package-\$installed-\$architecture.npk\"\r\ + \n } on-error={ :put \"Error downloading the file. On a 404, note t\ + hat the package may not exist for the specified architecture!\" }\r\ + \n }\r\ + \n}\r\ + \n" +add comment="Script for setup routeros scrypt system" \ + dont-require-permissions=no name=AM-setup owner=AM-setup policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + !rsc by Vados\r\ + \n# RouterOS script: AM-setup\r\ + \n# Script comment: Script for setup routeros scrypt system\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# :local ScriptName [ :jobname ];\r\ + \n# Additional commands:\r\ + \n#\r\ + \n# For scripts:\r\ + \n#:global NewScript \"script_name\"; \r\ + \n#:global GlobalScriptsUrl \"https://ros.vados.ru/\";\r\ + \n#/system/script/add name=\$NewScript owner=\$NewScript source=([/tool/fe\ + tch check-certificate=yes-without-crl (\$GlobalScriptsUrl . \$ScriptAdd . \ + \".rsc\") output=user as-value ]->\"data\");\r\ + \n#:global NewScript (a);\r\ + \n#:global ScriptInstallUpdate; \$ScriptInstallUpdate;\r\ + \n#\r\ + \n# For run from terminal:\r\ + \n#/system/script/add name=AM-setup owner=AM-Setup source=([/tool/fetch ch\ + eck-certificate=yes-without-crl \"https://ros.vados.ru/AM-setup.rsc\" outp\ + ut=user as-value ]->\"data\");\r\ + \n#\r\ + \n#:foreach Script in=[ /system/script/find where source~\"^#!rsc by Vados\ + \" ] do={\r\ + \n# if (\$ScriptUpdatesCRLF = true) do={\r\ + \n# /system/script/set source=[ :tocrlf [ get \$Script source ] ] \$Scri\ + pt;\r\ + \n# } else={\r\ + \n# /system/script/set source=[ :tolf [ get \$Script source ] ] \$Script\ + ;\r\ + \n# }\r\ + \n#}\r\ + \n# /import verbose=no \$ScriptName\r\ + \n:global SetupScript [ :jobname ];\r\ + \n:global RemoveMe;\r\ + \n:global InitSetup true;\r\ + \n:global tmpfs true;\r\ + \n\r\ + \n{\r\ + \n :local RmMe [:tobool \$1];\r\ + \n\r\ + \n :global GlobalScriptsUrl;\r\ + \n :global SetupScript;\r\ + \n :global RemoveMe;\r\ + \n :global InitSetup;\r\ + \n :global tmpfs;\r\ + \n \r\ + \n :local CertCommonName \"Root YE\";\r\ + \n :local CertFileName \"Root-YE.pem\";\r\ + \n :local CertFingerprint \"e14ffcad5b0025731006caa43a121a22d8e9700f4fb9c\ + f852f02a708aa5d5666\";\r\ + \n\r\ + \n :if (\$SetupScript = false) do={\r\ + \n :global SetupScript \"AM-setup\";\r\ + \n }\r\ + \n :if (\$RemoveMe != false) do={\r\ + \n :set RemoveMe true;\r\ + \n }\r\ + \n\r\ + \n :log warning (\"\\n\\\$GlobalScriptsUrl = \" . \$GlobalScriptsUrl);\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 \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 \"Thr tmpfs variable is true. Checking for tmpfs/scripts director\ + y...\";\r\ + \n :if (\$tmpfs = true && [/file find name=\"tmpfs/scripts\"] != \"\") do\ + ={\r\ + \n :log debug (\$0 . \"Directory tmpfs/scripts exsist.\");\r\ + \n :return \$true;\r\ + \n } else={\r\ + \n :log error (\$0 . \"Directory tmpfs/scripts does not exsist. Remove \ + global variable tmpfs!\");\r\ + \n :global tmpfs (a);\r\ + \n return false;\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 /system/script run \$Script;\r\ + \n :delay 2s;\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 :if (\$RemoveMe = true) do={\r\ + \n :put \"Add Scheduler for remove this script...\";\r\ + \n :local OnEvent (\":delay 30s;\\n\" . \"/system/script/remove [ find \ + where name=\\\"\$SetupScript\\\" ];\\n\" . \\\r\ + \n \":delay 2s;\\n\" . \"/system/scheduler/remove [ find where name=\\\ + \"_RemoveSetup\\\" ];\\n\" . \\\r\ + \n \":delay 2s;\\n\" . \":global RemoveMe (a);\\n\");\r\ + \n :local Comment \"_RemoveSetup tmp scheduler for remove setup script.\ + \";\r\ + \n /system/scheduler/add name=\"_RemoveSetup\" comment=\$Comment start-\ + time=startup interval=30s on-event=\$OnEvent;\r\ + \n :log warning (\$0 . \"\\nI've done everything, and now I'm tired..\ + . I'm leaving.\\nThere will be an error below, this is normal.\");\r\ + \n }\r\ + \n :delay 1;\r\ + \n :put \"Loading configuration and functions...\";\r\ + \n :do { \r\ + \n :global ScriptInstallUpdate; \$ScriptInstallUpdate;\r\ + \n :put \"Normal removing temporary global environment variables.\";\ + \r\ + \n :global SetupScript (a);\r\ + \n :global InitSetup (a);\r\ + \n :global RemoveMe (a);\r\ + \n } on-error={\r\ + \n :local ErrorMsg \"Loading configuration and functions error!\";\r\ + \n :log error (\$0 . \$ErrorMsg . :error);\r\ + \n :error \$ErrorMsg;\r\ + \n }\r\ + \n}\r\ + \n" +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# Git commit id & info, expected configuration version\r\ + \n:global CommitId \"main/80/71f092a6\";\r\ + \n:global CommitTAG \"unknown\";\r\ + \n:global CommitInfo \"Autocommit in repo: ros.vados.ru, generated by owne\ + r: root, in 14:51:02 09.03.2026.\";\r\ + \n\r\ + \n# The variables are received right here.\r\ + \n:global GlobalConfVersion 138;\r\ + \n\r\ + \n:global SumsDirAndFileName \"tmp/checksums.json\";\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 SumsDirAndFileName;\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 . \$SumsDirAndFileName . \$GlobalScr\ + iptsUrlSuffix);\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 dont-require-permissions=no name=fetchCustom owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="\ + \r\ + \n\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.10.pub\") dst-path=\"/mikro_bak_rsa@10.30.30.10.pub\";\r\ + \n#/usb1/mikro_bak_rsa.pub" +add dont-require-permissions=yes name=MkTmpfs owner=vados policy=\ + ftp,read,write,policy,test,sniff,sensitive source=\ + ":global MkDir;\r\ + \n\r\ + \n\$MkDir /usb1/tmpfs;" +add dont-require-permissions=no name=CreateContainer owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=":\ + local contIF \"veth1\";\r\ + \n:local contIP \"10.10.10.10/24\";\r\ + \n:local contGW \"10.10.10.1\";\r\ + \n#/interface/veth/add name=\$contIF address=\$contIP gateway=\$contGW;\r\ + \n:local contBridgeIF \"Bridge-DOC\";\r\ + \n:local contBridgeIP \"10.10.10.1/24\";\r\ + \n/interface/bridge/add name=\$contBridgeIF;\r\ + \n/ip/address/add address=\$contBridgeIP interface=\$contBridgeIF;\r\ + \n/interface/bridge/port/add bridge=\$contBridgeIF interface=\$contIF;\r\ + \n/container/config/set ram-high=768M registry-url=https://registry-1.dock\ + er.io tmpdir=sata1/tmp\r\ + \n" +add dont-require-permissions=no name=carkeeperbot owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="/\ + container/mounts/add list=carkeeper_configs/.profile src=sata1/carkeeper/c\ + onfigs/.profile dst=/root/.ashrc;\r\ + \n/container/mounts/add list=carkeeper_configs/php.ini src=sata1/carkeeper\ + /configs/php.ini dst=/etc/php82/php.ini;\r\ + \n#/container/mounts/add list=carkeeper_configs src=sata1/carkeeper/config\ + s dst=/configs;\r\ + \n/container/mounts/add list=carkeeper_app src=sata1/carkeeper/app dst=/ap\ + p;\r\ + \n/container/mounts/add list=carkeeper_scripts src=sata1/carkeeper/scripts\ + \_dst=/scripts;\r\ + \n/container/mounts/add list=carkeeper_configs/sshd_config src=sata1/carke\ + eper/configs/sshd_config dst=/etc/ssh/sshd_config;\r\ + \n\r\ + \n/container/mounts/add list=carkeeper_tmp src=sata1/carkeeper/tmp dst=/va\ + r/tmp;\r\ + \n/container/mounts/add list=carkeeper_sync src=sata1/carkeeper/sync dst=/\ + var/sync;\r\ + \n" +/tool e-mail +set certificate-verification=no from=MikroNUC port=587 \ + server=smtp.mail.me.com tls=starttls user=vadossio@icloud.com +/tool netwatch +add disabled=yes down-script=\ + ":local msg \"Host MikroYellow is DOWN\";\r\ + \n\$TGSendMessage \$msg;" host=10.30.30.86 http-codes="" interval=10s \ + test-script="" type=simple up-script=\ + ":global TGSendMessage;\r\ + \n\$TGSendMessage \"Host MikroYellow is UP\";" +/user aaa +set accounting=no diff --git a/MikroNUC/history/20260312/20260312064322-Diff-Config.rsc b/MikroNUC/history/20260312/20260312064322-Diff-Config.rsc new file mode 100644 index 0000000..7a91a2c --- /dev/null +++ b/MikroNUC/history/20260312/20260312064322-Diff-Config.rsc @@ -0,0 +1,36 @@ +1c1 +< # 2026-03-12 06:43:22 by RouterOS 7.21.1 +--- +> # 2026-03-03 09:00:01 by RouterOS 7.21.1 +192,193c192,193 +< set forwarding-enabled=both password-authentication=no \ +< publickey-authentication-options=verify-required strong-crypto=yes +--- +> set forwarding-enabled=both publickey-authentication-options=verify-required \ +> strong-crypto=yes +905,910d904 +< \n# Git commit id & info, expected configuration version\r\ +< \n:global CommitId \"main/80/71f092a6\";\r\ +< \n:global CommitTAG \"unknown\";\r\ +< \n:global CommitInfo \"Autocommit in repo: ros.vados.ru, generated by owne\ +< r: root, in 14:51:02 09.03.2026.\";\r\ +< \n\r\ +914,915d907 +< \n:global SumsDirAndFileName \"tmp/checksums.json\";\r\ +< \n\r\ +1585d1576 +< \n :global SumsDirAndFileName;\r\ +1612c1603 +< \n\r\ +--- +> \n \r\ +1616c1607 +< \n\r\ +--- +> \n \r\ +1620,1621c1611,1612 +< \n :local Url (\$GlobalScriptsUrl . \$SumsDirAndFileName . \$GlobalScr\ +< iptsUrlSuffix);\r\ +--- +> \n :local Url (\$GlobalScriptsUrl . \"checksums.json\" . \$GlobalScrip\ +> tsUrlSuffix);\r\ -- 2.52.0