Community discussions

MikroTik App
 
User avatar
Sertik
Member
Member
Topic Author
Posts: 435
Joined: Fri Sep 25, 2020 3:30 pm
Location: Russia, Moscow

Function of transferring the script over SSH

Thu Jan 19, 2023 6:21 pm

In continuation of the topic, viewtopic.php?t=174803#p976428 (where did we manage to figure out how to pass the function) wrote a script transfer function from one router to another. I had to use ftp for transmission, and SSH for placement in the repository and launch. I couldn't pass the script through a variable. This is a test version, and it works. The bad thing about it is that it is probably not rational: it uses two services and writes to flash, which is bad for Microtics with flash memory. I will be glad if someone points out how to transfer the script in another way, without ftp.

#  < SSHtransfer > function of forwarding the SSH client script to the SSH server
#  by Sertik 19/01/2023
# use SSH and ftp
# to work, you need to configure the local variables parameters for ftp: fport 21, fuser and fpassword (see below)
# the length of the portable script is limited to 4096 bytes
#

# $1 - address SSH-server
# $2 - port SSH service
# $3 - userName SSH-server
# $4 - name of the source script
# $5 - dst script name
# $6 - "run", if you need to execute the transmitted script immediately

# examples usage:
#   :put [$SSHtransfer 192.168.1.2 22 admin sourceScript DstScript]
#   :put [$SSHtransfer 192.168.1.2 22 admin sourceScript DstScript run]


:global SSHtransfer do={

# fetch ftp transfer parametrs:

# :local fport 21
# :local fuser admin
# :local fpassword "user`s password"

:if ([:len $1]=0) do={:return "Error IP SSH-Server"}
do {:set $1 [:toip $1]} on-error={:return "Error syntax address IP SSH-Server"}
:if (!any $2) do={:return "Error port"}
do {:set $2 [:tonum $2]} on-error={:return "Error syntax port"}
:if ([:len $3]=0) do={:return "Error username"}
:if ([:len $4]=0) do={:return "Error Source Script name not set"}
:if ([:len $5]=0) do={:return "Error Dst Script name on SSH-server not set"}
:if (([:len $6]>0) && ($6!="run")) do={:return "Error parametr \$6 $6"}

:if ([:len [/system script find name=$4]]=0) do={:return "Error Source Script $4 no find in repository router SSH-client"}
:if ([:len [/system script get $4 source]]>4096) do={:return "Error long source script"}

    :global fileContent
       :if ([:len [/file find name="transferSSH.txt"]]>0) do={[/file remove transferSSH.txt]}
        :delay 1s
       /file print file=transferSSH.txt;
   do {
          :set fileContent [/system script get $4 source]
       :delay 3s
         :execute script=":put [/system script get \"$4\" source]" file="transferSSH.txt"
           } on-error={
                  [/file remove transferSSH.txt]
                  :set fileContent
                  :return "Error script to long"}
         :delay 3s
  do {
        /tool fetch address=$1 port=$fport src-path=transferSSH.txt user=$fuser mode=ftp password=$fpassword dst-path=tSSH.rsc upload=yes
           } on-error={:set fileContent; [/file remove transferSSH.txt]; :return "Error ftp transfer script on SSH-server"}
         :delay 3s
:set  fileContent
[/file remove transferSSH.txt]
  :if ($6!="run") do={
  :do {
         [/system ssh-exec address=$1 port=$2 user=$3 command=":if ([:len [/system script find name=\"$5\"]]>0) do={/system script remove \"$5\"}; \
        /system script add name=\"$5\" source=[/file get tSSH.rsc contents]; :delay 2s; /file remove tSSH.rsc"]; \ 
      } on-error={:return "Error add script $5 in SSH-server repository"}
   } else={\
     :do {
         [/system ssh-exec address=$1 port=$2 user=$3 command=":if ([:len [/system script find name=\"$5\"]]>0) do={/system script remove \"$5\"}; \
        /system script add name=\"$5\" source=[/file get tSSH.rsc contents]; :delay 3s; /file remove tSSH.rsc; \
        :put RUN;\
        /system script run \"$5\""]
      } on-error={:return "Error add script $5 in SSH-server repository or run"}
   :set $6 ("and $6")
   }

  :return "Done: Script $5 add to SSH-server repository $6"
}
# Call examples:
:local Answer [$SSHtransfer 192.168.1.2 22 admin sourceScript DstScript] 
:if ([:len [:find $Answer "Error"]]!=0) do={:log error $Answer} else={:log warning $Answer}

