29
Fri, Nov
0 New Articles

The Hierarchical File System APIs

APIs
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

Have you ever thought, "If only my AS/400 program could read a PC file directly from the shared folders, I'd have it made!" Then, in walks the boss, who says, "I have this new project...."

Suddenly, a wistful thought escalates to a frantic search for the technical knowledge to pull yet another rabbit out of your hat. Fortunately, you remember hearing about the lesser-known system APIs that enable AS/400 applications to work transparently with PC files residing on the shared folders-Hierarchical File System (HFS) APIs.

With a knowledge of HFS APIs, you'd be in a better position to jump into that new project the boss has planned. When you've finished reading this article, you won't need magic hats or rabbits-knowledge of HFS APIs will be your sleight of hand, and techniques of modularity will be your tool for reproduction. It's all a matter of getting the pieces to fit together.

As the need for distributed systems continues to dominate our industry, the landscape most of us are accustomed to is changing drastically. Some things take a bit more time to change than others, however. For one reason or another, management may wish some functions (such as the payment and receipt of cash) to remain host-centric, while other functions (such as the entry of bills or invoices) are served by distributed applications. Yet, as is often the case, one is in opposition to the other, and the need to seamlessly access data from a diverse set of file systems becomes even more critical to the productivity and sanity of users.

In today's computing environment, it is common to need to upload data from DOS, OS/2, UNIX, or other file systems. These other file systems may be numerous and geographically dispersed, making wide area network (WAN) access an expensive option. If you're not careful to select development techniques that promote consolidation and integration of user activities, applications can become fragmented and start to look like a jigsaw puzzle. Getting the pieces to fit together smoothly can be challenging.

You could take several approaches to access PC file data. One might be to have remote users send PC (ASCII) text file data on diskettes to the corporate office. However, this has the disadvantages of excessive postal charges, slow response time, and poor error-correction facilities (if the data is wrong, the remote user must send another diskette). Additional considerations are the cost of diskettes (since these might need to be sent more than once a week from several locations), potential damage in transit, and the possibility of being infected by viruses arising from such widespread diskette circulation.

Then, once the diskettes arrive for processing, the PC file data must be uploaded to an AS/400 file member for corporate systems processing. Such a transformation creates additional steps for the corporate staff, causing a loss in direct traceability. For example, the data flows from the PC file to a transient AS/400 file member to the corporate payable batch file, instead of directly from the PC file to the corporate payables batch file.

With each group of invoices contained in a PC file being assigned a batch number, an audit trail is made that carries the identity through the system for the life of the data. However, when data is uploaded to transient file members, identification may change because of incompatibility of naming conventions between file systems. For example, A&P0494.TXT is entirely appropriate for an MS-DOS file name, but inappropriate for an AS/400 file name.

Some clear advantages come with using AS/400 shared folders as a repository for data awaiting integration into AS/400 files: the elimination of physical handling of media; good delivery response (you can connect and deposit PC files on shared folders); and, for users, conceptual association with a common technique used by many BBSs today-batch file (or offline) transfer (connect-deposit-disconnect).

Only one obstacle remains: that of direct access of PC file data residing on the AS/400 shared folders from an AS/400 application.

Why direct access to shared folders data, anyway? After all, with the Copy from PC Document (CPYFRMPCD) command, you can copy PC file data residing on an AS/400 folder to an AS/400 file member with automatic ASCII-to-EBCDIC data translation. However, if interactive response is an important consideration for your application, such an approach produces less than acceptable results. Using HFS APIs requires the programmer to handle the ASCII-to-EBCDIC translation, but when both techniques were benchmarked, CPYFRMPCD required 3-5 times as long to process as the HFS API method.

Suppose you have a process whereby remote AS/400 users can dial up and deposit PC file data into AS/400 shared folders-sort of like a BBS or offline E-mail. All you need is a way for local (corporate) AS/400 users to get to the data. With HFS APIs, you can display a list of folders to the local users for selection. After selection, the users are presented with a list of PC shared folder files (from the selected folder) like that illustrated in 1. The files can in turn be selected for further processing. Although the Display Folder (DSPFLR) command with the OUTFILE option selected could also have been used to build this list, interactive performance would have suffered significantly.

Suppose you have a process whereby remote AS/400 users can dial up and deposit PC file data into AS/400 shared folders-sort of like a BBS or offline E-mail. All you need is a way for local (corporate) AS/400 users to get to the data. With HFS APIs, you can display a list of folders to the local users for selection. After selection, the users are presented with a list of PC shared folder files (from the selected folder) like that illustrated in Figure 1. The files can in turn be selected for further processing. Although the Display Folder (DSPFLR) command with the OUTFILE option selected could also have been used to build this list, interactive performance would have suffered significantly.

Accessing the data directly from the shared folders can be accomplished through HFS APIs. Shared folders is a document library services (DLS) file system and uses a hierarchical file system architecture similar to that used by MS-DOS for the storage and management of user files. The architecture organizes files and programs according to the directorysubdirectoryfile trees most of us are acquainted with, as illustrated in 2.

