I was recently lurking in the HPSYS forum on CompuServe and picked up a thread on having your programs talk to FTP. Craig Engel responded with a little program he had written to do just such a thing, and received a bunch of requests for it, including one from me. Craig's program was specifically desinged for an application he was working on, so I ripped it apart and made a generic utility out of it. Turned out this was a timely bit of technology for a project I was working on.
What's the point of all this you may ask. First a little background for those of you who don't know what I'm talking about. FTP stands for File Transfer Protocol, and is one of the older protocols on the Intnet for transferring files. HP started bundeling FTP on the HP a while back, it's kind of nice because you can use it as both a client and server FTP process, not to mention it is blazingly fast on your local network, I can transfer 10 Meg of data in about 20 seconds.
Since FTP is a standard protocol, that means you can have an FTP server running on your Netware server, NT server, Unix server, whatever, and be able to easily transfer files from your HP to any of these other environments. The only real drawback is that you have to sit and run the FTP client and pass all the information. The idea to this utility is that it will read a file that contains a file name that you want to transfer, read the destination information out of a config file, and then send it off to the program featured here, which will then feed it to FTP. These means you can automatically, and programmatically ship stuff around your network very easily.
Let's talk about the config file that FTPSCHED will use, figure 1 has an example. I am only going to care about the first line, so the rest is documentation. My notes in the file should explain everything that is required from the config file.
This program has everything in it. We are using macros, we are getting JCW's, we are using intrinsics to do timed reads on message files. We are use the HPCICOMMAND intrinsic to run another program as a child process while passing parameters to it's STDIN via I/O redirection. This program is filled with lots of little tricks that can be used in other programs. One of the things I do here that I started some years ago, is use a JCW in conjunction with a macro to get run time statistics. The advantage to this method is that it can be applied to sub-programs, and programs that are 'created' from other programs where you can't set a run PARM to use standard debugging techniques. It can be placed anywhere in the program, and set up to display anything.
One of the things I stripped out of this example, was that we wanted to purge the file on the host after the FTP ran, so there was a series of code to save the access date on each file, and compare to the current, once it was exceeded, and we passed a P flag in the message file, I would purge the file on the host. I had to strip the code due to size constraints.
The only real change I would make to this program is to allow you to send an overriding destination node inside FTPIN with the file name, but this is more applicable in a multi node environment.
I hope you enjoyed our little foray into the Internet. I'm not really sure what I am going to do next month, but it might have something to do with carriage control.
Figure 1
print ftpcon.data.smga
PRODUCTION
FTPSCHED,MANAGER.SYS ,TRASH
*Only the first line of this file will be read, the first
20
*bytes should contain the IP address, or node name as
defined
*in HOSTS.NET.SYS to connect too. From byte 21
to 70 it should
*contain the complete logon name and password for that
node.
*This will be read by FTPSCHED.PROG.SMGA everytime it
goes
*to launch a new instance of FTP. This allows you
to change
*the destination without bringing down the server.
*To shut down the server explicitly just put the string
SHUTDOWN
*in FTPPIPE.DATA. this file MUST be 72 bytes wide.
Figure 2
$CONTROL BOUNDS,POST85,USLINIT
IDENTIFICATION DIVISION.
PROGRAM-ID. FTPSCHED.
AUTHOR.
Shawn M. Gordon.
DATE-WRITTEN. THU, FEB 27, 1997.
DATE-COMPILED.
******************************************************************
*
Program Description
*
*----------------------------------------------------------------*
* Program reads message file, picks up additional
data from *
* config file. It will pause for 5 minutes
so as to group as *
* many transactions into a single create as possible.
We then *
* FTP the files to the IP address found in the
config file. *
******************************************************************
*
Compilation Data
*
*----------------------------------------------------------------*
* CAP=PH
*
******************************************************************
*
Record of Changes
*
*----------------------------------------------------------------*
*
*
* mm/dd/yy xxx Initial Installation.
*
******************************************************************
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. HP3000 WITH DEBUGGING MODE.
OBJECT-COMPUTER. HP3000.
SPECIAL-NAMES.
CONDITION-CODE IS CC.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT FTPCON ASSIGN TO "FTPCON.DATA.SMGA".
SELECT FTPIN ASSIGN TO "FTPIN.DATA.SMGA".
DATA DIVISION.
***************************************************************
FILE SECTION.
***************************************************************
FD FTPCON
RECORD CONTAINS 72 CHARACTERS.
01 FTPCON-RECORD.
03 FR-NODE
PIC X(20).
03 FR-LOGON
PIC X(50).
03
PIC X(02).
FD FTPIN
RECORD CONTAINS 132 CHARACTERS.
01 FTPIN-RECORD
PIC X(132).
*
WORKING-STORAGE SECTION.
01 FNUM
PIC S9(4) COMP VALUE 0.
01 ERR
PIC S9(4) COMP VALUE 0.
01 ERR-LEN
PIC S9(4) COMP VALUE 80.
01 ERR-PARM
PIC S9(4) COMP VALUE 0.
01 MSG-LEVEL
PIC S9(4) COMP VALUE 0.
01 P
PIC S9(4) COMP VALUE 0.
01 S1
PIC S9(4) COMP VALUE 0.
01 PIPE-FILE
PIC X(26) VALUE "FTPPIPE.DATA.SMGA".
01 ERR-MSG
PIC X(76) VALUE SPACES.
01 OUT-BUFF
PIC X(80) VALUE SPACES.
01 MSG-BUFF.
03 MB-PURGE
PIC X VALUE SPACES.
03 MB-FROM-FILE
PIC X(26) VALUE SPACES.
03 MB-TO-FILE
PIC X(101) VALUE SPACES.
*
01 COM-IMAGE.
03 COMMAND-IMAGE
PIC X(79) VALUE SPACES.
03
PIC X VALUE %15.
01 TRACE-JCW.
03 TJ-NAME
PIC X(14) VALUE "FTPSCHEDTRACE".
03 TJ-VALUE
PIC S9(4) COMP VALUE 0.
88 STATS-ON
VALUE 1.
01 TIMER-JCW.
03 TW-NAME
PIC X(15) VALUE "FTPSCHEDTIMER".
03 TW-TIMER
PIC S9(4) COMP VALUE 0.
01 JCW-STATUS
PIC S9(4) COMP VALUE 0.
*
PROCEDURE DIVISION.
$INCLUDE DEBUG.I
FTPSCHED-SECT01
SECTION 1.
A0000-MACROS.
$DEFINE %COMIMAGE=
MOVE
!1
TO COMMAND-IMAGE
CALL INTRINSIC
'HPCICOMMAND' USING COM-IMAGE,
ERR,
ERR-PARM,
MSG-LEVEL#
*
$DEFINE %STATS=
IF STATS-ON
DISPLAY !1
!2
END-IF#
A1000-MAIN.
DISPLAY 'FTPSCHED Version 10.70227
'
'(S.M.Gordon & Associates (C) 1997)'.
CALL INTRINSIC "FINDJCW" USING
TW-NAME, TW-TIMER, JCW-STATUS.
IF JCW-STATUS = 3
MOVE 600
TO TW-TIMER
DISPLAY 'JCW
FTPSCHEDTIMER not found - defaulting to '
'10 minute time out'
ELSE
DISPLAY 'FTPSCHEDTIME
is set to ' TW-TIMER ' seconds'.
CALL INTRINSIC 'FINDJCW' USING
TJ-NAME, TJ-VALUE, JCW-STATUS.
%STATS("Tracing is enabled"#).
CALL INTRINSIC 'FOPEN' USING
PIPE-FILE, %32105, %2340
GIVING FNUM.
IF CC < 0
DISPLAY 'Failed
to open ' PIPE-FILE
CALL INTRINSIC
'FCHECK' USING FNUM, ERR
CALL INTRINSIC
'FERRMSG' USING ERR, OUT-BUFF, ERR-LEN
DISPLAY OUT-BUFF
DISPLAY 'FTPSCHED
- ' OUT-BUFF UPON CONSOLE
STOP RUN.
%STATS("Successfully opened
"#, PIPE-FILE#).
CALL INTRINSIC "FCONTROL" USING
FNUM, 4, TW-TIMER.
IF CC <> 0
DISPLAY 'Failed
on FCONTROL 4'
CALL INTRINSIC
'FCHECK' USING FNUM, ERR
CALL INTRINSIC
'FERRMSG' USING ERR, OUT-BUFF, ERR-LEN
DISPLAY OUT-BUFF
STOP RUN.
MOVE 1
TO S1.
CALL INTRINSIC "FCONTROL" USING
FNUM, 45, S1.
IF CC < 0
DISPLAY 'Failed
on FCONTROL 45'
CALL INTRINSIC
'FCHECK' USING FNUM, ERR
CALL INTRINSIC
'FERRMSG' USING ERR, OUT-BUFF, ERR-LEN
DISPLAY OUT-BUFF
DISPLAY 'FTPSCHED
- ' OUT-BUFF UPON CONSOLE
STOP RUN.
%STATS("Extended waits have
been enabled on "#, PIPE-FILE#).
OPEN OUTPUT FTPIN.
A2000-READ.
%STATS("A2000-READ"#).
MOVE SPACES
TO MSG-BUFF.
CALL INTRINSIC 'FREAD' USING
FNUM, MSG-BUFF, -128.
IF CC < 0
CALL INTRINSIC
'FCHECK' USING FNUM, ERR
* Our timed read timed out so do time out processing
IF ERR = 22
IF MSG-BUFF = SPACES
GO TO A2000-READ
END-IF
PERFORM B1000-PROCESS THRU B1000-EXIT
ELSE
CALL INTRINSIC 'FERRMSG' USING ERR, OUT-BUFF, ERR-LEN
DISPLAY OUT-BUFF
DISPLAY 'FTPSCHED - ' OUT-BUFF UPON CONSOLE
STOP RUN.
A2000-TAG.
IF MSG-BUFF = SPACES
GO TO A2000-READ.
%STATS("OPEN INPUT FTPCON"#).
OPEN INPUT FTPCON.
READ FTPCON AT END DISPLAY "BAD END OF FILE ON FTPCON".
%STATS(FTPCON-RECORD#).
CLOSE FTPCON.
MOVE SPACES
TO FTPIN-RECORD.
STRING "OPEN " DELIMITED BY
SIZE
FTPCON-RECORD(1:20) DELIMITED BY SPACES
INTO FTPIN-RECORD.
WRITE FTPIN-RECORD.
%STATS("WRITE"#).
%STATS(FTPIN-RECORD#).
MOVE SPACES
TO FTPIN-RECORD.
STRING "USER " DELIMITED BY
SIZE
FTPCON-RECORD(21:50) DELIMITED BY SIZE
INTO FTPIN-RECORD.
WRITE FTPIN-RECORD.
%STATS("WRITE"#).
%STATS(FTPIN-RECORD#).
A2000-LOOP.
%STATS("A2000-LOOP"#).
MOVE SPACES
TO FTPIN-RECORD.
STRING "PUT " DELIMITED BY SIZE
MB-FROM-FILE DELIMITED BY SPACES
" " DELIMITED BY SIZE
MB-TO-FILE DELIMITED BY SPACES
INTO FTPIN-RECORD.
WRITE FTPIN-RECORD.
%STATS("WRITE"#).
%STATS(FTPIN-RECORD#).
MOVE SPACES
TO MSG-BUFF.
CALL INTRINSIC 'FREAD' USING
FNUM, MSG-BUFF, -128.
IF CC < 0
CALL INTRINSIC
'FCHECK' USING FNUM, ERR
* Our timed read timed out so do time out processing
IF ERR = 22
PERFORM B1000-PROCESS THRU B1000-EXIT
GO TO A2000-READ
ELSE
CALL INTRINSIC 'FERRMSG' USING ERR, OUT-BUFF, ERR-LEN
DISPLAY OUT-BUFF
DISPLAY 'FTPSCHED - ' OUT-BUFF UPON CONSOLE
STOP RUN.
IF MSG-BUFF = "SHUTDOWN"
GO TO C9000-EOJ.
GO TO A2000-LOOP.
A2000-EXIT.
*
B1000-PROCESS.
%STATS("B1000-PROCESS"#).
MOVE "CLOSE"
TO FTPIN-RECORD.
WRITE FTPIN-RECORD.
CLOSE FTPIN.
%COMIMAGE("RUN FTP.ARPA.SYS<FTPIN.DATA.SMGA"#).
OPEN OUTPUT FTPIN.
B1000-EXIT. EXIT.
*
C9000-EOJ.
CALL INTRINSIC "FCLOSE" USING
FNUM, 0, 0.
DISPLAY 'Normal termination
of FTPSCHED on ' CURRENT-DATE
' @ ' TIME-OF-DAY.
STOP RUN.