FLUC-Satzschnittstelle

Die Satzschnittstelle für Originaldaten (Zugriffsmethode) basiert auf der Byteschnittstelle des FLUC und ermöglicht den sequentiellen Zugriff in Form von Records (Länge und Daten) auf originale Datenbestände, wie dies beim File-I/O in der Mainframe-Welt (GET/PUT für COBOL oder PL1) üblich ist. Hierbei können die Datenbestände lokal oder remote gelesen bzw. geschreiben werden und es stehen alle Konvertierungsmöglichkeiten von FLAM beim Lesen und Schreiben von Originaldaten zur Verfügung. Dies bedeutet, dass man zum Beispiel transparent Sätze in EBCDIC IBM-1141 lesen kann, obwohl hierbei die Daten von einem Member einer konkatenierten GZIP-Datei stammen, welche sich verschlüsselt und BASE64-enkodiert auf einer lokalen Platte oder einem fremden System (Cloud/HOST/DMZ) befindet und deren klarer Text eigentlich in UTF-16LE enkodiert und mit 0x0D000A00 terminiert war.
 

Die Satzschnittstelle wird für COBOL, PL1, C, Assembler oder andere Programmiersprachen in Form von einzelnen Lademodulen (FCROPN, FCRGET, FCRPUT, FCRCLS) bereitgestellt. Hierbei sind alle Parameter Call-by-Reference und es gibt keinen Rückgabewert. Input-Zeichenketten werden entweder ohne Null-Terminierung mit Hilfe eines zusätzlichen Längenparameter entgegen genommen oder als Null-terminierter String akzeptiert, wobei der Längenparameter hierfür auf NULL gesetzt werden muss. Bei der String-Rückgabe wird die Länge gesetzt aber zusätzlich auch eine Null-Terminierung durchgeführt, welche man nutzen kann, auf die man aber nicht angewiesen ist. Der externe Entry entspricht dem Modulnamen (FCROPN), so dass man die Lademodule dynamisch oder statisch an die Anwendung auf der Host binden kann. 

Allgemein kann man über die Satzschnittstelle jede Art von Dataset (PS, PDS, PDSE, VSAM, FB, VB mit und ohne ASA bzw. Maschinensteuerzeichen) auf der Host sowie FLAMFILEs aber auch (hierfür ist die Schnittstelle eigentlich gedacht) Formate von Windows- oder Unix-Systemen (incl. USS) satzorientiert lesen und bekommt die Records beispielsweise im gewünschten Zeichensatz zurück. Hierdurch ist es unter anderem möglich, auf der Host ein Member aus einem ZIP-Archive in UTF-8 mit Delimitern zu lesen oder zu schreiben, obwohl die Records mit Länge und Daten wie üblich in EBCDIC über- bzw. zurückgegeben werden. Das Lesen geschieht hierbei vollkommen transparent. Man muss in COBOL nur den Dateinamen für den FCROPN() wissen, um normale Datasets, FLAMFILEs, Windows-Textdateien oder GZIP-Files von einem UNIX-Systemen satzorientiert lesen zu können.

Die Satzschnittstelle überführt hierbei Texte (read.text()) immer in den systemspezifischen Zeichensatz, es sei denn ein anderer Zeichensatz (z.B. ccsid='UTF-8')) wird angegeben, damit man die Daten zum Beispiel mit Stringkonstanten direkt vergleichen kann. Die Satzschnittstelle bietet somit ein plattformneutrales Interface für den Zugriff auf alle Arten und Formate von Dateien. Sofern eine SSH Verbindung aufgebaut werden kann, ist es z.B. einem COBOL-Programmierer auf der Host möglich eine XML-Datei in Form von EBCDIC Records zu schreiben, welche dann in UTF-8 als verschlüsselte PGP-Datei in einem ZIP-Archiv auf einem entferenten System bereitgestellt wird, ohne das lokal eine I/O-Operation notwendig wäre.

Beim Lesen von Records kann man entscheiden, ob man mit ASA oder Maschinensteuerzeichen Lesen und Schreiben möchte (Retain) oder ob diese ignoriert (DETACH (default)) oder ob diese wie beim Drucken umgesetzt werden sollen (RPLFFD=26 (replace form feed with a page size of 26 rows)), wenn es sich zum Beispiel um eine FBA bzw. VBA Datei handelt. Bei relativen Dateien kann man die Lücken als leere Sätze erhalten oder sie ignorieren. Des Weiteren steht auch hier die Zeichensatzkonvertierung zur Verfügung. Man kann entscheiden, ob Trailing Whitespace entfernt oder Steuerzeichen umgesetzt werden sollen und vieles mehr. Des Weiteren wird, wenn ein Record länger als der zur Verfügung stehende Puffer ist, dies mit einem speziellen Returncode kenntlich gemacht, so dass man dieses Record mit einem größeren Puffer vollständig lesen kann.