Accessing the data directly from the shared folders can be accomplished through HFS APIs. Shared folders is a document library services (DLS) file system and uses a hierarchical file system architecture similar to that used by MS-DOS for the storage and management of user files. The architecture organizes files and programs according to the directorysubdirectoryfile trees most of us are acquainted with, as illustrated in Figure 2.

IBM developed the HFS APIs to enable an AS/400 application to extract data directly from a DOS-type or byte-stream file without having to upload that file to an AS/400 file before it could be used. However, interfacing with those APIs can be complex in comparison to typical AS/400 development. Such complexity precludes, or at least makes difficult, using these APIs on a widespread basis. However, by developing and documenting a set of globally callable functions, you can make the services that are available through the HFS APIs more appealing for use in a greater number of applications. To make these global functions more extensible, we take a modular approach and construct black box interface programs that make it easy for any program in your application to open, read, and close PC files residing on the shared folders.

We can build a generic utility program that services our HFS API needs, so client (requester) applications don't have to know its implementation to use it. By creating a public interface with a standard set of functions that embody HFS API services, we can hide the complexity of their implementation from client applications.

As depicted in 3, the client (requester) program first issues an *OPEN request to the black box utility to open the byte-stream file. Next, the client program issues consecutive *READ requests to extract the PC file records one at a time. Finally, the client program issues a *CLOSE request to close the stream file. The HFS APIs needed to accomplish each of these objectives are presented in 3 as calls from our black box program, but they are not visible to client programs. The client program is thus insulated from the complexity of arbitrating directly with the HFS APIs for their services.

As depicted in Figure 3, the client (requester) program first issues an *OPEN request to the black box utility to open the byte-stream file. Next, the client program issues consecutive *READ requests to extract the PC file records one at a time. Finally, the client program issues a *CLOSE request to close the stream file. The HFS APIs needed to accomplish each of these objectives are presented in Figure 3 as calls from our black box program, but they are not visible to client programs. The client program is thus insulated from the complexity of arbitrating directly with the HFS APIs for their services.

HFS API names begin with Q followed by HF, which designates HFS APIs. The translation API that will be called to convert the ASCII text data read from byte-stream files to EBCDIC for host presentations is designated as a data conversion (DC) API and not a part of the HFS API suite. Each of these APIs are well-documented in the OS/400 System API Reference V3R1.

The black box or generic utility application that will service our PC data extraction needs, shown in part in 4, has as its interface one input parameter and one output parameter. Only the portions of the black box code required to explain the HFS APIs are included here; however, the complete program (XA0020R) can be found on MC-BBS or on the Internet at www.as400.com/mc/prog. (Complete code for another HFS black box program (XA0021R) that returns shared folder directory information can also be found on MC-BBS and at www.as400.com/mc/prog. XA0021R was used by the program that produced the list of invoice files displayed in the pop-up window in 1.)

The black box or generic utility application that will service our PC data extraction needs, shown in part in Figure 4, has as its interface one input parameter and one output parameter. Only the portions of the black box code required to explain the HFS APIs are included here; however, the complete program (XA0020R) can be found on MC-BBS or on the Internet at www.as400.com/mc/prog. (Complete code for another HFS black box program (XA0021R) that returns shared folder directory information can also be found on MC-BBS and at www.as400.com/mc/prog. XA0021R was used by the program that produced the list of invoice files displayed in the pop-up window in Figure 1.)

Some of the fields in the 256-byte input parameter data structure (XA0020), shown in label A of 4, are requester options, while others serve as feedback information to the requester application about the status of the last request. The XA0020 subfields and their usage are as follows:

Some of the fields in the 256-byte input parameter data structure (XA0020), shown in label A of Figure 4, are requester options, while others serve as feedback information to the requester application about the status of the last request. The XA0020 subfields and their usage are as follows:

o FUNCTN=Name of requester function to be performed (required, no defaults). The valid functions are *OPEN, *READ, and *CLOSE.

o FILSYS=File system (optional, defaults to /QDLS when blank).

o PATH=Path name for PC file, including file name (required, no defaults).

o RECLEN=Expected record length of one logical PC file record from the extraction file (required, no defaults).

o LASTR=Last record indicator on a *READ function.

o RESRVD=Bytes reserved for black box services expansion.

o RTNCOD=Return code (0=no errors).

The output parameter data structure (INRECD) shown in label B of 4 is used strictly as an output buffer for data extracted from the PC file. It may be as large as 4KB, but specifying a record length larger than that required by your application will cause the black box utility to perform inefficiently. Specifying too short a record length can cause this utility to abort with a terminal return code (RTNCOD) if the end-of-record indication (X'0D0A') cannot be found.

The output parameter data structure (INRECD) shown in label B of Figure 4 is used strictly as an output buffer for data extracted from the PC file. It may be as large as 4KB, but specifying a record length larger than that required by your application will cause the black box utility to perform inefficiently. Specifying too short a record length can cause this utility to abort with a terminal return code (RTNCOD) if the end-of-record indication (X'0D0A') cannot be found.

