Based on the article in the
Developer Connection, he wrote his own class implementation for calling commands of the server operating system where Caché or Ensemble is installed.
The class can be useful when you need to do something from Caché on the host OS: manage backup files, set up version control systems, and other useful actions.
The class allows you to execute a command on any host OS and get an answer to the global or local variable.
Class code with commentsClass Server.Manage Extends% RegisteredObject
{
Parameter cmdlist = "dir, type, ver" ;
/// method removes command sequences from the command line
/// leaves only allowed commands
ClassMethod safeCmd ( cmd ) As% String
{
set cmd = $ piece ( cmd , "&&" ) // leave one command
set cmd = $ piece ( cmd , "|" )
for i = 1: 1: $ length (.. #cmdlist , "," ) set safe ( $ p (.. #cmdlist , "," , i )) = "" // list of allowed commands
if ' $ data ( safe ( $ piece ( cmd , "" ))) set cmd = ""
quit cmd
}
')
/// method executes the cmd command on the server and adds the result to the global ad such that:
/// @ ad = number of lines
/// @ ad @ (line number) = value a
ClassMethod runCmd ( cmd , ad As% String ) As% Status
{
set sc = $$$ OK
do $ SYSTEM .Process . SetZEOF (1) // turn off the error generation mode on EOF
// make the command line safe
set cmd (1) = .. safeCmd ( cmd )
quit : cmd (1) = "" $$$ ERROR ( $$$ GeneralError , "Invalid Command" _ cmd )
set cmd = cmd (1)
// clear the sent global
kill @ ad
set count = 0
try {
// open the device with the command line and reading the response
open cmd : "QR: K \ CP866 \" if ' $ test $$$ ThrowStatus ( $$$ ERROR ( $$$ GeneralError , "Failed to execute the command" _ cmd ))
Set IO = $ IO // remember the current device
// subtract line by line the result of the command until the end of the file comes and add it to the global
for {
use cmd
read str quit : $ zeof = -1
set @ ad @ ( $ Increment ( count )) = str
}
set @ ad = count
// close the device
#dim e as % Exception.AbstractException
} Catch e {
set sc = e . AsStatus ()
// do e.Log () //
}
// close the device
close cmd
// return the current device
If $ data ( IO ) Use IO
quit sc
}
}
The cmdlist parameter contains a list of allowed commands separated by commas.
The safeCmd () method brushes the command line.
The runCmd () method actually executes the cmd command and puts the result in the indirect address ad.
The code above works on all operating systems supported by Caché, executes commands, gets results and handles errors. Unlike the implementation described in the
article , the work is organized through the CommandPipe device - the “QR” mode for the open command. You can read more
in the documentation .
Demo
An example of use can be seen
here - a small project compiled on CSP + Twitter Bootstrap.
The server is not given to slaughter - the allowed commands are: type, ver,
format with, dir.
The code for the class and the web project is laid out on a
github .