Sie sind nun wieder eingeladen, die Diskussion spezieller technischer Probleme mit zu verfolgen. Bitte schicken Sie Fragen, Anregungen oder Antworten zu den vorgestellten Themen – ebenso wie Ihre Kritik – an unsere e-Mail-Adressen: dieter.bender@MidrangeMagazin.de oder Redaktion@MidrangeMagazin.de

Frage:

Wir übertragen häufig Dateien mit FTP. Kann man das sinnvoll automatisieren?

Antwort:

Als ersten Schritt kann man sich FTP-Skripten schreiben, die man in einer Quelldatei ablegt. Durch OVRDBF auf die Dateinamen INPUT und OUTPUT kann man nun dafür sorgen, dass sich der OS/400-Befehl FTP die Eingaben aus einer Quelldatei holt und die Protokollierungen in eine Ausgabedatei schreibt. Das FTP-Skript beinhaltet nunmehr alle Eingaben, die man in einer FTP-Sitzung am Prompt auch interaktiv vollziehen könnte.

***************** Datenanfang ************************
bender kennwort
binary
put bender/qclsrc.testftp /home/bender/Work/testftp.cl
quit
******************Datenende **************************

In dem einfachen Beispiel erfolgt eine FTP-Anmeldung mit dem Benutzer BENDER; das Kennwort muss im Klartext in der Textdatei stehen. Mit der Anweisung „binary“ wird der Übertragungsmodus eingestellt – hier wäre auch „ascci“ oder „ebcdic“ möglich. Die put-Anweisung sendet eine Source-Datei an ein Linux-System und stellt diese im Unterverzeichnis „Work“ des Benutzers unter dem Namen „testftp.cl“ ab.

Zu den Nachteilen dieses Ansatzes zählt, dass die Ausgaben nicht gut zu finden sind und dass alle Angaben statisch in einer Textdatei stehen müssen. Das Versenden oder Empfangen von Dateien nach einer Liste, die erst ermittelt wird, ist so nicht möglich.

Mit einer generierten Übertragungsdatei lässt sich dieser Nachteil allerdings beheben. Dazu benötigt man zunächst einmal ein Programm, das seine Angaben als Parameter bekommt und das dann mit diesen Parametern ein FTP-Skript generiert und ausführt. CL scheidet hier eher aus, wegen der eingeschränkten Möglichkeiten Dateien zu verarbeiten.
In diesem RPG-Prototyp sind die Parameter beschrieben, die das Programm FTPCPP verwendet. Der Prototyp wird in eine eigene Quelldatei ausgelagert, die später in das Programm sowie in alle aufrufenden Programme kopiert wird. Die Prä-Compiler-Anweisungen zu Beginn und am Ende verhindern Fehler durch doppeltes Kopieren.

/IF NOT DEFINED (FTPCPP_QRPGLEH)
/DEFINE FTPCPP_QRPGLEH
/**************************************************************/
/* Header File Name: FTPCPP */
/* Generierung eines FTP Skriptes und Ausführung */
/* leitet FTP Meldungen in Spooldatei um */
/**************************************************************/
D FTPCPP PR EXTPGM(‚FTPCPP‘)
D ZielSystem 32A CONST
D User 10A CONST
D Password 10A CONST
D Mode 10A CONST
* ascii ebcdic oder binary
D Direction 3A CONST
* put oder get
D Fromfile 32A CONST
* Pfadangabe lokales System
D Tofile 32A CONST
* Pfadangabe entferntes System
/ENDIF

Unter dem Parameter „Direction“ wird mit den Werten „put“ oder „get“ festgelegt, ob gesendet oder empfangen werden soll. Die Pfadangaben in den Parametern „FromFile“ und „ToFile“ müssen der von FTP geforderten Syntax für qualifizierte Dateiangaben entsprechen. Werden längere Pfade verwendet, kann man das Programm leicht anpassen. Die Header-Datei wird unter dem Namen des Programms FTPCPP in einer Quelldatei QRPGLEH gespeichert. Für die Ausführung des späteren Skriptes sind eine Reihe von CL-Befehlen erforderlich, die man allerdings auch direkt aus dem RPG-Programm erledigen kann. Die Verwendung des C-API system ist dafür einfacher und besser lesbar als der besser bekannte QCMDEXC. Für die Verwendung von system () ist ein Prototyp erforderlich und das Binding Directory QC2LE muss beim Binden des Programms mit verwendet werden.

/**************************************************************/
/* Header File Name: SYSTEM */
/* Definitionen für Benutzung C API system () */
/* Aufruf Systemfunktion */
/**************************************************************/
/IF NOT DEFINED (SYSTEM_QRPGLEH)
/DEFINE SYSTEM_QRPGLEH
/*=============================================================*/
* return: 0 = command successfull
* -1 = Null pointer exception
* 1 = execution not successfull
*—————————————————–
Dsystem PR 10I 0 EXTPROC(’system‘)
* Commandstring
D * VALUE OPTIONS(*STRING)
/ENDIF