:local Answer [$SSHtransfer 192.168.1.2 22 admin sourceScript DstScript run] 
:if ([:len [:find $Answer "Error"]]!=0) do={:log error $Answer} else={:log warning $Answer}

I will be glad to comments and criticism. I hope someone will suggest a better and more rational option
 
User avatar
Sertik
Member
Member
Topic Author
Posts: 435
Joined: Fri Sep 25, 2020 3:30 pm
Location: Russia, Moscow

Re: Function of transferring the script over SSH

Thu Jan 19, 2023 8:37 pm

As I am adding to myself:

instead of the string:
/system script add name=\"$5\" source=[/file get tSSH.rsc contents]; :delay 2s; /file remove tSSH.rsc"]; \ 

you can use the string:
:import file=tSSH.rsc; :delay 2s; /file remove tSSH.rsc"]; \ 

This allows you to overcome the limitation of the length of the transferred script 4Kb and allows you to transfer scripts 63Kb and maybe more, did not check.
But, at the same time, the script is immediately executed, but not added to the repository ... That's a pity ...
 
zainarbani
Frequent Visitor
Frequent Visitor
Posts: 54
Joined: Thu Jul 22, 2021 9:42 am
Location: Pati, Indonesia

Re: Function of transferring the script over SSH

Fri Jan 20, 2023 10:45 am

Maybe using REST API?
# Rest API endpoint
:local restUrl "https://hostname/rest";

# Rest API creds
:local restUser "admin";
:local restPassw "passwd";

# Script to send
:local scrName "myScr";
:local scrPolicy "read,write,policy";
:local scrSource ":log warning \\\"Hi From REST\\\"";

# HTTP Headers
:set $httpHdr ("content-type: application/json");

# Delete script if exists, coz no "PATCH" methods
:set $chkScr ([/tool fetch http-method="get" url=("$restUrl/system/script\?name=$scrName") http-header-field=$httpHdr user=$restUser password=$restPassw output=user as-value]->"data");
:if ([:len $chkScr] != 2) do={
 :set $scrId [:pick $chkScr ([:find $chkScr "\".id\":\""]+7) [:find $chkScr "\","]];
 /tool fetch http-method="delete" url=("$restUrl/system/script/$scrId") http-header-field=$httpHdr user=$restUser password=$restPassw output=none
}

# Send script
:set $payld ("{\"name\":\"$scrName\",\"source\":\"$scrSource\",\"policy\":\"$scrPolicy\"}");
:set $makeScr ([/tool fetch http-method="put" url=("$restUrl/system/script") http-data=$payld http-header-field=$httpHdr user=$restUser password=$restPassw output=user as-value]->"data");
:set $scrId [:pick $makeScr ([:find $makeScr "\".id\":\""]+7) [:find $makeScr "\","]];

# Run script
:set $payld ("{\".id\":\"$scrId\"}");
/tool fetch http-method="post" url=("$restUrl/system/script/run") http-data=$payld http-header-field=$httpHdr user=$restUser password=$restPassw output=none

 
User avatar
Sertik
Member
Member
Topic Author
Posts: 435
Joined: Fri Sep 25, 2020 3:30 pm
Location: Russia, Moscow

Re: Function of transferring the script over SSH

Fri Jan 20, 2023 10:58 am

Thanks ! Very cool ! Your script will definitely come in handy.
But, unfortunately, the REST API only works on ROS7, and I would like to do it universally for both 6 and 7
 
zainarbani
Frequent Visitor
Frequent Visitor
Posts: 54
Joined: Thu Jul 22, 2021 9:42 am
Location: Pati, Indonesia

Re: Function of transferring the script over SSH

Fri Jan 20, 2023 11:32 am

I dont think there's any way to interract with routeros machine besides SSH.
Also, translate something like this to .rsc lang likely impossible.
What kind of script you'r going to send btw?
 
User avatar
Sertik
Member
Member
Topic Author
Posts: 435
Joined: Fri Sep 25, 2020 3:30 pm
Location: Russia, Moscow

Re: Function of transferring the script over SSH

Fri Jan 20, 2023 11:56 am