Über die Satzschittstelle lässt sich frei entscheiden, wie die Daten gelesen werden. Im Gegensatz zur Byteschnittstelle werden aber alle Daten in Form von Records entgegengenommen oder zurückgegeben. Die Satzschnittstelle ist eine Spezialisierung der Byteschnittstelle, wo für die Formatierung immer die Methode Record (format.record()) oder Element (format.element()) genutzt werden kann.

Die Formattierung von FLAM5-Elementen in Records ist vorallem nützlich, wenn man z.B. in COBOL XML-Elemente direkt mit einer Picture-Clause weiterverarbeiten möchte. Hierfür bietet die Satzschnittstelle eine Menge von V-Funktionen, wo man individuelle Konvertierungen pro Element verwenden kann, um Strings und Zahlen der XML-Datei über Typen der jeweiligen Programmiersprache direkt weiterverarbeiten zu können. Zusätzlich wurde noch mit FCRLOC(V) die Möglichkeit geschaffen, einen Zeiger auf das Record und dessen Länge zu bekommen, um sich das Umkopieren des Satzes zu ersparen. Für das einfache Parsen von Elementlisten wurde noch FCRPRV zur Verfügung gestellt, mit dessen Hilfe man ein Element/Record beim Lesen zurückstellen kann, um es beim nächsten FCRGET(V) oder FCRLOC(V) noch einmal zu bekommen. All diese Feature der Satzschnittstelle ermöglichen es, z.B. in Cobol oder PL1 XML-Daten, welche sich in einem lokalen order remoten BZIP2-File in UTF-8 befinden können, unabhängig von deren Darstellung im XML immer auf die gleiche Art und Weise als Elementsatz in EBCDIC zurück zu bekommen. Hierbei können Strings "collapsed" werden oder Zahlen von möglichen Darstellungen in XML (    .45    ) in eine Darstellung für eine Picture-Clause (0000.45) überführt werden.

Im Rahmen des Table-Supports kann man sich zum Beispiel eine CSV- oder XML-Datei als fixe Datenstruktur in Form eines Records (Copybook) aufbereiten lassen. Oder auch variable Records beim Schreiben in CSV- oder XML-Datein wandeln lassen. Wenn sich mehrer Tabllen in einer Datei befinden, kann man den End-Of-Table-Support beim Lesen aktivieren, welcher es gestattet nach dem Open den Tabellennamen abzufragen, damit man die Daten richtig verarbeiten kann (Auswahl des richtigen Overlays/Unions). Der Switch führt auch dazu, dass man am Ende der Tabelle einen EOT-Error bekommt, wonach wieder der neue Tabellennamen abgefragt werden kann, bis man am Ende EOF bekommt. Beim Schreiben von verschiedenen Tabellen in eine Datei kann man über den Tabellennamen, welcher in der Row-Spezifikation vergeben wird, dan Aufbau der nachfolgenden Daten vorgeben.  Wird dies nicht genutzt wird, die Autodetektierung der Tabellenformate genutzt, um die Daten richtig zu interpretieren.

Die Satzschnittstelle bietet auch die Möglichkeit alle Konvertierungen des FLUC im Speicher aus zu üben. Was FLAM damit zu einen Enterprise-Service-Bus für Transaktionelle/Online-Daten macht. Des weiteren steht die Satzschnittstelle, wie auch alles anderen Lade-Module für z/OS unter der EDZ Umgbung von Microfocus (Linux und Windows) zur Verfügung. Diese Lösung wird zum Beispiel für die Realisierung des Instant-Payments in der Krditwirtschaft genutzt.

Beispiel

COBOL