Damit sich das Programm später einfach mit CRTBNDRPG erstellen lässt, erfolgen in den H-Bestimmungen einige Steuereinträge für den Compiler. Bei der Umwandlung muss eine passende Datei mit dem Namen QFTPSRC gefunden werden. Diese kann man sich mit CRTSRCPF QFTPSRC erstellen.
Die Datei QFTPSRC wird mit dem Schlüsselwort USROPN gekennzeichnet, damit man sie noch zur Programmlaufzeit in der QTEMP erstellen kann. Ein drumherumliegendes CL-Programm wird so überflüssig. Der RENAME auf den Formatnamen ist aus Rücksichtnahme auf RPG-Steinzeit weiterhin erforderlich, obwohl Multiformat-Dateien längst der Vergangenheit angehören sollten.

Die /COPY-Anweisungen ziehen die bereits diskutierten Prototypen in die Umwandlungsliste rein. Das folgende Main Interface ersetzt bei ILE die *ENTRY PLIST-Anweisungen. Aus den globalen C-Bestimmungen wird sofort eine Subprozedur aufgerufen, für die auch der einzige lokale Prototyp benötigt wird.

H copyright(‚Dieter Bender 03/2002‘)
H DFTACTGRP(*NO) BNDDIR(‚QC2LE‘)
* erstellen mit CRTBNDRPG
FQFTPSRC UF A E K DISK USROPN
F RENAME(QFTPSRC:QFTPSRCR)
/*— Import Prototypen
/COPY QRPGLEH,SYSTEM
/COPY QRPGLEH,FTPCPP
/*— lokale Prototypen
D Work PR
/*— Main Interface
D FTPCPP PI
D SystemName 32A CONST
D FtpUser 10A CONST
D Password 10A CONST
D FtpMode 10A CONST
D Direction 3A CONST
D Fromfile 32A CONST
D Tofile 32A CONST
/*— very unimportant procedure main ————————*/
C
C Callp Work
C return
/*============================================================*/
P Work B
/*————————————————————*/
C callp system (‚DLTF QTEMP/QFTPSRC‘)
C callp system (‚CRTSRCPF QTEMP/QFTPSRC‘)
C callp system (‚ADDPFM QTEMP/QFTPSRC IN‘)
C callp system (‚ADDPFM QTEMP/QFTPSRC OUT‘)
C callp system (‚OVRDBF QFTPSRC QTEMP/QFTPSRC‘
C + ‚ IN OVRSCOPE(*JOB)‘)

C open QFTPSRC
C eval SRCDTA = FtpUser + ‚ ‚ + Password
C write QFTPSRCR
C eval SRCDTA = FtpMode
C write QFTPSRCR
C eval SRCDTA = Direction + ‚ ‚ +
C %trim(FromFile) + ‚ ‚ +
C %trim(ToFile)
C write QFTPSRCR
C eval SRCDTA = ‚quit‘
C write QFTPSRCR
C close QFTPSRC

C callp system (‚DLTOVR QFTPSRC LVL(*JOB)‘)
c callp system (‚OVRDBF INPUT QTEMP/QFTPSRC‘
C + ‚ IN OVRSCOPE(*JOB)‘)
c callp system (‚OVRDBF OUTPUT QTEMP/QFTPSRC‘
C + ‚ OUT OVRSCOPE(*JOB)‘)
c callp system (‚FTP ‚ + %trim(SystemName))
c callp system (‚CPYSRCF QTEMP/QFTPSRC ‚
c + ‚*PRINT OUT‘)
c callp system (‚DLTOVR *ALL *JOB‘)

C return
P Work E

Im ersten Block mit den system ()-Aufrufen wird eine Arbeitsdatei QFTPSRC in der Bibliothek QTEMP angelegt und die Teildatei IN für das RPG-Programm geöffnet. Anschließend wird mit den Parameterangaben ein FTP-Skript in diese Datei geschrieben und die Datei wieder geschlossen. Im abschließenden Block wird wieder mit Aufrufen von system () nach Umleitung der Ein- und Ausgabe FTP aufgerufen. Zuletzt werden die Dateiüberschreibungen aufgeräumt und die Protokollierungen des FTP-Aufrufes in eine Spool-Datei gestellt.
Dieser doch recht einfache Mechanismus lässt sich nach weiteren Anforderungen relativ leicht modifizieren und kann in den Programmen eingesetzt werden, um alle Automatisierungsanforderungen abzudecken. Durch mehrfachen Aufruf dieses Programms lassen sich dynamisch erzeugte Listen von Dateien versenden oder, was ebenfalls eine gängige Anforderung darstellt, Dateinamen für die Zieldateien generieren.
Die Benutzung des Programms lässt sich auch durch die Erstellung eines benutzerdefinierten Befehls weiter vereinfachen; in der Quelle des Befehls kann man auch bereits einfache Prüfungen für die Parameter hinterlegen. Die Parameter-Übergabe wird weiter stabilisiert.

Den Autor Dieter Bender erreichen Sie unter dieter.bender@midrangemagazin.de