I want to have (write) a universal function that could send any repository scripts. Mine is limited to sending scripts with a length of 4096 bytes. Moreover, it can save a script of any length as a file, it can also transmit any length. When /system script add on the SHH server, a script larger than 4096 bytes is added as an empty script, i.e. the restriction is here. With /import, you can pass scripts of any length, but they are not added to the repository if they themselves do not have the /system script add instruction, and for some reason they are executed immediately, although this is not always necessary.
 
zainarbani
Frequent Visitor
Frequent Visitor
Posts: 54
Joined: Thu Jul 22, 2021 9:42 am
Location: Pati, Indonesia

Re: Function of transferring the script over SSH

Fri Jan 20, 2023 12:00 pm

How about using something like pastebin service?
 
User avatar
Sertik
Member
Member
Topic Author
Posts: 435
Joined: Fri Sep 25, 2020 3:30 pm
Location: Russia, Moscow

Re: Function of transferring the script over SSH

Fri Jan 20, 2023 12:13 pm

I would not like to use an external service, the task is to implement everything by means of Mikrotik.
 
User avatar
Sertik
Member
Member
Topic Author
Posts: 435
Joined: Fri Sep 25, 2020 3:30 pm
Location: Russia, Moscow

Re: Function of transferring the script over SSH

Wed Jan 25, 2023 4:19 pm

P/S for Rex... What I'm not happy about in my function:

1. That it uses two services ssh and ftp. You can, of course, configure both services on the same port, but somehow it seems crooked to me ...
2. with /import, you can transfer a script up to 40 kB, but the script does not fit into the repository, but immediately starts on the fly and disappears into nowhere.
3.I can't get around the 4096 bytes limit of the passed script without /import
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Function of transferring the script over SSH

Wed Jan 25, 2023 4:21 pm

... done ...
Last edited by rextended on Wed Jan 25, 2023 6:48 pm, edited 1 time in total.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Function of transferring the script over SSH

Wed Jan 25, 2023 4:39 pm

... done ...
Last edited by rextended on Wed Jan 25, 2023 6:47 pm, edited 1 time in total.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Function of transferring the script over SSH

Wed Jan 25, 2023 6:11 pm

search tag # rextended escape script