Das folgende Beispiel in COBOL liest Sätze aus einer GZIP-Datei, welche sich zum Beispiel (binär übertragen) in einem XMIT.PDS auf der Host befindet. Es nutzt hierbei die Auto-Erkennung des Zeichensatzes und lässt sich die Records in IBM-1141 bereitstellen. Das Original war hierbei eine Textdatei von Windows in CP1252 mit 0x0D0A als Delimiter, wobei der Zeichensatz egal ist, da für das Lesen die Auto-Erkennung genutzt wird. Wichtig ist nur, dass es sich beim Original um eine Textdatei mit Delimittern handeln muss. Hierbei kann es vorkommen, dass leere Records ("\n\n") erkannt werden. Da COBOL eine Mindestlänge von 1 für ein Record verlangt, muss dieser Spezialfall entsprechend abgefangen werden. In dem Beispiel unten fügen wir in diesem Fall ein Blank ein.

       IDENTIFICATION DIVISION.
       PROGRAM-ID.  SOFCRGET.
       AUTHOR.      LIMES DATENTECHNIK GMBH.
      *
      *           EXAMPLE FOR USING FLUC RECORD INTERFACE
      *
      *  SOFCRGET READS WITH THE FLUC-RECORD-INTERFACE A TEXT FILE. THE
      *           THE FILE CAN BE COMPRESSED (GZIP/BZIP2/XZ(LZMA)) OR
      *           NOT AND MUST BASED ON TEXT DELIMITER
      *
      *  DD-NAMES USED IN THIS EXAMPLE:
      *
      *    INPUT  THE FILE FLUC HAS TO READ
      *    OUTPUT OUR OUTPUT DATA SET
      *
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT      OUTDAT
           ASSIGN TO   S-OUTPUT
           ACCESS MODE IS SEQUENTIAL.
      *
       DATA DIVISION.
      *
       FILE SECTION.
       FD  OUTDAT  BLOCK CONTAINS 0 CHARACTERS
                   RECORDING MODE V
                   RECORD IS VARYING FROM 1 TO 2040 CHARACTERS
                          DEPENDING ON OUTLEN
                   LABEL  RECORD IS STANDARD.
       01  OUTDAT-RECORD.
           02 FILLER   PIC X(2040).
      *
       WORKING-STORAGE SECTION.
      *
       77  OUTLEN      PIC  9(5).
       77  OPERATION   PIC  X(6).
       77  MAXLEN      PIC  9(8)  COMP VALUE 2040.
      *
       01  FLUC-PARAMETER.
      *
      *  USED FOR ALL FLUC-CALLS
      *
           02 F-ID     PIC S9(8)  COMP.
           02 F-RETCO  PIC S9(8)  COMP.
              88 FLUCOK            VALUE  0.
              88 END-OF-FILE       VALUE  43.
      *
      *  USED FOR FLUC OPEN
      *
           02  F-FILELEN  PIC S9(8)  COMP VALUE 60.
           02  F-FILE     PIC X(60)  VALUE
               'READ.TEXT(FILE=''DD:INPUT'' RECLEN=2040)'.
           02  F-FORMLEN  PIC S9(8)  COMP SYNC VALUE 20.
           02  F-FORM     PIC X(20)  VALUE
               'CCSID=''1141'''.
           02  F-STATLEN  PIC S9(8)  COMP SYNC VALUE 512.
           02  F-STAT     PIC X(512) VALUE ' '.
      *
      *  USED FOR FLUC GET
      *
           02  F-INLEN   PIC S9(8) COMP.
      *
      *  USED FOR FLUC MSG
      *
           02  MSGRC     PIC S9(8) COMP.
           02  MSGLEN    PIC S9(8) COMP VALUE 800.
           02  MSGBUFF   PIC X(800) VALUE SPACES.
      *
      *  USED FOR FLUC CLS
      *
           02  C-DELETE  PIC S9(8) COMP VALUE 0.
           02  C-STATFMT PIC S9(8) COMP VALUE 1.
           02  C-STATLEN PIC S9(8) COMP VALUE 4096.
           02  C-STATBUF PIC X(4096) VALUE SPACES.
      /
       PROCEDURE DIVISION.
      *
       MAIN SECTION.
      *
       OPEN-OUTPUT-DATA.
      *
      *  OPEN DATA SET TO WRITE RECORDS
      *
           OPEN OUTPUT OUTDAT.
      *
       OPEN-FLUC.
      *
      *  CALL THE FLAM UNIVERSAL CONVERTER MODULE FOR OPEN
      *
           CALL  'FCROPN' USING F-ID, F-RETCO,
                                F-FILELEN, F-FILE,
                                F-FORMLEN, F-FORM,
                                F-STATLEN, F-STAT.
           IF  NOT FLUCOK
              THEN  MOVE 'OPEN' TO OPERATION
                    PERFORM FLUC-ERROR
                    GO TO CLOSE-DATA.

           DISPLAY F-STAT.

       READ-RECORD.
      *
      *  READ A RECORD WITH FLAM IN OUTPUT AREA
      *
           MOVE MAXLEN   TO  F-INLEN
      *
           CALL 'FCRGET' USING F-ID, F-RETCO,
                               F-INLEN, OUTDAT-RECORD.
      *
           IF  FLUCOK
             THEN  NEXT SENTENCE
             ELSE  IF  END-OF-FILE
                      THEN GO TO CLOSE-FLUC
                      ELSE MOVE 'GET' TO OPERATION
                           PERFORM FLUC-ERROR
                           GO TO CLOSE-FLUC.
      *
      *  DO WHAT YOU LIKE WITH THE RECORD
      *  .
      *  .
      *
       WRITE-RECORD.
      *
      *  WRITE THE CONVERTED RECORD
      *
           MOVE  F-INLEN  TO OUTLEN
           IF OUTLEN = 0 THEN
               MOVE 1   TO OUTLEN
               MOVE ' ' TO OUTDAT-RECORD
           END-IF
           WRITE OUTDAT-RECORD
      *
           GO TO READ-RECORD.
      *
       CLOSE-FLUC.
      *
      *  CLOSE TO FLUC
      *
           CALL 'FCRCLS' USING F-ID, F-RETCO, C-DELETE
                               C-STATFMT, C-STATLEN, C-STATBUF
           IF  NOT FLUCOK
             THEN MOVE 'CLOSE' TO OPERATION
                  PERFORM FLUC-ERROR.
       CLOSE-DATA.
      *
      *  CLOSE OUTPUT DATA
      *
           CLOSE  OUTDAT.
       MAIN-END.
           MOVE F-RETCO  TO RETURN-CODE
      *
      *  PRINT STATISTIC
      *
           DISPLAY 'READ-STATISTIC FROM FLUC'
           DISPLAY C-STATBUF

           STOP RUN.
      *
      * PRINT THE ERROR SITUATION
      *
       FLUC-ERROR SECTION.
       FLUC-ERROR-1.
           DISPLAY 'SOFCRGET: ERROR IN OPERATION ' OPERATION
           DISPLAY 'ERROR MESSAGE FROM FLUC:'
           MOVE F-RETCO  TO MSGRC
      *  GET THE ERROR MESSAGE
           CALL 'FCRMSG' USING MSGRC, F-RETCO, MSGLEN, MSGBUFF
           DISPLAY MSGBUFF.
       FLUC-ERROR-99.
           EXIT.

