gco.pl

This is little PERL function that is stored in the file gco.pl and can be included into any PERL plugin to perform basic operation needed during interaction with remote host. It will send command to remote host, collect command output into PERL variable (for further processing, if needed) and wait for the remote host to respond with "expected" prompt at the end of the command output.

This function encapsulates all heavy details of direct handling of the STDIN/STDOUT/STDERR byte pipes (those pipes are connecting terminal window I/O streams and PLUGIN process I/O streams). Unfortunately, PERL STDIN/STDOUT/STDERR stream handles are not implemented as simple global variables, so for the use inside of the subroutines, they have to be passed by reference from the main program. That adds more arguments to the function call. User does not have to work with those handles directly but still have to pass them to the subroutine on every call.

This function can be seen as some sort of very simple open-source PERL-to-TERMINAL glue interface library that is by itself written in PERL and helps programmer to control terminal easily from PERL programs. User can modify this function directly to fine tune its behavior. For example, very peculiar behavior of the remote equipment can be worked around as shown here.

To be able to use this function in any PERL plugin simply add following line in the beginning of the plugin code:

require "./plug/perl/gco.pl";

This line is assuming that . in path to gco.pl file is referring to Proxy32 startup directory (which is made current directory for any plugin process). Before including this line, please, download file gco.pl and place it into subdirectory plug/perl inside of the proxy32 startup directory.

If the file gco.pl is present in referred location, then user can use gco function (in the PLUGIN code after require statement) to query Oracle DB server via interactive Oracle SQLPLUS client in the following fashion:

Example of one-liner PERL PLUGIN using gco.pl as terminal interface

Example of one-liner PERL PLUGIN using gco.pl as terminal interface

1
2
3
4
5
6
7
8
9
10
11
12
perl -e '
require "./plug/perl/gco.pl";
gco(\*STDIN,\*STDOUT,\*STDERR,"sqlplus\r\n","Enter user-name:",1,$buffer);
gco(\*STDIN,\*STDOUT,\*STDERR,"dbadmin\r\n","Enter password:",1,$buffer);
gco(\*STDIN,\*STDOUT,\*STDERR,"dbadmin\r\n","SQL>",1,$buffer);
gco(\*STDIN,\*STDOUT,\*STDERR,"set head off\r\n","SQL>",1,$buffer);
gco(\*STDIN,\*STDOUT,\*STDERR,"set echo off\r\n","SQL>",1,$buffer);
gco(\*STDIN,\*STDOUT,\*STDERR,"set linesize 300\r\n","SQL>",1,$buffer);
gco(\*STDIN,\*STDOUT,\*STDERR,"set pagesize 0\r\n","SQL>",1,$buffer);
gco(\*STDIN,\*STDOUT,\*STDERR,"select NAME from ORDERS;\r\n","SQL>",1,$buffer);
gco(\*STDIN,\*STDOUT,\*STDERR,"quit\r\n","\]",1,$buffer);
'

or instead of using perl one-liner, one can put the perl script into the plugin.pl file and populate PLUGIN command line as follows:

perl ./plug/perl/plugin.pl

where file ./plug/perl/plugin.pl would contain following lines:

1
2
3
4
5
6
7
8
9
10
require "./plug/perl/gco.pl";
gco(\*STDIN,\*STDOUT,\*STDERR,"sqlplus\r\n","Enter user-name:",1,$buffer);
gco(\*STDIN,\*STDOUT,\*STDERR,"dbadmin\r\n","Enter password:",1,$buffer);
gco(\*STDIN,\*STDOUT,\*STDERR,"dbadmin\r\n","SQL>",1,$buffer);
gco(\*STDIN,\*STDOUT,\*STDERR,"set head off\r\n","SQL>",1,$buffer);
gco(\*STDIN,\*STDOUT,\*STDERR,"set echo off\r\n","SQL>",1,$buffer);
gco(\*STDIN,\*STDOUT,\*STDERR,"set linesize 300\r\n","SQL>",1,$buffer);
gco(\*STDIN,\*STDOUT,\*STDERR,"set pagesize 0\r\n","SQL>",1,$buffer);
gco(\*STDIN,\*STDOUT,\*STDERR,"select NAME from ORDERS;\r\n","SQL>",1,$buffer);
gco(\*STDIN,\*STDOUT,\*STDERR,"quit\r\n","\]",1,$buffer);

As can be seen from the above example:

To download gco.pl file click here.

Below is syntax-colored and line-numbered code of the gco function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
##############################################################################################
# This subroutine receives command string as a first parameter and sends it to the remote host.
# Then it collects the output of the command as one big string ($CommandOutput) 
# and as array of strings (@CommandOutputLines). End of the command is determined 
# by the prompt REGEX that is passed as the second argument to the function.
# showprogress argument is to control echoing of the output of the command to the terminal
# 0 - do not show, 1- verbose, 2 - show '#' sign for every new received chunk of command output 
# CommandOutput argument is to return output of the command to calling code for post-processing
# 04/14/06 Sergey A. Belous
# *******************************************************************************************
# 05/02/06 passing file handles correctly into subroutine
# 04/18/08 made as separate library for use in inline PERL PLUGINs
# *******************************************************************************************
# example how to call:
# gco(\*STDIN,\*STDOUT,\*STDERR,"show sub aaa user $ARGV[0]\r\n","#",0, $buffer);
##############################################################################################
sub gco{
    my $myin = shift;
    my $myout = shift;
    my $myerr = shift;
    my $commandtoexecute = shift;
    my $promptregex = shift;
    my $showprogress = shift;
    #end of argument list, last one is in $_[0]
        my $greeting="";
        syswrite $myout,"$commandtoexecute";
        $CommandOutput="";
        #@CommandOutputLines = ();
        while(){
                sysread $myin, $greeting,1000;
                if($showprogress==1){syswrite $myerr,$greeting;}
                if($showprogress==2){syswrite $myerr,"#";}
                $CommandOutput.=$greeting;#append new output to the buffer
                last if $CommandOutput =~ /$promptregex/;
        }
        $CommandOutput =~ s/[\r\x00]//g;#clean-up
        #@CommandOutputLines = split("\n",$CommandOutput);#split into separate lines
        $_[0]=$CommandOutput;
}
1;