This function escape the string like when the script is exported on .rsc or printed on terminal:
:global escape do={
    :local ascii "\00\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\
                  \10\11\12\13\14\15\16\17\18\19\1A\1B\1C\1D\1E\1F\
                  \20\21\22\23\24\25\26\27\28\29\2A\2B\2C\2D\2E\2F\
                  \30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\
                  \40\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\
                  \50\51\52\53\54\55\56\57\58\59\5A\5B\5C\5D\5E\5F\
                  \60\61\62\63\64\65\66\67\68\69\6A\6B\6C\6D\6E\6F\
                  \70\71\72\73\74\75\76\77\78\79\7A\7B\7C\7D\7E\7F\
                  \80\81\82\83\84\85\86\87\88\89\8A\8B\8C\8D\8E\8F\
                  \90\91\92\93\94\95\96\97\98\99\9A\9B\9C\9D\9E\9F\
                  \A0\A1\A2\A3\A4\A5\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\
                  \B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\
                  \C0\C1\C2\C3\C4\C5\C6\C7\C8\C9\CA\CB\CC\CD\CE\CF\
                  \D0\D1\D2\D3\D4\D5\D6\D7\D8\D9\DA\DB\DC\DD\DE\DF\
                  \E0\E1\E2\E3\E4\E5\E6\E7\E8\E9\EA\EB\EC\ED\EE\EF\
                  \F0\F1\F2\F3\F4\F5\F6\F7\F8\F9\FA\FB\FC\FD\FE\FF"
    :local ASCIItoESCAPE {"\\00";"\\01";"\\02";"\\03";"\\04";"\\05";"\\06";"\\a";"\\b";"\\t";"\\n";"\\v";"\\f";"\\r";"\\0E";"\\0F";
                          "\\10";"\\11";"\\12";"\\13";"\\14";"\\15";"\\16";"\\17";"\\18";"\\19";"\\1A";"\\1B";"\\1C";"\\1D";"\\1E";"\\1F";
                          " ";"!";"\\\"";"#";"\\\$";"%";"&";"'";"(";")";"*";"+";",";"-";".";"/";
                          "0";"1";"2";"3";"4";"5";"6";"7";"8";"9";":";";";"<";"=";">";"\\\?";
                          "@";"A";"B";"C";"D";"E";"F";"G";"H";"I";"J";"K";"L";"M";"N";"O";
                          "P";"Q";"R";"S";"T";"U";"V";"W";"X";"Y";"Z";"[";"\\\\";"]";"^";"_";
                          "`";"a";"b";"c";"d";"e";"f";"g";"h";"i";"j";"k";"l";"m";"n";"o";
                          "p";"q";"r";"s";"t";"u";"v";"w";"x";"y";"z";"{";"|";"}";"~";"\\7F";
                          "\\80";"\\81";"\\82";"\\83";"\\84";"\\85";"\\86";"\\87";"\\88";"\\89";"\\8A";"\\8B";"\\8C";"\\8D";"\\8E";"\\8F";
                          "\\90";"\\91";"\\92";"\\93";"\\94";"\\95";"\\96";"\\97";"\\98";"\\99";"\\9A";"\\9B";"\\9C";"\\9D";"\\9E";"\\9F";
                          "\\A0";"\\A1";"\\A2";"\\A3";"\\A4";"\\A5";"\\A6";"\\A7";"\\A8";"\\A9";"\\AA";"\\AB";"\\AC";"\\AD";"\\AE";"\\AF";
                          "\\B0";"\\B1";"\\B2";"\\B3";"\\B4";"\\B5";"\\B6";"\\B7";"\\B8";"\\B9";"\\BA";"\\BB";"\\BC";"\\BD";"\\BE";"\\BF";
                          "\\C0";"\\C1";"\\C2";"\\C3";"\\C4";"\\C5";"\\C6";"\\C7";"\\C8";"\\C9";"\\CA";"\\CB";"\\CC";"\\CD";"\\CE";"\\CF";
                          "\\D0";"\\D1";"\\D2";"\\D3";"\\D4";"\\D5";"\\D6";"\\D7";"\\D8";"\\D9";"\\DA";"\\DB";"\\DC";"\\DD";"\\DE";"\\DF";
                          "\\E0";"\\E1";"\\E2";"\\E3";"\\E4";"\\E5";"\\E6";"\\E7";"\\E8";"\\E9";"\\EA";"\\EB";"\\EC";"\\ED";"\\EE";"\\EF";
                          "\\F0";"\\F1";"\\F2";"\\F3";"\\F4";"\\F5";"\\F6";"\\F7";"\\F8";"\\F9";"\\FA";"\\FB";"\\FC";"\\FD";"\\FE";"\\FF"
                         }
    :local string $1
    :if (([:typeof $string] != "str") or ($string = "")) do={ :return "" }
    :local lenstr [:len $string]
    :local constr ""
    :for pos from=0 to=($lenstr - 1) do={
        :local esc ($ASCIItoESCAPE->[:find $ascii [:pick $string $pos ($pos + 1)] -1])
        :set constr "$constr$esc"
    }
    :return $constr
}
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Function of transferring the script over SSH

Wed Jan 25, 2023 6:50 pm

This function transfer a script by SSH without using any additional methods beyond SSH:

set code