Beim FCROPN einen DD-Namen zu verwenden ist an dieser Stelle als Beispiel genommen wurden, um das mitgelierferte Lademodul direkt als Utility in einem Job (EXEC PGM=SCFCRGET) verwenden zu können. Aber eigentlich ist die Satzschnittstelle dafür gedacht, einen Dateinamen direkt anzugeben (read.file='meine.datei.dat'). Hierbei kann man sogar das Leseverfahren (xml/text/char/binary/record/flam) automatisch (read.auto()) bestimmen lassen. Auf dieser Basis kann man jede Art von Datei transparent in klare Records überführen, wobei man nur den Dateinamen wissen muss.

C

Das Beispiel ist ein einfaches C-Programm, welches den File- und Formatstring zum Lesen als auch zum Schreiben entgegennimmt und über das Record-Interface die Dateien kopiert, wobei Kopieren hier nicht ganz richtig ist, denn es können über die Filestrings ja jegliche Konvertierungen  von FLAM ausgeführt werden. Insofern stellt dieses einfache Programm einen Großteil der Funktionalitäten des FLUC zur Verfügung, nur dass hierbei die Konvertierung immer über Records erfolgt.

/**
 * @file   SCFCRCPY.c
 * @brief  Sample program in C to copy files via the FLUC record interface
 * @author limes datentechnik gmbh
 ******************************************************************************/

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#include"FLCRECLB.h"

/**
 * This test program takes four parameters to convert files via the
 * FLUC record interface.
 *
 * @param  argc must be 5
 * @param  argv contains the strings for FCROPN
 * @return 8=parameter error
 *         6=open file error
 *         4=read write error
 *         2=close error
 *         0=Success
 */
int main(int argc, char * argv[])
{
   void*                   pvRed;
   void*                   pvWrt;
   static char             acBuf[65536];
   char                    acSta[2048];
   int                     siLn1,siLn2,siLen,siSta;
   int                     siRtc,siHlp,siWat,siDep,i;
   int                     siDel=1;

   char*                   h;
   char*                   a[5];

   if (argc==2) { // parse HOST parameter string
      i=2; a[0]=argv[0]; a[1]=argv[1];
      h=strchr(a[1],',');
      if (h!=NULL) { h[0]=0x00; a[2]=h+1; i++; }
      h=strchr(a[2],',');
      if (h!=NULL) { h[0]=0x00; a[3]=h+1; i++; }
      h=strchr(a[3],',');
      if (h!=NULL) { h[0]=0x00; a[4]=h+1; i++; }
      argc=i; argv=a;
   }

   siDep=1;
   if (argc!=5) {
      fprintf(stderr,"Parameter count (%d) not correct!\n",argc);
      fprintf(stderr,"Given parameters:\n");
      for (i=0;i<argc;i++) fprintf(stderr,"--> P%2.2d(%s)\n",i,argv[i]);
      fprintf(stderr,"Required parameters:\n");
      fprintf(stderr,"%s \"read file string\" \"read format string\""
         " \"write file string\" \"write format string\"\n",argv[0]);
      siWat=FCR_READ_FILE; siLen=sizeof(acBuf); siHlp=0;
      FCRSYN(&siRtc,&siWat,&siDep,&siHlp,NULL,&siLen,acBuf);
      fprintf(stderr,"READ FILE STRING   : \"%s\"\n",acBuf);
      siWat=FCR_READ_FORMAT;  siLen=sizeof(acBuf); siHlp=0;
      FCRSYN(&siRtc,&siWat,&siDep,&siHlp,NULL,&siLen,acBuf);
      fprintf(stderr,"READ FORMAT STRING : \"%s\"\n",acBuf);
      siWat=FCR_WRITE_FILE;   siLen=sizeof(acBuf); siHlp=0;
      FCRSYN(&siRtc,&siWat,&siDep,&siHlp,NULL,&siLen,acBuf);
      fprintf(stderr,"WRITE FILE STRING  : \"%s\"\n",acBuf);
      siWat=FCR_WRITE_FORMAT; siLen=sizeof(acBuf); siHlp=0;
      FCRSYN(&siRtc,&siWat,&siDep,&siHlp,NULL,&siLen,acBuf);
      fprintf(stderr,"WRITE FORMAT STRING: \"%s\"\n",acBuf);
      exit(8);
   }

   siLn1=strlen(argv[1]); siLn2=strlen(argv[2]); siSta=sizeof(acSta);
   FCROPN(&pvRed,&siRtc,&siLn1,argv[1],&siLn2,argv[2],&siSta,acSta);
   if (pvRed==NULL) {
      fprintf(stderr,"Open file for read operation failed!\n");
      fprintf(stderr,"FCROPN(&pvRed,%d,%d,\"%s\",%d,\"%s\");\n\n",
              siRtc,siLn1,argv[1],siLn2,argv[2]);
      siLen=sizeof(acBuf);
      FCRMSG(&siHlp,&siRtc,&siLen,acBuf);
      fprintf(stderr,"ERRMSG:\n%s\n\n",acBuf);
      siLen=sizeof(acBuf);
      FCRTRC(&siHlp,&siRtc,&siLen,acBuf);
      fprintf(stderr,"ERRTRC:\n%s\n"  ,acBuf);
      exit(6);
   }

   /*Use zero terminated strings*/
   FCROPN(&pvWrt,&siRtc,NULL,argv[3],NULL,argv[4],&siSta,acSta);
   if (pvWrt==NULL) {
      fprintf(stderr,"Open file for write operation failed!\n");
      fprintf(stderr,"FCROPN(&pvWrt,%d,%d,\"%s\",%d,\"%s\");\n\n",
              siRtc,siLn1,argv[3],siLn2,argv[4]);
      siLen=sizeof(acBuf);
      FCRMSG(&siHlp,&siRtc,&siLen,acBuf);
      fprintf(stderr,"ERRMSG:\n%s\n\n",acBuf);
      siLen=sizeof(acBuf); FCRTRC(&siHlp,&siRtc,&siLen,acBuf);
      fprintf(stderr,"ERRTRC:\n%s\n"  ,acBuf);
      FCRCLS(&pvRed,NULL,NULL,NULL,NULL,NULL);
      exit(6);
   }

   for (siLen=sizeof(acBuf),FCRGET(&pvRed,&siRtc,&siLen,acBuf); siRtc==0;
        siLen=sizeof(acBuf),FCRGET(&pvRed,&siRtc,&siLen,acBuf)) {
      FCRPUT(&pvWrt,&siRtc,&siLen,acBuf);
      if (siRtc) {
         fprintf(stderr,"Write data to file failed!\n");
         fprintf(stderr,"FCRPUT(&pvWrt,%d,%d,acBuf);\n\n",
                 siRtc,siLen);
         siLen=sizeof(acBuf);
         FCRMSG(&siHlp,&siRtc,&siLen,acBuf);
         fprintf(stderr,"ERRMSG:\n%s\n\n",acBuf);
         siLen=sizeof(acBuf);
         FCRTRC(&siHlp,&siRtc,&siLen,acBuf);
         fprintf(stderr,"ERRTRC:\n%s\n"  ,acBuf);
         FCRCLS(&pvRed,NULL,NULL,NULL,NULL,NULL);
         FCRCLS(&pvWrt,NULL,NULL,NULL,NULL,NULL);
         exit(4);
      }
   }
   if (siRtc!=FLMRTC_OK && siRtc!=FLMRTC_EOF) {
      fprintf(stderr,"Read data from file failed!\n");
      fprintf(stderr,"FCRGET(&pvRed,%d,%d,acBuf);\n\n",
              siRtc,(int)sizeof(acBuf));
      siLen=sizeof(acBuf);
      FCRMSG(&siHlp,&siRtc,&siLen,acBuf);
      fprintf(stderr,"ERRMSG:\n%s\n\n",acBuf);
      siLen=sizeof(acBuf);
      FCRTRC(&siHlp,&siRtc,&siLen,acBuf);
      fprintf(stderr,"ERRTRC:\n%s\n"  ,acBuf);
      FCRCLS(&pvRed,NULL,NULL,NULL,NULL,NULL);
      FCRCLS(&pvWrt,NULL,NULL,NULL,NULL,NULL);
      exit(4);
   }

   siLen=sizeof(acBuf);
   FCRCLS(&pvWrt,&siRtc,&siDel,NULL,&siLen,acBuf);
   if (siRtc) {
      fprintf(stderr,"Close file for write operation failed!\n");
      fprintf(stderr,"FCRCLS(&pvWrt,%d);\n\n",siRtc);
      siLen=sizeof(acBuf);
      FCRMSG(&siHlp,&siRtc,&siLen,acBuf);
      fprintf(stderr,"ERRMSG:\n%s\n\n",acBuf);
      siLen=sizeof(acBuf);
      FCRTRC(&siHlp,&siRtc,&siLen,acBuf);
      fprintf(stderr,"ERRTRC:\n%s\n"  ,acBuf);
      FCRCLS(&pvRed,NULL,NULL,NULL,NULL,NULL);
      exit(2);
   } else {
      fprintf(stderr,"Statistic for FCROPN(\"%s\",\"%s\")\n",argv[3],argv[4]);
      fprintf(stderr,"%s",acBuf);
   }

   siLen=sizeof(acBuf);
   FCRCLS(&pvRed,&siRtc,&siDel,NULL,&siLen,acBuf);
   if (siRtc) {
      fprintf(stderr,"Close file for read operation failed!\n");
      fprintf(stderr,"FCRCLS(&pvRed,%d);\n\n",siRtc);
      siLen=sizeof(acBuf);
      FCRMSG(&siHlp,&siRtc,&siLen,acBuf);
      fprintf(stderr,"ERRMSG:\n%s\n\n",acBuf);
      siLen=sizeof(acBuf);
      FCRTRC(&siHlp,&siRtc,&siLen,acBuf);
      fprintf(stderr,"ERRTRC:\n%s\n"  ,acBuf);
      exit(2);
   } else {
      fprintf(stderr,"Statistic for FCROPN(\"%s\",\"%s\")\n",argv[1],argv[2]);
      fprintf(stderr,"%s",acBuf);
   }

   exit(0);
}

/**********************************************************************/

Mehr Information können Sie der Schnittstellenspezifikation im Downloadbereich entnehmen.