/system script environment
:foreach item in=[find] do={
:local vname [get $item name]
:local vvalue [get $item value]
:if ($vvalue~"^\\*") do={:set vvalue "ID$vvalue"}
:if ($vvalue~"^(\\(code\\)|;\?\\(eva\?l )") do={:set vvalue "(code)"}
/ip firewall layer7
remove [find where name=$vname]
add name=$vname comment="$vvalue"
:delay 10ms
:execute "/ip firewall layer7 set [find where name=$vname] regexp=[:typeof \$$vname]"
:if ($vvalue="(code)") do={:delay 10ms ; set [find where name=$vname] regexp="code"}
}
/ip firewall layer7
:foreach item in=[find where regexp~"^(array|bool|code|id|ip|ip-prefix|ip6|ip6-prefix|lookup|nil|nothing|num|str|time)\$"] do={
:local vname [get $item name]
:local vvalue [get $item comment]
:local vtype [get $item regexp]
/system script environment
remove [find where name=$vname]
:if ($vtype~"^(array|ip|ip6|num|str|time)\$") do={
:execute ":global $vname [:to$vtype [/ip firewall layer7 get [find where name=$vname] comment]]"
} else={
:if ($vtype~"^(bool|id|ip-prefix|ip6-prefix|lookup|nil|nothing)\$") do={
:if ($vtype="bool") do={:execute ":global $vname [:tobool $vvalue]"}
:if ($vtype="id") do={:execute ":global $vname [:toid $[:pick $vvalue [:find $vvalue "*" -1] [:len $vvalue]]]"}
:if (($vtype="ip-prefix") or \
($vtype="ip6-prefix")) do={:execute ":global $vname [[:parse \":return $vvalue\"]]"}
:if ($vtype="lookup") do={:execute ":global $vname \"\$$vname\""}
:if ($vtype="nil") do={:execute ":global $vname"}
:if ($vtype="nothing") do={:execute ":global $vname [:nothing]"}
} else={
# vtype="code"
:log error "Unknow variable >$vname< of type >$vtype<"
:execute ":global $vname [/ip firewall layer7 get [find where name=$vname] comment]"
}
}
:delay 10ms
}
:if ($vtype = "bool") do={
[[:parse ":global $vname [:to$vtype $[/ip firewall layer7 get [find where name=$vname] regexp]]"]]}
:if ($vvalue = "(function)") do={:set vtype "function" }
When restoring, restoring boolean variables via :execute does not work for me,
all boolean variables are restored as nil (have no values).
I had to insert such a check and restore via :parseCode: Select all:if ($vtype = "bool") do={ [[:parse ":global $vname [:to$vtype $[/ip firewall layer7 get [find where name=$vname] regexp]]"]]}
:if ($vtype="bool") do={:execute ":global $vname [:tobool $vvalue]"}
#
# The function of saving/restoring global environment variables v 01/06/2022
# $1 parameter can take values:
# "save" - saving global variables in /ip firewall layer7
# "recover" - restoring global variables from layer7
# "erase" - cleaning layer7 only ! from global variables
# "print" - printing to the log and terminal of the list of variables located at the time of printing in Layer7
#
:global FuncGlobal do={
:if ([:typeof $0]="lookup") do={
:local count 0
:if (($1="save") or ($1="recover") or ($1="erase") or ($1="print")) do={
:if ($1="save") do={
/system script environment
:foreach item in=[find] do={
:local vname [get $item name]
:local vvalue [get $item value]
/ip firewall layer7
remove [find where name=$vname]
:if (([:typeof [:find [:tostr $vvalue] "(eval " -1]] = "nil") and ([:typeof [:find [:tostr $vvalue] "(evl " -1]] = "nil")) do={
:if ([:find $vvalue "*" -1] = 0) do={:set vvalue "ID$vvalue"}
add name=$vname regex="$vvalue"
:set count ($count+1)
}
:delay 10ms
:execute "/ip firewall layer7 set [find where name=$vname] comment=[:typeof \$$vname]"
}
:log warning ("Function $0 has saved $count variables")
:return $count}
:if ($1="recover") do={
/ip firewall layer7
:foreach item in=[find where comment~"^(array|bool|id|ip|ip-prefix|ip6|ip6-prefix|num|str|time|code|nothing|nil)\$"] do={
:set count ($count+1)
:local vname [get $item name]
:local vvalue [get $item regexp]
:local vtype [get $item comment]
# :if ($vvalue = "(function)") do={:set vtype "function" }
/system script environment
remove [find where name=$vname]
:if ($vtype~"^(array|bool|id|ip|ip6|num|str|time)\$") do={
:if ($vtype = "id") do={
:set vvalue [:pick $vvalue [:find $vvalue "*" -1] [:len $vvalue]]
:execute ":global $vname [:to$vtype $vvalue]"}
:if ($vtype = "bool") do={
[[:parse ":global $vname [:to$vtype $[/ip firewall layer7 get [find where name=$vname] regexp]]"]]
# :if ($vtype="bool") do={:execute ":global $vname [:tobool $vvalue]"}
} else={
:execute ":global $vname [:to$vtype [/ip firewall layer7 get [find where name=$vname] regexp]]"
}
} else={
:if ($vtype~"^(ip-prefix|ip6-prefix|nothing|nil)\$") do={
:if ($vtype~"^(ip-prefix|ip6-prefix)\$") do={:execute ":global $vname [[:parse \":return $vvalue\"]]"}
:if ($vtype="nothing") do={:execute ":global $vname [:nothing]"}
:if ($vtype="nil") do={:execute ":global $vname"}
} else={
:log error "Unknow variable type >$vtype<"
:execute ":global $vname [/ip firewall layer7 get [find where name=$vname] regexp]"
}
}
:delay 10ms;
}
:log warning ("Function $0 restored $count variables")
:return $count}
:if ($1="erase") do={
/ip firewall layer7
:foreach item in=[find where comment~"^(array|bool|id|ip|ip-prefix|ip6|ip6-prefix|num|str|time|code|nothing|nil)\$"] do={remove $item; :set count ($count+1)
}
:log warning ("The repository has been cleared of $count global variables")
:return $count}
:if ($1="print") do={
/ip firewall layer7
:foreach item in=[find where comment~"^(array|bool|id|ip|ip-prefix|ip6|ip6-prefix|num|str|time|code|nothing|nil)\$"] do={
:set count ($count+1)
:local vname [get $item name];
:local vvalue [get $item regexp];
:local vtype [get $item comment];
:put ("$vname "."$vtype "."$vvalue");
:log info ("$vname "."[ $vtype ] "."$vvalue");
}
:log warning ("In Layer7 repository has $count global variables")
:put ("In Layer7 repository has $count global variables")
:return $count}
} else={
:if ([:typeof $1]="nothing") do={:log error ("The function $0 parameter is not set"); :return ("Error $0")}}
:log error ("The function $0 parameter is not valid"); :return ("Error $0");
}
}
# usage examples:
# :log info [$FuncGlobal save]
# :log info [$FuncGlobal recover]
# :log info [$FuncGlobal erase]
# :log info [$FuncGlobal print]
# examples of erroneous usage:
# :log info [$FuncGlobal]
# :log info [$FuncGlobal anovertext]
You try the "new version" if do same error?...
Hi Rex,You try the "new version" if do same error?
EEEEEEEHHHHHHHHHHHHH???????????[…] it is now possible to save/restore the content of a function. Congratulations!
I am going to capture screenshots, just a secondEEEEEEEHHHHHHHHHHHHH???????????[…] it is now possible to save/restore the content of a function. Congratulations!
look at the screenshotsCheck twice.... after reboot....
If the function is
:global f do={ /interface print }
It's normal this:
:put [$f]
(function)
Is just a text "(function)" or another script set again the function correctly...
You are right, some functions are not restored properly. With the last modification you have made now save the functions as "(function)" in the comments.Yes, but the function work?
Is easy copy & paste the "eval / evl" code, but is restored just as string...
on the code is present:
:if ($vvalue~"\\(eval|evl) ") do={:set vvalue "(function)"}
is missing one (another) ( before eval, now the script is fixed
Completely nonsense: if a "virus" has access to the routerboard, it doesn't give a damn about "reading" functions from Layer7,If the Mikrotik developers allow saving the function code in Layer7 and restoring it from there ... this can lead to both good (for example, creating copyright protection) and dangerous consequences (for example, creating virus scripts)
:put [:typeof (>[])]
????????????????????????????????????????????????????????????I found another lost data type:
Return:Code: Select all:put [:typeof (>[])]
op
this data type behaves like code
I found another lost data type:
:global optype (>[:global z "blah"])
$optype
:put $z
# "blah"
:global optype (>[:do {:put "$1"}])
:put [:typeof $optype]
# op
$optype "hmm"
# hmm
:put $optype
# (evl (evl /docommand=;(evl (evl /putmessage=$1))))
:global shortThanToArray (>{})
:put "$shortThanToArray $[:typeof $shortThanToArray] $[:len $shortThanToArray]"
# array 0
Columns: TYPE, COMPLETION, STYLE, OFFSET, PREFERENCE, SHOW
TYPE COMPLETION STYLE OFFSET PREFERENCE SHOW
completion none 2 80 no
completion ( syntax-meta 2 75 no
completion $ syntax-meta 2 75 no
completion [ syntax-meta 2 75 no
completion { syntax-meta 2 75 no
completion " syntax-meta 2 75 no
completion ! syntax-meta 2 75 no
completion - syntax-meta 2 75 no
completion ~ syntax-meta 2 75 no
completion > syntax-meta 2 75 no
completion syntax-meta 2 75 no
completion <value> none 2 -1 no
:put $varWithCodeDataType
or
:put [ :parse "local var" ]
or
:put ( $function->1 )
:put [ /system script environment get [ find name="globalFunction" ] value ]
/environment print
(evl /localname=$var)
{(evl [/local{name=$var}])}
:global arraytest {"a";"b";"c";{"q";"z"}} :put $arraytest :global pointer (>($arraytest->1)) :put $pointer :put [$pointer] :set ($arraytest->1) "x" :put $arraytest :put $pointer :put [$pointer] :set [$pointer] "W" :set pointer "J" :put $arraytest :put $pointer :put [$pointer] :global pointer (>($arraytest->3)) :put $pointer :put [$pointer] :put ([$pointer]->1) :set ([$pointer]->1) "RR" :put $pointer :put [$pointer] :put $arraytest
Anyway to use this data type to write a script that uses mac-telnet to log into another device by MAC address and execute a command? Something I've been struggling with since there seems to be no way to pass credentials into the mac-telnet command once you launch it. (and since someone will suggest it, no I cannot SSH into the device, this need exists in situations where there is no IP address defined on a device, it is ONLY accessible via mac-telnet)I found another lost data type:
Return:Code: Select all:put [:typeof (>[])]
op
this data type behaves like code
The break is mainly in the regex part. could you please double check? Thanks:if ($vvalue~"^(\(code\)|;\\(eva\?l )") do={:set $vvalue "(code)"};
Hi Rex. The code seams to break in ROS 7.11 stable. for the store script
The break is mainly in the regex part. could you please double check? Thanks:if ($vvalue~"^(\(code\)|;\\(eva\?l )") do={:set $vvalue "(code)"};
Only simple arrays are exported, do not work for array of array and more complex data structure.