Wednesday, April 28, 2010

Using x3270if commands against s3270 without calling a script

Recently I needed to start playing around with automating SLES installs on IBM z Series mainframe guests.  I needed to be able to have a script be able to send commands to the guest thorugh a 3270 terminal.  I found s3270 which starts a 3270 terminal that can then be passed commands via a script to be ran against the guest.  This was good but I ran into a limitation that I had to open s3270 and then tell it to run a script that contained what I wanted to due.  This was limiting because I wanted the script to be more dynamic in asking for username/passwords/ips/etc and monitoring output with expect to work through different scenarios.

This initially led me to develop multiple shell and expect scripts that called eachother passing arguments between eachother that was received from a 'master' script.  This is very ugly though codewise and also that you could see entered passwords via 'ps' because I was passing it as an argument to other scripts.

To get around my issues I needed to:
  • Use 1 script
  • Have script start s3270 and be able to pass commands to it (not have s3270 call a script)
  • have expect functionality
First I figured out how to pass commands to s3270 instead of having s3270 call a script with a list of commands.  This was done be creating 2 FIFOs and redirecting stdin and stdout to those FIFOs when starting s3270:
mkfifo /tmp/3270.in /tmp/3270.out
s3270 /tmp/3270.out &
I also backgorunded the s3270 process because otherwise you are stuck in s3270 to enter commands for it.

I then created filedescripors that copied my FIFOs:
exec 5>/tmp/3270.in 6
rm -f /tmp/3270.in /tmp/3270.out
Now I set 2 enviornment variables that x3270if uses to know what filedescriptors to use when communicating with an s3270 process:
X3270INPUT=5
X3270OUTPUT=6
export X3270INPUT X3270OUTPUT
That's it for goal #1!  I can now do commands such as the following:
x3270if "connect(192.168.1.100)"
Which would instruct my s3270 terminal to connect to a frame on IP 192.168.1.100.

With this functionality alone I can then use expect scripting alone to do everything I want which meets my other goals.  However, I don't like Tcl expect so I chose to use python scripting using pexpect for expect functionality to script everything.

I found the redirect solution I detailed above after scouring google and finding the following link to a script that someone else made @ http://www.sfr-fresh.com/unix/misc/x3270-3.3.9ga12.tgz:a/x3270-3.3/Examples/cms_logon.sh