From 5265c74ac546d25c99c482810df8144c4847ec97 Mon Sep 17 00:00:00 2001 From: vados-dev Date: Mon, 4 May 2026 11:00:21 +0300 Subject: [PATCH] Backup for MikroMaster created successfully at May 04 11:00:21. --- .../20260504/20260504110001-Binary.backup | Bin 0 -> 263007 bytes .../20260504/20260504110001-Config.rsc | 4316 +++++++++++++++++ .../20260504/20260504110001-Diff-Config.rsc | 4200 ++++++++++++++++ 3 files changed, 8516 insertions(+) create mode 100644 MikroMaster/20260504/20260504110001-Binary.backup create mode 100644 MikroMaster/20260504/20260504110001-Config.rsc create mode 100644 MikroMaster/history/20260504/20260504110001-Diff-Config.rsc diff --git a/MikroMaster/20260504/20260504110001-Binary.backup b/MikroMaster/20260504/20260504110001-Binary.backup new file mode 100644 index 0000000000000000000000000000000000000000..e029717eaa74a571557c2978a7bfd631e26abe17 GIT binary patch literal 263007 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

cFQYg5=ae-Ns2WA>l8T)(fFR0x$E>^TT>u;?J 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

TLT3@CQlpuOhxqbBDi!aN)9*cUgo=zj#) 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 literal 0 HcmV?d00001 diff --git a/MikroMaster/20260504/20260504110001-Config.rsc b/MikroMaster/20260504/20260504110001-Config.rsc new file mode 100644 index 0000000..d7e91f7 --- /dev/null +++ b/MikroMaster/20260504/20260504110001-Config.rsc @@ -0,0 +1,4316 @@ +# 2026-05-04 11:00:02 by RouterOS 7.22.1 +# software id = A8L5-07YF +# +# model = RB952Ui-5ac2nD +# serial number = D3D50CEDCD38 +/caps-man configuration +add channel.band=2ghz-b/g/n .control-channel-width=20mhz .extension-channel=\ + XX country=belarus datapath.client-to-client-forwarding=yes \ + .local-forwarding=yes name=cfg-2ghz ssid=vados +add channel.band=5ghz-a/n/ac .control-channel-width=20mhz .extension-channel=\ + XXXX country=belarus datapath.client-to-client-forwarding=yes \ + .local-forwarding=yes name=cfg-5ghz-ac ssid=vados5g +add channel.band=5ghz-a/n .control-channel-width=20mhz .extension-channel=XX \ + country=belarus datapath.client-to-client-forwarding=yes \ + .local-forwarding=yes name=cfg-5ghz-an ssid=vados5g +/interface ethernet +set [ find default-name=ether1 ] comment="WAN - Unet" mac-address=\ + 48:8F:5A:8E:1A:C2 name="ether1 - Unet" +set [ find default-name=ether3 ] comment=LEN +set [ find default-name=ether4 ] comment=NUC +set [ find default-name=ether5 ] poe-out=off +/interface l2tp-server +add comment=Server disabled=yes name=l2tp-in1 user=vados +/interface l2tp-client +add comment="Starless 2 MikroSPb" connect-to=176.53.203.171 name=l2tp-EoIP \ + user=vados +add allow=mschap2 allow-fast-path=yes comment=Starless connect-to=\ + vpn.starless.ru max-mru=1280 name=l2tp-vpn use-ipsec=yes use-peer-dns=yes \ + user=vados +/interface wireguard +add listen-port=13231 mtu=1280 name=WG +/disk +add slot=tmpfs tmpfs-max-size=22369621 type=tmpfs +/interface list +add name=WAN +add name=LAN +/interface lte apn +set [ find default=yes ] ip-type=ipv4 use-network-apn=no +/interface wifi channel +add band=5ghz-ax disabled=no frequency=5180,5200,5220,5240 name=5G-AX +add band=5ghz-ac disabled=no frequency=5180,5200,5220,5240 name=5G-AC +add band=2ghz-n disabled=no frequency=2422,2442,2462 name=2G-N +add band=2ghz-ax disabled=no frequency=2422,2442,2462 name=2G-AX +add band=2ghz-g disabled=no frequency=2422,2442,2462 name=2G-G +add band=5ghz-n disabled=no frequency=5180,5200,5220,5240 name=5G-AN +/interface wifi security +add authentication-types=wpa2-psk,wpa3-psk disabled=no group-encryption=ccmp \ + group-key-update=1h management-protection=allowed name=sec2g +add authentication-types=wpa3-psk disable-pmkid=yes disabled=no \ + group-encryption=ccmp group-key-update=5m management-encryption=cmac \ + management-protection=required name=sec5G +/interface wifi configuration +add channel=5G-AX disabled=no mode=ap name=5G-AX security=sec5G security.ft=\ + yes .ft-over-ds=yes ssid=vados +add channel=5G-AN disabled=no mode=ap name=5G-AN security=sec5G ssid=vados +/interface wireless security-profiles +set [ find default=yes ] supplicant-identity=MikroTik +/ip dhcp-server option +add code=12 name=HostName +add code=119 force=yes name=domain-search-list value="0x03'WORKGROUP'0x00" +/ip dhcp-server option sets +add name=HP1505n options=HostName +add name=StartLife1 options=HostName +add name=amsterDev options=HostName +add name=MiTV options=HostName +add name=miller options=HostName +add name=amster options=HostName +add name=garage options=HostName +add name=domain-search-set options=domain-search-list +add name=VADOS-LEN options=HostName +add name=VADOS-NUC options=HostName +add name=MikroNUC options=HostName +add name=master options=HostName +add name=MikroYellow options=HostName +add name="=\"Client ID\"" options=HostName +/ip dns forwarders +add dns-servers=1.1.1.1,1.0.0.1 name=blsp.at verify-doh-cert=no +add comment=Kra dns-servers=1.0.0.1,1.1.1.1 name=slon2.to verify-doh-cert=no +add dns-servers=1.1.1.1,1.0.0.1 name=slon3.at verify-doh-cert=no +add dns-servers=1.0.0.1,1.1.1.1 name=slon3.cc verify-doh-cert=no +add dns-servers=1.1.1.1,1.0.0.1 name=bs2web.at verify-doh-cert=no +add dns-servers=1.1.1.1,1.0.0.1 name=bs2best.at verify-doh-cert=no +add dns-servers=1.0.0.1,1.1.1.1 name=psrms.is verify-doh-cert=no +/ip ipsec proposal +set [ find default=yes ] disabled=yes +/ip pool +add name=dhcp ranges=10.30.30.83-10.30.30.254 +/ip smb users +set [ find default=yes ] disabled=yes +add disabled=yes name=vados +/ppp profile +set *FFFFFFFE use-upnp=no +/routing bgp template +set default disabled=no output.network=bgp-networks +/routing table +add disabled=no fib name=To-VPN +/system logging action +add email-start-tls=yes email-to=vados@vados.ru name=email target=email +/system script +add dont-require-permissions=no name=fetchCustom owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + /tool/fetch mode=https url=(\$GlobalScriptsUrl . #\".bak/mikro_bak_rsa@10.\ + 30.30.86.pub\") dst-path=\"/mikro_bak_rsa@10.30.30.86.pub\";\ + \n#:local Script AM-setup\ + \n#/system/script/add name=\$Script owner=\$Script source=([ /tool/fetch c\ + heck-certificate=yes-without-crl url=(\$GlobalScriptsUrl . \$Script . \".r\ + sc\") output=user as-value ]->\"data\");\ + \n#/usb1/mikro_bak_rsa.pub\ + \n\ + \n#\ + \n#/tool/fetch mode=https url=(\$GlobalScriptsUrl . \".bak/mikro_bak_rsa@1\ + 0.30.30.10.pub\") dst-path=\"/mikro_bak_rsa@10.30.30.10.pub\";\ + \n#\ + \n#root.mnuc.backuper\ + \n\ + \n#/tool/fetch mode=https url=(\$GlobalScriptsUrl . \".bak/mikro_bak_rsa@1\ + 0.30.30.81.pub\") dst-path=\"/mikro_bak_rsa@10.30.30.81.pub\";\ + \n#:local Script AM-GlobalConfig;\ + \n#/system/script/add name=\$Script owner=\$Script source=([ /tool/fetch c\ + heck-certificate=yes-without-crl url=(\$GlobalScriptsUrl . \$Script . \".r\ + sc\") output=user as-value ]->\"data\");\ + \n#/usb1/mikro_bak_rsa.pub\ + \n#:local FetchFile AM-DOHCert.rsc\ + \n\ + \n:global GlobalScriptsUrl \"https://ros.vados.ru/tmp/\";\ + \n:global MkDir;\ + \n\ + \n:local FetchFile Binary.backup\ + \n:local localDir \"\";\ + \n\ + \n#\$MkDir \$localDir;\ + \n\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \$FetchFile) dst-path=(\ + \$localDir . \$FetchFile);" +add comment="Example add WU servers to AddrList" dont-require-permissions=no \ + name=WU-add-to-list owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + \_Script to add target web sites DNS IP addresses into address list\r\ + \n# Tested with Mikrotik 6.4x\r\ + \n# Syed Jahanzaib / aacable@hotmail.com\r\ + \n# List name\r\ + \n:local LISTNAME \"windowsupdateslist\"\r\ + \n# Web site names which will be added in address list\r\ + \n:local TARGET1 \"update.microsoft.com\"\r\ + \n:local TARGET2 \"download.windowsupdate.com\"\r\ + \n:local TARGET3 \"download.microsoft.com\"\r\ + \n:local TARGET4 \"windowsupdate.com\"\r\ + \n:local TARGET5 \"ntservicepack.microsoft.com\"\r\ + \n:local TARGET6 \"wustat.windows.com\"\r\ + \n:local TARGET7 \"stats.microsoft.com\"\r\ + \n:local TARGET8 \"mp.microsoft.com\"\r\ + \n:local TARGET9 \"ws.microsoft.com\"\r\ + \n:local TARGET10 \"sls.update.microsoft.com.akadns.net\"\r\ + \n:local TARGET11 \"vortex.data.microsoft.com\"\r\ + \n:local TARGET12 \"vortex-win.data.microsoft.com\"\r\ + \n:local TARGET13 \"fe2.update.microsoft.com.akadns.net\"\r\ + \n:local TARGET14 \"statsfe2.update.microsoft.com.akadns.net\"\r\ + \n \r\ + \n# 1st time runner, check if address list is not created previously and a\ + dd entries in it for 1st time usage\r\ + \n:if ( [/ip firewall address-list find where list=\$LISTNAME] = \"\") do=\ + {\r\ + \n:log warning \"No address list for \$TARGET1 found ! creating and adding\ + \_resolved entry for 1st time usage ... zaib\"\r\ + \n \r\ + \n:local FirstAddr [resolve \$TARGET1];\r\ + \n\r\ + \n/ip firewall address-list add address=\$FirstAddr list=\$LISTNAME commen\ + t=\$TARGET1;\r\ + \n} else={\r\ + \n:log warning \"Previous List for \$LISTNAME found ! moving forward and c\ + hecking if DNS entries can be added in it ...\"\r\ + \n}\r\ + \n \r\ + \n# Check DNS entries and collect matching names\r\ + \n:foreach i in=[/ip dns cache find name~\"(\$TARGET1|\$TARGET2|\$TARGET3|\ + \$TARGET4|\$TARGET5|\$TARGET6|\$TARGET7|\$TARGET8|\$TARGET9|\$TARGET10|\$T\ + ARGET11|\$TARGET12|\$TARGET13|\$TARGET14)\" && \$type ~ \"^(A|CNAME)\\\$\"\ + \_] do={\r\ + \n \r\ + \n# Get IP Address from the names and hold it in temporary buffer\r\ + \n:local Buffer [/ip dns cache get \$i data];\r\ + \ndelay delay-time=10ms\r\ + \n \r\ + \n# Check if entry is already not exists, then OK, otherwise ignore duplic\ + ation\r\ + \n:if ( [/ip firewall address-list find where address=\$Buffer] = \"\") do\ + ={\r\ + \n \r\ + \n# Fetch DNS names for the entries\r\ + \n:local sitednsname [/ip dns cache get \$i name] ;\r\ + \n \r\ + \n# Print name in LOG window\r\ + \n:log info (\"added entry: \$sitednsname \$Buffer\");\r\ + \n \r\ + \n# Add IP addresses and there names to the address list\r\ + \n/ip firewall address-list add address=\$Buffer list=\$LISTNAME comment=\ + \$sitednsname;\r\ + \n}\r\ + \n}" +add comment="Add Hosts DNS names to NoWG addres list" \ + dont-require-permissions=no name=Add2vdsina owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + \_Script to add target web sites DNS IP addresses into address list\r\ + \n# Tested with Mikrotik 6.4x\r\ + \n# \r\ + \n# List name\r\ + \n:local LISTNAME \"NoWG\"\r\ + \n#\r\ + \n# Web site names which will be added in address list\r\ + \n:local TARGET1 \"comp-lenta.ru\"\r\ + \n:local TARGET2 \"ok.ru\"\r\ + \n:local TARGET3 \"vk.com\"\r\ + \n#:local TARGET4 \"smtp.mail.me.com\"\r\ + \n#:local TARGET4 \"windowsupdate.com\"\r\ + \n#:local TARGET5 \"ntservicepack.microsoft.com\"\r\ + \n#:local TARGET6 \"wustat.windows.com\"\r\ + \n#:local TARGET7 \"stats.microsoft.com\"\r\ + \n#:local TARGET8 \"mp.microsoft.com\"\r\ + \n#:local TARGET9 \"ws.microsoft.com\"\r\ + \n#:local TARGET10 \"sls.update.microsoft.com.akadns.net\"\r\ + \n#:local TARGET11 \"vortex.data.microsoft.com\"\r\ + \n#:local TARGET12 \"vortex-win.data.microsoft.com\"\r\ + \n#:local TARGET13 \"fe2.update.microsoft.com.akadns.net\"\r\ + \n#:local TARGET14 \"statsfe2.update.microsoft.com.akadns.net\"\r\ + \n \r\ + \n# 1st time runner, check if address list is not created previously and a\ + dd entries in it for 1st time usage\r\ + \n:if ( [/ip firewall address-list find where list=\$LISTNAME] = \"\") do=\ + {\r\ + \n:log warning \"No address list for \$TARGET1 found ! creating and adding\ + \_resolved entry for 1st time usage ... zaib\"\r\ + \n\r\ + \n:local FirstAddr [resolve \$TARGET1];\r\ + \n\r\ + \n/ip firewall address-list add address=\$FirstAddr list=\$LISTNAME commen\ + t=\$TARGET1;\r\ + \n\r\ + \n} else={\r\ + \n:log warning \"Previous List for \$LISTNAME found ! moving forward and c\ + hecking if DNS entries can be added in it ...\"\r\ + \n}\r\ + \n\r\ + \n# Check DNS entries and collect matching names\r\ + \n:foreach i in=[/ip dns cache find name~\"(\$TARGET1|\$TARGET2|\$TARGET3|\ + \$TARGET4)\" && \$type ~ \"^(A|CNAME)\\\$\" ] do={\r\ + \n\r\ + \n:log info (\"start entry: \$c \$sitednsname \$Buffer\");\r\ + \n\r\ + \n# Get IP Address from the names and hold it in temporary buffer\r\ + \n:local Buffer [/ip dns cache get \$i data];\r\ + \ndelay delay-time=10ms\r\ + \n:log info (\"1: \$Buffer\"); \r\ + \n\r\ + \n# Check if entry is already not exists, then OK, otherwise ignore duplic\ + ation\r\ + \n:if ( [/ip firewall address-list find where address=\$Buffer] = \"\") do\ + ={\r\ + \n\r\ + \n:log info (\"2: \$Buffer\"); \r\ + \n \r\ + \n# Fetch DNS names for the entries\r\ + \n:local sitednsname [/ip dns cache get \$i name] ;\r\ + \n \r\ + \n# Print name in LOG window\r\ + \n:log info (\"added entry: \$i \$sitednsname \$Buffer\");\r\ + \n \r\ + \n# Add IP addresses and there names to the address list\r\ + \n/ip firewall address-list add address=\$Buffer list=\$LISTNAME comment=\ + \$sitednsname;\r\ + \n}\r\ + \n}" +add comment="Flush DNS Cache" dont-require-permissions=no name=\ + DNS_Flush_Cache owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=\ + "/ip dns cache flush" +add comment="Certificates CloudFlare, Quad9 " dont-require-permissions=no \ + name=Update-Certificates owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + \_CloudFlare\r\ + \n#/tool/fetch mode=https url=https://cacerts.digicert.com/DigiCertGlobalR\ + ootCA.crt.pem;\r\ + \n#/certificate/import file-name=DigiCertGlobalRootCA.crt.pem passphrase=\ + \"\";\r\ + \n#/tool/ fetch mode=https url=https://cacerts.digicert.com/DigiCertGlobal\ + G2TLSRSASHA2562020CA1-1.crt.pem;\r\ + \n#/certificate/import file-name=DigiCertGlobalG2TLSRSASHA2562020CA1-1.crt\ + .pem passphrase=\"\";\r\ + \n# Quad9\r\ + \n#/tool/fetch mode=https url=\"https://cacerts.digicert.com/DigiCertGloba\ + lG3TLSECCSHA3842020CA1-1.crt.pem\"\r\ + \n#/certificate/import file-name=DigiCertGlobalG3TLSECCSHA3842020CA1-1.crt\ + .pem passphrase=\"\";\r\ + \n\r\ + \n:global GlobalScriptsUrl;\r\ + \n#google\r\ + \n:local CertName \"DigiCert-Global-Root-CA.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Global-Root-CA\" [ find where common-na\ + me=\"DigiCert Global Root CA\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Assured-ID-Root-CA.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Assured-ID-Root-CA\" [ find where commo\ + n-name=\"DigiCert Assured ID Root CA\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Assured-ID-Root-G2.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Assured-ID-Root-G2\" [ find where commo\ + n-name=\"DigiCert Assured ID Root G3\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Assured-ID-Root-G3.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Assured-ID-Root-G3\" [ find where commo\ + n-name=\"DigiCert Assured ID Root G3\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Global-G2-TLS-RSA-SHA256-2020-CA1.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Global-G2-TLS-RSA-SHA256-2020-CA1\" [ f\ + ind where common-name=\"DigiCert Global G2 TLS RSA SHA256 2020 CA1\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Global-G3-TLS-ECC-SHA384-2020-CA1.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Global-G3-TLS-ECC-SHA384-2020-CA1\" [ f\ + ind where common-name=\"DigiCert Global G3 TLS ECC SHA384 2020 CA1\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Global-Root-G2.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Global-Root-G2\" [ find where common-na\ + me=\"DigiCert Global Root G2\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Global-Root-G3.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Global-Root-G3\" [ find where common-na\ + me=\"DigiCert Global Root G3\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-TLS-ECC-P384-Root-G5.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-TLS-ECC-P384-Root-G5\" [ find where com\ + mon-name=\"DigiCert TLS ECC P384 Root G5\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-TLS-RSA4096-Root-G5.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-TLS-RSA4096-Root-G5\" [ find where comm\ + on-name=\"DigiCert TLS RSA4096 Root G5\" ];\r\ + \n\r\ + \n:set CertName \"DigiCert-Trusted-Root-G4.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"DigiCert-Trusted-Root-G4\" [ find where common-n\ + ame=\"DigiCert Trusted Root G4\" ];\r\ + \n\r\ + \n:set CertName \"GTS-Root-R4.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"GTS-Root-R4\" [ find where common-name=\"GTS Roo\ + t R4\" ];\r\ + \n\r\ + \n:set CertName \"Go-Daddy-Root-Certificate-Authority-G2.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"Go-Daddy-Root-Certificate-Authority-G2\" [ find \ + where common-name=\"Go Daddy Root Certificate Authority - G2\" ];\r\ + \n\r\ + \n:set CertName \"ISRG-Root-X1.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"ISRG-Root-X1\" [ find where common-name=\"ISRG R\ + oot X1\" ];\r\ + \n\r\ + \n:set CertName \"Root-YE.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"Root-YE\" [ find where common-name=\"Root YE\" ]\ + ;\r\ + \n\r\ + \n:set CertName \"Starfield-Root-Certificate-Authority-G2.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"Starfield-Root-Certificate-Authority-G2\" [ find\ + \_where common-name=\"Starfield Root Certificate Authority - G2\" ];\r\ + \n\r\ + \n:set CertName \"USERTrust-RSA-Certification-Authority.pem\";\r\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \"certs/Master/\" . \$C\ + ertName);\r\ + \n/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n/certificate/set name=\"USERTrust-RSA-Certification-Authority\" [ find w\ + here common-name=\"USERTrust RSA Certification Authority\" ];\r\ + \n\r\ + \n#/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n#/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n#:set CertName \"GTS-Root-RX.pem\";\r\ + \n#/tool/fetch mode=https url=(\$AmScriptsUrl . \"certs/\" . \$CertName);\ + \r\ + \n#/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n#internet\r\ + \n#/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n#:set CertName \"ISRG-Root-X2.pem\";\r\ + \n#/tool/fetch mode=https url=(\$AmScriptsUrl . \"certs/\" . \$CertName);\ + \r\ + \n#/certificate/import file-name=\$CertName passphrase=\"\";\r\ + \n\r\ + \n\r\ + \n#/ip/dns/set allow-remote-requests=yes doh-max-concurrent-queries=100 do\ + h-max-server-connections=20 use-doh-server=https://security.cloudflare-dns\ + .com/dns-query verify-doh-cert=yes;\r\ + \n#/ip/dns/static remove [find where address=1.1.1.1];\r\ + \n#/ip/dns/static add address=1.1.1.1 name=security.cloudflare-dns.com com\ + ment=\"cloudflare-dns IPv4 1\";\r\ + \n#/ip/dns/ static remove [find where address=1.0.0.1];\r\ + \n#/ip/dns/static add address=1.0.0.1 name=security.cloudflare-dns.com com\ + ment=\"cloudflare-dns IPv4 2\"\r\ + \n#/ip dns static add address=2606:4700:4700::1111 name=security.cloudflar\ + e-dns.com type=AAAA\r\ + \n#/ip dns static add address=2606:4700:4700::1001 name=security.cloudflar\ + e-dns.com type=AAAA\r\ + \n#/ip/dns set servers=\"1.0.0.1, 8.8.4.4\";\r\ + \n#/ip/dns set servers=\"\";" +add dont-require-permissions=no name=script1 owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="/\ + tool/netwatch/add comment=\"doh-fallback, doh-url=https://security.cloudfl\ + are-dns.com/dns-query, doh-cert=DigiCert Global Root CA, notify, name=Clou\ + dFlare-doh IPv4 1\" host=1.1.1.1;\r\ + \n/tool/netwatch/add comment=\"doh, doh-url=https://security.cloudflare-dn\ + s.com/dns-query, doh-cert=DigiCert Global Root CA, notify, name=CloudFlare\ + -doh IPv4 2\" host=1.0.0.1;\r\ + \n/tool/netwatch/add comment=\"doh-fallback, dns-fallback, doh-url=https:/\ + /dns.google/dns-query, doh-cert=DigiCert Global Root G2, notify, name=Goog\ + le-doh IPv4 1\" host=8.8.8.8;\r\ + \n/tool/netwatch/add comment=\"doh-fallback, dns-fallback, doh-url=https:/\ + /dns.google/dns-query, doh-cert=DigiCert Global Root G2, notify, name=Goog\ + le-doh IPv4 2\" host=8.8.4.4;\r\ + \n/tool/netwatch/add comment=\"doh-fallback, dns-fallback, doh-url=https:/\ + /dns.quad9.net/dns-query, doh-cert=DigiCert Global Root G3, notify, name=C\ + uad9-doh IPv4 1\" host=9.9.9.9;\r\ + \n/tool/netwatch/add comment=\"doh-fallback, dns-fallback, doh-url=https:/\ + /dns.quad9.net/dns-query, doh-cert=DigiCert Global Root G3, notify, name=C\ + uad9-doh IPv4 2\" host=149.112.112.112;\r\ + \n\r\ + \n/tool/netwatch/add comment=\"dns, notify, name=ns1.unet.ws\" host=91.192\ + .189.2;" +add dont-require-permissions=no name=script2 owner=vados policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + \r\ + \n\r\ + \n:global InspectVar;\r\ + \n#:global RouterBoard;\r\ + \n#:do {:set RouterBoard [[ :parse \"/system/routerboard/get\" ]]} on-erro\ + r={}\r\ + \n#:global Resources;\r\ + \n#:do {:set Resources [[ :parse \"/system/resource/get\" ]]} on-error={}\ + \r\ + \n\r\ + \n#:global Updates;\r\ + \n#:do {:set Updates [[ :parse \"/system/package/update/get\" ]]} on-error\ + ={}\r\ + \n\r\ + \n#:global PkgUpdStatus \"undefined\";\r\ + \n#:local Update [/system/package/update/get];\r\ + \n#:retry command={:set PkgUpdStatus (\$Update->\"status\")} delay=200ms m\ + ax=5 on-error={};\r\ + \n\r\ + \n#:log warning [\$InspectVar \$RouterBoard];\r\ + \n#:put [\$InspectVar \$RouterBoard];\r\ + \n\r\ + \n#:retry command={/system/package/update check-for-updates without-paging\ + \_as-value} delay=300ms max=5 on-error={};\r\ + \n\r\ + \n#:global arrDeviceInfo ({});\r\ + \n#:local arrDeviceInfo ({\"section\":{\"key\":\"\"; \"value\":\"\";};});\ + \r\ + \n#:set (\$arrDeviceInfo->\"RouterBoard\") [[ :parse \"/system/routerboard\ + /get\" ]];\r\ + \n#:retry command={:set (\$arrDeviceInfo->\"Updates\") [[ :parse \"/system\ + /package/update/get\" ]]} delay=500ms max=5 on-error={:log error (\"Error\ + \")};\r\ + \n# [:toarray {\"section\"={\"key\"=\"\"; \"value\"=\"\";} }];\r\ + \n# [:toarray \"\"];\r\ + \n:local arrDeviceInfo ({});\r\ + \n\r\ + \n:set (\$arrDeviceInfo->\"devUpdates\") {\"channel\"; \"stable\";};\r\ + \n#:do {:set (arrDeviceInfo->\"Updates\") [[ :parse \"/system/package/upda\ + te/get\" ]]} on-error={:log error (\$error)}\r\ + \n\$InspectVar \$arrDeviceInfo;\r\ + \n" +add comment="Script for setup routeros script 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 script 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\r\ + \n:global ScriptUpdatesCRLF \"LF\";\r\ + \n#:if (\$ScriptUpdatesCRLF != false) do={\r\ + \n# :foreach Script in=[ /system/script/find where source~\"^#!rsc by Vad\ + os\" ] do={\r\ + \n# if (\$ScriptUpdatesCRLF = true) do={\r\ + \n# /system/script/set source=[ :tocrlf [ get \$Script source ] ] \$S\ + cript;\r\ + \n# } else={\r\ + \n# /system/script/set source=[ :tolf [ get \$Script source ] ] \$Scr\ + ipt;\r\ + \n# }\r\ + \n# }\r\ + \n#}\r\ + \n\r\ + \n# /import verbose=no \$ScriptName\r\ + \n:global SetupScript [ :jobname ];\r\ + \n:global RemoveMe;\r\ + \n:global RunOnce;\r\ + \n:global InitSetup true;\r\ + \n:global tmpfs false;\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 ([ :len [ /certificate/find where fingerprint=\$CertFingerprint ] \ + ] != 1) do={\r\ + \n :error \"Something is wrong with your certificates!\";\r\ + \n } else={\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 /tool/fetch (\$GlobalScriptsUrl . \"certs/ipall/\" . \$CertFileN\ + ame) dst-path=\$CertFileName as-value;\r\ + \n :delay 1s;\r\ + \n /certificate/import file-name=\$CertFileName passphrase=\"\";\r\ + \n :delay 1s;\r\ + \n };\r\ + \n };\r\ + \n\r\ + \n:local MkTmpfs do={\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 :log info (\"The tmpfs is disabled, enabling.\");\r\ + \n /disk/enable \$TmpFs;\r\ + \n }\r\ + \n :return true;\r\ + \n }\r\ + \n :log info (\"Try to removing directory 'tmpfs'.\");\r\ + \n :do {\r\ + \n :retry {\r\ + \n /file/remove tmpfs;\r\ + \n :return true;\r\ + \n } delay=100ms max=10;\r\ + \n } on-error={ }\r\ + \n# \$RmDir \"tmpfs\";\r\ + \n :onerror Err {\r\ + \n /disk/add slot=tmpfs type=tmpfs tmpfs-max-size=([ /system/resource/g\ + et total-memory ] / 3);\r\ + \n :do {\r\ + \n :retry {\r\ + \n /file/get tmpfs;\r\ + \n :return true;\r\ + \n } delay=222ms max=10;\r\ + \n } on-error={ }\r\ + \n } do={\r\ + \n :log warning (\"Creating disk of type tmpfs failed: \" . \$Err);\r\ + \n :return false;\r\ + \n }\r\ + \n# :return true;\r\ + \n}\r\ + \n:if (\$tmpfs = true) do={\r\ + \n :put \"Tmpfs variable is true. Checking for tmpfs/scripts directory...\ + \";\r\ + \n :if ([/file find name=\"tmpfs/scripts\"] != \"\") do={\r\ + \n :log info (\$0 . \"Directory tmpfs/scripts exsist.\");\r\ + \n :return \$true;\r\ + \n } else={\r\ + \n :log warning (\$0 . \"Directory tmpfs/scripts does't exsist.\");\r\ + \n :if ([ \$MkTmpfs ] = false) do={\r\ + \n :log error (\$0 . \"Directory tmpfs is not created!\");\r\ + \n :return false;\r\ + \n } else={\r\ + \n :onerror Err {\r\ + \n /file/add type=\"directory\" name=/tmpfs/scripts;\r\ + \n :do {\r\ + \n :retry {\r\ + \n /file/get /tmpfs/scripts;\r\ + \n :return true;\r\ + \n } delay=100ms max=10;\r\ + \n } on-error={ }\r\ + \n } do={\r\ + \n :log warning (\$0 . \"Making directory 'scripts' failed: \" . \$\ + Err);\r\ + \n :return false;\r\ + \n }\r\ + \n# :return true;\r\ + \n# [ /file/get \$FileName ]\r\ + \n }\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}\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 Identity [ /system identity get name ];\r\ + \n:global GlobalConfReady false;\r\ + \n#\r\ + \n#\r\ + \n# Global Url For Amster scripts to fetch\r\ + \n# most be defined in AM-Init-Script or AM-setup scripts\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\";\r\ + \n#: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:global CertRenewUrl (\$GlobalScriptsUrl . \"certs/\" . \$Identity . \"/\ + \");\r\ + \n:global CertRenewTime 2w;\r\ + \n:global CertRenewPass {\r\ + \n \"\";\r\ + \n# \"v3ry-s3cr3t\";\r\ + \n# \"4n0th3r-s3cr3t\";\r\ + \n};\r\ + \n:global CertWarnTime 1w;\r\ + \n:global CertIssuedExportPass {\r\ + \n \"\";\r\ + \n# \"cert1-cn\"=\"v3ry-s3cr3t\";\r\ + \n# \"cert2-cn\"=\"4n0th3r-s3cr3t\";\r\ + \n};\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# Copyright (c) 2005-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# requires RouterOS, version=7.19\r\ + \n# requires device-mode, fetch, scheduler\r\ + \n\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/543/2586b4eb\";\r\ + \n:global CommitTAG \"unknown\";\r\ + \n:global CommitInfo \"Autocommit in repo: ros.vados.ru, generated by owne\ + r: root, in 10:45:03 04.05.2026.\";\r\ + \n\r\ + \n# The variables are received right here.\r\ + \n:global GlobalConfVersion 140;\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 ExitOnError;\r\ + \n:global CharacterMultiply;\r\ + \n:global CharacterReplace;\r\ + \n:global CleanFilePath;\r\ + \n:global CleanName;\r\ + \n\r\ + \n:global CommitBrief;\r\ + \n\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\r\ + \n:global FetchUserAgentStr;\r\ + \n:global CertificateAvailable;\r\ + \n:global CertificateDownload;\r\ + \n:global CertificateNameByCN;\r\ + \n:global CharacterMultiply;\r\ + \n:global FetchLargeFiles;\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 :global currentUpdateChannel;\r\ + \n :global ROsVerAvail;\r\ + \n :global arrDeviceInfo;\r\ + \n \$LogPrint debug \$0 (\"\\\$isInfo = \" . \$isInfo); \r\ + \n :local CurrentChannel [ /system/package/update/get channel ];\r\ + \n :if ([ :len \$updateChannel ] > 0 && \$CurrentChannel != \$updateChann\ + el) 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 [ :tostr (\$Update->\"channel\") ];\r\ + \n :set currentUpdateChannel \$Channel;\r\ + \n \$LogPrint debug \$0 (\"Update Channel: \" . \$Channel . \".\");\r\ + \n\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 :set ROsVerAvail [ :tostr [ /system/package/update/get latest-version \ + ] ];\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 ([ :typeof \$arrDeviceInfo ] != \"array\") do={\r\ + \n :set arrDeviceInfo [:toarray \$arrDeviceInfo];\r\ + \n }\r\ + \n :retry command={:set (\$arrDeviceInfo->\"devUpdates\") [ /system/pac\ + kage/update/get ]} delay=500ms max=5 on-error={:log error (\"Error\")};\r\ + \n :return true;\r\ + \n } else={\r\ + \n :return \$PkgUpdStatus;\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n:set WaitCheckUpdates do={\r\ + \n :global IsCheckUpdates;\r\ + \n :global PkgUpdStatus;\r\ + \n :global currentUpdateChannel;\r\ + \n :global ROsVerAvail;\r\ + \n :global arrDeviceInfo;\r\ + \n\r\ + \n :local Status \"\";\r\ + \n :local Update;\r\ + \n :local WaitCount 0;\r\ + \n\r\ + \n :if ([ \$IsCheckUpdates true ] = false) do={\r\ + \n :return false;\r\ + \n }\r\ + \n\r\ + \n :set Status [ :tostr [ /system/package/update/get status ] ];\r\ + \n :while ((\$Status = \"\" || \$Status = \"finding out latest version...\ + \") && \$WaitCount < 60) do={\r\ + \n :delay 1s;\r\ + \n :set WaitCount (\$WaitCount + 1);\r\ + \n :set Status [ :tostr [ /system/package/update/get status ] ];\r\ + \n }\r\ + \n\r\ + \n :set Update [ /system/package/update/get ];\r\ + \n :set currentUpdateChannel [ :tostr (\$Update->\"channel\") ];\r\ + \n :set ROsVerAvail [ :tostr (\$Update->\"latest-version\") ];\r\ + \n :if ((\$Update->\"status\") = \"New version is available\") do={\r\ + \n :set PkgUpdStatus true;\r\ + \n } else={\r\ + \n :set PkgUpdStatus false;\r\ + \n }\r\ + \n :if ([ :typeof \$arrDeviceInfo ] != \"array\") do={\r\ + \n :set arrDeviceInfo [:toarray \$arrDeviceInfo];\r\ + \n }\r\ + \n :set (\$arrDeviceInfo->\"devUpdates\") \$Update;\r\ + \n\r\ + \n :if (\$Status = \"\" || \$Status = \"finding out latest version...\") \ + do={\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\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 :global arrDeviceInfo;\r\ + \n\r\ + \n :global devBoardName;\r\ + \n :global devModel;\r\ + \n :global devRunning;\r\ + \n :global devCurArch;\r\ + \n :global devRbRevision;\r\ + \n :global devRbSerialNumber;\r\ + \n :global devBuildTime;\r\ + \n :global runningChannelVersion;\r\ + \n :global runningChannel;\r\ + \n :global runningVersion;\r\ + \n :global currentUpdateChannel;\r\ + \n :global ROsVerAvail;\r\ + \n\r\ + \n :local DeviceInfo;\r\ + \n :local Resource [/system/resource/get];\r\ + \n :local Update [ /system/package/update/get ];\r\ + \n :local VersionString [ :tostr (\$Resource->\"version\") ];\r\ + \n :local ChannelStart [ :find \$VersionString \" (\" ];\r\ + \n :local RouterBoard;\r\ + \n :local IsRouterBoard false;\r\ + \n :local RunningMode \"\";\r\ + \n\r\ + \n :set devCurArch [ :tostr (\$Resource->\"architecture-name\") ];\r\ + \n :set devBuildTime [ :tostr (\$Resource->\"build-time\") ];\r\ + \n :set runningChannelVersion \$VersionString;\r\ + \n :set runningVersion \$VersionString;\r\ + \n :set runningChannel \"\";\r\ + \n\r\ + \n :if ([ :typeof \$ChannelStart ] = \"num\" && \$ChannelStart >= 0) do=\ + {\r\ + \n :set runningVersion [ :pick \$VersionString 0 \$ChannelStart ];\r\ + \n :local ChannelRest [ :pick \$VersionString (\$ChannelStart + 2) [ :\ + len \$VersionString ] ];\r\ + \n :local ChannelEnd [ :find \$ChannelRest \")\" ];\r\ + \n :if ([ :typeof \$ChannelEnd ] = \"num\" && \$ChannelEnd >= 0) do={\ + \r\ + \n :set runningChannel [ :pick \$ChannelRest 0 \$ChannelEnd ];\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :if ([:pick \$devBoardName 0 3] != \"CHR\" or [:pick \$devBoardName 0\ + \_3] != \"x86\") do={\r\ + \n :do {\r\ + \n :set RouterBoard [[ :parse \"/system/routerboard/get\" ]];\r\ + \n# :set RouterBoard [ /system/routerboard/get ];\r\ + \n :if ((\$RouterBoard->\"routerboard\") = true) do={\r\ + \n :set IsRouterBoard true;\r\ + \n }\r\ + \n } on-error={}\r\ + \n }\r\ + \n\r\ + \n :do {\r\ + \n :set RunningMode [ /system/device-mode/get mode ];\r\ + \n } on-error={\r\ + \n :do {\r\ + \n :set RunningMode [ /system/device-mode/get running ];\r\ + \n } on-error={\r\ + \n :set RunningMode \"\";\r\ + \n }\r\ + \n }\r\ + \n :set devRunning \$RunningMode;\r\ + \n\r\ + \n :if (\$IsRouterBoard = true) do={\r\ + \n :set devModel [ :tostr (\$RouterBoard->\"model\") ];\r\ + \n :set devRbRevision [ :tostr (\$RouterBoard->\"revision\") ];\r\ + \n :set devRbSerialNumber [ :tostr (\$RouterBoard->\"serial-number\") \ + ];\r\ + \n } else={\r\ + \n :set devModel \$devBoardName;\r\ + \n :set devRbRevision \"\";\r\ + \n :set devRbSerialNumber \"\";\r\ + \n }\r\ + \n\r\ + \n :set currentUpdateChannel [ :tostr (\$Update->\"channel\") ];\r\ + \n :set ROsVerAvail [ :tostr (\$Update->\"latest-version\") ];\r\ + \n\r\ + \n :set (\$DeviceInfo->\"board-name\") \$devBoardName;\r\ + \n :set (\$DeviceInfo->\"architecture-name\") \$devCurArch;\r\ + \n :set (\$DeviceInfo->\"model\") \$devModel;\r\ + \n :set (\$DeviceInfo->\"revision\") \$devRbRevision;\r\ + \n :set (\$DeviceInfo->\"serial-number\") \$devRbSerialNumber;\r\ + \n :set (\$DeviceInfo->\"running-mode\") \$devRunning;\r\ + \n :set (\$DeviceInfo->\"build-time\") \$devBuildTime;\r\ + \n :set (\$DeviceInfo->\"running-channel-version\") \$runningChannelVers\ + ion;\r\ + \n :set (\$DeviceInfo->\"running-version\") \$runningVersion;\r\ + \n :set (\$DeviceInfo->\"running-channel\") \$runningChannel;\r\ + \n :set (\$DeviceInfo->\"routerboard\") \$IsRouterBoard;\r\ + \n :set (\$DeviceInfo->\"current-firmware\") [ :tostr (\$RouterBoard->\"\ + current-firmware\") ];\r\ + \n :set (\$DeviceInfo->\"upgrade-firmware\") [ :tostr (\$RouterBoard->\"\ + upgrade-firmware\") ];\r\ + \n :set (\$DeviceInfo->\"package-channel\") \$currentUpdateChannel;\r\ + \n :set (\$DeviceInfo->\"installed-version\") [ :tostr (\$Update->\"inst\ + alled-version\") ];\r\ + \n :set (\$DeviceInfo->\"latest-version\") \$ROsVerAvail;\r\ + \n :set (\$DeviceInfo->\"update-status\") [ :tostr (\$Update->\"status\"\ + ) ];\r\ + \n\r\ + \n :set arrDeviceInfo \$DeviceInfo;\r\ + \n :return \$DeviceInfo;\r\ + \n}\r\ + \n\r\ + \n:set DeviceInfo do={\r\ + \n :global GetArrDeviceInfo;\r\ + \n :global GlobalConfVersion;\r\ + \n :global Identity;\r\ + \n :global IfThenElse;\r\ + \n :global FormatLine;\r\ + \n :global CommitBrief;\r\ + \n\r\ + \n :local License [/system/license/get];\r\ + \n :local Snmp [ /snmp/get ];\r\ + \n :local Info [ \$GetArrDeviceInfo ];\r\ + \n\r\ + \n :if ([ :typeof \$Info ] != \"array\") do={\r\ + \n :return false;\r\ + \n }\r\ + \n\r\ + \n :return ( \\\r\ + \n [ \$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\" (\$Info->\"board-name\") ] . \"\\n\" . \ + \\\r\ + \n [ \$FormatLine \" Arch\" (\$Info->\"architecture-name\") ] . \"\\\ + n\" . \\\r\ + \n [ \$FormatLine \" Model\" (\$Info->\"model\") ] . \\\r\ + \n [ \$IfThenElse ([ :len (\$Info->\"revision\") ] > 0) \\\r\ + \n (\" \" . (\$Info->\"revision\")) ] . \"\\n\" . \\\r\ + \n [ \$IfThenElse ([ :len (\$Info->\"serial-number\") ] > 0) \\\r\ + \n ([ \$FormatLine \" Serial\" (\$Info->\"serial-number\") ] . \"\ + \\n\") ] . \\\r\ + \n [ \$IfThenElse ([ :len (\$License->\"nlevel\") ] > 0) \\\r\ + \n ([ \$FormatLine \" License\" (\"level \" . (\$License->\"nlevel\ + \")) ] . \"\\n\") ] . \\\r\ + \n \"RouterOS:\\n\" . \\\r\ + \n [ \$IfThenElse ([ :len (\$License->\"level\") ] > 0) \\\r\ + \n ([ \$FormatLine \" License\" (\"level \" . (\$License->\"level\ + \")) ] . \"\\n\") ] . \\\r\ + \n [ \$FormatLine \" Channel\" (\$Info->\"package-channel\") ] . \"\ + \\n\" . \\\r\ + \n [ \$FormatLine \" Installed\" (\$Info->\"installed-version\") ] .\ + \_\"\\n\" . \\\r\ + \n [ \$IfThenElse ([ :len (\$Info->\"running-channel\") ] > 0) \\\r\ + \n ([ \$FormatLine \" Running\" ((\$Info->\"running-version\") . \ + \" (\" . (\$Info->\"running-channel\") . \")\") ] . \"\\n\") \\\r\ + \n ([ \$FormatLine \" Running\" (\$Info->\"running-version\") ] . \ + \"\\n\") ] . \\\r\ + \n [ \$IfThenElse ([ :len (\$Info->\"latest-version\") ] > 0 && \\\r\ + \n (\$Info->\"installed-version\") != (\$Info->\"latest-version\"))\ + \_\\\r\ + \n ([ \$FormatLine \" Available\" (\$Info->\"latest-version\") ] .\ + \_\"\\n\") ] . \\\r\ + \n [ \$IfThenElse ((\$Info->\"routerboard\") = true && \\\r\ + \n (\$Info->\"current-firmware\") != (\$Info->\"upgrade-firmware\")\ + ) \\\r\ + \n ([ \$FormatLine \" Firmware\" ((\$Info->\"current-firmware\") .\ + \_\" -> \" . (\$Info->\"upgrade-firmware\")) ] . \"\\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 CommitBrief do={\r\ + \n :global CommitId;\r\ + \n :global CommitInfo;\r\ + \n :if (\$CommitId = \"unknown\") do={\r\ + \n :return \"unknown\";\r\ + \n }\r\ + \n :return (\$CommitInfo . \"/\" . [ :pick \$CommitId 0 8 ]);\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\r\ + \n :local PubIpAddr false;\r\ + \n :local Url \$DetectIpAddrDefault;\r\ + \n :local JobName [ :jobname ];\r\ + \n\r\ + \n :do {\r\ + \n :log debug (\$0 . \" Trying to detect public IP using default serv\ + ice: \" . \$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={:log error (\$JobName . \" Failed to \ + detect public IP using default service: \" . \$Url . \".\")}\r\ + \n } on-error={\r\ + \n :log error (\$0 . \" Failed to detect public IP using default serv\ + ice: \" . \$Url . \".\");\r\ + \n :set Url \$DetectIpAddrFallBack;\r\ + \n :log debug (\$0 . \" Trying to detect public IP using fallback ser\ + vice: \" . \$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={:log error (\$JobName . \" Failed to\ + \_detect public IP using fallback service: \" . \$Url . \".\")}\r\ + \n };\r\ + \n :local IpLen ([ :len \$PubIpAddr ] -1);\r\ + \n :if (\$PubIpAddr = false) do={:set PubIpAddr \"not-detected\"} else=\ + {:set PubIpAddr [:pick \$PubIpAddr 0 \$IpLen]}\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\r\ + \n :global CertificateDownload;\r\ + \n :global ParseKeyValueStore;\r\ + \n\r\ + \n :if ([ :len \$UseFor ] = 0) do={\r\ + \n :log warning (\$0 . \"The intended use is undefined!\");\r\ + \n :set UseFor \"undefined\";\r\ + \n }\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 :log 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 :log 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 :log info (\$0 . \"Certificate with CommonName '\" . \$CommonName . \ + \"' not available.\");\r\ + \n :if ([ \$CertificateDownload \$CommonName ] = false) do={\r\ + \n :return false;\r\ + \n }\r\ + \n }\r\ + \n :if ([ :len [ /certificate/find where common-name=\$CommonName ] ] > 1\ + ) do={\r\ + \n :log 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 :log info (\$0 . \"Certificate chain for '\" . \$CommonName . \"' \ + is incomplete, missing '\" . \$IssuerCN . \"'.\");\r\ + \n :if ([ \$CertificateDownload \$IssuerCN ] = false) do={\r\ + \n :return false;\r\ + \n }\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 ScriptUpdatesBaseUrl;\r\ + \n :global ScriptUpdatesUrlSuffix;\r\ + \n :global CertificateNameByCN;\r\ + \n :global CleanName;\r\ + \n :global FetchUserAgentStr;\r\ + \n :global RmFile;\r\ + \n :global WaitForFile;\r\ + \n\r\ + \n :log info (\$0 . \"Downloading and importing certificate with \" . \\\ + \r\ + \n \"CommonName '\" . \$CommonName . \"'.\");\r\ + \n :local FileName ([ \$CleanName \$CommonName ] . \".pem\");\r\ + \n :do {\r\ + \n /tool/fetch check-certificate=yes-without-crl mode=https http-header\ + -field=({ [ \$FetchUserAgentStr \$0 ] }) \\\r\ + \n (\$ScriptUpdatesBaseUrl . \"certs/\" . \$FileName . \$ScriptUpdate\ + sUrlSuffix) \\\r\ + \n dst-path=\$FileName as-value;\r\ + \n \$WaitForFile \$FileName;\r\ + \n } on-error={\r\ + \n :log warning (\$0 . \" Failed downloading certificate with CommonNam\ + e '\" . \$CommonName . \\\r\ + \n \"' from repository! Trying fallback to mkcert.org...\");\r\ + \n :do {\r\ + \n :local CertSettings [ /certificate/settings/get ];\r\ + \n :if ([ :len [ /certificate/find where common-name=\"ISRG Root X1\"\ + \_] ] = 0 && \\\r\ + \n !(((\$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=\"ISRG\ + \_Root X1\" ] ] > 0)) do={\r\ + \n :log error (\$0 . \" Required certificate is not available.\");\ + \r\ + \n :return false;\r\ + \n }\r\ + \n /tool/fetch check-certificate=yes-without-crl mode=https http-head\ + er-field=({ [ \$FetchUserAgentStr \$0 ] }) \\\r\ + \n url=\"https://mkcert.org/generate/\" http-data=[ :serialize to=jso\ + n ({ \$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 :log error (\$0 . \" Failed downloading certificate with CommonNam\ + e '\" . \$CommonName . \"'!\");\r\ + \n :return false;\r\ + \n }\r\ + \n }\r\ + \n /certificate/import file-name=\$FileName passphrase=\"\" as-value;\r\ + \n :delay 1s;\r\ + \n \$RmFile \$FileName;\r\ + \n :if ([ :len [ /certificate/find where common-name=\$CommonName ] ] = 0\ + ) do={\r\ + \n /certificate/remove [ find where name~(\"^\" . \$FileName . \"_[0-9]\ + +\\\$\") ];\r\ + \n :log warning (\$0 . \" Certificate with CommonName '\" . \$CommonNam\ + e . \"' 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 :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 :log 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 FetchUserAgentStr do={\r\ + \n :local Caller [ :tostr \$1 ];\r\ + \n\r\ + \n :global GlobalScriptsUrl;\r\ + \n :global CommitBrief;\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 (\" . \$GlobalScriptsUrl . \"; \" . [ \$\ + CommitBrief ] . \")\");\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\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 :if (\$ExitOK = \"false\") do={\r\ + \n :log 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 ExitOnError do={\r\ + \n :local Name [ :tostr \$1 ];\r\ + \n :local Error [ :tostr \$2 ];\r\ + \n :global IfThenElse;\r\ + \n :log error (\$Name . \" \" . [ \$IfThenElse ([ :pick \$Name 0 1 ] = \"\ + \\\$\") \\\r\ + \n \"Function\" \"Script\" ] . \" '\" . \$Name . \"' exited with erro\ + r\" . \\\r\ + \n [ \$IfThenElse (!(\$Error ~ \"^(|true|false)\\\$\")) (\": \" . \$E\ + rror) \".\" ]);\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={\r\ + \n :return false;\r\ + \n }\r\ + \n :local FileVal false;\r\ + \n :do {\r\ + \n :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 :log debug (\$0 . \" Removing directory: \". \$DirName);\r\ + \n :local DirVal [ \$FileGet \$DirName ];\r\ + \n :if (\$DirVal = false) do={\r\ + \n :log debug (\$0 . \" ... which does not exist.\");\r\ + \n :return true;\r\ + \n };\r\ + \n :if (\$DirVal->\"type\" != \"directory\") do={\r\ + \n :log error (\$0 . \" Directory '\" . \$DirName . \"' is not a direct\ + ory.\");\r\ + \n :return false;\r\ + \n };\r\ + \n :onerror Err {\r\ + \n /file/remove \$DirName;\r\ + \n } do={\r\ + \n :log error (\$0 . \" Removing directory '\" . \$DirName . \"' failed\ + : \" . \$Err);\r\ + \n :return false;\r\ + \n };\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 :log debug (\$0 . \" Removing file: \". \$FileName);\r\ + \n :local FileVal [ \$FileGet \$FileName ];\r\ + \n :if (\$FileVal = false) do={\r\ + \n :log debug (\$0 . \" ... which does not exist.\");\r\ + \n :return true;\r\ + \n }\r\ + \n :if (\$FileVal->\"type\" = \"directory\" || \$FileVal->\"type\" = \"di\ + sk\") do={\r\ + \n :log error (\$0 . \" File '\" . \$FileName . \"' is not a file.\");\ + \r\ + \n :return false;\r\ + \n }\r\ + \n :onerror Err {\r\ + \n /file/remove \$FileName;\r\ + \n } do={\r\ + \n :log error (\$0 . \" Removing file '\" . \$FileName . \"' failed: \"\ + \_. \$Err); :return false;\r\ + \n }\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\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 :log info (\$0 . \" The tmpfs is disabled, enabling.\");\r\ + \n /disk/enable \$TmpFs;\r\ + \n }\r\ + \n :return true;\r\ + \n }\r\ + \n :log 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 :log 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 :log debug (\$0 . \" Making directory: \" . \$Path);\r\ + \n :local PathVal [ \$FileGet \$Path ];\r\ + \n :if (\$PathVal->\"type\" = \"directory\") do={\r\ + \n :log 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 :log 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 VersionToNum;\r\ + \n :if (!(\$Required ~ \"^\\\\d+\\\\.\\\\d+((alpha|beta|rc|\\\\.)\\\\d+|)\ + \\\$\")) do={\r\ + \n :log 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 :log warning (\$0 . \" This \" . [ \$IfThenElse ([ :pick \$Caller \ + 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\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 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 :log error (\$0 . \" A script named '\" . \$Script . \"' does not ex\ + ist!\");\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 :log error (\$0 . \" More tickets than running scripts '\" . \$Scrip\ + t . \"', 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\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\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\r\ + \n:set SymbolByUnicodeName do={\r\ + \n :local Name [ :tostr \$1 ];\r\ + \n :global EitherOr;\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 :log 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\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\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\r\ + \n:set ValidateSyntax do={\r\ + \n :local Code [ :tostr \$1 ];\r\ + \n :onerror Err {\r\ + \n [ :parse (\":local Validate do={\\n\" . \$Code . \"\\n}\") ];\r\ + \n } do={\r\ + \n :log debug (\$0 . \"Validation failed: \" . \$Err);\r\ + \n :return false;\r\ + \n }\r\ + \n :return true;\r\ + \n}\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\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\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# Description of parameters:\r\ + \n# \$1 - script name for logging and user agent\r\ + \n# \$2 - url to fetch from\r\ + \n# \$3 - check-certificate value for /tool/fetch (true/false)\r\ + \n# \$4 - mode value for /tool/fetch (optional, e.g. \"keep-broken\", \"ht\ + tps-only\", \"http-only\"\r\ + \n# \"no-redirects\", \"background\", \"background-and-keep-broken\",\ + \_\"background-and-https-only\",\r\ + \n# \"background-and-http-only\", \"background-and-no-redirects\", \"\ + background-and-keep-broken-and-https-only\", \"background-and-keep-broken-\ + and-http-only\",\r\ + \n# \"background-and-keep-broken-and-no-redirects\")\r\ + \n# \$5 - fetch method for /tool/fetch (optional, e.g. \"get\", \"head\", \ + \"post\", \"put\", \"patch\", \"delete\")\r\ + \n:set FetchLargeFiles do={\r\ + \n :local FetchLargeScript [: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 \$FetchLargeScript ]);\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 \$FetchLargeScript ] }) 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 \$FetchLargeScript ] })\ + \_as-value);\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\ + \_\$FetchLargeScript ] }) 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: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 CommitId;\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 CommitIdBefore \$CommitId;\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={\r\ + \n :global ExitOnError; \$ExitOnError \$0 \$Err;\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 \"Every Day Set Global Environment Variables\";\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:log warning (\"This script \$ScriptName Loaded \" . \\\r\ + \n [ \$IfThenElse (\$CommitId != \"unknown\") ([ \$CommitBrief ] . \" \ + \") ] . \\\r\ + \n \"on \" . \$devBoardName . \"\\nRouterOS: \" . \$devCurVersion . \"\ + \\nArchitecture: \" . \$devCurArch . \"\\nIdentity: \" . \$Identity);\r\ + \n\r\ + \n# signal we are ready\r\ + \n:set GlobalFuncReady true;\r\ + \n\r\ + \n:do {\r\ + \n:onerror Err {\r\ + \n :global GlobalConfReady;\r\ + \n :retry { :if (\$GlobalConfReady != true) \\\r\ + \n do={ :error (\"Global config not ready.\"); }; } delay=500ms max=50;\ + \r\ + \n } do={\r\ + \n :global ExitOnError; \$ExitOnError \$0 \$Err;\r\ + \n }\r\ + \n}\r\ + \n" +add comment="download, import and update firewall address-lists" \ + dont-require-permissions=no name=AM-FwAddrLists owner=AM-FwAddrLists \ + policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + source="#!rsc by Vados\r\ + \n# RouterOS script: AM-FwAddrLists\r\ + \n# Script comment: download, import and update firewall address-lists\r\ + \n# Copyright (c) 2007-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# requires RouterOS, version=7.19\r\ + \n# https://ros.vados.ru/doc/fw-addr-lists.md\r\ + \n:local ExitOK false;\r\ + \n:onerror Err {\r\ + \n :global GlobalConfReady; :global GlobalFuncReady;\r\ + \n :retry { :if (\$GlobalConfReady != true || \$GlobalFuncReady != true) \ + \\\r\ + \n do={ :error (\"Global config and/or functions not ready.\"); }; } \ + delay=500ms max=50;\r\ + \n :local ScriptName [ :jobname ];\r\ + \n\r\ + \n :global GlobalScriptsUrl;\r\ + \n :local FwAddrListsUrl (\$GlobalScriptsUrl . \"fw-addr-lists.d/\");\r\ + \n :local FwAddrListsIndexUrl (\$FwAddrListsUrl . \"index\");\r\ + \n :local FwAddrListTimeOut 1d;\r\ + \n :local FetchMode \"\";\r\ + \n\r\ + \n :global CertificateAvailable;\r\ + \n :global EitherOr;\r\ + \n :global FetchLargeFiles;\r\ + \n :global HumanReadableNum;\r\ + \n :global IfThenElse;\r\ + \n :global LogPrint;\r\ + \n\r\ + \n :global NetMask4;\r\ + \n :global NetMask6;\r\ + \n :global ScriptLock;\r\ + \n \r\ + \n :local FindDelim do={\r\ + \n :local ValidChars \"0123456789.:/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghi\ + jklmnopqrstuvwxyz-\";\r\ + \n :for I from=0 to=([ :len \$1 ] - 1) do={\r\ + \n :if ([ :typeof [ :find \$ValidChars [ :pick \$1 \$I ] ] ] != \"num\ + \") do={\r\ + \n :return \$I;\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :local GetBranch do={\r\ + \n :global EitherOr;\r\ + \n :return [ :pick [ :convert transform=md5 to=hex [ :pick \$1 0 [ \$Ei\ + therOr [ :find \$1 \"/\" ] [ :len \$1 ] ] ] ] 0 2 ];\r\ + \n }\r\ + \n \r\ + \n :if ([ \$ScriptLock \$ScriptName ] = false) do={\r\ + \n :set ExitOK true;\r\ + \n :error false;\r\ + \n }\r\ + \n\r\ + \n :if ([ :len [ /log/find where topics=({\"script\"; \"warning\"}) \\\r\ + \n message=(\"\\\$LogPrint: The message is already in log, scripting \ + subsystem may have crashed before!\") ] ] > 0) do={\r\ + \n :log warning (\$ScriptName . \" Scripting subsystem may have crashed\ + , possibly caused by us. Delaying!\");\r\ + \n :delay 5m;\r\ + \n }\r\ + \n\r\ + \n :local ListComment (\"managed by \" . \$ScriptName);\r\ + \n :local FwAddrListsIndex false;\r\ + \n\r\ + \n :for I from=1 to=5 do={\r\ + \n :if (\$FwAddrListsIndex = false) do={\r\ + \n :set FwAddrListsIndex [ :tolf [ \$FetchLargeFiles \$ScriptName \$F\ + wAddrListsIndexUrl true \$FetchMode ] ];\r\ + \n :if (\$FwAddrListsIndex = false && \$I < 5) do={\r\ + \n :log warning (\$ScriptName . \" Failed downloading address-list \ + index, \" . \$I . \". try from: \" . \$FwAddrListsIndexUrl);\r\ + \n :delay ((\$I * \$I) . \"s\");\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n :if (\$FwAddrListsIndex = false) do={\r\ + \n :log warning (\$ScriptName . \" Failed downloading address-list inde\ + x from: \" . \$FwAddrListsIndexUrl);\r\ + \n :set FwAddrListsIndex \"\";\r\ + \n }\r\ + \n\r\ + \n :foreach FwListFile in=[ :deserialize \$FwAddrListsIndex delimiter=\"\ + \\n\" from=dsv options=dsv.plain ] do={\r\ + \n :local FwListName (\$FwListFile->0);\r\ + \n :local Delim [ \$FindDelim \$FwListName ];\r\ + \n :if (\$Delim = 0) do={ :set FwListName \"\"; };\r\ + \n :if ([ :len \$FwListName ] = 0) do={ :error true; }\r\ + \n :set FwListName [ :pick \$FwListName 0 \$Delim ];\r\ + \n\r\ + \n :local FwListUrl (\$FwAddrListsUrl . \$FwListName);\r\ + \n :local CntAdd 0;\r\ + \n :local CntRenew 0;\r\ + \n :local CntRemove 0;\r\ + \n :local IPv4Addresses ({});\r\ + \n :local IPv6Addresses ({});\r\ + \n :local Failure false;\r\ + \n :local Data false;\r\ + \n :local TimeOut \$FwAddrListTimeOut;\r\ + \n\r\ + \n :for I from=1 to=5 do={\r\ + \n :if (\$Data = false) do={\r\ + \n :set Data [ :tolf [ \$FetchLargeFiles \$ScriptName \$FwListUrl t\ + rue \$FetchMode ] ];\r\ + \n :if (\$Data = false && \$I < 5) do={\r\ + \n :log warning (\$ScriptName . \" Failed downloading for list '\ + \" . \$FwListName . \"', \" . \$I . \". try from: \" . \$FwListUrl);\r\ + \n :delay ((\$I * \$I) . \"s\");\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :if (\$Data = false) do={\r\ + \n :set Data \"\";\r\ + \n :set Failure true;\r\ + \n :log warning (\$ScriptName . \" Failed downloading for list '\" . \ + \$FwListName . \"' from: \" . \$FwListUrl);\r\ + \n } else={\r\ + \n :log debug (\$ScriptName . \" Downloaded \" . [ \$HumanReadableNum\ + \_[ :len \$Data ] 1024 ] . \"B for list '\" . \$FwListName . \"' from: \" \ + . \$FwListUrl);\r\ + \n }\r\ + \n\r\ + \n :foreach Line in=[ :deserialize \$Data delimiter=\"\\n\" from=dsv op\ + tions=dsv.plain ] do={\r\ + \n :set Line (\$Line->0);\r\ + \n :local Delim [ \$FindDelim \$Line ];\r\ + \n :if (\$Delim = 0) do={ :set Line \"\"; };\r\ + \n :if ([ :len \$Line ] = 0) do={ :error true; }\r\ + \n :local Address;\r\ + \n :if ([ :pick \$Line 0 1 ] = \"{\" && [ :pick \$Line ([ :len \$Line\ + \_] - 1) ] = \"}\") do={\r\ + \n :do {\r\ + \n :set Address [ :tostr ([ :deserialize from=json \$Line ]->\"ci\ + dr\") ];\r\ + \n } on-error={ }\r\ + \n } else={\r\ + \n :set Address [ :pick \$Line 0 [ \$FindDelim \$Line ] ];\r\ + \n }\r\ + \n :do {\r\ + \n :local Branch;\r\ + \n :if (\$Address ~ \"^[0-9]{1,3}\\\\.[0-9]{1,3}\\\\.[0-9]{1,3}\\\\\ + .[0-9]{1,3}(/[0-9]{1,2})\?\\\$\") do={\r\ + \n :local Net \$Address;\r\ + \n :local CIDR 32;\r\ + \n :local Slash [ :find \$Address \"/\" ];\r\ + \n :if ([ :typeof \$Slash ] = \"num\") do={\r\ + \n :set Net [ :toip [ :pick \$Address 0 \$Slash ] ]\r\ + \n :set CIDR [ :pick \$Address (\$Slash + 1) [ :len \$Address ]\ + \_];\r\ + \n :set Address [ :tostr (([ :toip \$Net ] & [ \$NetMask4 \$CID\ + R ]) . [ \$IfThenElse (\$CIDR < 32) (\"/\" . \$CIDR) ]) ];\r\ + \n }\r\ + \n :set Branch [ \$GetBranch \$Address ];\r\ + \n :if ([ :typeof (\$IPv4Addresses->\$Branch) ] != \"array\") do=\ + { :set (\$IPv4Addresses->\$Branch) ({}) };\r\ + \n :set (\$IPv4Addresses->\$Branch->\$Address) \$TimeOut;\r\ + \n :error true;\r\ + \n }\r\ + \n :if (\$Address ~ \"^[0-9a-zA-Z]*:[0-9a-zA-Z:\\\\.]+(/[0-9]{1,3})\ + \?\\\$\") do={\r\ + \n :local Net \$Address;\r\ + \n :local CIDR 128;\r\ + \n :local Slash [ :find \$Address \"/\" ];\r\ + \n :if ([ :typeof \$Slash ] = \"num\") do={\r\ + \n :set Net [ :toip6 [ :pick \$Address 0 \$Slash ] ]\r\ + \n :set CIDR [ :pick \$Address (\$Slash + 1) [ :len \$Address ]\ + \_];\r\ + \n }\r\ + \n :set Address (([ :toip6 \$Net ] & [ \$NetMask6 \$CIDR ]) . \"/\ + \" . \$CIDR);\r\ + \n :set Branch [ \$GetBranch \$Address ];\r\ + \n :if ([ :typeof (\$IPv6Addresses->\$Branch) ] != \"array\") do=\ + { :set (\$IPv6Addresses->\$Branch) ({}) };\r\ + \n :set (\$IPv6Addresses->\$Branch->\$Address) \$TimeOut;\r\ + \n :error true;\r\ + \n }\r\ + \n :if (\$Address ~ \"^[\\\\.a-zA-Z0-9-]+\\\\.[a-zA-Z]{2,}\\\$\") d\ + o={\r\ + \n :set Branch [ \$GetBranch \$Address ];\r\ + \n :if ([ :typeof (\$IPv4Addresses->\$Branch) ] != \"array\") do=\ + { :set (\$IPv4Addresses->\$Branch) ({}) };\r\ + \n :if ([ :typeof (\$IPv6Addresses->\$Branch) ] != \"array\") do=\ + { :set (\$IPv6Addresses->\$Branch) ({}) };\r\ + \n :set (\$IPv4Addresses->\$Branch->\$Address) \$TimeOut;\r\ + \n :set (\$IPv6Addresses->\$Branch->\$Address) \$TimeOut;\r\ + \n :error true;\r\ + \n }\r\ + \n } on-error={:log error (\$ScriptName . \" Failed parsing address: \ + \" . \$Line->0);}\r\ + \n }\r\ + \n\r\ + \n :foreach Entry in=[ /ip/firewall/address-list/find where \\\r\ + \n list=\$FwListName comment=\$ListComment ] do={\r\ + \n :local Address [ /ip/firewall/address-list/get \$Entry address ];\ + \r\ + \n :local Branch [ \$GetBranch \$Address ];\r\ + \n :local TimeOut (\$IPv4Addresses->\$Branch->\$Address);\r\ + \n :if ([ :typeof \$TimeOut ] = \"time\") do={\r\ + \n :log debug (\$ScriptName . \" Renewing IPv4 address \" . \$Addre\ + ss . \\\r\ + \n \" in list '\" . \$FwListName . \"' with \" . \$TimeOut . \"\ + .\");\r\ + \n /ip/firewall/address-list/set \$Entry timeout=\$TimeOut;\r\ + \n :set (\$IPv4Addresses->\$Branch->\$Address);\r\ + \n :set CntRenew (\$CntRenew + 1);\r\ + \n } else={\r\ + \n :if (\$Failure = false) do={\r\ + \n :log debug (\$ScriptName . \" Removing IPv4 address \" . \$Add\ + ress . \\\r\ + \n \" from list '\" . \$FwListName . \".\");\r\ + \n /ip/firewall/address-list/remove \$Entry;\r\ + \n :set CntRemove (\$CntRemove + 1);\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :foreach Entry in=[ /ipv6/firewall/address-list/find where \\\r\ + \n list=\$FwListName comment=\$ListComment ] do={\r\ + \n :local Address [ /ipv6/firewall/address-list/get \$Entry address ]\ + ;\r\ + \n :local Branch [ \$GetBranch \$Address ];\r\ + \n :local TimeOut (\$IPv6Addresses->\$Branch->\$Address);\r\ + \n :if ([ :typeof \$TimeOut ] = \"time\") do={\r\ + \n :log debug (\$ScriptName . \" Renewing IPv6 address \" . \$Addre\ + ss . \\\r\ + \n \" in list '\" . \$FwListName . \"' with \" . \$TimeOut . \"\ + .\");\r\ + \n /ipv6/firewall/address-list/set \$Entry timeout=\$TimeOut;\r\ + \n :set (\$IPv6Addresses->\$Branch->\$Address);\r\ + \n :set CntRenew (\$CntRenew + 1);\r\ + \n } else={\r\ + \n :if (\$Failure = false) do={\r\ + \n :log debug (\$ScriptName . \" Removing IPv6 address \" . \$Add\ + ress . \\\r\ + \n \" from list '\" . \$FwListName .\".\");\r\ + \n /ipv6/firewall/address-list/remove \$Entry;\r\ + \n :set CntRemove (\$CntRemove + 1);\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :foreach BranchName,Branch in=\$IPv4Addresses do={\r\ + \n :log debug (\$ScriptName . \" Handling branch: \" . \$BranchName);\ + \r\ + \n :foreach Address,Timeout in=\$Branch do={\r\ + \n :log debug (\$ScriptName . \" Adding IPv4 address \" . \$Address\ + \_. \\\r\ + \n \" to list '\" . \$FwListName . \"' with \" . \$Timeout . \"\ + .\");\r\ + \n :onerror Err {\r\ + \n /ip/firewall/address-list/add list=\$FwListName comment=\$List\ + Comment \\\r\ + \n address=\$Address timeout=\$Timeout;\r\ + \n :set CntAdd (\$CntAdd + 1);\r\ + \n } do={\r\ + \n :log warning (\$ScriptName . \" Failed to add IPv4 address \" \ + . \$Address . \\\r\ + \n \" to list '\" . \$FwListName . \"': \" . \$Err);\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :foreach BranchName,Branch in=\$IPv6Addresses do={\r\ + \n :log debug (\$ScriptName . \" Handling branch: \" . \$BranchName);\ + \r\ + \n :foreach Address,Timeout in=\$Branch do={\r\ + \n :log debug (\$ScriptName . \" Adding IPv6 address \" . \$Address\ + \_. \\\r\ + \n \" to list '\" . \$FwListName . \"' with \" . \$Timeout . \"\ + .\");\r\ + \n :onerror Err {\r\ + \n /ipv6/firewall/address-list/add list=\$FwListName comment=\$Li\ + stComment \\\r\ + \n address=\$Address timeout=\$Timeout;\r\ + \n :set CntAdd (\$CntAdd + 1);\r\ + \n } do={\r\ + \n :log warning (\$ScriptName . \" Failed to add IPv6 address \" \ + . \$Address . \\\r\ + \n \" to list '\" . \$FwListName . \"': \" . \$Err);\r\ + \n }\r\ + \n }\r\ + \n }\r\ + \n\r\ + \n :log info (\$ScriptName . \" list: \" . \$FwListName . \\\r\ + \n \" (\" . [ \$HumanReadableNum (\$CntAdd + \$CntRenew) 1000 ] . \ + \")\" . \\\r\ + \n \" -- added: \" . [ \$HumanReadableNum \$CntAdd 1000 ] . \\\r\ + \n \" - renewed: \" . [ \$HumanReadableNum \$CntRenew 1000 ] . \\\r\ + \n \" - removed: \" . [ \$HumanReadableNum \$CntRemove 1000 ]);\r\ + \n }\r\ + \n} do={\r\ + \n :global ExitError; \$ExitError \$ExitOK [ :jobname ] \$Err;\r\ + \n}\r\ + \n" +/user group +add name=backup policy="telnet,ssh,ftp,read,write,policy,test,sniff,sensitive,\ + !local,!reboot,!winbox,!password,!web,!api,!romon,!rest-api" +/interface bridge +add admin-mac=48:8F:5A:8E:1A:BC auto-mac=no mlag-peer-port="ether1 - Unet" \ + name=Bridge-LAN port-cost-mode=short +/interface wireless +# managed by CAPsMAN +# channel: 2422/20-Ce/gn(18dBm), SSID: vados, local forwarding +set [ find default-name=wlan1 ] ampdu-priorities=0,1,2,3,4,5,6,7 band=\ + 2ghz-b/g/n basic-rates-a/g=\ + 6Mbps,9Mbps,12Mbps,18Mbps,24Mbps,36Mbps,48Mbps,54Mbps basic-rates-b=\ + 1Mbps,2Mbps,5.5Mbps,11Mbps channel-width=20/40mhz-XX country=belarus \ + disabled=no frequency=auto hw-protection-mode=rts-cts mode=ap-bridge \ + rate-set=configured skip-dfs-channels=10min-cac ssid=vados \ + wds-default-bridge=Bridge-LAN wds-mode=dynamic-mesh wireless-protocol=\ + 802.11 wmm-support=enabled wps-mode=disabled +# managed by CAPsMAN +# channel: 5260/20-Ceee/ac/DP(18dBm), SSID: vados5g, local forwarding +set [ find default-name=wlan2 ] ampdu-priorities=0,1,2,3,4,5,6,7 band=\ + 5ghz-a/n/ac basic-rates-a/g=\ + 6Mbps,9Mbps,12Mbps,18Mbps,24Mbps,36Mbps,48Mbps,54Mbps channel-width=\ + 20/40/80mhz-XXXX country=belarus disabled=no frequency=auto \ + hw-protection-mode=rts-cts mode=ap-bridge rate-set=configured \ + skip-dfs-channels=10min-cac ssid=vados5g wds-default-bridge=Bridge-LAN \ + wds-mode=dynamic-mesh wireless-protocol=802.11 wmm-support=enabled \ + wps-mode=disabled +/interface wireless nstreme +# managed by CAPsMAN +# channel: 2422/20-Ce/gn(18dBm), SSID: vados, local forwarding +set wlan1 enable-nstreme=yes +# managed by CAPsMAN +# channel: 5260/20-Ceee/ac/DP(18dBm), SSID: vados5g, local forwarding +set wlan2 enable-nstreme=yes +/caps-man manager +set enabled=yes +/caps-man provisioning +add action=create-dynamic-enabled hw-supported-modes=gn master-configuration=\ + cfg-2ghz name-format=prefix-identity name-prefix=2ghz +add action=create-dynamic-enabled hw-supported-modes=ac master-configuration=\ + cfg-5ghz-ac name-format=prefix-identity name-prefix=5ghz-ac +add action=create-dynamic-enabled hw-supported-modes=an master-configuration=\ + cfg-5ghz-an name-format=prefix-identity name-prefix=5ghz-an +/certificate settings +set builtin-trust-store="ipsec,wpa-eap,capsman,fetch,sstp,ovpn,radius,userman,\ + openflow,tr069,dot1x,dns,www,api,reverse-proxy" crl-store=system +/interface bridge port +add bridge=Bridge-LAN disabled=yes interface="ether1 - Unet" +add bridge=Bridge-LAN interface=ether2 +add bridge=Bridge-LAN interface=ether3 +add bridge=Bridge-LAN interface=ether4 +add bridge=Bridge-LAN interface=ether5 +add bridge=Bridge-LAN interface=wlan2 +add bridge=Bridge-LAN interface=wlan1 +/ip firewall connection tracking +set udp-timeout=10s +/ip neighbor discovery-settings +set discover-interface-list=LAN +/ip settings +set max-neighbor-entries=8192 secure-redirects=no +/ipv6 settings +set allow-fast-path=no disable-ipv6=yes disable-link-local-address=yes \ + forward=no max-neighbor-entries=8192 +/interface detect-internet +set detect-interface-list=WAN internet-interface-list=WAN lan-interface-list=\ + LAN wan-interface-list=WAN +/interface l2tp-server server +set authentication=mschap2 use-ipsec=yes +/interface list member +add interface="ether1 - Unet" list=WAN +add interface=Bridge-LAN list=LAN +/interface ovpn-server server +add auth=sha1,md5 mac-address=FE:82:A5:78:8E:84 name=ovpn-server1 +/interface wifi configuration +add channel=2G-AX datapath=xs-DataPath disabled=no mode=ap name=2G-AX \ + security=sec2g security.ft=yes .ft-over-ds=yes ssid=vados +add channel=2G-N datapath=xs-DataPath disabled=no mode=ap name=2G-N security=\ + sec2g security.ft=yes .ft-over-ds=yes ssid=vados +add channel=5G-AC datapath=xs-DataPath disabled=no mode=ap name=5G-AC \ + security=sec5G security.authentication-types="" .ft=yes .ft-over-ds=yes \ + ssid=vados +add channel=2G-G datapath=xs-DataPath disabled=no mode=ap name=2G-G security=\ + sec2g security.authentication-types="" .ft=yes .ft-over-ds=yes ssid=vados +/interface wifi datapath +add bridge=Bridge-LAN disabled=no interface-list=all name=xs-DataPath +/interface wireguard peers +add allowed-address=10.8.0.2/32,0.0.0.0/0 client-allowed-address=0.0.0.0/0 \ + endpoint-address=89.110.101.17 endpoint-port=29185 interface=WG name=\ + MikroVados persistent-keepalive=10s public-key=\ + "64Y25EUZQQt8EIeAJYD8qWt+te8qvGEepnswdBgmzlY=" +/interface wireless cap +# +set bridge=Bridge-LAN caps-man-addresses=10.30.30.10 \ + caps-man-certificate-common-names=CAPsMAN-51B25E507D07 certificate=\ + CAP-488F5A8E1ABC discovery-interfaces=ether2 enabled=yes interfaces=\ + wlan1,wlan2 lock-to-caps-man=yes +/ip address +add address=10.30.30.81/24 interface=Bridge-LAN network=10.30.30.0 +add address=10.8.0.2/24 interface=WG network=10.8.0.0 +/ip dhcp-client +add add-default-route=special-classless default-route-distance=2 \ + default-route-tables=main interface="ether1 - Unet" name=client1 \ + use-peer-dns=no +/ip dhcp-server +add add-arp=yes address-pool=dhcp always-broadcast=yes bootp-support=none \ + dhcp-option-set=domain-search-set interface=Bridge-LAN lease-time=10m \ + name=masterDHCP server-address=10.30.30.81 +/ip dhcp-server config +set accounting=no +/ip dhcp-server lease +add address=10.30.30.101 client-id=1:48:8f:5a:8e:ee:a8 mac-address=\ + 48:8F:5A:8E:EE:A8 server=masterDHCP +add address=10.30.30.107 client-id=1:f0:de:f1:91:d:1e mac-address=\ + F0:DE:F1:91:0D:1E server=masterDHCP +add address=10.30.30.83 client-id=1:0:80:77:ec:43:86 mac-address=\ + 00:80:77:EC:43:86 server=masterDHCP +add address=10.30.30.70 dhcp-option=domain-search-list,HostName \ + dhcp-option-set=HP1505n mac-address=00:1E:0B:1A:88:8D server=masterDHCP +add address=10.30.30.50 client-id=1:4:7c:16:36:f5:37 mac-address=\ + 04:7C:16:36:F5:37 server=masterDHCP +add address=10.30.30.71 client-id=1:10:2d:41:2c:20:c2 mac-address=\ + 10:2D:41:2C:20:C2 server=masterDHCP +add address=10.30.30.61 client-id=1:10:8:c1:81:59:5f mac-address=\ + 10:08:C1:81:59:5F server=masterDHCP +add address=10.30.30.72 client-id=1:10:38:1f:d2:5f:13 mac-address=\ + 10:38:1F:D2:5F:13 server=masterDHCP +add address=10.30.30.99 client-id=1:10:b1:df:e9:d0:d5 mac-address=\ + 10:B1:DF:E9:D0:D5 server=masterDHCP +add address=10.30.30.111 client-id=1:fe:2:52:be:3f:16 mac-address=\ + FE:02:52:BE:3F:16 server=masterDHCP +add address=10.30.30.92 client-id=1:d4:6d:6d:fd:e5:49 mac-address=\ + D4:6D:6D:FD:E5:49 server=masterDHCP +add address=10.30.30.93 client-id=1:7e:8b:1e:cb:b8:cb mac-address=\ + CC:42:10:12:46:94 server=masterDHCP +add address=10.30.30.94 client-id=1:50:cc:f8:85:96:a mac-address=\ + 50:CC:F8:85:96:0A server=masterDHCP +add address=10.30.30.82 client-id=1:e4:18:6b:58:34:ab mac-address=\ + E4:18:6B:58:34:AB server=masterDHCP +add address=10.30.30.75 client-id=1:0:27:15:41:97:a9 mac-address=\ + 00:27:15:41:97:A9 server=masterDHCP +add address=10.30.30.77 dhcp-option=HostName dhcp-option-set=StartLife1 \ + mac-address=C4:82:E1:03:49:10 server=masterDHCP +add address=10.30.30.73 client-id=1:10:38:1f:82:81:f2 mac-address=\ + 10:38:1F:82:81:F2 server=masterDHCP +add address=10.30.30.95 client-id=1:88:ae:dd:60:39:54 dhcp-option=HostName \ + dhcp-option-set=VADOS-NUC mac-address=88:AE:DD:60:39:54 server=masterDHCP +add address=10.30.30.98 client-id=1:c8:5b:76:d8:cc:bf dhcp-option=HostName \ + dhcp-option-set=VADOS-LEN mac-address=C8:5B:76:D8:CC:BF server=masterDHCP +add address=10.30.30.96 client-id=iPhone mac-address=4A:91:ED:0E:1F:39 \ + server=masterDHCP +add address=10.30.30.74 client-id=MiTV dhcp-option=HostName dhcp-option-set=\ + MiTV mac-address=20:72:A9:D3:34:36 server=masterDHCP +add address=10.30.30.30 dhcp-option=HostName dhcp-option-set=miller \ + mac-address=F0:75:5D:1E:5F:71 server=masterDHCP +add address=10.30.30.100 client-id=iVados dhcp-option=HostName \ + dhcp-option-set="=\"Client ID\"" mac-address=DE:4D:72:F3:1A:9F server=\ + masterDHCP +/ip dhcp-server network +add address=10.30.30.0/24 caps-manager=10.30.30.10 dhcp-option=\ + domain-search-list dhcp-option-set=domain-search-set dns-server=\ + 10.30.30.81 domain=WORKGROUP gateway=10.30.30.81 netmask=24 ntp-server=\ + 10.30.30.81,10.30.30.10 wins-server=10.30.30.95,10.30.30.98 +/ip dns +set allow-remote-requests=yes cache-max-ttl=1d doh-max-concurrent-queries=100 \ + doh-max-server-connections=20 servers=8.8.8.8,8.8.4.4 verify-doh-cert=yes +/ip dns static +add address=10.30.30.33 name=ros.vados.ru type=A +add address=10.30.30.95 name=vados-nuc type=A +add address=10.30.30.33 name=amster-nuc type=A +add address=10.30.30.33 comment=AMSTER name=amster.vados.ru type=A +add address=10.30.30.33 name=amster type=A +add address=10.30.30.33 name=amster-reg type=A +add address=10.30.30.33 name=mng.vados.ru type=A +add address=10.30.30.33 name=mgr.vados.ru type=A +add address=10.30.30.33 name=prt.vados.ru type=A +add address=10.30.30.33 name=reg.vados.ru type=A +add address=10.30.30.33 match-subdomain=yes name=mikrots.vados.ru type=A +add address=10.30.30.33 name=oxidized.vados.ru type=A +add address=8.8.4.4 comment="Google-dns IPv4 2" name=dns.google type=A +add address=8.8.8.8 comment="Google-dns IPv4 1" name=dns.google type=A +add address=10.30.30.30 comment=MILLER name=miller.vados.ru type=A +add address=10.30.30.30 name=MILLER-LEN type=A +add address=10.30.30.30 name=miller type=A +add address=1.0.0.1 comment="CloudFlare-doh IPv4 2" name=\ + security.cloudflare-dns.com type=A +add address=1.1.1.1 comment="CloudFlare-doh IPv4 1" name=\ + security.cloudflare-dns.com type=A +add address=9.9.9.9 comment="Cuad9-dns IPv4 1" disabled=yes name=\ + dns.quad9.net type=A +add address=149.112.112.112 comment="Cuad9-dns IPv4 2" name=dns.quad9.net \ + type=A +add address=91.192.189.2 comment=Unet-DNS disabled=yes name=ns1.unet.ws type=\ + A +add address=10.30.30.81 comment=LocalNet name=MikroVados type=A +add address=10.30.30.10 name=MikroNUC type=A +add address=10.30.30.86 name=MikroYellow type=A +add address=10.30.30.85 name=MikroMic type=A +add address=10.30.30.95 name=VADOS-NUC type=A +add address=10.30.30.98 name=VADOS-LEN type=A +add address=10.30.30.20 name=garage type=A +add address=9.9.9.9 comment="Cuad9-dns IPv4 1" disabled=yes name=\ + dns.quad9.net type=A +add address=91.192.189.2 comment=Unet-DNS disabled=yes name=ns1.unet.ws type=\ + A +/ip firewall address-list +add address=91.215.120.206 list=TRUSTED +add address=185.71.70.78 disabled=yes list=TRUSTED +add address=176.53.203.171 disabled=yes list=TRUSTED +add address=176.53.203.170 disabled=yes list=TRUSTED +add address=176.53.202.194 disabled=yes list=TRUSTED +add address=10.30.30.100-255 list=KIDS +add address=8.8.4.0/24 list=YouTube +add address=8.8.8.0/24 list=YouTube +add address=8.34.208.0/20 list=YouTube +add address=8.35.192.0/20 list=YouTube +add address=23.236.48.0/20 list=YouTube +add address=23.251.128.0/19 list=YouTube +add address=34.0.0.0/15 list=YouTube +add address=34.2.0.0/16 list=YouTube +add address=34.3.0.0/23 list=YouTube +add address=34.3.3.0/24 list=YouTube +add address=34.3.4.0/24 list=YouTube +add address=34.3.8.0/21 list=YouTube +add address=34.3.16.0/20 list=YouTube +add address=34.3.32.0/19 list=YouTube +add address=34.3.64.0/18 list=YouTube +add address=34.4.0.0/14 list=YouTube +add address=34.8.0.0/13 list=YouTube +add address=34.16.0.0/12 list=YouTube +add address=34.32.0.0/11 list=YouTube +add address=34.64.0.0/10 list=YouTube +add address=34.128.0.0/10 list=YouTube +add address=35.184.0.0/13 list=YouTube +add address=35.192.0.0/14 list=YouTube +add address=35.196.0.0/15 list=YouTube +add address=35.198.0.0/16 list=YouTube +add address=35.199.0.0/17 list=YouTube +add address=35.199.128.0/18 list=YouTube +add address=35.200.0.0/13 list=YouTube +add address=35.208.0.0/12 list=YouTube +add address=35.224.0.0/12 list=YouTube +add address=35.240.0.0/13 list=YouTube +add address=57.140.192.0/18 list=YouTube +add address=64.15.112.0/20 list=YouTube +add address=64.233.160.0/19 list=YouTube +add address=66.22.228.0/23 list=YouTube +add address=66.102.0.0/20 list=YouTube +add address=66.249.64.0/19 list=YouTube +add address=70.32.128.0/19 list=YouTube +add address=72.14.192.0/18 list=YouTube +add address=74.125.0.0/16 list=YouTube +add address=104.154.0.0/15 list=YouTube +add address=104.196.0.0/14 list=YouTube +add address=104.237.160.0/19 list=YouTube +add address=107.167.160.0/19 list=YouTube +add address=107.178.192.0/18 list=YouTube +add address=108.59.80.0/20 list=YouTube +add address=108.170.192.0/18 list=YouTube +add address=108.177.0.0/17 list=YouTube +add address=130.211.0.0/16 list=YouTube +add address=136.22.160.0/20 list=YouTube +add address=136.22.176.0/21 list=YouTube +add address=136.22.184.0/23 list=YouTube +add address=136.22.186.0/24 list=YouTube +add address=142.250.0.0/15 list=YouTube +add address=146.148.0.0/17 list=YouTube +add address=152.65.208.0/22 list=YouTube +add address=152.65.214.0/23 list=YouTube +add address=152.65.218.0/23 list=YouTube +add address=152.65.222.0/23 list=YouTube +add address=152.65.224.0/19 list=YouTube +add address=162.120.128.0/17 list=YouTube +add address=162.216.148.0/22 list=YouTube +add address=162.222.176.0/21 list=YouTube +add address=172.110.32.0/21 list=YouTube +add address=172.217.0.0/16 list=YouTube +add address=172.253.0.0/16 list=YouTube +add address=173.194.0.0/16 list=YouTube +add address=173.255.112.0/20 list=YouTube +add address=192.158.28.0/22 list=YouTube +add address=192.178.0.0/15 list=YouTube +add address=193.186.4.0/24 list=YouTube +add address=199.36.154.0/23 list=YouTube +add address=199.36.156.0/24 list=YouTube +add address=199.192.112.0/22 list=YouTube +add address=199.223.232.0/21 list=YouTube +add address=207.223.160.0/20 list=YouTube +add address=208.65.152.0/22 list=YouTube +add address=208.68.108.0/22 list=YouTube +add address=208.81.188.0/22 list=YouTube +add address=208.117.224.0/19 list=YouTube +add address=209.85.128.0/17 list=YouTube +add address=216.58.192.0/19 list=YouTube +add address=216.73.80.0/20 list=YouTube +add address=216.239.32.0/19 list=YouTube +add address=2ip.ru list=Test +add address=157.240.247.174 list=Instagram +add address=46.53.178.107 list=Instagram +add address=179.60.195.174 list=Instagram +add address=157.240.205.174 list=Instagram +add address=31.13.24.0/21 list=Instagram +add address=31.13.64.0/18 list=Instagram +add address=45.64.40.0/22 list=Instagram +add address=66.220.144.0/20 list=Instagram +add address=69.63.176.0/20 list=Instagram +add address=69.171.224.0/19 list=Instagram +add address=74.119.76.0/22 list=Instagram +add address=103.4.96.0/22 list=Instagram +add address=129.134.0.0/16 list=Instagram +add address=157.240.0.0/16 list=Instagram +add address=173.252.64.0/18 list=Instagram +add address=179.60.192.0/22 list=Instagram +add address=185.60.216.0/22 list=Instagram +add address=204.15.20.0/22 list=Instagram +add address=157.240.200.63 list=Instagram +add address=185.60.219.63 list=Instagram +add address=129.134.31.12 list=Instagram +add address=66.81.203.132 list=Instagram +add address=185.89.218.12 list=Instagram +add address=31.13.66.63 list=Instagram +add address=84.15.65.162 list=Instagram +add address=68.66.224.28 list=Instagram +add address=157.240.253.63 list=Instagram +add address=83.174.11.224 list=Instagram +add address=157.240.9.52 list=Instagram +add address=157.240.252.174 list=Instagram +add address=157.240.195.63 list=Instagram +add address=31.13.71.52 list=Instagram +add address=57.144.110.192 list=Instagram +add address=157.240.252.17 list=Instagram +add address=84.15.66.97 list=Instagram +add address=217.168.6.33 list=Instagram +add address=31.13.83.52 list=Instagram +add address=157.240.241.63 list=Instagram +add address=129.134.30.12 list=Instagram +add address=185.89.219.12 list=Instagram +add address=157.240.252.10 list=Instagram +add address=157.240.201.63 list=Instagram +add address=66.81.203.197 list=Instagram +add address=179.60.195.52 list=Instagram +add address=66.81.203.7 list=Instagram +add address=216.40.34.41 list=Instagram +add address=157.240.202.63 list=Instagram +add address=157.240.229.63 list=Instagram +add address=157.240.252.63 list=Instagram +add address=31.13.72.53 list=Instagram +add address=124.108.16.224 list=Instagram +add address=157.240.205.63 list=Instagram +add address=92.46.37.96 list=Instagram +add address=157.240.247.63 list=Instagram +add address=157.240.234.63 list=Instagram +add address=157.240.235.63 list=Instagram +add address=87.245.208.97 list=Instagram +add address=216.58.192.0/19 list=Instagram +add address=209.85.128.0/17 list=Instagram +add address=198.105.240.0/20 list=Instagram +add address=173.194.0.0/16 list=Instagram +add address=172.217.0.0/16 list=Instagram +add address=142.250.0.0/15 list=Instagram +add address=108.177.0.0/17 list=Instagram +add address=87.245.197.140 list=Instagram +add address=74.125.0.0/16 list=Instagram +add address=64.233.160.0/19 list=Instagram +add address=157.240.0.1 list=Instagram +add address=157.240.238.63 list=Instagram +add address=157.240.238.174 list=Instagram +add address=157.240.0.63 list=Instagram +add address=157.240.224.63 list=Instagram +add address=157.240.224.174 list=Instagram +add address=157.240.251.36 list=Instagram +add address=157.240.253.12 list=Instagram +add address=157.240.253.35 list=Instagram +add address=157.240.238.13 list=Instagram +add address=157.240.238.56 list=Instagram +add address=157.240.238.175 list=Instagram +add address=57.144.112.141 list=Instagram +add address=157.240.251.60 list=Instagram +add address=157.240.251.128 list=Instagram +add address=157.240.238.5 list=Instagram +add address=157.240.253.13 list=Instagram +add address=157.240.253.5 list=Instagram +add address=157.240.238.2 list=Instagram +add address=157.240.238.37 list=Instagram +add address=157.240.251.5 list=Instagram +add address=157.240.251.34 list=Instagram +add address=57.144.112.1 list=Instagram +add address=157.240.238.54 list=Instagram +add address=129.134.26.123 list=Instagram +add address=157.240.252.3 list=Instagram +add address=31.13.84.4 list=Instagram +add address=157.240.224.12 list=Instagram +add address=157.240.238.4 list=Instagram +add address=157.240.0.13 list=Instagram +add address=3.33.139.32 list=Instagram +add address=157.240.0.35 list=Instagram +add address=157.240.238.14 list=Instagram +add address=157.240.238.60 list=Instagram +add address=57.144.112.145 list=Instagram +add address=157.240.251.35 list=Instagram +add address=151.101.84.159 list=Twitter +add address=pbs.twimg.com list=Twitter +add address=89.110.101.17 comment=VDSIna list=TRUSTED +add address=10.8.0.0/24 comment="WG VDSIna" list=TRUSTED +add address=ikus.pesc.ru comment=ikus.pesc.ru list=NoVdsina +add address=love.ru comment=love.ru list=NoVdsina +add address=gosuslugi.ru comment=gosuslugi.ru list=NoVdsina +add address=pochta.ru comment=pochta.ru list=NoVdsina +add address=vdsina.com list=NoVdsina +add address=vdsina.ru list=NoVdsina +add address=youla.ru list=NoVdsina +add address=kupiprodai.ru list=NoVdsina +add address=myip.ru list=Test +add address=geoip.co list=NoVdsina +add address=x.com list=Twitter +add address=facebook.com list=facebook +add address=fbcd.net list=facebook +add address=comp-lenta.ru list=NoVdsina +add address=128.85.102.70 comment=update.microsoft.com list=\ + windowsupdateslist +add address=wu-b-net.trafficmanager.net. comment=\ + ctldl.windowsupdate.com.delivery.microsoft.com list=windowsupdateslist +add address=ctldl.windowsupdate.com.delivery.microsoft.com. comment=\ + ctldl.windowsupdate.com list=windowsupdateslist +add address=redir.update.msft.com.trafficmanager.net. comment=\ + update.microsoft.com list=windowsupdateslist +add address=geo.prod.do.dsp.trafficmanager.net. comment=\ + geo.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=13.74.139.29 comment=array605.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=kv801.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + kv801.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=e12437.d.akamaiedge.net. comment=\ + kv801.prod.do.dsp.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=displaycatalog-rp.md.mp.microsoft.com.akadns.net. comment=\ + displaycatalog.mp.microsoft.com list=windowsupdateslist +add address=rp-consumer-prod-displaycatalog-geomap.trafficmanager.net. \ + comment=displaycatalog-rp.md.mp.microsoft.com.akadns.net list=\ + windowsupdateslist +add address=sls.update.microsoft.com. comment=slscr.update.microsoft.com \ + list=windowsupdateslist +add address=glb.sls.prod.dcat.dsp.trafficmanager.net. comment=\ + sls.update.microsoft.com list=windowsupdateslist +add address=fe3.delivery.mp.microsoft.com. comment=\ + fe3cr.delivery.mp.microsoft.com list=windowsupdateslist +add address=glb.cws.prod.dcat.dsp.trafficmanager.net. comment=\ + fe3.delivery.mp.microsoft.com list=windowsupdateslist +add address=fe2cr.update.msft.com.trafficmanager.net. comment=\ + fe2cr.update.microsoft.com list=windowsupdateslist +add address=download.windowsupdate.com.delivery.microsoft.com. comment=\ + download.windowsupdate.com list=windowsupdateslist +add address=wu-f-net.trafficmanager.net. comment=\ + download.windowsupdate.com.delivery.microsoft.com list=windowsupdateslist +add address=tsfe.trafficmanager.net. comment=\ + tsfe.trafficshaping.dsp.mp.microsoft.com list=windowsupdateslist +add address=edge.ds-c7110-microsoft.global.dns.qwilted-cds.cqloud.com. \ + comment=9.au.download.windowsupdate.com list=windowsupdateslist +add address=52.158.227.125 comment=array812.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=au.download.windowsupdate.com.delivery.microsoft.com. comment=\ + au.download.windowsupdate.com list=windowsupdateslist +add address=a767.dspw65.akamai.net. comment=\ + download.windowsupdate.com.edgesuite.net list=windowsupdateslist +add address=52.151.58.88 comment=array810.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=consumer-licensing-aks2aks.md.mp.microsoft.com.akadns.net. \ + comment=licensing.mp.microsoft.com list=windowsupdateslist +add address=licensing-prod-frontdoor-geomap.trafficmanager.net. comment=\ + consumer-licensing-aks2aks.md.mp.microsoft.com.akadns.net list=\ + windowsupdateslist +add address=star.f.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.f.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=cdp-f-nlu-net.trafficmanager.net. comment=\ + star.f.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=star.b.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.b.tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=cdp-f-tlu-net.trafficmanager.net. comment=\ + star.b.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=storeedgefd.xbetservices.akadns.net. comment=\ + storeedgefd.dsx.mp.microsoft.com list=windowsupdateslist +add address=\ + storeedgefd.dsx.mp.microsoft.com.edgekey.net.globalredir.akadns.net. \ + comment=storeedgefd.dsx.mp.microsoft.com.edgekey.net list=\ + windowsupdateslist +add address=e16646.dscg.akamaiedge.net. comment=\ + storeedgefd.dsx.mp.microsoft.com.edgekey.net.globalredir.akadns.net list=\ + windowsupdateslist +add address=40.69.76.189 comment=array621.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=bg.microsoft.map.fastly.net. comment=\ + 3.au.download.windowsupdate.com list=windowsupdateslist +add list=windowsupdateslist +add address=40.69.75.33 comment=array613.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=star.sf.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedgeextensions.sf.tlu.dl.delivery.mp.microsoft.com list=\ + windowsupdateslist +add address=cdp-f-ssl-tlu-net.trafficmanager.net. comment=\ + star.sf.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=a2033.dscd.akamai.net. comment=\ + star.sb.tlu.dl.delivery.mp.microsoft.com.edgesuite.net list=\ + windowsupdateslist +add address=13.74.138.242 comment=array602.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=dl.delivery.mp.microsoft.com.delivery.microsoft.com. comment=\ + dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=dcat-f-nlu-net.trafficmanager.net. comment=\ + dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=1d.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=1D.tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=dcat-b-tlu-net.trafficmanager.net. comment=\ + 1d.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=a122.dscg3.akamai.net. comment=\ + tlu.dl.delivery.mp.microsoft.com.edgesuite.net list=windowsupdateslist +add address=geover.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + geover.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=e10370.d.akamaiedge.net. comment=\ + geover.prod.do.dsp.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=52.232.182.21 comment=array511.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.70.77.95 comment=array519.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=a1683.dscd.akamai.net. comment=\ + dl.delivery.mp.microsoft.com-c.edgesuite.net list=windowsupdateslist +add address=consumer-collections-aks2eap.md.mp.microsoft.com.akadns.net. \ + comment=collections.mp.microsoft.com list=windowsupdateslist +add address=a1847.dscd.akamai.net. comment=\ + wildcard.f.tlu.dl.delivery.mp.microsoft.com.edgesuite.net list=\ + windowsupdateslist +add address=13.74.142.6 comment=array607.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=au.download.windowsupdate.com.edgesuite.net. comment=\ + 2.au.download.windowsupdate.com list=windowsupdateslist +add address=a767.dscg3.akamai.net. comment=\ + au.download.windowsupdate.com.edgesuite.net list=windowsupdateslist +add address=52.156.123.84 comment=array818.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.78.254 comment=array610.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=4.au.download.windowsupdate.com.delivery.microsoft.com. comment=\ + 4.au.download.windowsupdate.com list=windowsupdateslist +add address=cl-glcb907925.gcdn.co. comment=\ + 4.au.download.windowsupdate.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=52.167.167.111 comment=array510.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=40.69.70.43 comment=array623.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=tsfe.trafficshaping.dsp.mp.microsoft.com.delivery.microsoft.com. \ + comment=tsfe.trafficshaping.dsp.mp.microsoft.com list=windowsupdateslist +add address=ts-frontend.trafficmanager.net. comment=\ + tsfe.trafficshaping.dsp.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=40.69.75.248 comment=array616.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.74.84 comment=array615.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=sds.trafficmanager.net. comment=software-download.microsoft.com \ + list=windowsupdateslist +add address=40.69.74.80 comment=array611.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.175.242.182 comment=array804.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=dlc-shim.trafficmanager.net. comment=download.microsoft.com list=\ + windowsupdateslist +add address=e12671.dscd.akamaiedge.net. comment=\ + download.microsoft.com.edgekey.net list=windowsupdateslist +add address=20.187.55.34 comment=array808.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.167.231 comment=array513.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=52.167.222.13 comment=array518.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=kv601.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + kv601.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=e12358.d.akamaiedge.net. comment=\ + kv601.prod.do.dsp.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. comment=\ + tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=dcat-f-tlu-net.trafficmanager.net. comment=\ + tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=a1856.dspw65.akamai.net. comment=\ + tlu.dl.delivery.mp.microsoft.com-c.edgesuite.net list=windowsupdateslist +add address=52.167.164.252 comment=array506.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=13.74.137.54 comment=array601.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=kv501.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + kv501.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=collections-prod-frontdoor-geomap.trafficmanager.net. comment=\ + consumer-collections-aks2eap.md.mp.microsoft.com.akadns.net list=\ + windowsupdateslist +add address=52.167.160.173 comment=array509.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=40.70.77.148 comment=array516.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.200.126 comment=array507.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=52.167.167.59 comment=array508.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.76.172 comment=array620.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=82.202.162.184 comment=comp-lenta.ru list=NoWG +add address=smtp.mail.me.com.akadns.net. comment=smtp.mail.me.com list=NoWG +add address=17.57.155.37 comment=smtp.mail.me.com.akadns.net list=NoWG +add address=smtp.mail.me.com comment=smtp.mail.me.com list=NoVdsina +add address=40.70.76.5 comment=array514.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.186.119 comment=array618.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.177.176.186 comment=array520.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=40.70.76.27 comment=array515.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.160.43 comment=array503.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.110 comment=array817.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.142.8 comment=array614.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.138.254 comment=array603.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.167.96 comment=array501.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.76.215 comment=array622.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.143.200 comment=array606.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.111 comment=array818.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.112 comment=array819.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.137.53 comment=array608.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.98 comment=array805.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.96 comment=array803.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.104 comment=array811.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.101 comment=array808.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.99 comment=array806.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.17 comment=array802.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.97 comment=array804.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.103 comment=array810.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.16 comment=array801.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.70.77.177 comment=array517.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.164.84 comment=array512.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.105 comment=array812.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.107 comment=array814.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.232.161.82 comment=array502.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.108 comment=array815.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.161.91 comment=array505.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.102 comment=array809.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.109 comment=array816.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.106 comment=array813.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.117 comment=array622.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.107 comment=array612.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.108 comment=array613.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.105 comment=array610.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.113 comment=array618.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.116 comment=array621.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.98 comment=array603.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.114 comment=array619.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.111 comment=array616.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.97 comment=array602.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.106 comment=array611.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.110 comment=array615.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.119 comment=array624.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.135 comment=array514.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.97 comment=array503.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.99 comment=array604.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.61 comment=array504.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.131 comment=array510.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.132 comment=array511.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.96 comment=array601.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.104 comment=array609.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.138 comment=array517.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.60 comment=array501.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.139 comment=array518.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.118 comment=array623.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.113 comment=array820.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.103 comment=array608.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.100 comment=array807.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.129 comment=array508.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.134 comment=array513.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.62 comment=array505.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.137 comment=array516.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.101 comment=array606.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.96 comment=array502.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.130 comment=array509.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.112 comment=array617.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.100 comment=array605.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.115 comment=array620.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.136 comment=array515.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=purchase.md.mp.microsoft.com.akadns.net. comment=\ + purchase.mp.microsoft.com list=windowsupdateslist +add address=e110219.a.akamaiedge.net. comment=\ + purchase.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=72.153.5.140 comment=array519.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.141 list=windowsupdateslist +add address=72.153.5.63 comment=array506.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.128 comment=array507.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.102 comment=array607.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=storesdk.xbetservices.akadns.net. comment=\ + storesdk.dsx.mp.microsoft.com list=windowsupdateslist +add address=e16646.g.akamaiedge.net. comment=\ + storesdk.dsx.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=software-download.microsoft.com.delivery.microsoft.com. comment=\ + software-download.microsoft.com list=windowsupdateslist +add address=download.prss.microsoft.com.akamaized.net. comment=\ + software-download.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.109 comment=array614.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.133 comment=array512.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=213.180.192.0/19 comment=YandexDisk list=NoVdsina +add address=87.250.250.50 comment=YandexDisk list=NoVdsina +add address=consumer-prod-bcfd-v7-afd.trafficmanager.net. comment=\ + displaycatalog.mp.microsoft.com list=windowsupdateslist +add address=purchase-europeeap.md.mp.microsoft.com.akadns.net. comment=\ + purchase.md.mp.microsoft.com.akadns.net list=windowsupdateslist +add address=ne-az-conspurchase-mp.trafficmanager.net. comment=\ + purchase-europeeap.md.mp.microsoft.com.akadns.net list=windowsupdateslist +add address=storeedgefd.dsx.mp.microsoft.com.edgekey.net. comment=\ + cdn.storeedgefd.dsx.mp.microsoft.com list=windowsupdateslist +add address=star.f.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.f.tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=a1996.dscd.akamai.net. comment=\ + wildcard.f.dl.delivery.mp.microsoft.com.edgesuite.net list=\ + windowsupdateslist +add address=cp801.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + cp801.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=glb.tas02.sls-prod.dcat.dsp.mp.microsoft.com. comment=\ + tas02.sls.update.microsoft.com list=windowsupdateslist +add address=cp601.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + cp601.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=star.sb.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedgeextensions.sb.tlu.dl.delivery.mp.microsoft.com list=\ + windowsupdateslist +add address=star.sf.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.sf.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=cdp-f-ssl-nlu-net.trafficmanager.net. comment=\ + star.sf.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=tm-pifd-prod-gbl-weight.trafficmanager.net. comment=\ + paymentinstruments.mp.microsoft.com list=windowsupdateslist +add address=10.30.30.33 comment=NUC disabled=yes list=NoWG +add address=10.30.30.10 comment=MikroNUC list=NoWG +add address=89.110.101.17 comment=!!!VDSINA!!!! list=NoWG +add address=89.110.101.17 list=VPN-Server +add address=80.85.244.9 list=TRUSTED +add address=8.8.8.8 list=TRUSTED +add address=8.8.4.4 list=TRUSTED +add address=disc801.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + disc801.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=185.71.70.78 disabled=yes list=TRUSTED +add address=176.53.203.171 disabled=yes list=TRUSTED +add address=176.53.203.170 disabled=yes list=TRUSTED +add address=176.53.202.194 disabled=yes list=TRUSTED +add address=89.110.101.17 comment="!!!VDSina Server!!!" disabled=yes list=\ + NoVdsina +/ip firewall filter +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=12h chain=input comment="block honeypot DNS" \ + connection-state=new dst-port=53 in-interface="ether1 - Unet" protocol=\ + udp +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=4w2d chain=input connection-state=new dst-port=53 \ + in-interface="ether1 - Unet" protocol=tcp +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=4w2d chain=input comment=\ + "block honeypot ssh rdp winbox" connection-state=new dst-port=\ + 22,8291,2222 in-interface="ether1 - Unet" protocol=tcp src-address-list=\ + !TRUSTED +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=4w2d chain=input comment="block honeypot asterisk" \ + connection-state=new dst-port=5060 in-interface="ether1 - Unet" protocol=\ + udp +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=5d chain=input comment="block honeypot NTP" \ + connection-state=new dst-port=123 in-interface="ether1 - Unet" protocol=\ + udp src-address=!10.30.30.0/24 +add action=accept chain=input comment=\ + "accept NTP clients on local area network" dst-port=123 in-interface=\ + Bridge-LAN in-interface-list=LAN protocol=udp +add action=accept chain=input comment="accept WireGuard" dst-port=13231 \ + in-interface="ether1 - Unet" protocol=udp src-address-list=VPN-Server +add action=accept chain=input disabled=yes dst-port=443 in-interface=\ + "ether1 - Unet" protocol=tcp +add action=accept chain=output disabled=yes protocol=tcp src-port=443 +add action=fasttrack-connection chain=forward comment=\ + "FastTrack for non-VPN connections" connection-mark=!VPN_No_FastTrack \ + connection-state=established,related,new disabled=yes +add action=fasttrack-connection chain=forward comment="defconf: fasttrack" \ + connection-state=established,related,new disabled=yes routing-mark=\ + !To-VPN +add action=accept chain=input comment=\ + "defconf: accept established,related,untracked" connection-state=\ + established,related,untracked +add action=drop chain=input comment="defconf: drop invalid" connection-state=\ + invalid +add action=accept chain=input comment="defconf: accept ICMP" disabled=yes \ + protocol=icmp +add action=accept chain=input comment=\ + "defconf: accept to local loopback (for CAPsMAN)" disabled=yes \ + dst-address=127.0.0.1 +add action=accept chain=output disabled=yes src-address=127.0.0.1 +add action=accept chain=forward comment="defconf: accept in ipsec policy" \ + ipsec-policy=in,ipsec +add action=accept chain=forward comment="defconf: accept out ipsec policy" \ + ipsec-policy=out,ipsec +add action=accept chain=forward comment=\ + "defconf: accept established,related, untracked" connection-state=\ + established,related,untracked +add action=drop chain=forward comment="defconf: drop invalid" \ + connection-state=invalid +add action=drop chain=forward comment=\ + "defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat \ + connection-state=new in-interface="ether1 - Unet" +add action=accept chain=input connection-state=established disabled=yes +add action=accept chain=input connection-state=related disabled=yes +add action=drop chain=input disabled=yes in-interface-list=!LAN +add action=drop chain=forward comment=\ + "Filter Rule to block FB address LIST : )" disabled=yes dst-address-list=\ + facebook +add action=drop chain=forward comment=\ + "Filter Rule to block YOUTUBE address LIST : )" disabled=yes \ + dst-address-list=YouTube +/ip firewall mangle +add action=mark-connection chain=prerouting comment=\ + "Mark VPN connections to exclude from FastTrack" in-interface=WG \ + log-prefix=Mark-VPN-FT new-connection-mark=VPN_No_FastTrack +add action=mark-routing chain=prerouting comment="Test sites" disabled=yes \ + dst-address=!10.30.30.0/24 dst-address-list=Test new-routing-mark=To-VPN \ + passthrough=no src-address=10.30.30.0/24 +add action=mark-routing chain=prerouting comment=Instagram dst-address=\ + !10.30.30.0/24 dst-address-list=Instagram new-routing-mark=To-VPN \ + src-address=10.30.30.0/24 src-address-list=!NoWG +add action=mark-routing chain=prerouting comment=Twitter dst-address=\ + !10.30.30.0/24 dst-address-list=Twitter new-routing-mark=To-VPN \ + src-address=10.30.30.0/24 src-address-list=!NoWG +add action=mark-routing chain=prerouting comment=YouTube dst-address=\ + !10.30.30.0/24 dst-address-list=YouTube new-routing-mark=To-VPN \ + src-address=10.30.30.0/24 src-address-list=!NoWG +add action=mark-routing chain=prerouting comment=facebook dst-address=\ + !10.30.30.0/24 dst-address-list=facebook new-routing-mark=To-VPN \ + src-address=10.30.30.0/24 src-address-list=!NoWG +add action=mark-routing chain=prerouting comment="VDSIna for All sites" \ + dst-address=!10.30.30.0/24 dst-address-list=!NoVdsina log-prefix=VPN-all \ + new-routing-mark=To-VPN src-address=10.30.30.0/24 src-address-list=!NoWG +add action=change-mss chain=forward comment="MSS on WG" new-mss=1380 \ + out-interface=WG protocol=tcp tcp-flags=syn tcp-mss=1381-65535 +add action=mark-routing chain=prerouting comment="VPN Network" dst-address=\ + 10.8.0.0/24 dst-address-list=!NoVdsina log=yes log-prefix=VPN-Net \ + new-routing-mark=To-VPN src-address=10.30.30.0/24 src-address-list=!NoWG +/ip firewall nat +add action=redirect chain=dstnat comment=\ + "FORCE DNS TO LOCAL MIKROTIK DNS SERVER" dst-port=53 protocol=tcp \ + src-address=10.30.30.0/24 to-ports=53 +add action=redirect chain=dstnat dst-port=53 protocol=udp src-address=\ + 10.30.30.0/24 to-ports=53 +add action=masquerade chain=srcnat comment=WG dst-address-list=!NoVdsina \ + in-interface=Bridge-LAN log-prefix=WG-nat out-interface=WG routing-mark=\ + To-VPN +add action=masquerade chain=srcnat comment="masquerade Default" ipsec-policy=\ + out,none out-interface="ether1 - Unet" routing-mark=!To-VPN +add action=dst-nat chain=dstnat comment=npm dst-port=81 in-interface=\ + "ether1 - Unet" protocol=tcp to-addresses=10.30.30.33 to-ports=81 +add action=dst-nat chain=dstnat comment=amster.vados.ruhttps disabled=yes \ + dst-port=443 in-interface="ether1 - Unet" protocol=tcp to-addresses=\ + 10.30.30.33 to-ports=443 +add action=dst-nat chain=dstnat comment="amster.vados.ru For Certbot HTTP" \ + dst-port=80 in-interface="ether1 - Unet" protocol=tcp to-addresses=\ + 10.30.30.33 to-ports=80 +add action=dst-nat chain=dstnat dst-port=80 in-interface="ether1 - Unet" \ + protocol=tcp to-addresses=10.30.30.33 to-ports=80 +add action=dst-nat chain=dstnat comment="Yandex.DNS Family" disabled=yes \ + dst-port=53 in-interface=Bridge-LAN protocol=udp src-address-list=KIDS \ + time=6h-15m,sun,mon,tue,wed,thu,fri,sat to-addresses=77.88.8.3 +add action=dst-nat chain=dstnat disabled=yes dst-port=53 in-interface=\ + Bridge-LAN protocol=tcp src-address-list=KIDS time=\ + 6h-15m,sun,mon,tue,wed,thu,fri,sat to-addresses=77.88.8.3 +/ip firewall raw +add action=drop chain=prerouting comment="Drop Honeypot Hackers" \ + in-interface="ether1 - Unet" src-address-list="Honeypot Hacker" +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + extras.getpagespeed.com content=extras.getpagespeed.com disabled=yes +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=linux.duke.edu \ + content=linux.duke.edu disabled=yes +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=vk.com \ + content=vk.com +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=ok.ru content=\ + ok.ru +add action=add-dst-to-address-list address-list=Instagram \ + address-list-timeout=none-dynamic chain=prerouting comment=Instagram \ + content=instagram.com +add action=add-dst-to-address-list address-list=Twitter address-list-timeout=\ + none-dynamic chain=prerouting comment=Twitter content=twimg.com +add action=add-dst-to-address-list address-list=Twitter address-list-timeout=\ + none-dynamic chain=prerouting content=x.com +add action=add-dst-to-address-list address-list=Twitter address-list-timeout=\ + none-dynamic chain=prerouting content=twitter.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting comment=YouTube content=youtube.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=googleapis.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=ggpht.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=youtu.be +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=ytimg.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=googlevideo.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=gstatic.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=googleusercontent.com +add action=add-dst-to-address-list address-list=YouTube address-list-timeout=\ + none-dynamic chain=prerouting content=nhacmp3youtube.com +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=rutube.ru \ + content=rutube.ru +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=me.com \ + content=me.com +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=icloud.com \ + content=icloud.com +add action=add-dst-to-address-list address-list=facebook \ + address-list-timeout=none-dynamic chain=prerouting comment=facebook \ + content=fbcd.net +add action=add-dst-to-address-list address-list=facebook \ + address-list-timeout=none-dynamic chain=prerouting content=facebook.com +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=comp-lenta.ru \ + content=comp-lenta.ru +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + smtp.mail.me.com content=smtp.mail.me.com log=yes +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=gov.ru \ + content=gov.ru +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + r78.fssp.gov.ru content=r78.fssp.gov.ru +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=api.db-ip.com \ + content=api.db-ip.com +add action=add-dst-to-address-list address-list=NoVdsina \ + address-list-timeout=none-dynamic chain=prerouting comment=\ + api.telegram.org content=api.telegram.org +/ip firewall service-port +set ftp disabled=yes +set tftp disabled=yes +set irc disabled=no +set sip disabled=yes +set pptp disabled=yes +set rtsp disabled=no +/ip hotspot user profile +set [ find default=yes ] address-pool=dhcp +/ip hotspot walled-garden +add server=*1 +add server=*1 +/ip ipsec settings +set accounting=no +/ip ipsec policy +set 0 disabled=yes dst-address=0.0.0.0/0 src-address=0.0.0.0/0 +/ip ipsec profile +set [ find default=yes ] dpd-interval=2m dpd-maximum-failures=5 +/ip proxy +set cache-administrator="" max-cache-size=none port=80,443 src-address=\ + 0.0.0.0 +/ip route +add disabled=no distance=3 dst-address=192.168.0.0/24 gateway=l2tp-vpn +add disabled=no distance=4 dst-address=192.168.5.0/24 gateway=l2tp-vpn +add disabled=no distance=3 dst-address=192.168.0.0/24 gateway=l2tp-vpn +add disabled=no distance=4 dst-address=192.168.5.0/24 gateway=l2tp-vpn +add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=WG routing-table=\ + To-VPN scope=30 target-scope=10 +/ip service +set ftp disabled=yes +set telnet disabled=yes +set reverse-proxy disabled=yes +set ssh address=10.30.30.0/24 port=2222 +set winbox address=10.30.30.0/24 +set api address=10.30.30.0/24 disabled=yes +set api-ssl address=10.30.30.0/24 disabled=yes +set www-ssl port=18443 +set www address=10.30.30.0/24 disabled=yes port=18880 +/ip service webserver +set graphs-plain=no rest-plain=no webfig-plain=no +/ip ssh +set forwarding-enabled=both publickey-authentication-options=verify-required \ + strong-crypto=yes +/ip upnp +set enabled=yes +/ip upnp interfaces +add interface=Bridge-LAN type=internal +add interface="ether1 - Unet" type=external +/snmp community +set [ find default=yes ] addresses=10.30.30.0/24 read-access=no security=\ + private +/system clock +set time-zone-autodetect=no time-zone-name=Europe/Moscow +/system clock manual +set time-zone=+03:00 +/system identity +set name=MikroMaster +/system logging +add action=email disabled=yes regex="* added|changed|removed *" topics=\ + system,info +/system ntp client +set enabled=yes +/system ntp server +set enabled=yes manycast=yes multicast=yes use-local-clock=yes +/system ntp client servers +add address=0.ru.pool.ntp.org +add address=1.ru.pool.ntp.org +add address=2.ru.pool.ntp.org +add address=3.ru.pool.ntp.org +add address=time.google.com disabled=yes +/system scheduler +add comment="Scheduler for Update Certificates CloudFlare Quad9" disabled=yes \ + interval=1w name="Update Certificates CloudFlare Quad9" on-event=\ + "/system/script { run Update-Certificates; }" policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + start-date=2025-11-28 start-time=05:45:40 +add comment="Every Day Set Global Environment Variables" name=AM-SetGlobalEnv \ + on-event="/system/script { run AM-GlobalConfig; run AM-GlobalFunc; }" \ + policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + start-time=startup +add comment="Every Day Check For Update Scripts" interval=1d name=\ + AM-ScriptInstallUpdate on-event=\ + ":global ScriptInstallUpdate; \$ScriptInstallUpdate;" policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + start-time=startup +/system watchdog +set watchdog-timer=no +/tool e-mail +set certificate-verification=no from=MikroVados port=587 \ + server=smtp.mail.me.com tls=starttls user=vadossio@icloud.com +/tool mac-server +set allowed-interface-list=LAN +/tool mac-server mac-winbox +set allowed-interface-list=LAN +/tool netwatch +add comment="doh, doh-url=https://security.cloudflare-dns.com/dns-query, notif\ + y, name=CloudFlare-doh IPv4 1" disabled=yes down-script="" host=1.1.1.1 \ + http-codes="" test-script="" type=simple up-script="" +add check-certificate=no comment="doh-fallback, doh-url=https://security.cloud\ + flare-dns.com/dns-query, doh-cert=DigiCert Global Root CA, notify, name=Cl\ + oudFlare-doh IPv4" disabled=yes down-script="" host=1.0.0.1 http-codes="" \ + port=443 test-script="" type=simple up-script="" +add comment="dns-fallback, notify, name=Google-DNS IPv4" disabled=yes \ + down-script="" host=8.8.8.8 http-codes="" test-script="" type=simple \ + up-script="" +add comment="doh-fallback, doh-url=https://dns.google/dns-query, doh-cert=GTS \ + Root R1, notify, name=Google-DOH IPv4" disabled=yes down-script="" host=\ + 8.8.4.4 http-codes="" test-script="" type=simple up-script="" +add comment="dns, notify, name=Cuad9-DOH IPv4" disabled=yes down-script="" \ + host=9.9.9.9 http-codes="" test-script="" type=simple up-script="" +add comment="doh-fallback, doh-url=https://dns.quad9.net/dns-query, name=Cuad9\ + -DOH IPv4" disabled=yes down-script="" host=149.112.112.112 http-codes="" \ + test-script="" type=simple up-script="" +add comment="dns-fallback, notify, name=ns1.unet.ws" disabled=yes \ + down-script="" host=91.192.189.2 http-codes="" test-script="" type=simple \ + up-script="" +/tool sniffer +set filter-interface=Bridge-LAN filter-src-ip-address=10.30.30.50/32 +/user aaa +set accounting=no diff --git a/MikroMaster/history/20260504/20260504110001-Diff-Config.rsc b/MikroMaster/history/20260504/20260504110001-Diff-Config.rsc new file mode 100644 index 0000000..e402c63 --- /dev/null +++ b/MikroMaster/history/20260504/20260504110001-Diff-Config.rsc @@ -0,0 +1,4200 @@ +912,927c912,926 +< 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# Copyright (c) 2005-2026 Vados \r\ +< \n#\r\ +< \n#\r\ +< \n# requires RouterOS, version=7.19\r\ +< \n# requires device-mode, fetch, scheduler\r\ +< \n\r\ +< \n:local ScriptName [ :jobname ];\r\ +< \n#:global checkRunJob \$SriptName;\r\ +< \n#:global fixCRLF;\r\ +< \n#:if (\$fixCRLF != false) do={\r\ +--- +> add 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\ +> \n# RouterOS script: AM-GglobalFunc\ +> \n# Script comment: Global functions\ +> \n# Copyright (c) 2005-2026 Vados \ +> \n#\ +> \n#\ +> \n# requires RouterOS, version=7.19\ +> \n# requires device-mode, fetch, scheduler\ +> \n:local ExitOK false;\ +> \n:local ScriptName [ :jobname ];\ +> \n#:global checkRunJob \$SriptName;\ +> \n#:global fixCRLF;\ +> \n#:if (\$fixCRLF != false) do={\ +930c929 +< }\r\ +--- +> }\ +932,938c931,937 +< 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/543/2586b4eb\";\r\ +< \n:global CommitTAG \"unknown\";\r\ +--- +> et \$fixScript source ] ] \$fixScript};};\ +> \n#}\ +> \n:global GlobalFuncReady false;\ +> \n\ +> \n# Git commit id & info, expected configuration version\ +> \n:global CommitId \"main/532/43b89fd9\";\ +> \n:global CommitTAG \"unknown\";\ +940,1073c939,1073 +< r: root, in 10:45:03 04.05.2026.\";\r\ +< \n\r\ +< \n# The variables are received right here.\r\ +< \n:global GlobalConfVersion 140;\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 ExitOnError;\r\ +< \n:global CharacterMultiply;\r\ +< \n:global CharacterReplace;\r\ +< \n:global CleanFilePath;\r\ +< \n:global CleanName;\r\ +< \n\r\ +< \n:global CommitBrief;\r\ +< \n\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\r\ +< \n:global FetchUserAgentStr;\r\ +< \n:global CertificateAvailable;\r\ +< \n:global CertificateDownload;\r\ +< \n:global CertificateNameByCN;\r\ +< \n:global CharacterMultiply;\r\ +< \n:global FetchLargeFiles;\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 :global currentUpdateChannel;\r\ +< \n :global ROsVerAvail;\r\ +< \n :global arrDeviceInfo;\r\ +< \n \$LogPrint debug \$0 (\"\\\$isInfo = \" . \$isInfo); \r\ +< \n :local CurrentChannel [ /system/package/update/get channel ];\r\ +--- +> r: root, in 09:00:03 04.05.2026.\";\ +> \n\ +> \n# The variables are received right here.\ +> \n:global GlobalConfVersion 138;\ +> \n\ +> \n:global SumsDirAndFileName \"tmp/checksums.json\";\ +> \n\ +> \n:global Identity [/system/identity/get name];\ +> \n:global IdentityShort [:pick \$Identity 0 18];\ +> \n\ +> \n:global devBoardName [/system/resource/get board-name];\ +> \n:global devMode [/system/device-mode/get mode];\ +> \n:global devCurArch [/system/resource/get architecture-name];\ +> \n:global devCurVersion [/system/resource/get version];\ +> \n\ +> \n# Variables defined in AM-GlobalConfig.rsc\ +> \n:global TerminalColorOutput;\ +> \n:global CommentsInScripts;\ +> \n:global DetectIpAddrDefault;\ +> \n:global DetectIpAddrFallback;\ +> \n:global updateChannel;\ +> \n:global Domain;\ +> \n:global EmailGeneralTo;\ +> \n:global BackupAndUpdateMode;\ +> \n\ +> \n# Single functions, without nested functions.\ +> \n:global GlobalEnvRemove;\ +> \n:global MiniDateTimeStamp;\ +> \n\ +> \n# Include globals \$PrintDebug and \$PrintDebugOverride\ +> \n:global LogPrint;\ +> \n\ +> \n# DeviceInfo and Updates\ +> \n:global IsCheckUpdates;\ +> \n:global WaitCheckUpdates;\ +> \n:global GetPubIp;\ +> \n\ +> \n:global GetArrDeviceInfo;\ +> \n:global WaitArrDeviceInfo;\ +> \n\ +> \n:global devModel;\ +> \n:global devRunningMode;\ +> \n\ +> \n:global devRbRevision;\ +> \n:global devRbSerialNumber;\ +> \n:global devRbVerAvail;\ +> \n\ +> \n:global runningChannelVersion;\ +> \n:global runningChannel;\ +> \n:global runningVersion;\ +> \n\ +> \n:global devBuildTime;\ +> \n:global ROsVerAvail;\ +> \n:global PkgUpdStatus;\ +> \n:global currentUpdateChannel;\ +> \n\ +> \n:global ScriptInstallUpdate;\ +> \n\ +> \n:global DeviceInfo;\ +> \n\ +> \n:global OldMode;\ +> \n\ +> \n:global ParseKeyValueStore;\ +> \n:global RandomDelay;\ +> \n:global GetRandomNumber;\ +> \n:global EscapeForRegEx;\ +> \n:global ExitError;\ +> \n:global ExitOnError;\ +> \n:global CharacterMultiply;\ +> \n:global CharacterReplace;\ +> \n:global CleanFilePath;\ +> \n:global CleanName;\ +> \n\ +> \n:global CommitBrief;\ +> \n\ +> \n:global EitherOr;\ +> \n:global FormatLine;\ +> \n:global GetRandom20CharAlNum;\ +> \n:global Grep;\ +> \n:global IfThenElse;\ +> \n:global MAX;\ +> \n:global MIN;\ +> \n:global HumanReadableNum;\ +> \n\ +> \n:global IsFullyConnected;\ +> \n:global IsDNSResolving;\ +> \n:global IsTimeSync;\ +> \n:global IsTimeSyncCached;\ +> \n:global IsTimeSyncResetNtp;\ +> \n\ +> \n:global WaitDNSResolving;\ +> \n:global WaitFullyConnected;\ +> \n:global WaitTimeSync;\ +> \n:global MkDir;\ +> \n:global RmDir;\ +> \n:global RmFile;\ +> \n:global FileGet;\ +> \n:global Unix2Dos;\ +> \n:global UrlEncode;\ +> \n:global WaitForFile;\ +> \n:global ScriptLock;\ +> \n:global SendTelegram;\ +> \n:global NotificationFunctions;\ +> \n:global SendNotification;\ +> \n:global SendNotification2;\ +> \n:global SymbolForNotification;\ +> \n:global SymbolByUnicodeName;\ +> \n:global ValidateSyntax;\ +> \n:global CheckSumsVerify;\ +> \n:global GlobalConfChanges;\ +> \n:global GlobalConfMigration;\ +> \n:global VersionToNum;\ +> \n:global RequiredRouterOS;\ +> \n\ +> \n:global FetchHuge;\ +> \n:global FetchUserAgentStr;\ +> \n:global CertificateAvailable;\ +> \n:global CertificateDownload;\ +> \n:global CertificateNameByCN;\ +> \n:global CharacterMultiply;\ +> \n:global FetchLargeFiles;\ +> \n:global InspectVar;\ +> \n:global InspectVarRet;\ +> \n:global ParseCustom;\ +> \n\ +> \n:set IsCheckUpdates do={\ +> \n :local isInfo [:tobool \$1];\ +> \n :global LogPrint;\ +> \n :global updateChannel;\ +> \n :global PkgUpdStatus;\ +> \n :global currentUpdateChannel;\ +> \n :global ROsVerAvail;\ +> \n :global arrDeviceInfo;\ +> \n \$LogPrint debug \$0 (\"\\\$isInfo = \" . \$isInfo); \ +> \n :local CurrentChannel [ /system/package/update/get channel ];\ +1075c1075 +< el) do={\r\ +--- +> el) do={\ +1077c1077 +< \_delay=300ms max=5 on-error={};\r\ +--- +> \_delay=300ms max=5 on-error={};\ +1079,1089c1079,1088 +< \r\ +< \n }\r\ +< \n\r\ +< \n :local Update [ /system/package/update/get ];\r\ +< \n :local Channel [ :tostr (\$Update->\"channel\") ];\r\ +< \n :set currentUpdateChannel \$Channel;\r\ +< \n \$LogPrint debug \$0 (\"Update Channel: \" . \$Channel . \".\");\r\ +< \n\r\ +< \n\r\ +< \n :local StatusPkg \"undefined\";\r\ +< \n \$LogPrint debug \$0 (\"Checking for updates...\");\r\ +--- +> \n }\ +> \n\ +> \n :local Update [ /system/package/update/get ];\ +> \n :local Channel [ :tostr (\$Update->\"channel\") ];\ +> \n :set currentUpdateChannel \$Channel;\ +> \n \$LogPrint debug \$0 (\"Update Channel: \" . \$Channel . \".\");\ +> \n\ +> \n\ +> \n :local StatusPkg \"undefined\";\ +> \n \$LogPrint debug \$0 (\"Checking for updates...\");\ +1091,1093c1090,1092 +< dates without-paging as-value]->\"status\")} \\\r\ +< \n delay=300ms max=5 on-error={};\r\ +< \n \$LogPrint debug \$0 (\"\\\$StatusPkg = \" . \$StatusPkg);\r\ +--- +> dates without-paging as-value]->\"status\")} \\\ +> \n delay=300ms max=5 on-error={};\ +> \n \$LogPrint debug \$0 (\"\\\$StatusPkg = \" . \$StatusPkg);\ +1095c1094 +< s true; } else={ :set PkgUpdStatus false; }\r\ +--- +> s true; } else={ :set PkgUpdStatus false; }\ +1097,1103c1096,1102 +< ] ];\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 ([ :typeof \$arrDeviceInfo ] != \"array\") do={\r\ +< \n :set arrDeviceInfo [:toarray \$arrDeviceInfo];\r\ +< \n }\r\ +--- +> ] ];\ +> \n \$LogPrint debug \$0 (\"\\\$PkgUpdStatus = \" . \$PkgUpdStatus);\ +> \n :if (\$isInfo != false || \$PkgUpdStatus = true) do={\ +> \n \$LogPrint debug \$0 (\"\\\$PkgUpdStatus = \" . \$PkgUpdStatus);\ +> \n :if ([ :typeof \$arrDeviceInfo ] != \"array\") do={\ +> \n :set arrDeviceInfo [:toarray \$arrDeviceInfo];\ +> \n }\ +1105,1127c1104,1126 +< kage/update/get ]} delay=500ms max=5 on-error={:log error (\"Error\")};\r\ +< \n :return true;\r\ +< \n } else={\r\ +< \n :return \$PkgUpdStatus;\r\ +< \n }\r\ +< \n}\r\ +< \n\r\ +< \n:set WaitCheckUpdates do={\r\ +< \n :global IsCheckUpdates;\r\ +< \n :global PkgUpdStatus;\r\ +< \n :global currentUpdateChannel;\r\ +< \n :global ROsVerAvail;\r\ +< \n :global arrDeviceInfo;\r\ +< \n\r\ +< \n :local Status \"\";\r\ +< \n :local Update;\r\ +< \n :local WaitCount 0;\r\ +< \n\r\ +< \n :if ([ \$IsCheckUpdates true ] = false) do={\r\ +< \n :return false;\r\ +< \n }\r\ +< \n\r\ +< \n :set Status [ :tostr [ /system/package/update/get status ] ];\r\ +--- +> kage/update/get ]} delay=500ms max=5 on-error={:log error (\"Error\")};\ +> \n :return true;\ +> \n } else={\ +> \n :return \$PkgUpdStatus;\ +> \n }\ +> \n}\ +> \n\ +> \n:set WaitCheckUpdates do={\ +> \n :global IsCheckUpdates;\ +> \n :global PkgUpdStatus;\ +> \n :global currentUpdateChannel;\ +> \n :global ROsVerAvail;\ +> \n :global arrDeviceInfo;\ +> \n\ +> \n :local Status \"\";\ +> \n :local Update;\ +> \n :local WaitCount 0;\ +> \n\ +> \n :if ([ \$IsCheckUpdates true ] = false) do={\ +> \n :return false;\ +> \n }\ +> \n\ +> \n :set Status [ :tostr [ /system/package/update/get status ] ];\ +1129,1147c1128,1146 +< \") && \$WaitCount < 60) do={\r\ +< \n :delay 1s;\r\ +< \n :set WaitCount (\$WaitCount + 1);\r\ +< \n :set Status [ :tostr [ /system/package/update/get status ] ];\r\ +< \n }\r\ +< \n\r\ +< \n :set Update [ /system/package/update/get ];\r\ +< \n :set currentUpdateChannel [ :tostr (\$Update->\"channel\") ];\r\ +< \n :set ROsVerAvail [ :tostr (\$Update->\"latest-version\") ];\r\ +< \n :if ((\$Update->\"status\") = \"New version is available\") do={\r\ +< \n :set PkgUpdStatus true;\r\ +< \n } else={\r\ +< \n :set PkgUpdStatus false;\r\ +< \n }\r\ +< \n :if ([ :typeof \$arrDeviceInfo ] != \"array\") do={\r\ +< \n :set arrDeviceInfo [:toarray \$arrDeviceInfo];\r\ +< \n }\r\ +< \n :set (\$arrDeviceInfo->\"devUpdates\") \$Update;\r\ +< \n\r\ +--- +> \") && \$WaitCount < 60) do={\ +> \n :delay 1s;\ +> \n :set WaitCount (\$WaitCount + 1);\ +> \n :set Status [ :tostr [ /system/package/update/get status ] ];\ +> \n }\ +> \n\ +> \n :set Update [ /system/package/update/get ];\ +> \n :set currentUpdateChannel [ :tostr (\$Update->\"channel\") ];\ +> \n :set ROsVerAvail [ :tostr (\$Update->\"latest-version\") ];\ +> \n :if ((\$Update->\"status\") = \"New version is available\") do={\ +> \n :set PkgUpdStatus true;\ +> \n } else={\ +> \n :set PkgUpdStatus false;\ +> \n }\ +> \n :if ([ :typeof \$arrDeviceInfo ] != \"array\") do={\ +> \n :set arrDeviceInfo [:toarray \$arrDeviceInfo];\ +> \n }\ +> \n :set (\$arrDeviceInfo->\"devUpdates\") \$Update;\ +> \n\ +1149,1193c1148,1192 +< do={\r\ +< \n :return false;\r\ +< \n }\r\ +< \n :return true;\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 :global arrDeviceInfo;\r\ +< \n\r\ +< \n :global devBoardName;\r\ +< \n :global devModel;\r\ +< \n :global devRunning;\r\ +< \n :global devCurArch;\r\ +< \n :global devRbRevision;\r\ +< \n :global devRbSerialNumber;\r\ +< \n :global devBuildTime;\r\ +< \n :global runningChannelVersion;\r\ +< \n :global runningChannel;\r\ +< \n :global runningVersion;\r\ +< \n :global currentUpdateChannel;\r\ +< \n :global ROsVerAvail;\r\ +< \n\r\ +< \n :local DeviceInfo;\r\ +< \n :local Resource [/system/resource/get];\r\ +< \n :local Update [ /system/package/update/get ];\r\ +< \n :local VersionString [ :tostr (\$Resource->\"version\") ];\r\ +< \n :local ChannelStart [ :find \$VersionString \" (\" ];\r\ +< \n :local RouterBoard;\r\ +< \n :local IsRouterBoard false;\r\ +< \n :local RunningMode \"\";\r\ +< \n\r\ +< \n :set devCurArch [ :tostr (\$Resource->\"architecture-name\") ];\r\ +< \n :set devBuildTime [ :tostr (\$Resource->\"build-time\") ];\r\ +< \n :set runningChannelVersion \$VersionString;\r\ +< \n :set runningVersion \$VersionString;\r\ +< \n :set runningChannel \"\";\r\ +< \n\r\ +--- +> do={\ +> \n :return false;\ +> \n }\ +> \n :return true;\ +> \n}\ +> \n\ +> \n:set WaitArrDeviceInfo do={\ +> \n :global GetArrDeviceInfo;\ +> \n :while ([ \$GetArrDeviceInfo ] = false) do={\ +> \n :delay 1s;\ +> \n }\ +> \n}\ +> \n\ +> \n:set GetArrDeviceInfo do={\ +> \n :global LogPrint;\ +> \n :global arrDeviceInfo;\ +> \n\ +> \n :global devBoardName;\ +> \n :global devModel;\ +> \n :global devRunning;\ +> \n :global devCurArch;\ +> \n :global devRbRevision;\ +> \n :global devRbSerialNumber;\ +> \n :global devBuildTime;\ +> \n :global runningChannelVersion;\ +> \n :global runningChannel;\ +> \n :global runningVersion;\ +> \n :global currentUpdateChannel;\ +> \n :global ROsVerAvail;\ +> \n\ +> \n :local DeviceInfo;\ +> \n :local Resource [/system/resource/get];\ +> \n :local Update [ /system/package/update/get ];\ +> \n :local VersionString [ :tostr (\$Resource->\"version\") ];\ +> \n :local ChannelStart [ :find \$VersionString \" (\" ];\ +> \n :local RouterBoard;\ +> \n :local IsRouterBoard false;\ +> \n :local RunningMode \"\";\ +> \n\ +> \n :set devCurArch [ :tostr (\$Resource->\"architecture-name\") ];\ +> \n :set devBuildTime [ :tostr (\$Resource->\"build-time\") ];\ +> \n :set runningChannelVersion \$VersionString;\ +> \n :set runningVersion \$VersionString;\ +> \n :set runningChannel \"\";\ +> \n\ +1195,1196c1194,1195 +< {\r\ +< \n :set runningVersion [ :pick \$VersionString 0 \$ChannelStart ];\r\ +--- +> {\ +> \n :set runningVersion [ :pick \$VersionString 0 \$ChannelStart ];\ +1198,1199c1197,1198 +< len \$VersionString ] ];\r\ +< \n :local ChannelEnd [ :find \$ChannelRest \")\" ];\r\ +--- +> len \$VersionString ] ];\ +> \n :local ChannelEnd [ :find \$ChannelRest \")\" ];\ +1201,1205c1200,1203 +< \r\ +< \n :set runningChannel [ :pick \$ChannelRest 0 \$ChannelEnd ];\r\ +< \n }\r\ +< \n }\r\ +< \n\r\ +--- +> \n :set runningChannel [ :pick \$ChannelRest 0 \$ChannelEnd ];\ +> \n }\ +> \n }\ +> \n\ +1207,1230c1205,1228 +< \_3] != \"x86\") do={\r\ +< \n :do {\r\ +< \n :set RouterBoard [[ :parse \"/system/routerboard/get\" ]];\r\ +< \n# :set RouterBoard [ /system/routerboard/get ];\r\ +< \n :if ((\$RouterBoard->\"routerboard\") = true) do={\r\ +< \n :set IsRouterBoard true;\r\ +< \n }\r\ +< \n } on-error={}\r\ +< \n }\r\ +< \n\r\ +< \n :do {\r\ +< \n :set RunningMode [ /system/device-mode/get mode ];\r\ +< \n } on-error={\r\ +< \n :do {\r\ +< \n :set RunningMode [ /system/device-mode/get running ];\r\ +< \n } on-error={\r\ +< \n :set RunningMode \"\";\r\ +< \n }\r\ +< \n }\r\ +< \n :set devRunning \$RunningMode;\r\ +< \n\r\ +< \n :if (\$IsRouterBoard = true) do={\r\ +< \n :set devModel [ :tostr (\$RouterBoard->\"model\") ];\r\ +< \n :set devRbRevision [ :tostr (\$RouterBoard->\"revision\") ];\r\ +--- +> \_3] != \"x86\") do={\ +> \n :do {\ +> \n :set RouterBoard [[ :parse \"/system/routerboard/get\" ]];\ +> \n# :set RouterBoard [ /system/routerboard/get ];\ +> \n :if ((\$RouterBoard->\"routerboard\") = true) do={\ +> \n :set IsRouterBoard true;\ +> \n }\ +> \n } on-error={}\ +> \n }\ +> \n\ +> \n :do {\ +> \n :set RunningMode [ /system/device-mode/get mode ];\ +> \n } on-error={\ +> \n :do {\ +> \n :set RunningMode [ /system/device-mode/get running ];\ +> \n } on-error={\ +> \n :set RunningMode \"\";\ +> \n }\ +> \n }\ +> \n :set devRunning \$RunningMode;\ +> \n\ +> \n :if (\$IsRouterBoard = true) do={\ +> \n :set devModel [ :tostr (\$RouterBoard->\"model\") ];\ +> \n :set devRbRevision [ :tostr (\$RouterBoard->\"revision\") ];\ +1232,1248c1230,1246 +< ];\r\ +< \n } else={\r\ +< \n :set devModel \$devBoardName;\r\ +< \n :set devRbRevision \"\";\r\ +< \n :set devRbSerialNumber \"\";\r\ +< \n }\r\ +< \n\r\ +< \n :set currentUpdateChannel [ :tostr (\$Update->\"channel\") ];\r\ +< \n :set ROsVerAvail [ :tostr (\$Update->\"latest-version\") ];\r\ +< \n\r\ +< \n :set (\$DeviceInfo->\"board-name\") \$devBoardName;\r\ +< \n :set (\$DeviceInfo->\"architecture-name\") \$devCurArch;\r\ +< \n :set (\$DeviceInfo->\"model\") \$devModel;\r\ +< \n :set (\$DeviceInfo->\"revision\") \$devRbRevision;\r\ +< \n :set (\$DeviceInfo->\"serial-number\") \$devRbSerialNumber;\r\ +< \n :set (\$DeviceInfo->\"running-mode\") \$devRunning;\r\ +< \n :set (\$DeviceInfo->\"build-time\") \$devBuildTime;\r\ +--- +> ];\ +> \n } else={\ +> \n :set devModel \$devBoardName;\ +> \n :set devRbRevision \"\";\ +> \n :set devRbSerialNumber \"\";\ +> \n }\ +> \n\ +> \n :set currentUpdateChannel [ :tostr (\$Update->\"channel\") ];\ +> \n :set ROsVerAvail [ :tostr (\$Update->\"latest-version\") ];\ +> \n\ +> \n :set (\$DeviceInfo->\"board-name\") \$devBoardName;\ +> \n :set (\$DeviceInfo->\"architecture-name\") \$devCurArch;\ +> \n :set (\$DeviceInfo->\"model\") \$devModel;\ +> \n :set (\$DeviceInfo->\"revision\") \$devRbRevision;\ +> \n :set (\$DeviceInfo->\"serial-number\") \$devRbSerialNumber;\ +> \n :set (\$DeviceInfo->\"running-mode\") \$devRunning;\ +> \n :set (\$DeviceInfo->\"build-time\") \$devBuildTime;\ +1250,1253c1248,1251 +< ion;\r\ +< \n :set (\$DeviceInfo->\"running-version\") \$runningVersion;\r\ +< \n :set (\$DeviceInfo->\"running-channel\") \$runningChannel;\r\ +< \n :set (\$DeviceInfo->\"routerboard\") \$IsRouterBoard;\r\ +--- +> ion;\ +> \n :set (\$DeviceInfo->\"running-version\") \$runningVersion;\ +> \n :set (\$DeviceInfo->\"running-channel\") \$runningChannel;\ +> \n :set (\$DeviceInfo->\"routerboard\") \$IsRouterBoard;\ +1255c1253 +< current-firmware\") ];\r\ +--- +> current-firmware\") ];\ +1257,1258c1255,1256 +< upgrade-firmware\") ];\r\ +< \n :set (\$DeviceInfo->\"package-channel\") \$currentUpdateChannel;\r\ +--- +> upgrade-firmware\") ];\ +> \n :set (\$DeviceInfo->\"package-channel\") \$currentUpdateChannel;\ +1260,1261c1258,1259 +< alled-version\") ];\r\ +< \n :set (\$DeviceInfo->\"latest-version\") \$ROsVerAvail;\r\ +--- +> alled-version\") ];\ +> \n :set (\$DeviceInfo->\"latest-version\") \$ROsVerAvail;\ +1263,1287c1261,1285 +< ) ];\r\ +< \n\r\ +< \n :set arrDeviceInfo \$DeviceInfo;\r\ +< \n :return \$DeviceInfo;\r\ +< \n}\r\ +< \n\r\ +< \n:set DeviceInfo do={\r\ +< \n :global GetArrDeviceInfo;\r\ +< \n :global GlobalConfVersion;\r\ +< \n :global Identity;\r\ +< \n :global IfThenElse;\r\ +< \n :global FormatLine;\r\ +< \n :global CommitBrief;\r\ +< \n\r\ +< \n :local License [/system/license/get];\r\ +< \n :local Snmp [ /snmp/get ];\r\ +< \n :local Info [ \$GetArrDeviceInfo ];\r\ +< \n\r\ +< \n :if ([ :typeof \$Info ] != \"array\") do={\r\ +< \n :return false;\r\ +< \n }\r\ +< \n\r\ +< \n :return ( \\\r\ +< \n [ \$FormatLine \"Hostname\" \$Identity ] . \"\\n\" . \\\r\ +< \n [ \$IfThenElse ([ :len (\$Snmp->\"location\") ] > 0) \\\r\ +--- +> ) ];\ +> \n\ +> \n :set arrDeviceInfo \$DeviceInfo;\ +> \n :return \$DeviceInfo;\ +> \n}\ +> \n\ +> \n:set DeviceInfo do={\ +> \n :global GetArrDeviceInfo;\ +> \n :global GlobalConfVersion;\ +> \n :global Identity;\ +> \n :global IfThenElse;\ +> \n :global FormatLine;\ +> \n :global CommitBrief;\ +> \n\ +> \n :local License [/system/license/get];\ +> \n :local Snmp [ /snmp/get ];\ +> \n :local Info [ \$GetArrDeviceInfo ];\ +> \n\ +> \n :if ([ :typeof \$Info ] != \"array\") do={\ +> \n :return false;\ +> \n }\ +> \n\ +> \n :return ( \\\ +> \n [ \$FormatLine \"Hostname\" \$Identity ] . \"\\n\" . \\\ +> \n [ \$IfThenElse ([ :len (\$Snmp->\"location\") ] > 0) \\\ +1289,1290c1287,1288 +< \_. \\\r\ +< \n [ \$IfThenElse ([ :len (\$Snmp->\"contact\") ] > 0) \\\r\ +--- +> \_. \\\ +> \n [ \$IfThenElse ([ :len (\$Snmp->\"contact\") ] > 0) \\\ +1292,1293c1290,1291 +< \_\\\r\ +< \n \"Hardware:\\n\" . \\\r\ +--- +> \_\\\ +> \n \"Hardware:\\n\" . \\\ +1295c1293 +< \\\r\ +--- +> \\\ +1297,1301c1295,1299 +< n\" . \\\r\ +< \n [ \$FormatLine \" Model\" (\$Info->\"model\") ] . \\\r\ +< \n [ \$IfThenElse ([ :len (\$Info->\"revision\") ] > 0) \\\r\ +< \n (\" \" . (\$Info->\"revision\")) ] . \"\\n\" . \\\r\ +< \n [ \$IfThenElse ([ :len (\$Info->\"serial-number\") ] > 0) \\\r\ +--- +> n\" . \\\ +> \n [ \$FormatLine \" Model\" (\$Info->\"model\") ] . \\\ +> \n [ \$IfThenElse ([ :len (\$Info->\"revision\") ] > 0) \\\ +> \n (\" \" . (\$Info->\"revision\")) ] . \"\\n\" . \\\ +> \n [ \$IfThenElse ([ :len (\$Info->\"serial-number\") ] > 0) \\\ +1303,1304c1301,1302 +< \\n\") ] . \\\r\ +< \n [ \$IfThenElse ([ :len (\$License->\"nlevel\") ] > 0) \\\r\ +--- +> \\n\") ] . \\\ +> \n [ \$IfThenElse ([ :len (\$License->\"nlevel\") ] > 0) \\\ +1306,1308c1304,1306 +< \")) ] . \"\\n\") ] . \\\r\ +< \n \"RouterOS:\\n\" . \\\r\ +< \n [ \$IfThenElse ([ :len (\$License->\"level\") ] > 0) \\\r\ +--- +> \")) ] . \"\\n\") ] . \\\ +> \n \"RouterOS:\\n\" . \\\ +> \n [ \$IfThenElse ([ :len (\$License->\"level\") ] > 0) \\\ +1310c1308 +< \")) ] . \"\\n\") ] . \\\r\ +--- +> \")) ] . \"\\n\") ] . \\\ +1312c1310 +< \\n\" . \\\r\ +--- +> \\n\" . \\\ +1314,1315c1312,1313 +< \_\"\\n\" . \\\r\ +< \n [ \$IfThenElse ([ :len (\$Info->\"running-channel\") ] > 0) \\\r\ +--- +> \_\"\\n\" . \\\ +> \n [ \$IfThenElse ([ :len (\$Info->\"running-channel\") ] > 0) \\\ +1317c1315 +< \" (\" . (\$Info->\"running-channel\") . \")\") ] . \"\\n\") \\\r\ +--- +> \" (\" . (\$Info->\"running-channel\") . \")\") ] . \"\\n\") \\\ +1319,1320c1317,1318 +< \"\\n\") ] . \\\r\ +< \n [ \$IfThenElse ([ :len (\$Info->\"latest-version\") ] > 0 && \\\r\ +--- +> \"\\n\") ] . \\\ +> \n [ \$IfThenElse ([ :len (\$Info->\"latest-version\") ] > 0 && \\\ +1322c1320 +< \_\\\r\ +--- +> \_\\\ +1324,1325c1322,1323 +< \_\"\\n\") ] . \\\r\ +< \n [ \$IfThenElse ((\$Info->\"routerboard\") = true && \\\r\ +--- +> \_\"\\n\") ] . \\\ +> \n [ \$IfThenElse ((\$Info->\"routerboard\") = true && \\\ +1327c1325 +< ) \\\r\ +--- +> ) \\\ +1329,1334c1327,1332 +< \_\" -> \" . (\$Info->\"upgrade-firmware\")) ] . \"\\n\") ] . \\\r\ +< \n \"RouterOS-Scripts:\\n\" . \\\r\ +< \n [ \$FormatLine \" Commit\" [ \$CommitBrief ] ] . \"\\n\" . \\\r\ +< \n [ \$FormatLine \" Version\" \$GlobalConfVersion ]);\r\ +< \n}\r\ +< \n\r\ +--- +> \_\" -> \" . (\$Info->\"upgrade-firmware\")) ] . \"\\n\") ] . \\\ +> \n \"RouterOS-Scripts:\\n\" . \\\ +> \n [ \$FormatLine \" Commit\" [ \$CommitBrief ] ] . \"\\n\" . \\\ +> \n [ \$FormatLine \" Version\" \$GlobalConfVersion ]);\ +> \n}\ +> \n\ +1336,1338c1334,1336 +< tionFunctions ({})}\r\ +< \n:set GetRandom20CharAlNum do={\r\ +< \n :global EitherOr;\r\ +--- +> tionFunctions ({})}\ +> \n:set GetRandom20CharAlNum do={\ +> \n :global EitherOr;\ +1340,1347c1338,1345 +< 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\ +--- +> FGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\" ];\ +> \n}\ +> \n\ +> \n:global checkRunJob;\ +> \n:set checkRunJob do={\ +> \n :local Script [ :tostr \$1 ];\ +> \n :global ScriptLock; \ +> \n :if ([ \$ScriptLock \$Script ] = false) do={:return false}\ +1349c1347 +< :set Job [ /system/script/job/get \$Job ];\r\ +--- +> :set Job [ /system/script/job/get \$Job ];\ +1351c1349 +< stem/script/job/get [ find where .id=(\$Job->\"parent\") ] ]}\r\ +--- +> stem/script/job/get [ find where .id=(\$Job->\"parent\") ] ]}\ +1353,1380c1351,1378 +< 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 CommitBrief do={\r\ +< \n :global CommitId;\r\ +< \n :global CommitInfo;\r\ +< \n :if (\$CommitId = \"unknown\") do={\r\ +< \n :return \"unknown\";\r\ +< \n }\r\ +< \n :return (\$CommitInfo . \"/\" . [ :pick \$CommitId 0 8 ]);\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\ +--- +> lse; \ +> \n}\ +> \n\ +> \n:set InspectVar do={\ +> \n :global InspectVarRet;\ +> \n :put [ :tocrlf [ \$InspectVarRet \$1 ] ];\ +> \n}\ +> \n\ +> \n:set CommitBrief do={\ +> \n :global CommitId;\ +> \n :global CommitInfo;\ +> \n :if (\$CommitId = \"unknown\") do={\ +> \n :return \"unknown\";\ +> \n }\ +> \n :return (\$CommitInfo . \"/\" . [ :pick \$CommitId 0 8 ]);\ +> \n}\ +> \n\ +> \n:set InspectVarRet do={\ +> \n :local Input \$1;\ +> \n :local Level (0 + [ :tonum \$2 ]);\ +> \n :global CharacterReplace;\ +> \n :global IfThenElse;\ +> \n :global InspectVarRet;\ +> \n :local IndentReturn do={\ +> \n :local Prefix [ :tostr \$1 ];\ +> \n :local Value [ :tostr \$2 ];\ +> \n :local Level [ :tonum \$3 ];\ +> \n :global CharacterMultiply;\ +1382,1405c1380,1403 +< 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\ +--- +> fix . \"-> \" . \$Value);\ +> \n }\ +> \n :local TypeOf [ :typeof \$Input ];\ +> \n :local Len [ :len \$Input ];\ +> \n :local Return [ \$IndentReturn \"type\" \$TypeOf \$Level ];\ +> \n :if (\$TypeOf = \"array\") do={\ +> \n :foreach Key,Value in=\$Input do={\ +> \n :set \$Return (\$Return . \"\\n\" . \\\ +> \n [ \$IndentReturn \"key\" \$Key (\$Level + 1) ] . \"\\n\" . \\\ +> \n [ \$InspectVarRet \$Value (\$Level + 2) ]);\ +> \n }\ +> \n } else={\ +> \n :if (\$TypeOf = \"str\") do={\ +> \n :set \$Return (\$Return . \"\\n\" . \\\ +> \n [ \$IndentReturn \"len\" \$Len \$Level ]);\ +> \n :if ([ :typeof [ :find \$Input (\"\\r\") ] ] = \"num\") do={\ +> \n :set Input [ \$CharacterReplace \$Input (\"\\r\") \"\" ];\ +> \n }\ +> \n :if ([ :typeof [ :find \$Input (\"\\n\") ] ] = \"num\") do={\ +> \n :set Input [ \$CharacterReplace \$Input (\"\\n\") \" \" ];\ +> \n }\ +> \n }\ +> \n :if (\$TypeOf != \"nothing\") do={\ +> \n :set \$Return (\$Return . \"\\n\" . \\\ +1407,1420c1405,1418 +< \_\\\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 ([ :pick \$Input 0 77 ] . \"...\") \$Input ] \$Level ]);\ +> \n }\ +> \n }\ +> \n :return \$Return;\ +> \n}\ +> \n\ +> \n# !!! The function is not ready !!!\ +> \n:global FetchHttpInfo do={\ +> \n :local Mac [ :tostr \$1 ];\ +> \n :global CertificateAvailable;\ +> \n :global IsMacLocallyAdministered;\ +> \n :global LogPrint;\ +> \n :local Url \"https://api.macvendors.com/\";\ +1422,1423c1420,1421 +< y administered\";}\r\ +< \n :do {\r\ +--- +> y administered\";}\ +> \n :do {\ +1425c1423 +< o={\r\ +--- +> o={\ +1427,1434c1425,1432 +< \");\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 :error false;\ +> \n }\ +> \n :local Vendor ([ /tool/fetch \ +> \n (\$Url . [ :pick \$Mac 0 8 ]) output=user as-value ]->\"data\");\ +> \n :return \$Vendor;\ +> \n } on-error={\ +> \n :onerror Err {\ +1436c1434 +< as-value;\r\ +--- +> as-value;\ +1438c1436 +< );\r\ +--- +> );\ +1440,1453c1438,1451 +< 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\r\ +< \n :local PubIpAddr false;\r\ +< \n :local Url \$DetectIpAddrDefault;\r\ +< \n :local JobName [ :jobname ];\r\ +< \n\r\ +< \n :do {\r\ +--- +> rr); }\ +> \n :return \"unknown vendor\";\ +> \n }\ +> \n}\ +> \n\ +> \n:set GetPubIp do={\ +> \n :global DetectIpAddrDefault;\ +> \n :global DetectIpAddrFallback;\ +> \n\ +> \n :local PubIpAddr false;\ +> \n :local Url \$DetectIpAddrDefault;\ +> \n :local JobName [ :jobname ];\ +> \n\ +> \n :do {\ +1455c1453 +< ice: \" . \$Url . \"...\");\r\ +--- +> ice: \" . \$Url . \"...\");\ +1458c1456 +< )} \\\r\ +--- +> )} \\\ +1460,1461c1458,1459 +< detect public IP using default service: \" . \$Url . \".\")}\r\ +< \n } on-error={\r\ +--- +> detect public IP using default service: \" . \$Url . \".\")}\ +> \n } on-error={\ +1463,1464c1461,1462 +< ice: \" . \$Url . \".\");\r\ +< \n :set Url \$DetectIpAddrFallBack;\r\ +--- +> ice: \" . \$Url . \".\");\ +> \n :set Url \$DetectIpAddrFallBack;\ +1466c1464 +< vice: \" . \$Url . \"...\");\r\ +--- +> vice: \" . \$Url . \"...\");\ +1469c1467 +< )} \\\r\ +--- +> )} \\\ +1471,1473c1469,1471 +< \_detect public IP using fallback service: \" . \$Url . \".\")}\r\ +< \n };\r\ +< \n :local IpLen ([ :len \$PubIpAddr ] -1);\r\ +--- +> \_detect public IP using fallback service: \" . \$Url . \".\")}\ +> \n };\ +> \n :local IpLen ([ :len \$PubIpAddr ] -1);\ +1475,1489c1473,1487 +< {:set PubIpAddr [:pick \$PubIpAddr 0 \$IpLen]}\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\ +--- +> {:set PubIpAddr [:pick \$PubIpAddr 0 \$IpLen]}\ +> \n :return \$PubIpAddr;\ +> \n}\ +> \n\ +> \n:set FormatLine do={\ +> \n :local Key [ :tostr \$1 ];\ +> \n :local Value [ :tostr \$2 ];\ +> \n :local Indent [ :tonum \$3 ];\ +> \n :local Spaces;\ +> \n :local Return \"\";\ +> \n :global CharacterMultiply;\ +> \n :global EitherOr;\ +> \n :set Indent [ \$EitherOr \$Indent 16 ];\ +> \n :local Spaces [ \$CharacterMultiply \" \" \$Indent ];\ +> \n :if ([ :len \$Key ] > 0) do={ :set Return (\$Key . \":\")}\ +1491c1489 +< n\" . [ :pick \$Spaces 0 \$Indent ] . \$Value);\r\ +--- +> n\" . [ :pick \$Spaces 0 \$Indent ] . \$Value);\ +1493,1504c1491,1502 +< \$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\ +--- +> \$Return ]) ] . \$Value)}\ +> \n :return \$Return;\ +> \n}\ +> \n\ +> \n:set ParseCustom do={\ +> \n :local Str [ :tostr \$1 ];\ +> \n :local Start [:find [ \$Str ] [:tostr \$2]];\ +> \n :local End [ :tostr \$3 ];\ +> \n :local Num [ :tonum \$4 ];\ +> \n :local Return;\ +> \n :if ([:len \$Num] = 0) do={:set Num \"0\"}\ +> \n :local rest [:pick \$Str (\$Start+\$Num) [:len \$Str]]; \ +1506,1519c1504,1517 +< 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\ +--- +> lse={\ +> \n :set End [:find \$rest \$End];\ +> \n :set Return [:pick \$rest 0 \$End];\ +> \n }\ +> \n:return \$Return;\ +> \n}\ +> \n\ +> \n:set LogPrint do={\ +> \n :local Severity [ :tostr \$1 ];\ +> \n :local Name [ :tostr \$2 ];\ +> \n :local Message [ :tostr \$3 ];\ +> \n :global PrintDebug;\ +> \n :global PrintDebugOverride;\ +> \n :global EitherOr;\ +1521,1527c1519,1525 +< ];\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 PrintSeverity do={\ +> \n :global TerminalColorOutput;\ +> \n :if (\$TerminalColorOutput != true) do={:return \$1}\ +> \n :local Color { debug=96; info=97; warning=93; error=91 };\ +> \n :return (\"\\1B[\" . \$Color->\$1 . \"m\" . \$1 . \"\\1B[0m\");\ +> \n}\ +1529,1534c1527,1531 +< \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 ~ (\"^(custom|debug|error|info)\\\$\")) do={\ +> \n :if (\$Severity = \"debug\") do={:log debug \$Log}\ +> \n :if (\$Severity = \"error\") do={:log error \$Log}\ +> \n :if (\$Severity = \"info\" ) do={:log info \$Log}\ +> \n } else={:log warning \$Log; :set Severity \"warning\"}\ +1536,1552c1533,1572 +< 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\r\ +< \n :global CertificateDownload;\r\ +< \n :global ParseKeyValueStore;\r\ +< \n\r\ +< \n :if ([ :len \$UseFor ] = 0) do={\r\ +< \n :log warning (\$0 . \"The intended use is undefined!\");\r\ +< \n :set UseFor \"undefined\";\r\ +< \n }\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\ +--- +> erity \$Severity ] . \": \" . \$Message)}\ +> \n}\ +> \n\ +> \n# check and download required certificate\ +> \n# Description: This function checks if a certificate with given Common N\ +> ame is available in the system or not.\ +> \n# If not, it tries to download it from repository. It also \ +> checks the certificate chain and downloads missing intermediate certificat\ +> es if needed.\ +> \n# Arguments: \"Common Name\" - the common name of the certificate to che\ +> ck\ +> \n# \"fetch\" - if the intended use for certificate is \"fetch\ +> \", it will check if the certificate is available for fetch option and ret\ +> urn true if it is, otherwise it will check other options as well and retur\ +> n true if the certificate is available for at least one of the options.\ +> \n# \"tls\" - if the intended use for certificate is \"tls\", i\ +> t will check if the certificate is available for tls option and return tru\ +> e if it is, otherwise it will check other options as well and return true \ +> if the certificate is available for at least one of the options.\ +> \n# \"all\" - if the intended use is \"all\", it will check all\ +> \_options and return true if the certificate is available for at least one\ +> \_of the options.\ +> \n# \"undefined\" - if the intended use for certificate is not \ +> defined, it will check all options and log a warning as well.\ +> \n# Usage: \$CertificateAvailable \"Common Name\" \"intended use for certi\ +> ficate (e.g. \"fetch\", \"tls\", \"all\", \"undefined\")\"\ +> \n:set CertificateAvailable do={\ +> \n :local CommonName [ :tostr \$1 ];\ +> \n :local UseFor [ :tostr \$2 ];\ +> \n\ +> \n :global CertificateDownload;\ +> \n :global ParseKeyValueStore;\ +> \n\ +> \n :if ([ :len \$UseFor ] = 0) do={\ +> \n :log warning (\$0 . \"The intended use is undefined!\");\ +> \n :set UseFor \"undefined\";\ +> \n }\ +> \n :if ([ /system/resource/get free-hdd-space ] < 8388608 && \\\ +> \n [ /certificate/settings/get crl-download ] = true && \\\ +> \n [ /certificate/settings/get crl-store ] = \"system\") do={\ +1554,1561c1574,1581 +< \\\r\ +< \n \"is configured to download certificate CRLs to system!\");\r\ +< \n }\r\ +< \n :if ([ :len \$CommonName ] = 0) do={\r\ +< \n :log warning (\$0 . \"No CommonName given!\");\r\ +< \n :return false;\r\ +< \n }\r\ +< \n :local CertSettings [ /certificate/settings/get ];\r\ +--- +> \\\ +> \n \"is configured to download certificate CRLs to system!\");\ +> \n }\ +> \n :if ([ :len \$CommonName ] = 0) do={\ +> \n :log warning (\$0 . \"No CommonName given!\");\ +> \n :return false;\ +> \n }\ +> \n :local CertSettings [ /certificate/settings/get ];\ +1563,1565c1583,1584 +< \r\ +< \n (\$CertSettings->\"builtin-trust-store\") ~ \$UseFor || \\\r\ +< \n (\$CertSettings->\"builtin-trust-store\") = \"all\") && \\\r\ +--- +> \n (\$CertSettings->\"builtin-trust-store\") ~ \$UseFor || \\\ +> \n (\$CertSettings->\"builtin-trust-store\") = \"all\") && \\\ +1567,1569c1586,1588 +< \_] ] > 0) do={\r\ +< \n :return true;\r\ +< \n }\r\ +--- +> \_] ] > 0) do={\ +> \n :return true;\ +> \n }\ +1571c1590 +< ) do={\r\ +--- +> ) do={\ +1573,1577c1592,1596 +< \"' not available.\");\r\ +< \n :if ([ \$CertificateDownload \$CommonName ] = false) do={\r\ +< \n :return false;\r\ +< \n }\r\ +< \n }\r\ +--- +> \"' not available.\");\ +> \n :if ([ \$CertificateDownload \$CommonName ] = false) do={\ +> \n :return false;\ +> \n }\ +> \n }\ +1579c1598 +< ) do={\r\ +--- +> ) do={\ +1581,1583c1600,1602 +< \_CommonName '\" . \$CommonName . \"'. Should be ok.\");\r\ +< \n :return true;\r\ +< \n }\r\ +--- +> \_CommonName '\" . \$CommonName . \"'. Should be ok.\");\ +> \n :return true;\ +> \n }\ +1585c1604 +< e ] ];\r\ +--- +> e ] ];\ +1587c1606 +< ertVal->\"skid\")) do={\r\ +--- +> ertVal->\"skid\")) do={\ +1589c1608 +< \_= 0) do={\r\ +--- +> \_= 0) do={\ +1591c1610 +< >\"CN\");\r\ +--- +> >\"CN\");\ +1593,1597c1612,1616 +< is incomplete, missing '\" . \$IssuerCN . \"'.\");\r\ +< \n :if ([ \$CertificateDownload \$IssuerCN ] = false) do={\r\ +< \n :return false;\r\ +< \n }\r\ +< \n }\r\ +--- +> is incomplete, missing '\" . \$IssuerCN . \"'.\");\ +> \n :if ([ \$CertificateDownload \$IssuerCN ] = false) do={\ +> \n :return false;\ +> \n }\ +> \n }\ +1599,1613c1618,1650 +< \") ] ];\r\ +< \n }\r\ +< \n :return true;\r\ +< \n}\r\ +< \n\r\ +< \n:set CertificateDownload do={\r\ +< \n :local CommonName [ :tostr \$1 ];\r\ +< \n :global ScriptUpdatesBaseUrl;\r\ +< \n :global ScriptUpdatesUrlSuffix;\r\ +< \n :global CertificateNameByCN;\r\ +< \n :global CleanName;\r\ +< \n :global FetchUserAgentStr;\r\ +< \n :global RmFile;\r\ +< \n :global WaitForFile;\r\ +< \n\r\ +--- +> \") ] ];\ +> \n }\ +> \n :return true;\ +> \n}\ +> \n\ +> \n# download and import certificate\ +> \n# Description: This function downloads a certificate with given Common N\ +> ame from repository and imports it to the system.\ +> \n# It also checks the certificate chain and downloads missin\ +> g intermediate certificates if needed from repository.\ +> \n# If the certificate is already available, it does nothing.\ +> \n# If the certificate is not available in repository, it att\ +> empts to download it from mkcert.org.\ +> \n# If it is also not available there, it logs a warning and \ +> returns false.\ +> \n# If the certificate is downloaded but still not available \ +> after import, it removes all certificates with the same Common Name and lo\ +> gs a warning, assuming the certificate was imported but not named properly\ +> .\ +> \n# Or if there are multiple certificates with the same Commo\ +> n Name, it does nothing as well, assuming the certificate is already impor\ +> ted but not named properly.\ +> \n# Usage: \$CertificateDownload \"Common Name\"\ +> \n:set CertificateDownload do={\ +> \n :local CommonName [ :tostr \$1 ];\ +> \n :global ScriptUpdatesBaseUrl;\ +> \n :global ScriptUpdatesUrlSuffix;\ +> \n :global CertificateNameByCN;\ +> \n :global CleanName;\ +> \n :global FetchUserAgentStr;\ +> \n :global RmFile;\ +> \n :global WaitForFile;\ +> \n\ +1615,1618c1652,1654 +< \r\ +< \n \"CommonName '\" . \$CommonName . \"'.\");\r\ +< \n :local FileName ([ \$CleanName \$CommonName ] . \".pem\");\r\ +< \n :do {\r\ +--- +> \n \"CommonName '\" . \$CommonName . \"'.\");\ +> \n :local FileName ([ \$CleanName \$CommonName ] . \".pem\");\ +> \n :do {\ +1620c1656 +< -field=({ [ \$FetchUserAgentStr \$0 ] }) \\\r\ +--- +> -field=({ [ \$FetchUserAgentStr \$0 ] }) \\\ +1622,1625c1658,1661 +< sUrlSuffix) \\\r\ +< \n dst-path=\$FileName as-value;\r\ +< \n \$WaitForFile \$FileName;\r\ +< \n } on-error={\r\ +--- +> sUrlSuffix) \\\ +> \n dst-path=\$FileName as-value;\ +> \n \$WaitForFile \$FileName;\ +> \n } on-error={\ +1627,1630c1663,1666 +< e '\" . \$CommonName . \\\r\ +< \n \"' from repository! Trying fallback to mkcert.org...\");\r\ +< \n :do {\r\ +< \n :local CertSettings [ /certificate/settings/get ];\r\ +--- +> e '\" . \$CommonName . \\\ +> \n \"' from repository! Trying fallback to mkcert.org...\");\ +> \n :do {\ +> \n :local CertSettings [ /certificate/settings/get ];\ +1632c1668 +< \_] ] = 0 && \\\r\ +--- +> \_] ] = 0 && \\\ +1634c1670 +< || \\\r\ +--- +> || \\\ +1636c1672 +< \\\r\ +--- +> \\\ +1638d1673 +< \r\ +1640c1675 +< \_Root X1\" ] ] > 0)) do={\r\ +--- +> \_Root X1\" ] ] > 0)) do={\ +1642,1644c1677,1678 +< \r\ +< \n :return false;\r\ +< \n }\r\ +--- +> \n :return false;\ +> \n }\ +1646c1680 +< er-field=({ [ \$FetchUserAgentStr \$0 ] }) \\\r\ +--- +> er-field=({ [ \$FetchUserAgentStr \$0 ] }) \\\ +1648,1655c1682,1689 +< n ({ \$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 ({ \$CommonName }) ] \\\ +> \n dst-path=\$FileName as-value;\ +> \n \$WaitForFile \$FileName;\ +> \n :if ([ /file/get \$FileName size ] = 0) do={\ +> \n \$RmFile \$FileName;\ +> \n :error false;\ +> \n }\ +> \n } on-error={\ +1657,1663c1691,1697 +< e '\" . \$CommonName . \"'!\");\r\ +< \n :return false;\r\ +< \n }\r\ +< \n }\r\ +< \n /certificate/import file-name=\$FileName passphrase=\"\" as-value;\r\ +< \n :delay 1s;\r\ +< \n \$RmFile \$FileName;\r\ +--- +> e '\" . \$CommonName . \"'!\");\ +> \n :return false;\ +> \n }\ +> \n }\ +> \n /certificate/import file-name=\$FileName passphrase=\"\" as-value;\ +> \n :delay 1s;\ +> \n \$RmFile \$FileName;\ +1665c1699 +< ) do={\r\ +--- +> ) do={\ +1667c1701 +< +\\\$\") ];\r\ +--- +> +\\\$\") ];\ +1669,1671c1703,1705 +< e . \"' still unavailable!\");\r\ +< \n :return false;\r\ +< \n }\r\ +--- +> e . \"' still unavailable!\");\ +> \n :return false;\ +> \n }\ +1673,1681c1707,1725 +< \"_[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\ +--- +> \"_[0-9]+\\\$\") ] do={\ +> \n \$CertificateNameByCN [ /certificate/get \$Cert common-name ];\ +> \n }\ +> \n :return true;\ +> \n}\ +> \n\ +> \n# name a certificate by its common-name\ +> \n# Description: Some RouterOS functions require certificate name instead \ +> of common-name or fingerprint.\ +> \n# This function finds a certificate by common-name, fingerp\ +> rint or name and sets its name to a clean version of common-name\ +> \n# (only letters, numbers and dashes, other chars are replac\ +> ed with dash).\ +> \n# If there are multiple certificates with the same common-n\ +> ame, it will rename the first one found and log a warning.\ +> \n# Usage: \$CertificateNameByCN \"Common Name\"\ +> \n:set CertificateNameByCN do={\ +> \n :local Match [ :tostr \$1 ];\ +> \n :global CleanName;\ +1683,1708c1727,1753 +< rint=\$Match or name=\$Match) ]->0);\r\ +< \n :if ([ :len \$Cert ] = 0) do={\r\ +< \n :log 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 FetchUserAgentStr do={\r\ +< \n :local Caller [ :tostr \$1 ];\r\ +< \n\r\ +< \n :global GlobalScriptsUrl;\r\ +< \n :global CommitBrief;\r\ +< \n :global IfThenElse;\r\ +< \n :local Resource [ /system/resource/get ];\r\ +--- +> rint=\$Match or name=\$Match) ]->0);\ +> \n :if ([ :len \$Cert ] = 0) do={\ +> \n :log warning (\$0 .\" No matching certificate found.\");\ +> \n :return false;\ +> \n }\ +> \n :local CommonName [ /certificate/get \$Cert common-name ];\ +> \n /certificate/set \$Cert name=[ \$CleanName \$CommonName ];\ +> \n :return true;\ +> \n}\ +> \n\ +> \n:set CharacterMultiply do={\ +> \n :local Str [ :tostr \$1 ];\ +> \n :local Num [ :tonum \$2 ];\ +> \n :if (\$Num = 0) do={:return \"\"}\ +> \n :local Return \"\";\ +> \n :for I from=1 to=\$Num do={:set Return (\$Return . \$Str)}\ +> \n :return \$Return;\ +> \n}\ +> \n\ +> \n\ +> \n:set FetchUserAgentStr do={\ +> \n :local Caller [ :tostr \$1 ];\ +> \n\ +> \n :global GlobalScriptsUrl;\ +> \n :global CommitBrief;\ +> \n :global IfThenElse;\ +> \n :local Resource [ /system/resource/get ];\ +1710c1755 +< \_\$Resource->\"architecture-name\" . \\\r\ +--- +> \_\$Resource->\"architecture-name\" . \\\ +1712,1717c1757,1762 +< CommitBrief ] . \")\");\r\ +< \n}\r\ +< \n\r\ +< \n:set Grep do={\r\ +< \n :local Input ([ :tostr \$1 ] . \"\\n\");\r\ +< \n :local Pattern [ :tostr \$2 ];\r\ +--- +> CommitBrief ] . \")\");\ +> \n}\ +> \n\ +> \n:set Grep do={\ +> \n :local Input ([ :tostr \$1 ] . \"\\n\");\ +> \n :local Pattern [ :tostr \$2 ];\ +1719,1721c1764,1766 +< }\r\ +< \n :do {\r\ +< \n :local Line [ :pick \$Input 0 [ :find \$Input \"\\n\" ] ];\r\ +--- +> }\ +> \n :do {\ +> \n :local Line [ :pick \$Input 0 [ :find \$Input \"\\n\" ] ];\ +1723c1768 +< \$Line}\r\ +--- +> \$Line}\ +1725,1747c1770,1792 +< 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\ +--- +> Input ] ];\ +> \n } while=([ :len \$Input ] > 0);\ +> \n :return [];\ +> \n}\ +> \n\ +> \n:set HumanReadableNum do={\ +> \n :local Input [ :tonum \$1 ];\ +> \n :local Base [ :tonum \$2 ];\ +> \n :global EitherOr;\ +> \n :global IfThenElse;\ +> \n :local Prefix \"kMGTPE\";\ +> \n :local Pow 1;\ +> \n :set Base [ \$EitherOr \$Base 1024 ];\ +> \n :local Bin [ \$IfThenElse (\$Base = 1024) \"i\" \"\" ];\ +> \n :if (\$Input < \$Base) do={:return \$Input}\ +> \n :for I from=0 to=[ :len \$Prefix ] do={\ +> \n :set Pow (\$Pow * \$Base);\ +> \n :if (\$Input / \$Base < \$Pow) do={\ +> \n :set Prefix [ :pick \$Prefix \$I ];\ +> \n :local Tmp1 (\$Input * 100 / \$Pow);\ +> \n :local Tmp2 (\$Tmp1 / 100);\ +> \n :if (\$Tmp2 >= 100) do={:return (\$Tmp2 . \$Prefix . \$Bin)}\ +> \n :return (\$Tmp2 . \".\" . \\\ +1749,1759c1794,1804 +< 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\ +--- +> 2 ] + 1) ] . \\\ +> \n \$Prefix . \$Bin);\ +> \n }\ +> \n }\ +> \n}\ +> \n\ +> \n:set CleanName do={\ +> \n :local Input [ :tostr \$1 ];\ +> \n :local Return \"\";\ +> \n :for I from=0 to=([ :len \$Input ] - 1) do={\ +> \n :local Char [ :pick \$Input \$I ];\ +1761,1762c1806,1807 +< stuvwxyz0123456789\" \$Char ] ] = \"nil\") do={\r\ +< \n :do {:if ([ :len \$Return ] = 0) do={:error true};\r\ +--- +> stuvwxyz0123456789\" \$Char ] ] = \"nil\") do={\ +> \n :do {:if ([ :len \$Return ] = 0) do={:error true};\ +1764,1771c1809,1816 +< 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\ +--- +> ror true}; :set Char \"-\"} on-error={:set Char \"\"}; \ +> \n };\ +> \n :set Return (\$Return . \$Char)};\ +> \n :return \$Return;\ +> \n}\ +> \n\ +> \n:set GetRandomNumber do={\ +> \n :global EitherOr;\ +1773,1782c1818,1826 +< \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}\ +> \n\ +> \n:set RandomDelay do={\ +> \n :local Time [ :tonum \$1 ];\ +> \n :local Unit [ :tostr \$2 ];\ +> \n :global EitherOr;\ +> \n :global GetRandomNumber;\ +> \n :global MAX;\ +> \n :if (\$Time = 0) do={:return false}\ +1784,1805c1828,1849 +< [ \$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\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 :if (\$ExitOK = \"false\") do={\r\ +--- +> [ \$EitherOr \$Unit \"s\" ]) ] ] / 1000000) ] ] . \"ms\");\ +> \n}\ +> \n\ +> \n:set EscapeForRegEx do={\ +> \n :local Input [ :tostr \$1 ];\ +> \n :if ([ :len \$Input ] = 0) do={:return \"\"}\ +> \n :local Return \"\";\ +> \n :local Chars (\"^.[]\\\$()|*+\?{}\\\\\");\ +> \n :for I from=0 to=([ :len \$Input ] - 1) do={\ +> \n :local Char [ :pick \$Input \$I ];\ +> \n :if ([ :find \$Chars \$Char ]) do={:set Char (\"\\\\\" . \$Char)}\ +> \n :set Return (\$Return . \$Char);\ +> \n }\ +> \n :return \$Return;\ +> \n}\ +> \n\ +> \n:set ExitError do={\ +> \n :local ExitOK [ :tostr \$1 ];\ +> \n :local Name [ :tostr \$2 ];\ +> \n :local Error [ :tostr \$3 ];\ +> \n :global IfThenElse;\ +> \n :if (\$ExitOK = \"false\") do={\ +1807c1851 +< \\\r\ +--- +> \\\ +1809c1853 +< ror\" . \\\r\ +--- +> ror\" . \\\ +1811,1818c1855,1862 +< \$Error) \".\" ]);\r\ +< \n }\r\ +< \n}\r\ +< \n\r\ +< \n:set ExitOnError do={\r\ +< \n :local Name [ :tostr \$1 ];\r\ +< \n :local Error [ :tostr \$2 ];\r\ +< \n :global IfThenElse;\r\ +--- +> \$Error) \".\" ]);\ +> \n }\ +> \n}\ +> \n\ +> \n:set ExitOnError do={\ +> \n :local Name [ :tostr \$1 ];\ +> \n :local Error [ :tostr \$2 ];\ +> \n :global IfThenElse;\ +1820c1864 +< \\\$\") \\\r\ +--- +> \\\$\") \\\ +1822c1866 +< r\" . \\\r\ +--- +> r\" . \\\ +1824,1835c1868,1879 +< rror) \".\" ]);\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\ +--- +> rror) \".\" ]);\ +> \n}\ +> \n\ +> \n:set MiniDateTimeStamp do={\ +> \n /system/clock;\ +> \n :local vdate [get date];\ +> \n :local vtime [get time];\ +> \n :local vdoff [:toarray \"0,4,5,7,8,10\"];\ +> \n :local MM [:pick \$vdate (\$vdoff->2) (\$vdoff->3)];\ +> \n :local M [:tonum \$MM];\ +> \n :if (\$vdate ~ \".../../....\") do={\ +> \n :set vdoff [:toarray \"7,11,1,3,4,6\"];\ +1837,1919c1881,1950 +< 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={\r\ +< \n :return false;\r\ +< \n }\r\ +< \n :local FileVal false;\r\ +< \n :do {\r\ +< \n :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 :log debug (\$0 . \" Removing directory: \". \$DirName);\r\ +< \n :local DirVal [ \$FileGet \$DirName ];\r\ +< \n :if (\$DirVal = false) do={\r\ +< \n :log debug (\$0 . \" ... which does not exist.\");\r\ +< \n :return true;\r\ +< \n };\r\ +< \n :if (\$DirVal->\"type\" != \"directory\") do={\r\ +< \n :log error (\$0 . \" Directory '\" . \$DirName . \"' is not a direct\ +< ory.\");\r\ +< \n :return false;\r\ +< \n };\r\ +< \n :onerror Err {\r\ +< \n /file/remove \$DirName;\r\ +< \n } do={\r\ +< \n :log error (\$0 . \" Removing directory '\" . \$DirName . \"' failed\ +< : \" . \$Err);\r\ +< \n :return false;\r\ +< \n };\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 :log debug (\$0 . \" Removing file: \". \$FileName);\r\ +< \n :local FileVal [ \$FileGet \$FileName ];\r\ +< \n :if (\$FileVal = false) do={\r\ +< \n :log debug (\$0 . \" ... which does not exist.\");\r\ +< \n :return true;\r\ +< \n }\r\ +--- +> PCTOVEC\" [:pick \$vdate (\$vdoff->2) (\$vdoff->3)] -1] / 2);\ +> \n :if (\$M>12) do={:set M (\$M - 12)}\ +> \n :set MM [:pick (100 + \$M) 1 3];\ +> \n }\ +> \n :local yyyy [:pick \$vdate (\$vdoff->0) (\$vdoff->1)];\ +> \n :local dd [:pick \$vdate (\$vdoff->4) (\$vdoff->5)];\ +> \n :local HH [:pick \$vtime 0 2];\ +> \n :local mm [:pick \$vtime 3 5];\ +> \n :local ss [:pick \$vtime 6 8];\ +> \n :return ([\$yyyy] . [\$MM] . [\$dd] . [\$HH] . [\$mm] . [\$ss]);\ +> \n}\ +> \n\ +> \n:set WaitForFile do={\ +> \n :local FileName [ :tostr \$1 ];\ +> \n :local WaitTime [ :totime \$2 ];\ +> \n :global CleanFilePath;\ +> \n :global EitherOr;\ +> \n :global MAX;\ +> \n :set FileName [ \$CleanFilePath \$FileName ];\ +> \n :local Delay ([ \$MAX [ \$EitherOr \$WaitTime 2s ] 100ms ] / 9);\ +> \n :do {\ +> \n :retry {\ +> \n /file/get \$FileName;\ +> \n :return true;\ +> \n } delay=\$Delay max=10;\ +> \n } on-error={ }\ +> \n :while ([ :len [ /file/find where name=\$FileName ] ] > 0) do={\ +> \n :do {\ +> \n /file/get \$FileName;\ +> \n :return true;\ +> \n } on-error={ }\ +> \n :delay \$Delay;\ +> \n :set Delay (\$Delay * 3 / 2);\ +> \n }\ +> \n :return false;\ +> \n}\ +> \n\ +> \n:set FileGet do={\ +> \n :local FileName [ :tostr \$1 ];\ +> \n :global WaitForFile;\ +> \n :if ([ \$WaitForFile \$FileName 0s ] = false) do={:return false}\ +> \n :local FileVal false;\ +> \n :do {:set FileVal [ /file/get \$FileName ];\ +> \n } on-error={ }\ +> \n :return \$FileVal;\ +> \n}\ +> \n\ +> \n:set RmDir do={\ +> \n :local DirName [ :tostr \$1 ];\ +> \n :global FileGet;\ +> \n :global LogPrint;\ +> \n \$LogPrint debug \$0 (\"Removing directory: \". \$DirName);\ +> \n :local DirVal [ \$FileGet \$DirName ];\ +> \n :if (\$DirVal = false) do={\$LogPrint debug \$0 (\"... which does not \ +> exist.\"); :return true};\ +> \n :if (\$DirVal->\"type\" != \"directory\") do={\$LogPrint error \$0 (\"\ +> Directory '\" . \$DirName . \"' is not a directory.\"); :return false};\ +> \n :onerror Err {/file/remove \$DirName} do={\$LogPrint error \$0 (\"Remo\ +> ving directory '\" . \$DirName . \"' failed: \" . \$Err); :return false};\ +> \n :return true;\ +> \n}\ +> \n\ +> \n:set RmFile do={\ +> \n :local FileName [ :tostr \$1 ];\ +> \n :global FileGet;\ +> \n :global LogPrint;\ +> \n \$LogPrint debug \$0 (\"Removing file: \". \$FileName);\ +> \n :local FileVal [ \$FileGet \$FileName ];\ +> \n :if (\$FileVal = false) do={\$LogPrint debug \$0 (\"... which does not\ +> \_exist.\"); :return true}\ +1921,1954c1952,1981 +< sk\") do={\r\ +< \n :log error (\$0 . \" File '\" . \$FileName . \"' is not a file.\");\ +< \r\ +< \n :return false;\r\ +< \n }\r\ +< \n :onerror Err {\r\ +< \n /file/remove \$FileName;\r\ +< \n } do={\r\ +< \n :log error (\$0 . \" Removing file '\" . \$FileName . \"' failed: \"\ +< \_. \$Err); :return false;\r\ +< \n }\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\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 :log info (\$0 . \" The tmpfs is disabled, enabling.\");\r\ +< \n /disk/enable \$TmpFs;\r\ +< \n }\r\ +< \n :return true;\r\ +< \n }\r\ +< \n :log info (\$0 . \" Creating disk of type tmpfs.\");\r\ +< \n \$RmDir \"tmpfs\";\r\ +< \n :onerror Err {\r\ +--- +> sk\") do={\ +> \n \$LogPrint error \$0 (\"File '\" . \$FileName . \"' is not a file.\"\ +> ); :return false}\ +> \n :onerror Err {\ +> \n /file/remove \$FileName;\ +> \n } do={\$LogPrint error \$0 (\"Removing file '\" . \$FileName . \"' fai\ +> led: \" . \$Err); :return false}\ +> \n :return true;\ +> \n}\ +> \n\ +> \n:set MkDir do={\ +> \n :local Path [ :tostr \$1 ];\ +> \n :global CleanFilePath;\ +> \n :global FileGet;\ +> \n :global RmDir;\ +> \n :global WaitForFile;\ +> \n :global LogPrint;\ +> \n :local MkTmpfs do={\ +> \n :global WaitForFile;\ +> \n :local TmpFs [ /disk/find where slot=tmpfs type=tmpfs ];\ +> \n :if ([ :len \$TmpFs ] = 1) do={\ +> \n :if ([ /disk/get \$TmpFs disabled ] = true) do={\ +> \n \$LogPrint info \$0 (\"The tmpfs is disabled, enabling.\");\ +> \n /disk/enable \$TmpFs;\ +> \n }\ +> \n :return true;\ +> \n }\ +> \n \$LogPrint info \$0 (\"Creating disk of type tmpfs.\");\ +> \n \$RmDir \"tmpfs\";\ +> \n :onerror Err {\ +1956,2012c1983,2039 +< /get total-memory ] / 3);\r\ +< \n \$WaitForFile \"tmpfs\";\r\ +< \n } do={\r\ +< \n :log 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 :log debug (\$0 . \" Making directory: \" . \$Path);\r\ +< \n :local PathVal [ \$FileGet \$Path ];\r\ +< \n :if (\$PathVal->\"type\" = \"directory\") do={\r\ +< \n :log 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 :log 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\ +--- +> /get total-memory ] / 3);\ +> \n \$WaitForFile \"tmpfs\";\ +> \n } do={\ +> \n \$LogPrint warning \$0 (\"Creating disk of type tmpfs failed: \" .\ +> \_\$Err);\ +> \n :return false;\ +> \n }\ +> \n :return true;\ +> \n }\ +> \n :set Path [ \$CleanFilePath \$Path ];\ +> \n :if (\$Path = \"\") do={\ +> \n :return true;\ +> \n }\ +> \n \$LogPrint debug \$0 (\"Making directory: \" . \$Path);\ +> \n :local PathVal [ \$FileGet \$Path ];\ +> \n :if (\$PathVal->\"type\" = \"directory\") do={\ +> \n \$LogPrint debug \$0 (\"... which already exists.\");\ +> \n :return true;\ +> \n }\ +> \n :if ([ :pick \$Path 0 5 ] = \"tmpfs\") do={\ +> \n :if ([ \$MkTmpfs ] = false) do={\ +> \n :return false;\ +> \n }\ +> \n }\ +> \n :onerror Err {\ +> \n /file/add type=\"directory\" name=\$Path;\ +> \n \$WaitForFile \$Path;\ +> \n } do={\ +> \n \$LogPrint warning \$0 (\"Making directory '\" . \$Path . \"' failed\ +> : \" . \$Err);\ +> \n :return false;\ +> \n }\ +> \n :return true;\ +> \n}\ +> \n\ +> \n:set MAX do={:if (\$1 > \$2) do={:return \$1}\ +> \n :return \$2;\ +> \n}\ +> \n:set MIN do={:if (\$1 < \$2) do={:return \$1}\ +> \n :return \$2;\ +> \n}\ +> \n\ +> \n:set CharacterMultiply do={\ +> \n :local Str [ :tostr \$1 ];\ +> \n :local Num [ :tonum \$2 ];\ +> \n :if (\$Num = 0) do={:return \"\"}\ +> \n :local Return \"\";\ +> \n :for I from=1 to=\$Num do={:set Return (\$Return . \$Str)}\ +> \n :return \$Return;\ +> \n}\ +> \n\ +> \n:set CharacterReplace do={\ +> \n :local String [ :tostr \$1 ];\ +> \n :local ReplaceFrom [ :tostr \$2 ];\ +> \n :local ReplaceWith [ :tostr \$3 ];\ +> \n :local Return \"\";\ +> \n :if (\$ReplaceFrom = \"\") do={:return \$String}\ +2014,2015c2041 +< \r\ +< \n :local Pos [ :find \$String \$ReplaceFrom ];\r\ +--- +> \n :local Pos [ :find \$String \$ReplaceFrom ];\ +2017d2042 +< \r\ +2019,2026c2044,2051 +< \_\$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\ +--- +> \_\$String ] ];\ +> \n }\ +> \n :return (\$Return . \$String);\ +> \n}\ +> \n\ +> \n:set CleanFilePath do={\ +> \n :local Path [ :tostr \$1 ];\ +> \n :global CharacterReplace;\ +2028c2053 +< \"//\" \"/\" ]};\r\ +--- +> \"//\" \"/\" ]};\ +2030c2055 +< \_\$Path ] ]};\r\ +--- +> \_\$Path ] ]};\ +2032,2036c2057,2061 +< pick \$Path 0 ([ :len \$Path ] - 1) ]};\r\ +< \n :return \$Path;\r\ +< \n}\r\ +< \n\r\ +< \n:set IfThenElse do={\r\ +--- +> pick \$Path 0 ([ :len \$Path ] - 1) ]};\ +> \n :return \$Path;\ +> \n}\ +> \n\ +> \n:set IfThenElse do={\ +2038,2043c2063,2068 +< \$2};\r\ +< \n :return \$3;\r\ +< \n}\r\ +< \n\r\ +< \n:set EitherOr do={\r\ +< \n :global IfThenElse;\r\ +--- +> \$2};\ +> \n :return \$3;\ +> \n}\ +> \n\ +> \n:set EitherOr do={\ +> \n :global IfThenElse;\ +2045c2070 +< \$1 \$2 ]}\r\ +--- +> \$1 \$2 ]}\ +2047,2058c2072,2083 +< \_\$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\ +--- +> \_\$1 \$2 ]}\ +> \n# this works for boolean values, literal ones with parentheses\ +> \n :return [ \$IfThenElse ([ :len [ :tostr \$1 ] ] > 0) \$1 \$2 ];\ +> \n}\ +> \n\ +> \n:set ParseKeyValueStore do={\ +> \n :local Source \$1;\ +> \n :if ([ :pick \$Source 0 1 ] = \"{\") do={\ +> \n :do {\ +> \n :return [ :deserialize from=json \$Source ];\ +> \n } on-error={ }\ +> \n } \ +2060,2064c2085,2089 +< }\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 Result ({});\ +> \n :foreach KeyValue in=[ :toarray \$Source ] do={\ +> \n :if ([ :find \$KeyValue \"=\" ]) do={\ +> \n :local Key [ :pick \$KeyValue 0 [ :find \$KeyValue \"=\" ] ];\ +2066,2079c2091,2105 +< \_: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 VersionToNum;\r\ +--- +> \_:len \$KeyValue ] ];\ +> \n :if (\$Value=\"true\") do={:set Value true}\ +> \n :if (\$Value=\"false\") do={:set Value false}\ +> \n :set (\$Result->\$Key) \$Value;\ +> \n } else={:set (\$Result->\$KeyValue) true}\ +> \n }\ +> \n :return \$Result;\ +> \n}\ +> \n:set RequiredRouterOS do={\ +> \n :local Caller [ :tostr \$1 ];\ +> \n :local Required [ :tostr \$2 ];\ +> \n :local Warn [ :tostr \$3 ];\ +> \n :global IfThenElse;\ +> \n :global LogPrint;\ +> \n :global VersionToNum;\ +2081,2084c2107,2110 +< \\\$\")) do={\r\ +< \n :log error (\$0 . \" No valid RouterOS version: \" . \$Required);\r\ +< \n :return false;\r\ +< \n }\r\ +--- +> \\\$\")) do={\ +> \n \$LogPrint error \$0 (\"No valid RouterOS version: \" . \$Required);\ +> \n :return false;\ +> \n }\ +2086,2089c2112,2115 +< e/update/get installed-version ] ]) do={\r\ +< \n :if (\$Warn = \"true\") do={\r\ +< \n :log warning (\$0 . \" This \" . [ \$IfThenElse ([ :pick \$Caller \ +< 0 ] = (\"\\\$\")) \"function\" \"script\" ] . \\\r\ +--- +> e/update/get installed-version ] ]) do={\ +> \n :if (\$Warn = \"true\") do={\ +> \n \$LogPrint warning \$0 (\"This \" . [ \$IfThenElse ([ :pick \$Call\ +> er 0 ] = (\"\\\$\")) \"function\" \"script\" ] . \\\ +2091,2103c2117,2129 +< 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\ +--- +> es RouterOS \" . \$Required . \". Please update!\");\ +> \n }\ +> \n :return false;\ +> \n }\ +> \n :return true;\ +> \n}\ +> \n:set VersionToNum do={\ +> \n :local Input [ :tostr \$1 ];\ +> \n :local Multi 0x1000000;\ +> \n :local Return 0;\ +> \n :global CharacterReplace;\ +> \n :set Input [ \$CharacterReplace \$Input \".\" \",\" ];\ +> \n :foreach I in={ \"zero\"; \"alpha\"; \"beta\"; \"rc\" } do={\ +2105,2114c2131,2139 +< \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 }\ +> \n :foreach Value in=([ :toarray \$Input ], 0) do={\ +> \n :local Num [ :tonum \$Value ];\ +> \n :if (\$Multi = 0x100) do={\ +> \n :if ([ :typeof \$Num ] = \"num\") do={\ +> \n :set Return (\$Return + 0xff00);\ +> \n :set Multi (\$Multi / 0x100);\ +> \n } else={\ +> \n :if (\$Value = \"zero\") do={ }\ +2116c2141 +< }\r\ +--- +> }\ +2118,2121c2143,2145 +< \r\ +< \n :if (\$Value = \"rc\") do={ :set Return (\$Return + 0x7f00); }\r\ +< \n }\r\ +< \n }\r\ +--- +> \n :if (\$Value = \"rc\") do={ :set Return (\$Return + 0x7f00); }\ +> \n }\ +> \n }\ +2123,2142c2147,2166 +< lue * \$Multi)); }\r\ +< \n :set Multi (\$Multi / 0x100);\r\ +< \n }\r\ +< \n :return \$Return;\r\ +< \n}\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 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\ +--- +> lue * \$Multi)); }\ +> \n :set Multi (\$Multi / 0x100);\ +> \n }\ +> \n :return \$Return;\ +> \n}\ +> \n:set ScriptLock do={\ +> \n :local Script [ :tostr \$1 ];\ +> \n :local WaitMax [ :totime \$2 ];\ +> \n :global GetRandom20CharAlNum;\ +> \n :global IfThenElse;\ +> \n :global LogPrint;\ +> \n :global ScriptLockOrder;\ +> \n :if ([ :typeof \$ScriptLockOrder ] = \"nothing\") do={\ +> \n :set ScriptLockOrder ({});\ +> \n }\ +> \n :if ([ :typeof (\$ScriptLockOrder->\$Script) ] = \"nothing\") do={\ +> \n :set (\$ScriptLockOrder->\$Script) ({});\ +> \n }\ +> \n :local JobCount do={\ +> \n :local Script [ :tostr \$1 ];\ +2144,2150c2168,2173 +< \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 }\ +> \n :local TicketCount do={\ +> \n :local Script [ :tostr \$1 ];\ +> \n :global ScriptLockOrder;\ +> \n :local Count 0;\ +> \n :foreach Ticket in=(\$ScriptLockOrder->\$Script) do={\ +2152,2161c2175,2184 +< + 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\ +--- +> + 1)}\ +> \n }\ +> \n :return \$Count;\ +> \n }\ +> \n :local IsFirstTicket do={\ +> \n :local Script [ :tostr \$1 ];\ +> \n :local Check [ :tostr \$2 ];\ +> \n :global ScriptLockOrder;\ +> \n :foreach Ticket in=(\$ScriptLockOrder->\$Script) do={\ +> \n :if (\$Ticket = \$Check) do={:return true}\ +2163,2174c2186,2197 +< 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\ +--- +> o={:return false}\ +> \n }\ +> \n :return false;\ +> \n }\ +> \n :local AddTicket do={\ +> \n :local Script [ :tostr \$1 ];\ +> \n :local Add [ :tostr \$2 ];\ +> \n :global ScriptLockOrder;\ +> \n :while (true) do={\ +> \n :local Pos [ :len (\$ScriptLockOrder->\$Script) ];\ +> \n :set (\$ScriptLockOrder->\$Script->\$Pos) \$Add;\ +> \n :delay 10ms;\ +2176,2204c2199,2227 +< 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 :log error (\$0 . \" A script named '\" . \$Script . \"' does not ex\ +< ist!\");\r\ +< \n :error false;\r\ +< \n }\r\ +< \n :if ([ \$JobCount \$Script ] = 0) do={\r\ +--- +> e}\ +> \n }\ +> \n }\ +> \n :local RemoveTicket do={\ +> \n :local Script [ :tostr \$1 ];\ +> \n :local Remove [ :tostr \$2 ];\ +> \n :global ScriptLockOrder;\ +> \n :foreach Id,Ticket in=(\$ScriptLockOrder->\$Script) do={\ +> \n :while ((\$ScriptLockOrder->\$Script->\$Id) = \$Remove) do={\ +> \n :set (\$ScriptLockOrder->\$Script->\$Id);\ +> \n :delay 10ms;\ +> \n }\ +> \n }\ +> \n }\ +> \n :local CleanupTickets do={\ +> \n :local Script [ :tostr \$1 ];\ +> \n :global ScriptLockOrder;\ +> \n :foreach Ticket in=(\$ScriptLockOrder->\$Script) do={\ +> \n :if ([ :typeof \$Ticket ] != \"nothing\") do={:return false}\ +> \n }\ +> \n :set (\$ScriptLockOrder->\$Script) ({});\ +> \n }\ +> \n :if ([ :typeof \$WaitMax ] = \"nil\" ) do={:set WaitMax 0s}\ +> \n :if ([ :len [ /system/script/find where name=\$Script ] ] = 0) do={\ +> \n \$LogPrint error \$0 (\"A script named '\" . \$Script . \"' does not\ +> \_exist!\");\ +> \n :error false;\ +> \n }\ +> \n :if ([ \$JobCount \$Script ] = 0) do={\ +2206,2231c2229,2254 +< );\r\ +< \n :error false;\r\ +< \n }\r\ +< \n :if ([ \$TicketCount \$Script ] >= [ \$JobCount \$Script ]) do={\r\ +< \n :log error (\$0 . \" More tickets than running scripts '\" . \$Scrip\ +< t . \"', 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 :error false;\ +> \n }\ +> \n :if ([ \$TicketCount \$Script ] >= [ \$JobCount \$Script ]) do={\ +> \n \$LogPrint error \$0 (\"More tickets than running scripts '\" . \$Sc\ +> ript . \"', resetting!\");\ +> \n :set (\$ScriptLockOrder->\$Script) ({});\ +> \n /system/script/job/remove [ find where script=\$Script ];\ +> \n }\ +> \n :local MyTicket [ \$GetRandom20CharAlNum 6 ];\ +> \n \$AddTicket \$Script \$MyTicket;\ +> \n :local WaitInterval (\$WaitMax / 20);\ +> \n :local WaitTime \$WaitMax;\ +> \n :while (\$WaitTime > 0 && \\\ +> \n ([ \$IsFirstTicket \$Script \$MyTicket ] = false || \\\ +> \n [ \$TicketCount \$Script ] < [ \$JobCount \$Script ])) do={\ +> \n :set WaitTime (\$WaitTime - \$WaitInterval);\ +> \n :delay \$WaitInterval;\ +> \n }\ +> \n :if ([ \$IsFirstTicket \$Script \$MyTicket ] = true && \\\ +> \n [ \$TicketCount \$Script ] = [ \$JobCount \$Script ]) do={\ +> \n \$RemoveTicket \$Script \$MyTicket;\ +> \n \$CleanupTickets \$Script;\ +> \n :return true;\ +> \n }\ +> \n \$RemoveTicket \$Script \$MyTicket;\ +2233c2256 +< once\" . \\\r\ +--- +> once\" . \\\ +2235,2240c2258,2262 +< \_lock\" \"\" ] . \"...\");\r\ +< \n :return false;\r\ +< \n}\r\ +< \n\r\ +< \n:set SendNotification do={ :onerror Err {\r\ +< \n :global SendNotification2;\r\ +--- +> \_lock\" \"\" ] . \"...\");\ +> \n :return false;\ +> \n}\ +> \n:set SendNotification do={ :onerror Err {\ +> \n :global SendNotification2;\ +2242,2249c2264,2270 +< \_silent=\$4 });\r\ +< \n} do={:global ExitOnError; \$ExitOnError \$0 \$Err}\r\ +< \n}\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\ +--- +> \_silent=\$4 });\ +> \n} do={:global ExitOnError; \$ExitOnError \$0 \$Err}\ +> \n}\ +> \n:set SendNotification2 do={\ +> \n :local Notification \$1;\ +> \n :global NotificationFunctions;\ +> \n :foreach FunctionName,Discard in=\$NotificationFunctions do={\ +2251,2306c2272,2327 +< ns->\\\"\" . \$FunctionName . \"\\\"\") \$Notification;\r\ +< \n }\r\ +< \n}\r\ +< \n\r\ +< \n:set SymbolByUnicodeName do={\r\ +< \n :local Name [ :tostr \$1 ];\r\ +< \n :global EitherOr;\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 :log warning (\$0 . \"No symbol available for name '\" . \$Name . \"\ +< '!\");\r\ +< \n :return \"\";\r\ +< \n }\r\ +--- +> ns->\\\"\" . \$FunctionName . \"\\\"\") \$Notification;\ +> \n }\ +> \n}\ +> \n:set SymbolByUnicodeName do={\ +> \n :local Name [ :tostr \$1 ];\ +> \n :global EitherOr;\ +> \n :global LogPrint;\ +> \n :global SymbolsExtra;\ +> \n :local Symbols ({\ +> \n \"abacus\"=\"\\F0\\9F\\A7\\AE\";\ +> \n \"alarm-clock\"=\"\\E2\\8F\\B0\";\ +> \n \"arrow-down\"=\"\\E2\\AC\\87\";\ +> \n \"arrow-up\"=\"\\E2\\AC\\86\";\ +> \n \"calendar\"=\"\\F0\\9F\\93\\85\";\ +> \n \"card-file-box\"=\"\\F0\\9F\\97\\83\";\ +> \n \"chart-decreasing\"=\"\\F0\\9F\\93\\89\";\ +> \n \"chart-increasing\"=\"\\F0\\9F\\93\\88\";\ +> \n \"cloud\"=\"\\E2\\98\\81\";\ +> \n \"cross-mark\"=\"\\E2\\9D\\8C\";\ +> \n \"earth\"=\"\\F0\\9F\\8C\\8D\";\ +> \n \"fire\"=\"\\F0\\9F\\94\\A5\";\ +> \n \"floppy-disk\"=\"\\F0\\9F\\92\\BE\";\ +> \n \"gear\"=\"\\E2\\9A\\99\";\ +> \n \"heart\"=\"\\E2\\99\\A5\";\ +> \n \"high-voltage-sign\"=\"\\E2\\9A\\A1\";\ +> \n \"incoming-envelope\"=\"\\F0\\9F\\93\\A8\";\ +> \n \"information\"=\"\\E2\\84\\B9\";\ +> \n \"large-orange-circle\"=\"\\F0\\9F\\9F\\A0\";\ +> \n \"large-red-circle\"=\"\\F0\\9F\\94\\B4\";\ +> \n \"link\"=\"\\F0\\9F\\94\\97\";\ +> \n \"lock-with-ink-pen\"=\"\\F0\\9F\\94\\8F\";\ +> \n \"memo\"=\"\\F0\\9F\\93\\9D\";\ +> \n \"mobile-phone\"=\"\\F0\\9F\\93\\B1\";\ +> \n \"pushpin\"=\"\\F0\\9F\\93\\8C\";\ +> \n \"scissors\"=\"\\E2\\9C\\82\";\ +> \n \"scroll\"=\"\\F0\\9F\\93\\9C\";\ +> \n \"smiley-partying-face\"=\"\\F0\\9F\\A5\\B3\";\ +> \n \"smiley-smiling-face\"=\"\\E2\\98\\BA\";\ +> \n \"smiley-winking-face-with-tongue\"=\"\\F0\\9F\\98\\9C\";\ +> \n \"sparkles\"=\"\\E2\\9C\\A8\";\ +> \n \"speech-balloon\"=\"\\F0\\9F\\92\\AC\";\ +> \n \"star\"=\"\\E2\\AD\\90\";\ +> \n \"warning-sign\"=\"\\E2\\9A\\A0\";\ +> \n \"white-heavy-check-mark\"=\"\\E2\\9C\\85\"\ +> \n }, \$SymbolsExtra);\ +> \n :local Magic [ :pick [ /system/clock/get date ] 4 10 ];\ +> \n :local Special {\ +> \n \"information-04-01\"=\"\\F0\\9F\\9A\\BB\";\ +> \n \"large-orange-circle-04-01\"=\"\\F0\\9F\\8D\\8A\";\ +> \n \"large-orange-circle-10-31\"=\"\\F0\\9F\\8E\\83\";\ +> \n \"large-red-circle-04-01\"=\"\\F0\\9F\\8D\\92\" };\ +> \n :if ([ :len (\$Symbols->\$Name) ] = 0) do={\ +> \n \$LogPrint warning \$0 (\"No symbol available for name '\" . \$Name \ +> . \"'!\");\ +> \n :return \"\";\ +> \n }\ +2308,2314c2329,2334 +< me) ] . \"\\EF\\B8\\8F\");\r\ +< \n}\r\ +< \n\r\ +< \n:set SymbolForNotification do={\r\ +< \n :global NotificationsWithSymbols;\r\ +< \n :global SymbolByUnicodeName;\r\ +< \n :global IfThenElse;\r\ +--- +> me) ] . \"\\EF\\B8\\8F\");\ +> \n}\ +> \n:set SymbolForNotification do={\ +> \n :global NotificationsWithSymbols;\ +> \n :global SymbolByUnicodeName;\ +> \n :global IfThenElse;\ +2316,2317c2336,2337 +< \_:len \$2 ] > 0) ([ :tostr \$2 ] . \" \") \"\" ]}\r\ +< \n :local Return \"\";\r\ +--- +> \_:len \$2 ] > 0) ([ :tostr \$2 ] . \" \") \"\" ]}\ +> \n :local Return \"\";\ +2319,2328c2339,2347 +< mbolByUnicodeName \$Symbol ])}\r\ +< \n :return (\$Return . \" \");\r\ +< \n}\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\ +--- +> mbolByUnicodeName \$Symbol ])}\ +> \n :return (\$Return . \" \");\ +> \n}\ +> \n:set Unix2Dos do={:return [ :tocrlf [ :tostr \$1 ] ]}\ +> \n:set UrlEncode do={\ +> \n :local Input [ :tostr \$1 ];\ +> \n :if ([ :len \$Input ] = 0) do={:return \"\"}\ +> \n :local Return \"\";\ +> \n :local Chars (\"\\n\\r !\\\"#\\\$%&'()*+,:;<=>\?@[\\\\]^`{|}~\");\ +2330c2349 +< %24\"; \"%25\"; \"%26\"; \"%27\";\r\ +--- +> %24\"; \"%25\"; \"%26\"; \"%27\";\ +2332c2351 +< \"%3C\"; \"%3D\"; \"%3E\"; \"%3F\";\r\ +--- +> \"%3C\"; \"%3D\"; \"%3E\"; \"%3F\";\ +2334,2337c2353,2356 +< \"%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\ +--- +> \"%7C\"; \"%7D\"; \"%7E\" };\ +> \n :for I from=0 to=([ :len \$Input ] - 1) do={\ +> \n :local Char [ :pick \$Input \$I ];\ +> \n :local Replace [ :find \$Chars \$Char ];\ +2339,2382c2358,2398 +< ce)}\r\ +< \n :set Return (\$Return . \$Char);\r\ +< \n }\r\ +< \n :return \$Return;\r\ +< \n}\r\ +< \n\r\ +< \n:set ValidateSyntax do={\r\ +< \n :local Code [ :tostr \$1 ];\r\ +< \n :onerror Err {\r\ +< \n [ :parse (\":local Validate do={\\n\" . \$Code . \"\\n}\") ];\r\ +< \n } do={\r\ +< \n :log debug (\$0 . \"Validation failed: \" . \$Err);\r\ +< \n :return false;\r\ +< \n }\r\ +< \n :return true;\r\ +< \n}\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\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\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\ +--- +> ce)}\ +> \n :set Return (\$Return . \$Char);\ +> \n }\ +> \n :return \$Return;\ +> \n}\ +> \n:set ValidateSyntax do={\ +> \n :local Code [ :tostr \$1 ];\ +> \n :global LogPrint;\ +> \n :onerror Err {\ +> \n [ :parse (\":local Validate do={\\n\" . \$Code . \"\\n}\") ];\ +> \n } do={\ +> \n \$LogPrint debug \$0 (\"Valdation failed: \" . \$Err);\ +> \n :return false;\ +> \n }\ +> \n :return true;\ +> \n}\ +> \n:set IsDNSResolving do={\ +> \n :do {:resolve \"api.telegram.org\"} on-error={:return false}\ +> \n :return true;\ +> \n}\ +> \n:set IsFullyConnected do={\ +> \n :global IsDNSResolving;\ +> \n :global IsTimeSync;\ +> \n :if ([ \$IsDNSResolving ] = false) do={:return false};\ +> \n :if ([ \$IsTimeSync ] = false) do={:return false};\ +> \n :return true;\ +> \n}\ +> \n:set IsTimeSync do={\ +> \n :global IsTimeSyncCached;\ +> \n :global IsTimeSyncResetNtp;\ +> \n :if (\$IsTimeSyncCached = true) do={:return true}\ +> \n :if ([ /system/ntp/client/get enabled ] = true) do={\ +> \n :if ([ /system/ntp/client/get status ] = \"synchronized\") do={\ +> \n :set IsTimeSyncCached true;\ +> \n :return true;\ +> \n }\ +> \n :local Uptime [ /system/resource/get uptime ];\ +> \n :if ([ :typeof \$IsTimeSyncResetNtp ] = \"nothing\") do={\ +> \n :set IsTimeSyncResetNtp \$Uptime;\ +> \n }\ +> \n :if (\$Uptime - \$IsTimeSyncResetNtp < 3m) do={:return false}\ +2384,2392c2400,2408 +< ;\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 :set IsTimeSyncResetNtp \$Uptime;\ +> \n /system/ntp/client/set enabled=no;\ +> \n :delay 20ms;\ +> \n /system/ntp/client/set enabled=yes;\ +> \n :return false;\ +> \n }\ +> \n :if ([ /system/license/get ]->\"level\" = \"free\" || \\\ +> \n [ /system/resource/get ]->\"board-name\" = \"x86\") do={\ +2394,2403c2410,2419 +< 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\ +--- +> ee license and x86.\";\ +> \n :return true;\ +> \n }\ +> \n :if ([ /ip/cloud/get update-time ] = true) do={\ +> \n :if ([ :typeof [ /ip/cloud/get public-address ] ] = \"ip\") do={\ +> \n :set IsTimeSyncCached true;\ +> \n :return true;\ +> \n }\ +> \n :return false;\ +> \n }\ +2405,2441c2421,2442 +< \r\ +< \n :return true;\r\ +< \n}\r\ +< \n\r\ +< \n# read parts of a large file\r\ +< \n# Description of parameters:\r\ +< \n# \$1 - script name for logging and user agent\r\ +< \n# \$2 - url to fetch from\r\ +< \n# \$3 - check-certificate value for /tool/fetch (true/false)\r\ +< \n# \$4 - mode value for /tool/fetch (optional, e.g. \"keep-broken\", \"ht\ +< tps-only\", \"http-only\"\r\ +< \n# \"no-redirects\", \"background\", \"background-and-keep-broken\",\ +< \_\"background-and-https-only\",\r\ +< \n# \"background-and-http-only\", \"background-and-no-redirects\", \"\ +< background-and-keep-broken-and-https-only\", \"background-and-keep-broken-\ +< and-http-only\",\r\ +< \n# \"background-and-keep-broken-and-no-redirects\")\r\ +< \n# \$5 - fetch method for /tool/fetch (optional, e.g. \"get\", \"head\", \ +< \"post\", \"put\", \"patch\", \"delete\")\r\ +< \n:set FetchLargeFiles do={\r\ +< \n :local FetchLargeScript [: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 :return true;\ +> \n}\ +> \n\ +> \n# read parts of a large file\ +> \n:set FetchLargeFiles do={\ +> \n :local FetchLargeScript [:tostr \$1];\ +> \n :local fetchUrl [:tostr \$2];\ +> \n :local CheckCert [:tostr \$3];\ +> \n :local fetchMode [:tostr \$4];\ +> \n :local fetchMethod [:tostr \$5];\ +> \n :local FetchString \"undefined\";\ +> \n \ +> \n :global CleanName;\ +> \n :global FetchUserAgentStr;\ +> \n :global GetRandom20CharAlNum;\ +> \n :global IfThenElse;\ +> \n :global LogPrint;\ +> \n :global MkDir;\ +> \n :global RmDir;\ +> \n :global RmFile;\ +> \n :global WaitForFile;\ +> \n\ +2443c2444 +< ithout-crl\" ];\r\ +--- +> ithout-crl\" ];\ +2445c2446 +< ode=\" . \$fetchMode)] ];\r\ +--- +> ode=\" . \$fetchMode)] ];\ +2447,2453c2448,2454 +< \"http-method=\\\"\" . \$fetchMethod . \"\\\"\") ]];\r\ +< \n \r\ +< \n :local DirName (\"tmpfs/\" . [ \$CleanName \$FetchLargeScript ]);\r\ +< \n :if ([ \$MkDir \$DirName ] = false) do={\r\ +< \n \$LogPrint error \$0 (\"Failed creating directory!\");\r\ +< \n :return false;\r\ +< \n }\r\ +--- +> \"http-method=\\\"\" . \$fetchMethod . \"\\\"\") ]];\ +> \n \ +> \n :local DirName (\"tmpfs/\" . [ \$CleanName \$FetchLargeScript ]);\ +> \n :if ([ \$MkDir \$DirName ] = false) do={\ +> \n \$LogPrint error \$0 (\"Failed creating directory!\");\ +> \n :return false;\ +> \n }\ +2455c2456 +< \$GetRandom20CharAlNum ]);\r\ +--- +> \$GetRandom20CharAlNum ]);\ +2458,2461c2459,2462 +< ;\r\ +< \n #:log warning (\"\\\$fUrl =\" . \$2 . ({[ \$fMode ]}));\r\ +< \n :onerror Err {\r\ +< \n :set FetchString (\"/tool/fetch \" . \\\r\ +--- +> ;\ +> \n #:log warning (\"\\\$fUrl =\" . \$2 . ({[ \$fMode ]}));\ +> \n :onerror Err {\ +> \n :set FetchString (\"/tool/fetch \" . \\\ +2463c2464 +< \_. \$fetchMethod . \"\\\" \")] . \\\r\ +--- +> \_. \$fetchMethod . \"\\\" \")] . \\\ +2465c2466 +< \_. \"\\\") \" . \\\r\ +--- +> \_. \"\\\") \" . \\\ +2467c2468 +< e . \" \")] . \\\r\ +--- +> e . \" \")] . \\\ +2469,2471c2470,2472 +< \_as-value);\r\ +< \n :log warning (\"\\\$FetchSring = \" . \$FetchString);\r\ +< \n :put [\$FetchString];\r\ +--- +> \_as-value);\ +> \n :log warning (\"\\\$FetchSring = \" . \$FetchString);\ +> \n :put [\$FetchString];\ +2474,2478c2475,2479 +< \_\$FetchLargeScript ] }) as-value];\r\ +< \n } do={\r\ +< \n :if ([ \$WaitForFile \$FileName 500ms ] = true) do={\r\ +< \n \$RmFile \$FileName;\r\ +< \n }\r\ +--- +> \_\$FetchLargeScript ] }) as-value];\ +> \n } do={\ +> \n :if ([ \$WaitForFile \$FileName 500ms ] = true) do={\ +> \n \$RmFile \$FileName;\ +> \n }\ +2480,2484c2481,2485 +< \_- \" . \$Err);\r\ +< \n \$RmDir \$DirName;\r\ +< \n :return false;\r\ +< \n }\r\ +< \n :if ([ \$WaitForFile \$FileName 5s ] = false) do={\r\ +--- +> \_- \" . \$Err);\ +> \n \$RmDir \$DirName;\ +> \n :return false;\ +> \n }\ +> \n :if ([ \$WaitForFile \$FileName 5s ] = false) do={\ +2486,2492c2487,2493 +< \" 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\ +--- +> \" did not show up.\");\ +> \n :return false;\ +> \n }\ +> \n :local FileSize [ /file/get \$FileName size ];\ +> \n :local Return \"\";\ +> \n :local VarSize 0;\ +> \n :while (\$VarSize != \$FileSize) do={\ +2494,2531c2495,2532 +< 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: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 CommitId;\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\ +--- +> 768 file=\$FileName as-value ]->\"data\"));\ +> \n :set FileSize [ /file/get \$FileName size ];\ +> \n :set VarSize [ :len \$Return ];\ +> \n :if (\$VarSize > \$FileSize) do={\ +> \n :delay 100ms;\ +> \n }\ +> \n }\ +> \n \$RmDir \$DirName;\ +> \n :return \$Return;\ +> \n}\ +> \n\ +> \n:set ScriptInstallUpdate do={ :onerror Err {\ +> \n :local Scripts [ :toarray \$1 ];\ +> \n :local NewComment [ :tostr \$2 ];\ +> \n :global InitSetup;\ +> \n\ +> \n :global CommitId;\ +> \n :global ScriptUpdatesCRLF;\ +> \n :global GlobalConfVersion;\ +> \n :global Identity;\ +> \n :global CertificateAvailable;\ +> \n :global CheckSumsVerify;\ +> \n :global GlobalScriptsUrl;\ +> \n :global SumsDirAndFileName;\ +> \n :global GlobalScriptsUrlSuffix;\ +> \n :global EitherOr;\ +> \n :global FetchUserAgentStr;\ +> \n :global Grep;\ +> \n :global IfThenElse;\ +> \n :global LogPrint;\ +> \n :global ParseKeyValueStore;\ +> \n :global RequiredRouterOS;\ +> \n :global SendNotification2;\ +> \n :global SymbolForNotification;\ +> \n :global ValidateSyntax;\ +> \n :global CommentsInScripts;\ +> \n\ +> \n :if ([ \$CertificateAvailable \"Root YE\" \"fetch\" ] = false) do={\ +2533,2536c2534,2537 +< hout.\");\r\ +< \n }\r\ +< \n\r\ +< \n :foreach Script in=\$Scripts do={\r\ +--- +> hout.\");\ +> \n }\ +> \n\ +> \n :foreach Script in=\$Scripts do={\ +2538,2539c2539 +< \r\ +< \n \$LogPrint info \$0 (\"Adding new script: \" . \$Script);\r\ +--- +> \n \$LogPrint info \$0 (\"Adding new script: \" . \$Script);\ +2541,2552c2541,2552 +< Vados\\n\" comment=\$NewComment;\r\ +< \n }\r\ +< \n }\r\ +< \n\r\ +< \n :local CommitIdBefore \$CommitId;\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\ +--- +> Vados\\n\" comment=\$NewComment;\ +> \n }\ +> \n }\ +> \n\ +> \n :local CommitIdBefore \$CommitId;\ +> \n :local GlobalConfVersionBefore \$GlobalConfVersion;\ +> \n :local ReloadGlobal false;\ +> \n :local DeviceMode [ /system/device-mode/get ];\ +> \n\ +> \n :if (\$CheckSumsVerify = true) do={\ +> \n :local CheckSums ({});\ +> \n :do {\ +2554c2554 +< iptsUrlSuffix);\r\ +--- +> iptsUrlSuffix);\ +2556d2555 +< \r\ +2558c2557 +< ficate=yes-without-crl \\\r\ +--- +> ficate=yes-without-crl \\\ +2560,2563c2559,2562 +< =user as-value ]->\"data\") ];\r\ +< \n } on-error={ \$LogPrint warning \$0 (\"Err = \" . \$Err); }\r\ +< \n }\r\ +< \n\r\ +--- +> =user as-value ]->\"data\") ];\ +> \n } on-error={ \$LogPrint warning \$0 (\"Err = \" . \$Err); }\ +> \n }\ +> \n\ +2565,2566c2564,2565 +< s\" ] do={\r\ +< \n :local ScriptVal [ /system/script/get \$Script ];\r\ +--- +> s\" ] do={\ +> \n :local ScriptVal [ /system/script/get \$Script ];\ +2568,2570c2567,2569 +< ];\r\ +< \n :local SourceNew;\r\ +< \n\r\ +--- +> ];\ +> \n :local SourceNew;\ +> \n\ +2572,2574c2571,2573 +< \\b\" . \$ScriptVal->\"name\" . \"\\\\b\") ] do={\r\ +< \n :local SchedulerVal [ /system/scheduler/get \$Scheduler ];\r\ +< \n :if (\$ScriptVal->\"policy\" != \$SchedulerVal->\"policy\") do={\r\ +--- +> \\b\" . \$ScriptVal->\"name\" . \"\\\\b\") ] do={\ +> \n :local SchedulerVal [ /system/scheduler/get \$Scheduler ];\ +> \n :if (\$ScriptVal->\"policy\" != \$SchedulerVal->\"policy\") do={\ +2577,2581c2576,2580 +< \"'!\");\r\ +< \n }\r\ +< \n }\r\ +< \n :do {\r\ +< \n :if (\$ScriptInfo->\"ignore\" = true) do={\r\ +--- +> \"'!\");\ +> \n }\ +> \n }\ +> \n :do {\ +> \n :if (\$ScriptInfo->\"ignore\" = true) do={\ +2583,2587c2582,2586 +< e\" . \"', as requested.\");\r\ +< \n :error true;\r\ +< \n }\r\ +< \n :if (\$CheckSumsVerify = true) do={\r\ +< \n :local CheckSum (\$CheckSums->(\$ScriptVal->\"name\"));\r\ +--- +> e\" . \"', as requested.\");\ +> \n :error true;\ +> \n }\ +> \n :if (\$CheckSumsVerify = true) do={\ +> \n :local CheckSum (\$CheckSums->(\$ScriptVal->\"name\"));\ +2589c2588 +< ptInfo->\"url-suffix\") ] = 0 && \\\r\ +--- +> ptInfo->\"url-suffix\") ] = 0 && \\\ +2591c2590 +< rce\") ] ] = \$CheckSum) do={\r\ +--- +> rce\") ] ] = \$CheckSum) do={\ +2593,2597c2592,2596 +< >\"name\" . \"' matches, ignoring.\");\r\ +< \n :error true;\r\ +< \n }\r\ +< \n }\r\ +< \n :if ([ :len (\$ScriptInfo->\"certificate\") ] > 0) do={\r\ +--- +> >\"name\" . \"' matches, ignoring.\");\ +> \n :error true;\ +> \n }\ +> \n }\ +> \n :if ([ :len (\$ScriptInfo->\"certificate\") ] > 0) do={\ +2599c2598 +< fetch\" ] = false) do={\r\ +--- +> fetch\" ] = false) do={\ +2601,2604c2600,2603 +< ng without.\");\r\ +< \n }\r\ +< \n }\r\ +< \n :onerror Err {\r\ +--- +> ng without.\");\ +> \n }\ +> \n }\ +> \n :onerror Err {\ +2606c2605 +< lScriptsUrl ];\r\ +--- +> lScriptsUrl ];\ +2608c2607 +< lobalScriptsUrlSuffix ];\r\ +--- +> lobalScriptsUrlSuffix ];\ +2610c2609 +< Suffix);\r\ +--- +> Suffix);\ +2612c2611 +< name\") . \"' from url: \" . \$Url);\r\ +--- +> name\") . \"' from url: \" . \$Url);\ +2614d2612 +< \r\ +2616,2620c2614,2618 +< ut=user as-value ];\r\ +< \n :if (\$Result->\"status\" = \"finished\") do={\r\ +< \n :set SourceNew [ :tolf (\$Result->\"data\") ];\r\ +< \n } \r\ +< \n } do={\r\ +--- +> ut=user as-value ];\ +> \n :if (\$Result->\"status\" = \"finished\") do={\ +> \n :set SourceNew [ :tolf (\$Result->\"data\") ];\ +> \n } \ +> \n } do={\ +2622,2626c2620,2624 +< 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\ +--- +> al->\"name\" . \"': \" . \$Err);\ +> \n :if (\$Err != \"Fetch failed with status 404\") do={\ +> \n :error false;\ +> \n }\ +> \n :if (\$ScriptVal->\"source\" = \"#!rsc by Vados\") do={\ +2628,2632c2626,2630 +< \?\");\r\ +< \n /system/script/remove \$Script;\r\ +< \n :error false;\r\ +< \n }\r\ +< \n :if (\$CheckSumsVerify = true) do={\r\ +--- +> \?\");\ +> \n /system/script/remove \$Script;\ +> \n :error false;\ +> \n }\ +> \n :if (\$CheckSumsVerify = true) do={\ +2634,2635c2632,2633 +< riptInfo->\"url-suffix\") ] = 0 && \\\r\ +< \n [ :len \$CheckSum ] = 0) do={\r\ +--- +> riptInfo->\"url-suffix\") ] = 0 && \\\ +> \n [ :len \$CheckSum ] = 0) do={\ +2637,2643c2635,2641 +< 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\ +--- +> pdates with 'ignore=true' in comment.\");\ +> \n }\ +> \n }\ +> \n :error false;\ +> \n }\ +> \n\ +> \n :if ([ :len \$SourceNew ] = 0) do={\ +2645,2649c2643,2647 +< >\"name\") . \"'.\");\r\ +< \n :error false;\r\ +< \n }\r\ +< \n\r\ +< \n :local SourceCRLF [ :tocrlf \$SourceNew ];\r\ +--- +> >\"name\") . \"'.\");\ +> \n :error false;\ +> \n }\ +> \n\ +> \n :local SourceCRLF [ :tocrlf \$SourceNew ];\ +2651c2649 +< lConfig\" || (\$ScriptVal->\"name\") != \"AM-GlobalFunc\")) do={\r\ +--- +> lConfig\" || (\$ScriptVal->\"name\") != \"AM-GlobalFunc\")) do={\ +2653c2651 +< \$ScriptVal->\"source\")) do={\r\ +--- +> \$ScriptVal->\"source\")) do={\ +2655,2657c2653,2655 +< . \"' source did not change. End of lines set to CRLF.\");\r\ +< \n if (\$ScriptUpdatesCRLF = false) do={\r\ +< \n :put [ :tolf \$SourceNew ];\r\ +--- +> . \"' source did not change. End of lines set to CRLF.\");\ +> \n if (\$ScriptUpdatesCRLF = false) do={\ +> \n :put [ :tolf \$SourceNew ];\ +2659,2665c2657,2663 +< ) . \"' 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\ +--- +> ) . \"' source update end of lines to LF.\");\ +> \n }\ +> \n :error false;\ +> \n }\ +> \n }\ +> \n\ +> \n :if ([ :pick \$SourceNew 0 14 ] != \"#!rsc by Vados\") do={\ +2668,2672c2666,2670 +< );\r\ +< \n :error false;\r\ +< \n }\r\ +< \n\r\ +< \n :if (\$CommentsInScripts = true) do={\r\ +--- +> );\ +> \n :error false;\ +> \n }\ +> \n\ +> \n :if (\$CommentsInScripts = true) do={\ +2674,2675c2672,2673 +< \_\") ];\r\ +< \n :if ([ :len \$CommentLine ] = 0) do={\r\ +--- +> \_\") ];\ +> \n :if ([ :len \$CommentLine ] = 0) do={\ +2678,2680c2676,2678 +< noring!\");\r\ +< \n :error false;\r\ +< \n } else={\r\ +--- +> noring!\");\ +> \n :error false;\ +> \n } else={\ +2683c2681 +< ] + 2) [ :len \$CommentLine] ]) do={\r\ +--- +> ] + 2) [ :len \$CommentLine] ]) do={\ +2686c2684 +< ;\r\ +--- +> ;\ +2688c2686 +< ind \$CommentLine \":\"] + 2) [ :len \$CommentLine] ];\r\ +--- +> ind \$CommentLine \":\"] + 2) [ :len \$CommentLine] ];\ +2691,2692c2689,2690 +< ded!\");\r\ +< \n } else={\r\ +--- +> ded!\");\ +> \n } else={\ +2694,2699c2692,2697 +< al->\"name\") . \"' did not change.\");\r\ +< \n :error false;\r\ +< \n }\r\ +< \n } \r\ +< \n }\r\ +< \n\r\ +--- +> al->\"name\") . \"' did not change.\");\ +> \n :error false;\ +> \n }\ +> \n } \ +> \n }\ +> \n\ +2701c2699 +< \"\\23 requires RouterOS, \") ] ]->version);\r\ +--- +> \"\\23 requires RouterOS, \") ] ]->version);\ +2703c2701 +< \_false ] = false) do={\r\ +--- +> \_false ] = false) do={\ +2705c2703 +< \") . \"' requires RouterOS \" . \\\r\ +--- +> \") . \"' requires RouterOS \" . \\\ +2707,2709c2705,2707 +< gnoring!\");\r\ +< \n :error false;\r\ +< \n }\r\ +--- +> gnoring!\");\ +> \n :error false;\ +> \n }\ +2711,2713c2709,2711 +< \\23 requires device-mode, \") ] ];\r\ +< \n :local MissingDM ({});\r\ +< \n :foreach Feature,Value in=\$RequiredDM do={\r\ +--- +> \\23 requires device-mode, \") ] ];\ +> \n :local MissingDM ({});\ +> \n :foreach Feature,Value in=\$RequiredDM do={\ +2715,2719c2713,2717 +< ceMode->\$Feature) = false) do={\r\ +< \n :set MissingDM (\$MissingDM, \$Feature);\r\ +< \n }\r\ +< \n }\r\ +< \n :if ([ :len \$MissingDM ] > 0) do={\r\ +--- +> ceMode->\$Feature) = false) do={\ +> \n :set MissingDM (\$MissingDM, \$Feature);\ +> \n }\ +> \n }\ +> \n :if ([ :len \$MissingDM ] > 0) do={\ +2721c2719 +< \") . \"' requires disabled \" . \\\r\ +--- +> \") . \"' requires disabled \" . \\\ +2723,2727c2721,2725 +< gnoring!\");\r\ +< \n :error false;\r\ +< \n }\r\ +< \n\r\ +< \n :if ([ \$ValidateSyntax \$SourceNew ] = false) do={\r\ +--- +> gnoring!\");\ +> \n :error false;\ +> \n }\ +> \n\ +> \n :if ([ \$ValidateSyntax \$SourceNew ] = false) do={\ +2729,2732c2727,2730 +< ScriptVal->\"name\") . \"' failed! Ignoring!\");\r\ +< \n :error false;\r\ +< \n }\r\ +< \n \r\ +--- +> ScriptVal->\"name\") . \"' failed! Ignoring!\");\ +> \n :error false;\ +> \n }\ +> \n \ +2734,2735c2732,2733 +< ript comment: \" . (\$ScriptVal->\"comment\"));\r\ +< \n\r\ +--- +> ript comment: \" . (\$ScriptVal->\"comment\"));\ +> \n\ +2737c2735 +< Val->\"comment\") \\\r\ +--- +> Val->\"comment\") \\\ +2739,2741c2737,2739 +< F \$SourceNew ] \$Script;\r\ +< \n :if (\$ScriptVal->\"name\" = \"AM-GlobalConfig\" || \\\r\ +< \n \$ScriptVal->\"name\" = \"AM-GlobalFunc\" || \\\r\ +--- +> F \$SourceNew ] \$Script;\ +> \n :if (\$ScriptVal->\"name\" = \"AM-GlobalConfig\" || \\\ +> \n \$ScriptVal->\"name\" = \"AM-GlobalFunc\" || \\\ +2743,2748c2741,2746 +< o={\r\ +< \n :set ReloadGlobal true;\r\ +< \n }\r\ +< \n } on-error={ }\r\ +< \n }\r\ +< \n :if (\$ReloadGlobal = true) do={\r\ +--- +> o={\ +> \n :set ReloadGlobal true;\ +> \n }\ +> \n } on-error={ }\ +> \n }\ +> \n :if (\$ReloadGlobal = true) do={\ +2750,2753c2748,2751 +< \");\r\ +< \n :onerror Err {\r\ +< \n :global InitSetup (a);\r\ +< \n /system/script {run AM-GlobalConfig; run AM-GlobalFunc;};\r\ +--- +> \");\ +> \n :onerror Err {\ +> \n :global InitSetup (a);\ +> \n /system/script {run AM-GlobalConfig; run AM-GlobalFunc;};\ +2755,2757c2753,2755 +< ctions failed! \" . \$Err)}\r\ +< \n }\r\ +< \n :if (\$GlobalConfVersionBefore > \$GlobalConfVersion) do={\r\ +--- +> ctions failed! \" . \$Err)}\ +> \n }\ +> \n :if (\$GlobalConfVersionBefore > \$GlobalConfVersion) do={\ +2759,2770c2757,2768 +< \" . \\\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 \$GlobalConfVersionBefore . \" to \" . \$GlobalConfVersion . \\\ +> \n \". Installed an older version\?\");\ +> \n }\ +> \n :if (\$GlobalConfVersionBefore < \$GlobalConfVersion) do={\ +> \n :global GlobalConfChanges;\ +> \n :global GlobalConfMigration;\ +> \n :local ChangeLogCode;\ +> \n :if ([ :len \$ChangeLogCode ] > 0) do={\ +> \n :if ([ \$ValidateSyntax \$ChangeLogCode ] = true) do={\ +> \n :onerror Err {\ +> \n [ :parse \$ChangeLogCode ];\ +2772c2770 +< . \$Err)}\r\ +--- +> . \$Err)}\ +2774,2776c2772,2774 +< dation!\")}\r\ +< \n }\r\ +< \n :if ([ :len \$GlobalConfMigration ] > 0) do={\r\ +--- +> dation!\")}\ +> \n }\ +> \n :if ([ :len \$GlobalConfMigration ] > 0) do={\ +2778,2781c2776,2779 +< \_do={\r\ +< \n :local Migration (\$GlobalConfMigration->[ :tostr \$I ]);\r\ +< \n :do {\r\ +< \n :if ([ :typeof \$Migration ] != \"str\") do={\r\ +--- +> \_do={\ +> \n :local Migration (\$GlobalConfMigration->[ :tostr \$I ]);\ +> \n :do {\ +> \n :if ([ :typeof \$Migration ] != \"str\") do={\ +2783,2786c2781,2784 +< \_\" is not available.\");\r\ +< \n :error false;\r\ +< \n }\r\ +< \n :if ([ \$ValidateSyntax \$Migration ] = false) do={\r\ +--- +> \_\" is not available.\");\ +> \n :error false;\ +> \n }\ +> \n :if ([ \$ValidateSyntax \$Migration ] = false) do={\ +2788,2789c2786,2787 +< \_. \" failed syntax validation!\");\r\ +< \n :error false}\r\ +--- +> \_. \" failed syntax validation!\");\ +> \n :error false}\ +2791,2793c2789,2791 +< . \": \" . \$Migration);\r\ +< \n :onerror Err {\r\ +< \n [ :parse \$Migration ];\r\ +--- +> . \": \" . \$Migration);\ +> \n :onerror Err {\ +> \n [ :parse \$Migration ];\ +2795,2798c2793,2796 +< \_\$I . \" failed to run: \" . \$Err)}\r\ +< \n } on-error={ }\r\ +< \n }\r\ +< \n }\r\ +--- +> \_\$I . \" failed to run: \" . \$Err)}\ +> \n } on-error={ }\ +> \n }\ +> \n }\ +2800c2798 +< entity . \" increased \" . \\\r\ +--- +> entity . \" increased \" . \\\ +2802c2800 +< d modification. \" . \\\r\ +--- +> d modification. \" . \\\ +2804,2806c2802,2804 +< bal-config.\");\r\ +< \n \$LogPrint info \$0 (\$NotificationMessage);\r\ +< \n :if ([ :len \$GlobalConfChanges ] > 0) do={\r\ +--- +> bal-config.\");\ +> \n \$LogPrint info \$0 (\$NotificationMessage);\ +> \n :if ([ :len \$GlobalConfChanges ] > 0) do={\ +2808c2806 +< \");\r\ +--- +> \");\ +2810,2811c2808,2809 +< \_do={\r\ +< \n :local Change (\$GlobalConfChanges->[ :tostr \$I ]);\r\ +--- +> \_do={\ +> \n :local Change (\$GlobalConfChanges->[ :tostr \$I ]);\ +2813,2816c2811,2813 +< \r\ +< \n [ \$SymbolForNotification \"pushpin\" \"*\" ] . \$Change);\r\ +< \n \$LogPrint info \$0 (\"Change \" . \$I . \": \" . \$Change);\r\ +< \n }\r\ +--- +> \n [ \$SymbolForNotification \"pushpin\" \"*\" ] . \$Change);\ +> \n \$LogPrint info \$0 (\"Change \" . \$I . \": \" . \$Change);\ +> \n }\ +2818,2828c2815,2824 +< ws and changes are not available.\")}\r\ +< \n\r\ +< \n :set GlobalConfChanges;\r\ +< \n :set GlobalConfMigration;\r\ +< \n }\r\ +< \n} do={\r\ +< \n :global ExitOnError; \$ExitOnError \$0 \$Err;\r\ +< \n} }\r\ +< \n\r\ +< \n# Add and fix global scheduler\r\ +< \n:put \"Add or/and fix Global scheduler...\";\r\ +--- +> ws and changes are not available.\")}\ +> \n\ +> \n :set GlobalConfChanges;\ +> \n :set GlobalConfMigration;\ +> \n }\ +> \n} do={:global ExitOnError; \$ExitOnError \$0 \$Err}\ +> \n}\ +> \n\ +> \n# Add and fix global scheduler\ +> \n:put \"Add or/and fix Global scheduler...\";\ +2830,2831c2826,2827 +< ; }\";\r\ +< \n:local Comment \"Every Day Set Global Environment Variables\";\r\ +--- +> ; }\";\ +> \n:local Comment \"Every Day Set Global Environment Variables\";\ +2833c2829 +< = 0) do={\r\ +--- +> = 0) do={\ +2835,2836c2831,2832 +< ent=\$OnEvent start-time=startup;\r\ +< \n}\r\ +--- +> ent=\$OnEvent start-time=startup;\ +> \n}\ +2838,2840c2834,2836 +< \_do={\r\ +< \n /system/scheduler/set \"AM-SetGlobalEnv\" comment=\$Comment;\r\ +< \n}\r\ +--- +> \_do={\ +> \n /system/scheduler/set \"AM-SetGlobalEnv\" comment=\$Comment;\ +> \n}\ +2842,2846c2838,2842 +< ) 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\ +--- +> ) do={\ +> \n /system/scheduler/set \"AM-SetGlobalEnv\" on-event=\$OnEvent;\ +> \n}\ +> \n# Add Update Script scheduler\ +> \n:put \"Add or/and fix Update Script scheduler\";\ +2848,2849c2844 +< \r\ +< \n:set Comment \"Every Day Check For Update Scripts\";\r\ +--- +> \n:set Comment \"Every Day Check For Update Scripts\";\ +2851c2846 +< \" ] ] = 0) do={\r\ +--- +> \" ] ] = 0) do={\ +2853,2855c2848,2864 +< start-time=startup interval=1d on-event=\$OnEvent;\r\ +< \n}\r\ +< \n:log warning (\"This script \$ScriptName Loaded \" . \\\r\ +--- +> start-time=startup interval=1d on-event=\$OnEvent;\ +> \n}\ +> \n\ +> \n#:local Resource [ /system/resource/get ];\ +> \n#:log info (\$ScriptName . \" Loaded on \" . \$Resource->\"board-name\" \ +> . \" with RouterOS \" . \$Resource->\"version\" . \" and Architecture \" .\ +> \".\");\ +> \n\ +> \n:onerror Err {\ +> \n :global GlobalConfReady;\ +> \n :retry { :if (\$GlobalConfReady != true) do={ :error (\"Global configs\ +> \_not ready.\"); }; } delay=100ms max=5;\ +> \n\ +> \n# signal we are ready\ +> \n:set GlobalFuncReady true;\ +> \n:set ExitOK true;\ +> \n:log warning (\"This script \$ScriptName Loaded \" . \\\ +2857c2866 +< \") ] . \\\r\ +--- +> \") ] . \\\ +2859,3173c2868,2873 +< \\nArchitecture: \" . \$devCurArch . \"\\nIdentity: \" . \$Identity);\r\ +< \n\r\ +< \n# signal we are ready\r\ +< \n:set GlobalFuncReady true;\r\ +< \n\r\ +< \n:do {\r\ +< \n:onerror Err {\r\ +< \n :global GlobalConfReady;\r\ +< \n :retry { :if (\$GlobalConfReady != true) \\\r\ +< \n do={ :error (\"Global config not ready.\"); }; } delay=500ms max=50;\ +< \r\ +< \n } do={\r\ +< \n :global ExitOnError; \$ExitOnError \$0 \$Err;\r\ +< \n }\r\ +< \n}\r\ +< \n" +< add comment="download, import and update firewall address-lists" \ +< dont-require-permissions=no name=AM-FwAddrLists owner=AM-FwAddrLists \ +< policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ +< source="#!rsc by Vados\r\ +< \n# RouterOS script: AM-FwAddrLists\r\ +< \n# Script comment: download, import and update firewall address-lists\r\ +< \n# Copyright (c) 2007-2026 Vados \r\ +< \n#\r\ +< \n#\r\ +< \n# requires RouterOS, version=7.19\r\ +< \n# https://ros.vados.ru/doc/fw-addr-lists.md\r\ +< \n:local ExitOK false;\r\ +< \n:onerror Err {\r\ +< \n :global GlobalConfReady; :global GlobalFuncReady;\r\ +< \n :retry { :if (\$GlobalConfReady != true || \$GlobalFuncReady != true) \ +< \\\r\ +< \n do={ :error (\"Global config and/or functions not ready.\"); }; } \ +< delay=500ms max=50;\r\ +< \n :local ScriptName [ :jobname ];\r\ +< \n\r\ +< \n :global GlobalScriptsUrl;\r\ +< \n :local FwAddrListsUrl (\$GlobalScriptsUrl . \"fw-addr-lists.d/\");\r\ +< \n :local FwAddrListsIndexUrl (\$FwAddrListsUrl . \"index\");\r\ +< \n :local FwAddrListTimeOut 1d;\r\ +< \n :local FetchMode \"\";\r\ +< \n\r\ +< \n :global CertificateAvailable;\r\ +< \n :global EitherOr;\r\ +< \n :global FetchLargeFiles;\r\ +< \n :global HumanReadableNum;\r\ +< \n :global IfThenElse;\r\ +< \n :global LogPrint;\r\ +< \n\r\ +< \n :global NetMask4;\r\ +< \n :global NetMask6;\r\ +< \n :global ScriptLock;\r\ +< \n \r\ +< \n :local FindDelim do={\r\ +< \n :local ValidChars \"0123456789.:/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghi\ +< jklmnopqrstuvwxyz-\";\r\ +< \n :for I from=0 to=([ :len \$1 ] - 1) do={\r\ +< \n :if ([ :typeof [ :find \$ValidChars [ :pick \$1 \$I ] ] ] != \"num\ +< \") do={\r\ +< \n :return \$I;\r\ +< \n }\r\ +< \n }\r\ +< \n }\r\ +< \n\r\ +< \n :local GetBranch do={\r\ +< \n :global EitherOr;\r\ +< \n :return [ :pick [ :convert transform=md5 to=hex [ :pick \$1 0 [ \$Ei\ +< therOr [ :find \$1 \"/\" ] [ :len \$1 ] ] ] ] 0 2 ];\r\ +< \n }\r\ +< \n \r\ +< \n :if ([ \$ScriptLock \$ScriptName ] = false) do={\r\ +< \n :set ExitOK true;\r\ +< \n :error false;\r\ +< \n }\r\ +< \n\r\ +< \n :if ([ :len [ /log/find where topics=({\"script\"; \"warning\"}) \\\r\ +< \n message=(\"\\\$LogPrint: The message is already in log, scripting \ +< subsystem may have crashed before!\") ] ] > 0) do={\r\ +< \n :log warning (\$ScriptName . \" Scripting subsystem may have crashed\ +< , possibly caused by us. Delaying!\");\r\ +< \n :delay 5m;\r\ +< \n }\r\ +< \n\r\ +< \n :local ListComment (\"managed by \" . \$ScriptName);\r\ +< \n :local FwAddrListsIndex false;\r\ +< \n\r\ +< \n :for I from=1 to=5 do={\r\ +< \n :if (\$FwAddrListsIndex = false) do={\r\ +< \n :set FwAddrListsIndex [ :tolf [ \$FetchLargeFiles \$ScriptName \$F\ +< wAddrListsIndexUrl true \$FetchMode ] ];\r\ +< \n :if (\$FwAddrListsIndex = false && \$I < 5) do={\r\ +< \n :log warning (\$ScriptName . \" Failed downloading address-list \ +< index, \" . \$I . \". try from: \" . \$FwAddrListsIndexUrl);\r\ +< \n :delay ((\$I * \$I) . \"s\");\r\ +< \n }\r\ +< \n }\r\ +< \n }\r\ +< \n :if (\$FwAddrListsIndex = false) do={\r\ +< \n :log warning (\$ScriptName . \" Failed downloading address-list inde\ +< x from: \" . \$FwAddrListsIndexUrl);\r\ +< \n :set FwAddrListsIndex \"\";\r\ +< \n }\r\ +< \n\r\ +< \n :foreach FwListFile in=[ :deserialize \$FwAddrListsIndex delimiter=\"\ +< \\n\" from=dsv options=dsv.plain ] do={\r\ +< \n :local FwListName (\$FwListFile->0);\r\ +< \n :local Delim [ \$FindDelim \$FwListName ];\r\ +< \n :if (\$Delim = 0) do={ :set FwListName \"\"; };\r\ +< \n :if ([ :len \$FwListName ] = 0) do={ :error true; }\r\ +< \n :set FwListName [ :pick \$FwListName 0 \$Delim ];\r\ +< \n\r\ +< \n :local FwListUrl (\$FwAddrListsUrl . \$FwListName);\r\ +< \n :local CntAdd 0;\r\ +< \n :local CntRenew 0;\r\ +< \n :local CntRemove 0;\r\ +< \n :local IPv4Addresses ({});\r\ +< \n :local IPv6Addresses ({});\r\ +< \n :local Failure false;\r\ +< \n :local Data false;\r\ +< \n :local TimeOut \$FwAddrListTimeOut;\r\ +< \n\r\ +< \n :for I from=1 to=5 do={\r\ +< \n :if (\$Data = false) do={\r\ +< \n :set Data [ :tolf [ \$FetchLargeFiles \$ScriptName \$FwListUrl t\ +< rue \$FetchMode ] ];\r\ +< \n :if (\$Data = false && \$I < 5) do={\r\ +< \n :log warning (\$ScriptName . \" Failed downloading for list '\ +< \" . \$FwListName . \"', \" . \$I . \". try from: \" . \$FwListUrl);\r\ +< \n :delay ((\$I * \$I) . \"s\");\r\ +< \n }\r\ +< \n }\r\ +< \n }\r\ +< \n\r\ +< \n :if (\$Data = false) do={\r\ +< \n :set Data \"\";\r\ +< \n :set Failure true;\r\ +< \n :log warning (\$ScriptName . \" Failed downloading for list '\" . \ +< \$FwListName . \"' from: \" . \$FwListUrl);\r\ +< \n } else={\r\ +< \n :log debug (\$ScriptName . \" Downloaded \" . [ \$HumanReadableNum\ +< \_[ :len \$Data ] 1024 ] . \"B for list '\" . \$FwListName . \"' from: \" \ +< . \$FwListUrl);\r\ +< \n }\r\ +< \n\r\ +< \n :foreach Line in=[ :deserialize \$Data delimiter=\"\\n\" from=dsv op\ +< tions=dsv.plain ] do={\r\ +< \n :set Line (\$Line->0);\r\ +< \n :local Delim [ \$FindDelim \$Line ];\r\ +< \n :if (\$Delim = 0) do={ :set Line \"\"; };\r\ +< \n :if ([ :len \$Line ] = 0) do={ :error true; }\r\ +< \n :local Address;\r\ +< \n :if ([ :pick \$Line 0 1 ] = \"{\" && [ :pick \$Line ([ :len \$Line\ +< \_] - 1) ] = \"}\") do={\r\ +< \n :do {\r\ +< \n :set Address [ :tostr ([ :deserialize from=json \$Line ]->\"ci\ +< dr\") ];\r\ +< \n } on-error={ }\r\ +< \n } else={\r\ +< \n :set Address [ :pick \$Line 0 [ \$FindDelim \$Line ] ];\r\ +< \n }\r\ +< \n :do {\r\ +< \n :local Branch;\r\ +< \n :if (\$Address ~ \"^[0-9]{1,3}\\\\.[0-9]{1,3}\\\\.[0-9]{1,3}\\\\\ +< .[0-9]{1,3}(/[0-9]{1,2})\?\\\$\") do={\r\ +< \n :local Net \$Address;\r\ +< \n :local CIDR 32;\r\ +< \n :local Slash [ :find \$Address \"/\" ];\r\ +< \n :if ([ :typeof \$Slash ] = \"num\") do={\r\ +< \n :set Net [ :toip [ :pick \$Address 0 \$Slash ] ]\r\ +< \n :set CIDR [ :pick \$Address (\$Slash + 1) [ :len \$Address ]\ +< \_];\r\ +< \n :set Address [ :tostr (([ :toip \$Net ] & [ \$NetMask4 \$CID\ +< R ]) . [ \$IfThenElse (\$CIDR < 32) (\"/\" . \$CIDR) ]) ];\r\ +< \n }\r\ +< \n :set Branch [ \$GetBranch \$Address ];\r\ +< \n :if ([ :typeof (\$IPv4Addresses->\$Branch) ] != \"array\") do=\ +< { :set (\$IPv4Addresses->\$Branch) ({}) };\r\ +< \n :set (\$IPv4Addresses->\$Branch->\$Address) \$TimeOut;\r\ +< \n :error true;\r\ +< \n }\r\ +< \n :if (\$Address ~ \"^[0-9a-zA-Z]*:[0-9a-zA-Z:\\\\.]+(/[0-9]{1,3})\ +< \?\\\$\") do={\r\ +< \n :local Net \$Address;\r\ +< \n :local CIDR 128;\r\ +< \n :local Slash [ :find \$Address \"/\" ];\r\ +< \n :if ([ :typeof \$Slash ] = \"num\") do={\r\ +< \n :set Net [ :toip6 [ :pick \$Address 0 \$Slash ] ]\r\ +< \n :set CIDR [ :pick \$Address (\$Slash + 1) [ :len \$Address ]\ +< \_];\r\ +< \n }\r\ +< \n :set Address (([ :toip6 \$Net ] & [ \$NetMask6 \$CIDR ]) . \"/\ +< \" . \$CIDR);\r\ +< \n :set Branch [ \$GetBranch \$Address ];\r\ +< \n :if ([ :typeof (\$IPv6Addresses->\$Branch) ] != \"array\") do=\ +< { :set (\$IPv6Addresses->\$Branch) ({}) };\r\ +< \n :set (\$IPv6Addresses->\$Branch->\$Address) \$TimeOut;\r\ +< \n :error true;\r\ +< \n }\r\ +< \n :if (\$Address ~ \"^[\\\\.a-zA-Z0-9-]+\\\\.[a-zA-Z]{2,}\\\$\") d\ +< o={\r\ +< \n :set Branch [ \$GetBranch \$Address ];\r\ +< \n :if ([ :typeof (\$IPv4Addresses->\$Branch) ] != \"array\") do=\ +< { :set (\$IPv4Addresses->\$Branch) ({}) };\r\ +< \n :if ([ :typeof (\$IPv6Addresses->\$Branch) ] != \"array\") do=\ +< { :set (\$IPv6Addresses->\$Branch) ({}) };\r\ +< \n :set (\$IPv4Addresses->\$Branch->\$Address) \$TimeOut;\r\ +< \n :set (\$IPv6Addresses->\$Branch->\$Address) \$TimeOut;\r\ +< \n :error true;\r\ +< \n }\r\ +< \n } on-error={:log error (\$ScriptName . \" Failed parsing address: \ +< \" . \$Line->0);}\r\ +< \n }\r\ +< \n\r\ +< \n :foreach Entry in=[ /ip/firewall/address-list/find where \\\r\ +< \n list=\$FwListName comment=\$ListComment ] do={\r\ +< \n :local Address [ /ip/firewall/address-list/get \$Entry address ];\ +< \r\ +< \n :local Branch [ \$GetBranch \$Address ];\r\ +< \n :local TimeOut (\$IPv4Addresses->\$Branch->\$Address);\r\ +< \n :if ([ :typeof \$TimeOut ] = \"time\") do={\r\ +< \n :log debug (\$ScriptName . \" Renewing IPv4 address \" . \$Addre\ +< ss . \\\r\ +< \n \" in list '\" . \$FwListName . \"' with \" . \$TimeOut . \"\ +< .\");\r\ +< \n /ip/firewall/address-list/set \$Entry timeout=\$TimeOut;\r\ +< \n :set (\$IPv4Addresses->\$Branch->\$Address);\r\ +< \n :set CntRenew (\$CntRenew + 1);\r\ +< \n } else={\r\ +< \n :if (\$Failure = false) do={\r\ +< \n :log debug (\$ScriptName . \" Removing IPv4 address \" . \$Add\ +< ress . \\\r\ +< \n \" from list '\" . \$FwListName . \".\");\r\ +< \n /ip/firewall/address-list/remove \$Entry;\r\ +< \n :set CntRemove (\$CntRemove + 1);\r\ +< \n }\r\ +< \n }\r\ +< \n }\r\ +< \n\r\ +< \n :foreach Entry in=[ /ipv6/firewall/address-list/find where \\\r\ +< \n list=\$FwListName comment=\$ListComment ] do={\r\ +< \n :local Address [ /ipv6/firewall/address-list/get \$Entry address ]\ +< ;\r\ +< \n :local Branch [ \$GetBranch \$Address ];\r\ +< \n :local TimeOut (\$IPv6Addresses->\$Branch->\$Address);\r\ +< \n :if ([ :typeof \$TimeOut ] = \"time\") do={\r\ +< \n :log debug (\$ScriptName . \" Renewing IPv6 address \" . \$Addre\ +< ss . \\\r\ +< \n \" in list '\" . \$FwListName . \"' with \" . \$TimeOut . \"\ +< .\");\r\ +< \n /ipv6/firewall/address-list/set \$Entry timeout=\$TimeOut;\r\ +< \n :set (\$IPv6Addresses->\$Branch->\$Address);\r\ +< \n :set CntRenew (\$CntRenew + 1);\r\ +< \n } else={\r\ +< \n :if (\$Failure = false) do={\r\ +< \n :log debug (\$ScriptName . \" Removing IPv6 address \" . \$Add\ +< ress . \\\r\ +< \n \" from list '\" . \$FwListName .\".\");\r\ +< \n /ipv6/firewall/address-list/remove \$Entry;\r\ +< \n :set CntRemove (\$CntRemove + 1);\r\ +< \n }\r\ +< \n }\r\ +< \n }\r\ +< \n\r\ +< \n :foreach BranchName,Branch in=\$IPv4Addresses do={\r\ +< \n :log debug (\$ScriptName . \" Handling branch: \" . \$BranchName);\ +< \r\ +< \n :foreach Address,Timeout in=\$Branch do={\r\ +< \n :log debug (\$ScriptName . \" Adding IPv4 address \" . \$Address\ +< \_. \\\r\ +< \n \" to list '\" . \$FwListName . \"' with \" . \$Timeout . \"\ +< .\");\r\ +< \n :onerror Err {\r\ +< \n /ip/firewall/address-list/add list=\$FwListName comment=\$List\ +< Comment \\\r\ +< \n address=\$Address timeout=\$Timeout;\r\ +< \n :set CntAdd (\$CntAdd + 1);\r\ +< \n } do={\r\ +< \n :log warning (\$ScriptName . \" Failed to add IPv4 address \" \ +< . \$Address . \\\r\ +< \n \" to list '\" . \$FwListName . \"': \" . \$Err);\r\ +< \n }\r\ +< \n }\r\ +< \n }\r\ +< \n\r\ +< \n :foreach BranchName,Branch in=\$IPv6Addresses do={\r\ +< \n :log debug (\$ScriptName . \" Handling branch: \" . \$BranchName);\ +< \r\ +< \n :foreach Address,Timeout in=\$Branch do={\r\ +< \n :log debug (\$ScriptName . \" Adding IPv6 address \" . \$Address\ +< \_. \\\r\ +< \n \" to list '\" . \$FwListName . \"' with \" . \$Timeout . \"\ +< .\");\r\ +< \n :onerror Err {\r\ +< \n /ipv6/firewall/address-list/add list=\$FwListName comment=\$Li\ +< stComment \\\r\ +< \n address=\$Address timeout=\$Timeout;\r\ +< \n :set CntAdd (\$CntAdd + 1);\r\ +< \n } do={\r\ +< \n :log warning (\$ScriptName . \" Failed to add IPv6 address \" \ +< . \$Address . \\\r\ +< \n \" to list '\" . \$FwListName . \"': \" . \$Err);\r\ +< \n }\r\ +< \n }\r\ +< \n }\r\ +< \n\r\ +< \n :log info (\$ScriptName . \" list: \" . \$FwListName . \\\r\ +< \n \" (\" . [ \$HumanReadableNum (\$CntAdd + \$CntRenew) 1000 ] . \ +< \")\" . \\\r\ +< \n \" -- added: \" . [ \$HumanReadableNum \$CntAdd 1000 ] . \\\r\ +< \n \" - renewed: \" . [ \$HumanReadableNum \$CntRenew 1000 ] . \\\r\ +< \n \" - removed: \" . [ \$HumanReadableNum \$CntRemove 1000 ]);\r\ +< \n }\r\ +< \n} do={\r\ +< \n :global ExitError; \$ExitError \$ExitOK [ :jobname ] \$Err;\r\ +< \n}\r\ +--- +> \\nArchitecture: \" . \$devCurArch . \"\\nIdentity: \" . \$Identity);\ +> \n} do={:global ExitOnError; \$ExitOnError \$0 \$Err;}\ +> \n\ +> \n#} do={:global ExitError; \$ExitError \$ExitOK [ :jobname ] \$Err}\ +> \n# log the successful load of the script, or an error if it failed\ +> \n#:if ([\$GlobalFuncReady] = true && [\$GlobalConfReady] = true) do={\ -- 2.52.0