:global escape do={
    :local ascii "\00\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\
                  \10\11\12\13\14\15\16\17\18\19\1A\1B\1C\1D\1E\1F\
                  \20\21\22\23\24\25\26\27\28\29\2A\2B\2C\2D\2E\2F\
                  \30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\
                  \40\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\
                  \50\51\52\53\54\55\56\57\58\59\5A\5B\5C\5D\5E\5F\
                  \60\61\62\63\64\65\66\67\68\69\6A\6B\6C\6D\6E\6F\
                  \70\71\72\73\74\75\76\77\78\79\7A\7B\7C\7D\7E\7F\
                  \80\81\82\83\84\85\86\87\88\89\8A\8B\8C\8D\8E\8F\
                  \90\91\92\93\94\95\96\97\98\99\9A\9B\9C\9D\9E\9F\
                  \A0\A1\A2\A3\A4\A5\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\
                  \B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\
                  \C0\C1\C2\C3\C4\C5\C6\C7\C8\C9\CA\CB\CC\CD\CE\CF\
                  \D0\D1\D2\D3\D4\D5\D6\D7\D8\D9\DA\DB\DC\DD\DE\DF\
                  \E0\E1\E2\E3\E4\E5\E6\E7\E8\E9\EA\EB\EC\ED\EE\EF\
                  \F0\F1\F2\F3\F4\F5\F6\F7\F8\F9\FA\FB\FC\FD\FE\FF"
    :local ASCIItoESCAPE {"\\00";"\\01";"\\02";"\\03";"\\04";"\\05";"\\06";"\\a";"\\b";"\\t";"\\n";"\\v";"\\f";"\\r";"\\0E";"\\0F";
                          "\\10";"\\11";"\\12";"\\13";"\\14";"\\15";"\\16";"\\17";"\\18";"\\19";"\\1A";"\\1B";"\\1C";"\\1D";"\\1E";"\\1F";
                          " ";"!";"\\\"";"#";"\\\$";"%";"&";"'";"(";")";"*";"+";",";"-";".";"/";
                          "0";"1";"2";"3";"4";"5";"6";"7";"8";"9";":";";";"<";"=";">";"\\\?";
                          "@";"A";"B";"C";"D";"E";"F";"G";"H";"I";"J";"K";"L";"M";"N";"O";
                          "P";"Q";"R";"S";"T";"U";"V";"W";"X";"Y";"Z";"[";"\\\\";"]";"^";"_";
                          "`";"a";"b";"c";"d";"e";"f";"g";"h";"i";"j";"k";"l";"m";"n";"o";
                          "p";"q";"r";"s";"t";"u";"v";"w";"x";"y";"z";"{";"|";"}";"~";"\\7F";
                          "\\80";"\\81";"\\82";"\\83";"\\84";"\\85";"\\86";"\\87";"\\88";"\\89";"\\8A";"\\8B";"\\8C";"\\8D";"\\8E";"\\8F";
                          "\\90";"\\91";"\\92";"\\93";"\\94";"\\95";"\\96";"\\97";"\\98";"\\99";"\\9A";"\\9B";"\\9C";"\\9D";"\\9E";"\\9F";
                          "\\A0";"\\A1";"\\A2";"\\A3";"\\A4";"\\A5";"\\A6";"\\A7";"\\A8";"\\A9";"\\AA";"\\AB";"\\AC";"\\AD";"\\AE";"\\AF";
                          "\\B0";"\\B1";"\\B2";"\\B3";"\\B4";"\\B5";"\\B6";"\\B7";"\\B8";"\\B9";"\\BA";"\\BB";"\\BC";"\\BD";"\\BE";"\\BF";
                          "\\C0";"\\C1";"\\C2";"\\C3";"\\C4";"\\C5";"\\C6";"\\C7";"\\C8";"\\C9";"\\CA";"\\CB";"\\CC";"\\CD";"\\CE";"\\CF";
                          "\\D0";"\\D1";"\\D2";"\\D3";"\\D4";"\\D5";"\\D6";"\\D7";"\\D8";"\\D9";"\\DA";"\\DB";"\\DC";"\\DD";"\\DE";"\\DF";
                          "\\E0";"\\E1";"\\E2";"\\E3";"\\E4";"\\E5";"\\E6";"\\E7";"\\E8";"\\E9";"\\EA";"\\EB";"\\EC";"\\ED";"\\EE";"\\EF";
                          "\\F0";"\\F1";"\\F2";"\\F3";"\\F4";"\\F5";"\\F6";"\\F7";"\\F8";"\\F9";"\\FA";"\\FB";"\\FC";"\\FD";"\\FE";"\\FF"
                         }
    :local string $1
    :if (([:typeof $string] != "str") or ($string = "")) do={ :return "" }
    :local lenstr [:len $string]
    :local constr ""
    :for pos from=0 to=($lenstr - 1) do={
        :local esc ($ASCIItoESCAPE->[:find $ascii [:pick $string $pos ($pos + 1)] -1])
        :set constr "$constr$esc"
    }
    :return $constr
}