To begin the explanation of the stream file APIs in 4, I have defined some constants in label C of 4 to make the code more readable. The utilities' functions are identified in label D. In labels E and F of 4, parameters that will be passed to the Open Stream File (QHFOPNSF) API are initialized. In label F, the important values set are for the error code (ERRCOD) and the open information code (OPNINF). The error code is set to zero to direct the API to send an exception message to the calling application (our generic program) when an error occurs. The OPNINF parameter with a value of '100 200' directs the API to open the file in read-only mode. Other jobs can read this file, but they cannot write to it while it is being used by this application.

To begin the explanation of the stream file APIs in Figure 4, I have defined some constants in label C of Figure 4 to make the code more readable. The utilities' functions are identified in label D. In labels E and F of Figure 4, parameters that will be passed to the Open Stream File (QHFOPNSF) API are initialized. In label F, the important values set are for the error code (ERRCOD) and the open information code (OPNINF). The error code is set to zero to direct the API to send an exception message to the calling application (our generic program) when an error occurs. The OPNINF parameter with a value of '100 200' directs the API to open the file in read-only mode. Other jobs can read this file, but they cannot write to it while it is being used by this application.

Each byte in the OPNINF field has a specific meaning. For example, here's how IBM identifies possible values for the first byte (open action) if the file already exists:

o 0 Do not open the file. Return an error.

o 1 Open the file.

o 2 Replace the existing file.

IBM identifies which operations other jobs can perform on the file (file lock mode) in the fifth byte:

o 1 Deny none.

o 2 Deny write.

o 3 Deny read.

o 4 Deny read/write (exclusive).

The other bytes and their meanings are well-documented in the OS/400 System API Reference V3R1 and will not be discussed in this article.

In label E of 4, the full path, inclusive of the selected document (file) name, is constructed. For example, a file by the name of MAY0494 residing in shared folder INVOICES would appear as /QDLS/INVOICES/MAY0494.TXT.

In label E of Figure 4, the full path, inclusive of the selected document (file) name, is constructed. For example, a file by the name of MAY0494 residing in shared folder INVOICES would appear as /QDLS/INVOICES/MAY0494.TXT.

As you can see, the file system identification must prefix the path name presented to the QHFOPNSF API in label F. A table of the required parameters appears immediately below the call statement of the QHFOPNSF API in label F. The file handle (FILHDL) acquired as output in the QHFOPNSF API will be used by subsequently called APIs.

