Inside COBOL #71 (automating file transfers through termulators)
There was some recent traffic on the 3000-l where people were asking about how to programmatically deal with file transfers through terminal emulators such as MiniSoft and Reflection. About 8 years ago I had the same need. I wanted to be able to tell if it was a Windows or DOS PC that was running MiniSoft or Reflection, and at the time MiniSoft didn’t do the Mac, but Reflection did, so I would auto-sense that as well. The final step was to make sure that if someone tried to do this on a dumb terminal by mistake, that the terminal didn’t lock up, so I put some code in there to handle that as well.
First lets start with the auto-sensing portion of the code. We have some things to set up first.
01 STDIN PIC S9(4) COMP VALUE 0. 01 TIMEOUT PIC S9(4) COMP VALUE 7. 01 TERM-ID PIC X(09) VALUE SPACES. 01 FILE-TYPE PIC X VALUE SPACES. * First FOPEN the terminal so that we can enable FCONTROL for a * timeout in later calls. CALL INTRINSIC “FOPEN” USING \\, %45 GIVING STDIN. CALL INTRINSIC “FCONTROL” USING STDIN, 4, TIMEOUT. * Issue the escape sequence to request the terminal ID from the * termulator. %33 is the octal value for the escape key. DISPLAY %33 ‘*s12347^’. ACCEPT TERM-ID FREE ON INPUT ERROR DISPLAY ‘You are not using a PC’ STOP RUN. * Here is where we tell if it’s a MAC or not, we do this * specifically because the binary file transfer on a mac is * different than for the PC. IF(TERM-ID(1:1) = ‘M’) AND (TERM-ID(1:4) <> ‘MS92’) MOVE ‘WRQ’ TO TERM-ID DISPLAY ‘(A)scii, (B)inary or (M)acBinary? ‘ NO ADVANCING ELSE DISPLAY ‘(A)scii or (B)inary? ‘ NO ADVANCING. ACCEPT FILE-TYPE. IF TERM-ID(1:3) = ‘WRQ’ PERFORM C1000-REFLECT THRU C1000-EXIT. IF TERM-ID = ‘MS92 BEST’ PERFORM C2000-MS92 THRU C2000-EXIT. STOP RUN.
Now I am going to try and keep the code examples here concise, so you can decide how to prompt for the PC file name and the HP file name. One thing I’ve done is prompt for the PC file name, and then strip all the segments that aren’t the file name using UNSTRING, and then put it into a consistent group on the HP to control it further.
Another thing to keep in mind is if you want to make sure that you aren’t overwriting another file. I like to use a call to FLABELINFO to see if the file is there, if the call fails, then there is no conflicting file. You need to loop on the file name prompt to make sure that they can override their choice. Of course if you are transfering from the HP to the PC, then there really isn’t anything you can do with this process.
What I have illustrated here is how you can write a program that can autosense various things about the terminal emulator you are using, or if it is a dumb terminal. With this framework you can create a relatively secure environment for uploading or downloading files without giving the users full access to the file transfer protocols built into your emulator.
The trick after this point is to be able to startup the emulator file transfer program. There are sample applications that come with the various emulators that will describe how to do this. I recommend that you follow them exactly. In the case of MiniSoft, their sample shows how to do it using the CREATEPROCESS and ACTIVATE intrinsics. I’ve tried doing it my own way, and it just didn’t work. In the case of Reflection they show how to do it with the CREATE intrinsic.
What actually happens is that one of the escape sequences you issue will return the fully qualified name of the file transfer program that is configured in the emulator. If this file doesn’t exist, then the whole process will fail, so it does rely on having everything set up to work. Once the program name is returned, you have to spawn it as a child process, hence the calls to CREATE and CREATEPROCESS. Essentially you pass the scripting language directive to the emulator via an escape sequence and away you go.
It’s a bit on the confusing side when you first start out, but it really does work pretty darn good. Well, as usual, next month will be a surprise for me as well as you.