:global sendscript2ssh do={
    :local rem [:toip  $1] ; :local usr [:tostr $2] ;  :local src [:tostr $3] ; :local dst [:tostr $4]
    /system script
    :if ([:typeof $rem] = "nil")             do={:return "IP wrong or not defined"}
    :if ([:len $usr] < 1)                    do={:return "user not defined"}
    :if ([:len [find where name=$src]] != 1) do={:return "script not found or not defined"}
    :if ([:len $dst] < 1)                    do={:set dst $src}
    :local owner  [get $src owner]
    :local commnt [$escape [get $src comment]]
    :local drp    "no" ; :if ([get $src dont-require-permissions]) do={:set drp "yes"}
    :local policy ""
    :foreach item in=[get $src policy] do={:if ($policy = "") do={:set policy "$item"} else={:set policy "$policy,$item"}}
    :local source [$escape [get $src source]]
    :local cmdline "/system script add name=\"$dst\" owner=\"$owner\" dont-require-permissions=$drp policy=$policy comment=\"$commnt\" source=\"$source\""
    :return  [/system ssh-exec address=$rem user=$usr command="$cmdline;:return \"DONE\""]
}

example code

:put [$sendscript2ssh 127.0.0.1 testssh "ip2bin" "test"]
Last edited by rextended on Thu Jan 26, 2023 2:57 pm, edited 3 times in total.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Function of transferring the script over SSH

Wed Jan 25, 2023 7:12 pm

The MAXLENGTH of a script is 30000 characters (\tabulatin \newline \return etc. are included on limit)
The MAXLENGTH of a variable on memory (63K) are sufficent to escape such script.

I can successfully transfer that script by my method.

If more complex script is needed, is better create multiple script and put the functions on that scripts.



Just one idea...
Elaborating that script, is possible to send file with size less than 63K by SSH...
 
User avatar
pkt
just joined
Posts: 14
Joined: Tue Jan 24, 2023 10:12 pm
Location: /u/mw/ss/e/eu/es

Re: Function of transferring the script over SSH

Wed Jan 25, 2023 8:55 pm

Elaborating that script, is possible to send file with size less than 63K by SSH...
This will be very interesting, but it seems that it is needed to load the file in memory to pass it to ssh-exec.
How do you will overcome the 4K limit?
 
User avatar
Sertik
Member
Member
Topic Author
Posts: 435
Joined: Fri Sep 25, 2020 3:30 pm
Location: Russia, Moscow

Re: Function of transferring the script over SSH

Wed Jan 25, 2023 9:26 pm

Hello Rex! This is something great! I haven't had time to check yet, but since you wrote it, it means it definitely works! I understand from the code that this function first recodes each character of the transmitted script ... Is that so? Could you explain the correct algorithm of this function? I will definitely check it and write it. Thanks a lot !
Did you write it like this right off the bat? Or were there some blanks? You are so cool !
Your ASCIItoESCAPE array is especially interesting, it has elements of variable length! I would never write this...
As I understand it, you made the escape function so as not to make a mistake and not miss a single character in the conversion ... Great!
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Function of transferring the script over SSH

Wed Jan 25, 2023 10:41 pm

I understand from the code that this function first recodes each character of the transmitted script ... Is that so?
Exactly!

Could you explain the correct algorithm of this function? I will definitely check it and write it.
Oh... just read the code:
define 2 arrays of same number of items,
on the 1st "ascii", all possible RouterOS 7-bit ascii + 8th bit (no matter of the codepage, but is CP437)
on the 2nd "ASCIItoESCAPE", all corresponding escape symbol or same letter / number / character if are equal, like numbers, letter parenthesys, etc.
no matter if the escaped value are more than one character, what count is array position. (for example, also on URL encode space is +, the same size, but ? is %3F, 3 charactes)
at that point read the input string, one character at time
based on character position on "array", add the same position content on "ASCIItoESCAPE" on the output string.
Done...

Did you write it like this right off the bat? Or were there some blanks?
For the "escape" function is based on how I already have wroted for convert ASCII 8-bit CP1252 (1 character) to UTF-8 that often are more than 2 characters for each converted ASCII character
viewtopic.php?t=177551#p967513
For the function "sendscript2ssh" is a litte mod of the already done function "scr2sshcmd" for send a function over SSH
viewtopic.php?p=977667#p977528

As I understand it, you made the escape function so as not to make a mistake and not miss a single character in the conversion
Exactly, all 256 possible values of 8-bit characters, from 0x00 to 0xFF, are covered.
 
User avatar
Sertik
Member
Member
Topic Author
Posts: 435
Joined: Fri Sep 25, 2020 3:30 pm
Location: Russia, Moscow

Re: Function of transferring the script over SSH

Thu Jan 26, 2023 8:31 am

Great !

There are small wishes:

If we already pass "owner" and "policy" it would be nice to pass "comment" as well
:local comment  [get $src comment]
:local cmdline "/system script add name=\"$dst\" owner=\"$owner\" dont-require-permissions=$drp policy=$policy comment=\"$comment"\ source=\"$source\""

Now it remains to make the transfer of the task for the Scheduler.
Something like:
:local RB [/system identity get name]
:local cmdline "/system scheduler add name=("Run script "."$dst"."[/system clock get time]"."[/system clock get date]") start-time=[:totime $6] on-event=\"$source\" interval=[:totime $7] start-date=$5 comment=("added by SSH-exec "."from $RB")];

:put [$sendsched2ssh 192.168.1.2 testsshScheduller "ip2bin" "testScheduller" "Feb/06/2023" "21:06:30" "00:00:00"]

Plus, it is necessary to provide that if interval=00.00.00 (that is, execute once), then the Scheduler task would be added to the text of the Scheduler task after its first (and last) execution:
:set source ("$source".";"."/system scheduler remove name=("Run script "."$dst"."[/system clock get time]"."[/system clock get date]"))
Plus, the added task needs to be wrapped in an error handler
 :do { } on error={} 
so that if an error occurs during the execution of the task we passed, the script would not stop working and would still be deleted after execution.

I wrote a function module two years ago to add tasks to the Scheduler on a local router. It can be downloaded here (if anyone is interested):
https://cloud.mail.ru/public/pLnx/TdU4iEfFN
Unfortunately, the comments there are all in Russian, I did not translate them.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Function of transferring the script over SSH

Thu Jan 26, 2023 2:40 pm

If we already pass "owner" and "policy" it would be nice to pass "comment" as well
Done, I forget that field because usually the name I do to the script make useless the description, or I put inside the script, on top, the note.
Also the comment can contain special characters, escaped also that.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Function of transferring the script over SSH

Thu Jan 26, 2023 3:22 pm

This is for transfer the scheduler by SSH.

If the last parameter is not present (or is something) the scheduler is copied DISABLED, regardlessly if on the source are enabled or not.
If the last parameter is exactly ON, the scheduler is copied ENABLED, regardlessly if on the source are enabled or not.

obviously is needed the escape funcion code

:global sendsched2ssh do={
    :local rem [:toip  $1] ; :local usr [:tostr $2] ;  :local src [:tostr $3] ; :local dst [:tostr $4] ; :local dis [:tostr $5]
    /system scheduler
    :if ([:typeof $rem] = "nil")             do={:return "IP wrong or not defined"}
    :if ([:len $usr] < 1)                    do={:return "user not defined"}
    :if ([:len [find where name=$src]] != 1) do={:return "script not found or not defined"}
    :if ([:len $dst] < 1)                    do={:set dst $src}
    :if ($dis = "ON")                        do={:set dis "no"} else={:set dis "yes"}
    :local interv [get $src interval]
    :local stard  [get $src start-date]
    :local start  [get $src start-time]
    :local policy ""
    :foreach item in=[get $src policy] do={:if ($policy = "") do={:set policy "$item"} else={:set policy "$policy,$item"}}
    :local commnt [$escape [get $src comment]]
    :local onevnt [$escape [get $src on-event]]
    :local cmdline "/system scheduler add name=\"$dst\" disabled=$dis policy=$policy comment=\"$commnt\" \
        interval=$interv start-date=$stard start-time=$start on-event=\"$onevnt\""
    :return  [/system ssh-exec address=$rem user=$usr command="$cmdline;:return \"DONE\""]
}

:put [$sendsched2ssh 127.0.0.1 testssh "test_schedule" "test" ON]
 
User avatar
Sertik
Member
Member
Topic Author
Posts: 435
Joined: Fri Sep 25, 2020 3:30 pm
Location: Russia, Moscow

Re: Function of transferring the script over SSH

Thu Jan 26, 2023 3:32 pm

Ok.

Also, as I have already written, you can make the task set to a single trigger or work with a given periodicity (interval). I'll do it myself. Thank you very much for your help !

Who is online

Users browsing this forum: Ahrefs [Bot] and 14 guests