As shown in 4, one logical PC file record is read from the stream file on the shared folders (with each *READ call service request) with the aid of the Read Stream File (QHFRDSF) API in label G of 4, utilizing the FILHDL acquired by the QHFOPNSF API. The number of bytes to read (#TREAD) is passed by the caller through the input parameter data structure XA0020, subfield RECLEN. Next, in label H of 4, we scan the string read (as defined by INRECD) for the ASCII carriage return character (X'0D') that will signal the end of the record. After that, we translate the extracted string from its current ASCII encoding scheme to EBCDIC for AS/400 processing with the call to the Data Translation (QDCXLATE) API shown in label I.

As shown in Figure 4, one logical PC file record is read from the stream file on the shared folders (with each *READ call service request) with the aid of the Read Stream File (QHFRDSF) API in label G of Figure 4, utilizing the FILHDL acquired by the QHFOPNSF API. The number of bytes to read (#TREAD) is passed by the caller through the input parameter data structure XA0020, subfield RECLEN. Next, in label H of Figure 4, we scan the string read (as defined by INRECD) for the ASCII carriage return character (X'0D') that will signal the end of the record. After that, we translate the extracted string from its current ASCII encoding scheme to EBCDIC for AS/400 processing with the call to the Data Translation (QDCXLATE) API shown in label I.

In label J of 4, using the position of the carriage return obtained in label H, we calculate and reposition the file pointer to the first position following the carriage return (X'0D') and linefeed (X'0A') characters to ready it for the next extraction cycle. The algorithm to calculate the number of bytes to move the file pointer in the byte-stream is DSTTMV = F - (#READ + 1) or, simply stated, "the distance to move the file pointer=(the current position of X'0D' in the extracted string + 2) - (the number of actual characters read + 1)."

In label J of Figure 4, using the position of the carriage return obtained in label H, we calculate and reposition the file pointer to the first position following the carriage return (X'0D') and linefeed (X'0A') characters to ready it for the next extraction cycle. The algorithm to calculate the number of bytes to move the file pointer in the byte-stream is DSTTMV = F - (#READ + 1) or, simply stated, "the distance to move the file pointer=(the current position of X'0D' in the extracted string + 2) - (the number of actual characters read + 1)."

This calculation yields a negative number and has the effect of moving the file pointer backward the number of bytes previously overread, to reposition it to the beginning of the next logical record. This must be accomplished to extract the next logical PC file record since the pointer will, in all probability, be pointing to a position somewhere beyond the beginning of the next logical record after an extraction. Remember, the file pointer is positioned at the end of the actual character string read, which may or may not be the end of the record.

Our client program may have no way of knowing the record length of each file to be extracted. You may reposition the file pointer with the Change File Pointer (QHFCHGFP) API. The end-of-file indication is given when an error is received from QHFCHGFP in an attempt to move the file pointer beyond the end of the file. This causes a normal exit to occur from the loop processing. Once processing has been dispatched for the stream file, you should close it using the Close Stream File (QHFCLOSF) API in label K of 4. In every case, the FILHDL acquired in the QHFOPNSF operation was passed to the APIs for accessing the stream file.

Our client program may have no way of knowing the record length of each file to be extracted. You may reposition the file pointer with the Change File Pointer (QHFCHGFP) API. The end-of-file indication is given when an error is received from QHFCHGFP in an attempt to move the file pointer beyond the end of the file. This causes a normal exit to occur from the loop processing. Once processing has been dispatched for the stream file, you should close it using the Close Stream File (QHFCLOSF) API in label K of Figure 4. In every case, the FILHDL acquired in the QHFOPNSF operation was passed to the APIs for accessing the stream file.

Let's put this concept of reuse through modularity to the test by employing our generic utility program to extract the data in ASCII text PC files residing on the AS/400 shared folders. To accomplish this, we will view the generic utility program as a black box. That is, forget all the details of the generic utility program you just learned; all we should be concerned with to use this utility is what goes into the box (the input parameters or requester options) and what comes out (the feedback indicators and the translated PC data). 5 illustrates the code (not shown in its entirety) required by any client application to use this generic utility application.

Let's put this concept of reuse through modularity to the test by employing our generic utility program to extract the data in ASCII text PC files residing on the AS/400 shared folders. To accomplish this, we will view the generic utility program as a black box. That is, forget all the details of the generic utility program you just learned; all we should be concerned with to use this utility is what goes into the box (the input parameters or requester options) and what comes out (the feedback indicators and the translated PC data). Figure 5 illustrates the code (not shown in its entirety) required by any client application to use this generic utility application.

The section of code entitled "Open a request..." has the requirements for loading the necessary parameters for the call to our generic utility program. The black box program passes the data representing individual records from our selected PC file in the RECBFR data structure already translated to the EBCDIC data format expected by AS/400 programs.

It is of paramount importance to ensure that the options are properly initialized (in the request options parameter) for the call to our generic utility program. As shown in the *OPEN request in label A of 5, the path is the only required piece of information. When left blank, the file system will default to the QDLS system. As shown in the *READ request presented in the $EXTPC subroutine in 5, in addition to setting the last record (LASTR) and RTNCOD indicators to *OFF, in label B we must specify the expected record length for the PC file data being extracted. In the example here, we have chosen 512 bytes as our expected record length. Finally, in label C of 5 (in the section of code entitled "Close a request..."), the only information required is the function name, *CLOSE.

It is of paramount importance to ensure that the options are properly initialized (in the request options parameter) for the call to our generic utility program. As shown in the *OPEN request in label A of Figure 5, the path is the only required piece of information. When left blank, the file system will default to the QDLS system. As shown in the *READ request presented in the $EXTPC subroutine in Figure 5, in addition to setting the last record (LASTR) and RTNCOD indicators to *OFF, in label B we must specify the expected record length for the PC file data being extracted. In the example here, we have chosen 512 bytes as our expected record length. Finally, in label C of Figure 5 (in the section of code entitled "Close a request..."), the only information required is the function name, *CLOSE.

One final note: V3R1 of OS/400 introduces the Integrated File System (IFS), a feature for handling and manipulating files from diverse file systems. Besides handling the record-oriented file system with which we are all familiar (QSYS.LIB), interaction with four other types of file systems (root, QOpenSys, QDLS, and QLANSrv) that deal with byte-stream files is integrated into the already robust set of OS/400 file commands, menus, and displays.

After a brief review of the programming interfaces provided for the IFS, though, you quickly find that only one language is supported with a suitable programming interface to IFS functions: ILE C/400. For those installations still managing legacy RPG III or even RPG II code, ILE seems a bit too far in the future, to say nothing of ILE C/400. Regardless, ILE C/400 does offer a useful set of functions to open, read, write, and close byte-stream files. However, extended attributes (EAs) cannot be accessed through ILE C/400 functions. For those, you must still use the HFS APIs. You can read more about the IFS and ILE C/400 functions in the references listed at the end of this article.

As you can see from this example, you could easily construct commands, such as an AS/400 version of the DOS command TYPE, using this same generically called program, without having any knowledge of HFS APIs or shared folders. In fact, I wrote a TYPE utility for the AS/400 that allows any AS/400 user to view the contents of a PC file stored on a shared folder, even from a terminal. You can find the code for the TYPE utility on the MC-BBS or at www.as400.com/mc/prog.

Jim D. Barnes is the informations systems director of the Morningstar Group, based in Dallas, Texas. He has been a professional developer of software on the AS/400 and S/38 for over 13 years and is currently interested in object-oriented technology and its practical application in client/server development for the AS/400.


The Hierarchical File System APIs

Figure 1: Selecting PC Shared Folders Files from an AS/400 Application

 
  AP9999T1              Load and Edit Transmitted Invoices            5/27/95 
                                          ..................................  
                                          :     * Transfer Invoices *      :  
  Type options, press Enter.              :    South Dallas Distribution   : 
    1=Select                              :                                :  
                                          :  Type options, press Enter.    :  
  Opt Location      Location Name         :    1=Select                    :  
   1  DALLAS        South Dallas Distribut:                                :  
      DENVER        Denver Area Distributi:     MAY0294.TXT                :  
      CHICAGO       Chicago A & P Distribu:     MAY0494.TXT                :  
                                          :     MAY0694.TXT                :  
                                          :                                :  
                                          :                                :  
                                          :                                :  
                                          :                         Bottom :  
                                          :  F1=Help   F12=Cancel          :  
                                          :  F15=Move  F21=Print list      :  
                                          :                                :  
                                          :................................:  
                                                                                 
                                                                       Bottom 
  F1=Help      F3=Exit     F7=Backward      F8=Forward      F12=Cancel           
  F21=Print list                                                                 
  Your Company Name, LTD. 1994. 
  
The Hierarchical File System APIs

Figure 2: The Hierarchical File System


The Hierarchical File System APIs

Figure 3: An HFS Black Box Program



The Hierarchical File System APIs

Figure 4: Partial Code for the RPG HFS Black Box Program

 
  
      I*********************************************************************** 
      I*  Requester Input Parameter. 
      I*********************************************************************** 
      IXA0020      DS                            256 
      I                                        1  10 FUNCTN 
      I                                       11  20 FILSYS 
      I                                       21  83 PATH 
      I                                    P  84  860RECLEN 
      I                                       87  87 LASTR 
      I                                       88 255 RESRVD 
      I                                      256 256 RTNCOD 
      I*********************************************************************** 
      I*  Requester Output Parameter. 
      I*********************************************************************** 
      IINRECD      DS                           4096 
      I                                        1   1 RECBFR 
      I*********************************************************************** 
      I*  Program defined constants. 
      I*********************************************************************** 
      I              '/QDLS'               C         @QDLS 
      I              '9'                   C         @ERR 
      I              X'0D'                 C         @CRRTN 
      I              X'0A'                 C         @LNFED 
      I              X'20'                 C         @HEX20 
      I              'QCPFMSG   '          C         @MSGF 
      I              'QSYS      '          C         @MSGLB 
      C******************************************************************** 
       * 
       *--------- Reinitialize when the current client requester is not the 
       *--------- same as the last (indicating a proper "Close" was not 
       *--------- initiated). 
       * 
      C           CURPGM    IFNE LSTPGM 
      C                     EXSR $INZSR 
      C                     MOVELCURPGM    LSTPGM 
      C                     ENDIF 
       * 
       *--------- Scope of valid stream file operations include "open", 
       *--------- "read" and "close". All other operations are invalid. 
       * 
      C           FUNCTN    CASEQ'*OPEN'   $OPNSF 
      C           FUNCTN    CASEQ'*READ'   $REDSF 
      C           FUNCTN    CASEQ'*CLOSE'  $CLOSF 
      C                     CAS            $ERRSF 
      C                     ENDCS 
       * 
       *--------- The program is returned with *INLR *OFF. This terminates 
       *--------- it but keeps it resident (TSR) to substantially improve 
       *--------- CALL performance. 
       * 
      C                     RETRN 
      C******************************************************************** 
      C           $INZSR    BEGSR                           Initialize 
      C******************************************************************** 
      C           *ENTRY    PLIST 
      C                     PARM           XA0020 
      C                     PARM           INRECD 
       * 
       *--------- Initialize variables required for stream file option 
       *--------- defaults. 
       * 
      C                     MOVE *ZEROS    PTHLEN 
      C                     MOVE *OFF      RTNCOD 
      C                     MOVE *ZEROS    MSGLEN 
      C                     MOVE *ZEROS    MSGSTK 
      C           ' ':@HEX20XLATEASC20:1   ASC20 
       * 
      C                     MOVE *ZEROS    IJ      30 
       * 
       *--------- Set return code to '1' for NO path specified and end 
       *--------- program. 
       * 
      C           PATH      IFEQ *BLANKS 
      C                     MOVE '1'       RTNCOD 
      C                     EXSR $SNDMG 
      C                     EXSR $ENDPG 
      C                     ENDIF 
       * 
       *--------- When the input file system name is blank, default the 
       *--------- shared folders file system, "QDLS". 
       * 
      C           FILSYS    IFEQ *BLANKS 
      C                     MOVEL@QDLS     FILSYS 
      C                     ENDIF 
       * 
       *--------- Compile complete DLS path name (adding HFS identifier 
       *--------- for file system used by folders - QDLS). Calculate 
       *--------- total path length. 
       * 
      C                     MOVE *BLANKS   PTHNAM 63 
      C                     MOVELPATH      FWDSLH  1 
      C           PTHNAM    CAT  FILSYS:0  PTHNAM 
       * 
      C           FWDSLH    IFNE '/' 
      C           PTHNAM    CAT  '/':0     PTHNAM 
      C                     ENDIF 
       * 
      C           PTHNAM    CAT  PATH:0    PTHNAM 
      C           ' '       SCAN PTHNAM    IJ             30 
      C           *IN30     IFEQ *ON 
      C           IJ        ANDGT*ZERO 
      C                     SUB  1         IJ 
      C                     ELSE 
      C                     Z-ADD63        IJ 
      C                     ENDIF 
      C                     Z-ADDIJ        PTHLEN 
      C*-------- 
      C                     ENDSR 
      C******************************************************************** 
      C           $OPNSF    BEGSR                           Open Stream File 
      C******************************************************************** 
      C                     MOVE *BLANKS   FILHDL 
      C                     MOVEL'100 200' OPNINF 
      C                     MOVE *OFF      ACTTKN 
      C                     Z-ADD*ZERO     ERRCOD 
      C                     Z-ADD*ZEROS    TBLLEN 
       * 
       *--------- Open byte-stream file for defined path and file. 
       * 
      C                     CALL 'QHFOPNSF'             68  OPEN FILE 
      C                     PARM           FILHDL 
      C                     PARM           PTHNAM 
      C                     PARM           PTHLEN 
      C                     PARM           OPNINF 
      C                     PARM           ATRTBL  1 
      C                     PARM           TBLLEN 
      C                     PARM           ACTTKN 
      C                     PARM           ERRCOD 
       * 
       *	      Required Parameter Group: 
       *	 
       *	      1      Open file handle             Output  Char(16) 
       *	      2      Path name                    Input   Char(*) 
       *	      4      Open information             Input   Char(10) 
       *	      3      Path name length             Input   Binary(4) 
       *	      5      Attribute information table  Input   Char(*) 
       *	      6      Length of attribute infor-   Input   Binary(4) 
       *	             mation table 
       *	      7      Action taken                 Output  Char(1) 
       *	      8      Error code                   I/O     Char(*) or 
       *	                                                  Binary(4) 
       * 
       * 
      C           *IN68     IFEQ *ON 
      C                     MOVE '3'       RTNCOD 
      C                     EXSR $SNDMG 
      C                     EXSR $ENDPG 
      C                     ENDIF 
      C*-------- 
      C                     ENDSR 
      C******************************************************************** 
      C           $REDSF    BEGSR                           Read Stream File 
      C******************************************************************** 
       * 
       *--------- Read and translate byte-stream file. Then reposition 
       *--------- byte-stream pointer to next logical record. Cycle 
       *--------- through the stream file until end-of-file indication 
       *--------- given by failure in repositioning. 
       * 
      C                     Z-ADDRECLEN    #TREAD 
      C                     Z-ADD*ZEROS    #READ 
      C                     Z-ADD*ZERO     ERRCOD 
       * 
       *--------- Clear record area to ASCII X'20' which is the same as 
       *--------- EBCDIC X'40' or blank. 
       * 
      C                     MOVELASC20     INRECD 
       * 
       *--------- Read stream file bytes. 
       * 
      C                     CALL 'QHFRDSF'              68  READ ERROR 
      C                     PARM           FILHDL 
      C                     PARM           INRECD 
      C                     PARM           #TREAD 
      C                     PARM           #READ 
      C                     PARM           ERRCOD 
       * 
       *           Required Parameter Group: 
       * 
       *           1      Open file handle             Input   Char(16) 
       *           2      Data buffer                  Input   Char(*) 
       *           3      Bytes to read                Input   Binary(4) 
       *           4      Bytes actually read          Input   Binary(4) 
       *           5      Error code                   I/O     Char(*) or 
       *                                                       Binary(4) 
       * 
      C           *IN68     IFEQ *OFF 
       * 
       *--------- Scan for ASCII carriage return code signalling end 
       *--------- of PC file record. Use this to replace with HEX20 or 
       *--------- ASCII blanks, as well as to change position of stream 
       *--------- file pointer back to first byte after X'0D0A' or 
       *--------- carriage return and linefeed codes, signalling the 
       *--------- beginning of the next PC file record. 
       * 
      C                     MOVE *ZEROS    F       30 
      C           @CRRTN    SCAN INRECD    F              31 
      C           *IN31     IFEQ *ON 
      C                     MOVEAINRECD    INA 
      C                     MOVEAASC20     INA,F 
      C                     MOVEAINA       INRECD 
      C                     ELSE 
      C                     MOVE *ON       *IN68 
      C                     ENDIF 
       * 
      C           *IN68     IFEQ *OFF 
       * 
       *--------- Increment 'F' by two to put it beyond the X'0D'/X'0A' 
       *--------- string or end-of-record. 
       * 
      C                     ADD  2         F 
       * 
       *--------- Translate the retrieved ASCII buffer to EBCDIC for 
       *--------- AS/400 processing. 
       * 
      C                     CALL 'QDCXLATE'             68  CVT TO EBCDIC 
      C                     PARM RECLEN    INRLEN  50 
      C                     PARM           INRECD 
      C                     PARM 'QEBCDIC' SBCDNM 10 
      C                     PARM 'QSYS'    SBCSLB 10 
       * 
      C           *IN68     IFEQ *OFF 
       * 
       *--------- Change stream file pointer to the beginning of the 
       *--------- next PC file record. 
       * 
      C           #READ     ADD  1         BYTRED  30 
      C           F         SUB  BYTRED    FPA     30 
      C                     CALL 'QHFCHGFP'             68  CHANGE FILE PTR 
      C                     PARM           FILHDL 
      C                     PARM '1     '  MOVINF  6 
      C                     PARM FPA       DSTTMV 
      C                     PARM *ZERO     NEWOFS 
      C                     PARM *ZERO     ERRCOD 
       * 
       * 
       *           Required Parameter Group: 
       * 
       *           1      Open file handle             Input   Char(16) 
       *           2      Move information             Input   Char(6) 
       *           3      Distance to move             Input   Binary(4) 
       *           4      New offset                   Output  Binary(4) 
       *           5      Error code                   I/O     Char(*) or 
       *                                                       Binary(4) 
       * 
       * 
      C                     MOVE *IN68     LASTR 
       * 
      C                     ELSE 
      C                     MOVE '7'       RTNCOD 
      C                     ENDIF 
       * 
      C                     ELSE 
      C                     MOVE '8'       RTNCOD 
      C                     ENDIF 
       * 
      C                     ELSE 
      C                     MOVE '9'       RTNCOD 
      C                     ENDIF 
       * 
      C           RTNCOD    IFNE *OFF 
      C                     EXSR $SNDMG 
      C                     EXSR $ENDPG 
      C                     ENDIF 
      C*--------- 
      C                     ENDSR 
      C******************************************************************** 
      C           $CLOSF    BEGSR                           Close Stream File 
      C******************************************************************** 
       * 
       *--------- End stream file processing. 
       * 
      C                     Z-ADD*ZERO     ERRCOD 
       * 
       *--------- Close stream file. 
       * 
      C                     CALL 'QHFCLOSF'             68  CLOSE ERROR 
      C                     PARM           FILHDL 
      C                     PARM           ERRCOD 
       * 
       * 
       *          Required Parameter Group: 
       * 
       *          1      Open file handle             Input   Char(16) 
       *          2      Error code                   I/O     Char(*) or 
       *                                                      Binary(4) 
       * 
      C           RTNCOD    IFEQ *OFF 
      C           *IN68     ANDEQ*ON 
      C                     MOVE '5'       RTNCOD 
      C                     EXSR $SNDMG 
      C                     EXSR $ENDPG 
      C                     ENDIF 
      C*--------- 
      C                     ENDSR 
      C******************************************************************** 
      C           $ENDPG    BEGSR                           End Program 
      C******************************************************************** 
      C                     MOVE *ON       *INLR 
      C                     RETRN 
      C*--------- 
      C                     ENDSR 
  

The Hierarchical File System APIs

Figure 5: Partial Code for the Interface to the HFS Black Box Program

 
 Open a request... 
  
      C******************************************************************** 
      C           *INZSR    BEGSR                           INITIALIZE 
      C******************************************************************** 
      C           *ENTRY    PLIST 
      C                     PARM           INPPTH 50 
       * 
       *--------- Initialize all required default field values. 
       * 
      C                     MOVE *ZEROS    BYTRCV 
       * 
       *--------- Flip back slashes to forward slashes where found. 
       * 
      C           '':'/'   XLATEINPPTH    INPPTH 
       * 
       *--------- Call the generic program for extracting byte-stream file data 
       *--------- from files residing on AS/400 shared folders.                 
       * 
      C                     MOVE *BLANKS   XA0020 
      C                     MOVEL'*OPEN'   FUNCTN 
      C                     MOVELINPPTH    PATH 
      C                     MOVE *OFF      LASTR 
      C                     MOVE *OFF      RTNCOD 
       * 
      C                     CALL 'XA0020R'              68  OPEN STREAM FILE 
      C                     PARM           XA0020 
      C                     PARM           RECBFR 
       * 
      C           *IN68     IFEQ *ON 
      C           RTNCOD    ORNE *OFF 
      C                     MOVE *ON       *INLR 
      C                     RETRN 
      C                     ENDIF 
      C*-------- 
      C                     ENDSR 
       * 
      C******************************************************************** 
      C           $EXTPC    BEGSR                           EXTRACT PC DATA 
      C******************************************************************** 
      C                     MOVE *BLANKS   XA0020 
      C                     MOVEL'*READ'   FUNCTN 
      C                     Z-ADD512       RECLEN 
      C                     MOVE *OFF      RTNCOD 
      C                     MOVE *OFF      LASTR 
       * 
      C           *IN68     DOWEQ*OFF 
      C           RTNCOD    ANDEQ*OFF 
      C           LASTR     ANDEQ*OFF 
       * 
      C                     CALL 'XA0020R'              68  READ STREAM FILE 
      C                     PARM           XA0020 
      C                     PARM           RECBFR 
       *    
      C           *IN68     IFEQ *OFF 
      C           RTNCOD    ANDEQ*OFF 
       *                     : 
       *                     : 
       *    {Perform some unique application function - here we will extract 
       *           the translated record returned and apply to our application.} 
      C                      : 
      C                     ENDIF 
      C                     ENDDO  
       *                     : 
       *    Close a request... 
       *                     : 
      C           *IN68     IFEQ *OFF 
      C           RTNCOD    ANDEQ*OFF 
      C                     MOVE *BLANKS   XA0020 
      C                     MOVEL'*CLOSE'  FUNCTN 
      C                     CALL 'XA0020R'              68  CLOSE STREAM FILE 
      C                     PARM           XA0020 
      C                     PARM           RECBFR 
      C                     ENDDO 
  
  
BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$

Book Reviews

Resource Center

  • SB Profound WC 5536 Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. You can find Part 1 here. In Part 2 of our free Node.js Webinar Series, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Brian will briefly discuss the different tools available, and demonstrate his preferred setup for Node development on IBM i or any platform. Attend this webinar to learn:

  • SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation. Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects. The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the company are not aligned with the current IT environment.

  • SB HelpSystems ROBOT Generic IBM announced the E1080 servers using the latest Power10 processor in September 2021. The most powerful processor from IBM to date, Power10 is designed to handle the demands of doing business in today’s high-tech atmosphere, including running cloud applications, supporting big data, and managing AI workloads. But what does Power10 mean for your data center? In this recorded webinar, IBMers Dan Sundt and Dylan Boday join IBM Power Champion Tom Huntington for a discussion on why Power10 technology is the right strategic investment if you run IBM i, AIX, or Linux. In this action-packed hour, Tom will share trends from the IBM i and AIX user communities while Dan and Dylan dive into the tech specs for key hardware, including:

  • Magic MarkTRY the one package that solves all your document design and printing challenges on all your platforms. Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product. Make sure your data survives when catastrophe hits. Request your trial now!  Request Now.

  • SB HelpSystems ROBOT GenericForms of ransomware has been around for over 30 years, and with more and more organizations suffering attacks each year, it continues to endure. What has made ransomware such a durable threat and what is the best way to combat it? In order to prevent ransomware, organizations must first understand how it works.

  • SB HelpSystems ROBOT GenericIT security is a top priority for businesses around the world, but most IBM i pros don’t know where to begin—and most cybersecurity experts don’t know IBM i. In this session, Robin Tatam explores the business impact of lax IBM i security, the top vulnerabilities putting IBM i at risk, and the steps you can take to protect your organization. If you’re looking to avoid unexpected downtime or corrupted data, you don’t want to miss this session.

  • SB HelpSystems ROBOT GenericCan you trust all of your users all of the time? A typical end user receives 16 malicious emails each month, but only 17 percent of these phishing campaigns are reported to IT. Once an attack is underway, most organizations won’t discover the breach until six months later. A staggering amount of damage can occur in that time. Despite these risks, 93 percent of organizations are leaving their IBM i systems vulnerable to cybercrime. In this on-demand webinar, IBM i security experts Robin Tatam and Sandi Moore will reveal:

  • FORTRA Disaster protection is vital to every business. Yet, it often consists of patched together procedures that are prone to error. From automatic backups to data encryption to media management, Robot automates the routine (yet often complex) tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:

  • FORTRAManaging messages on your IBM i can be more than a full-time job if you have to do it manually. Messages need a response and resources must be monitored—often over multiple systems and across platforms. How can you be sure you won’t miss important system events? Automate your message center with the Robot Message Management Solution. Key features include:

  • FORTRAThe thought of printing, distributing, and storing iSeries reports manually may reduce you to tears. Paper and labor costs associated with report generation can spiral out of control. Mountains of paper threaten to swamp your files. Robot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing. Manage your reports with the Robot Report Management Solution. Key features include:

  • FORTRAFor over 30 years, Robot has been a leader in systems management for IBM i. With batch job creation and scheduling at its core, the Robot Job Scheduling Solution reduces the opportunity for human error and helps you maintain service levels, automating even the biggest, most complex runbooks. Manage your job schedule with the Robot Job Scheduling Solution. Key features include:

  • LANSA Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.

  • LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed. Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

  • LANSASupply Chain is becoming increasingly complex and unpredictable. From raw materials for manufacturing to food supply chains, the journey from source to production to delivery to consumers is marred with inefficiencies, manual processes, shortages, recalls, counterfeits, and scandals. In this webinar, we discuss how:

  • The MC Resource Centers bring you the widest selection of white papers, trial software, and on-demand webcasts for you to choose from. >> Review the list of White Papers, Trial Software or On-Demand Webcast at the MC Press Resource Center. >> Add the items to yru Cart and complet he checkout process and submit

  • Profound Logic Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application.

  • SB Profound WC 5536Join us for this hour-long webcast that will explore:

  • Fortra IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn: