Partner400 Logo
    SPECIAL Files - Sources
   
These are the source files for the USESPECIAL and DIRREADER programs disussed in the March 2010 edition of IBM i Extra

  All About Us

  Where To See Us

  Magazine Articles

  Downloads

  Code/400

  On-site Training

  The RPG Redbook

  Home Page

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

SPECIAL File Program DIRREADER


     H DftActGrp(*No) BndDir('QC2LE')
     H Option(*NoDebugIO : *SrcStmt)

       // DirReader
       //  - Used as SPECIAL file to read entries in a specified directory
       //  - Actual directory to open given by the fifth (extra) parm

      /Copy FSDIRPROT

      /Copy DIRDATA

      // Prototype for CEEUTCO API - Obtains current time zone offset
     D CEEUTCO         PR
     D   Hours                       10I 0
     D   Mins                        10I 0
     D   Secs                         8F
     D   fc                          12A   options(*omit)

       // Prototype to keep the compiler happy
     D DirReader       Pr                  ExtPGM('DIRREADER')
     D  requestedAction...
     D                                1a
     D  statusFlag                    1a
     D  errorCode                     5s 0
     D  recordData                         LikeDS(directoryData)
     D  directoryToOpen...
     D                              640a   Varying

       // Procedure Interface used instead of *Entry PList
     D DirReader       PI
       // First four are the standard parameter definitions
       //   passed for SPECIAL files from the RPG program
     D  action                        1a
     D  status                        1a
     D  error                         5s 0
     D  recordData                         LikeDS(directoryData)
      // This is the extra parameter specified within the RPG program
      //   In this case it supplies the name of the directory to open
     D  dirName                     640a   Varying

      *   Constants for SPECIAL file operation requests
     D OPEN            C                   'O'
     D READ            C                   'R'
     D CLOSE           C                   'C'

     D EOF             C                   '1'
     D ERR             C                   '2'
     D OK              C                   '0'

     D pdir            S               *

     D message         S             52a

      // Definitions for time zone offset calculations
     D hours           S             10i 0
     D minutes         S             10i 0
     D offsetSeconds   S              8f
     D epoch           c                   z'1970-01-01-00.00.00'
     D adjustedEpoch   s               z

      /FREE
       Select;
         When action = READ;

           p_dirEnt = ReadDir( pdir );  // Read next directory entry
           If p_dirEnt <> *Null;  // If pointer is valid we have a record
             recordData.name = %Subst( dE_name: 1: dE_nameLen );

             // Use the stat() function to retrieve informaqtion for the record
             If Stat( recordData.name: p_statDS ) < 0; // CHeck for failure
               dirName = 'File: ' + recordData.name; // Identify failing file name
               ExSr ReportError;
             Else;
               // Create required entries in the record buffer
               recordData.created  = adjustedEpoch + %seconds( st_ctime );
               recordData.accessed = adjustedEpoch + %seconds( st_atime );
               recordData.modified = adjustedEpoch + %seconds( st_mtime );
               recordData.type     = st_objtype;

               status = OK;

             EndIf;
           Else;              // otherwise we're at the end of the "File"
             status = EOF;
           Endif;

         When action = OPEN;
           pdir = OpenDir( dirName );
           If pdir = *Null;  // If pointer is null then open failed
             ExSr ReportError;  // Obtains error details and reports failure
           EndIf;

         When action = CLOSE;
           CloseDir( pdir );

       EndSl;


       Return;

       BegSr ReportError;

         // Obtains errno and sets it into the file's feedback area

         status = ERR;
         p_errno = GetPtr_errno();
         error = errno;

         // Form basic error message
         If action = OPEN;
           message = 'Open error: ' + %Str( strError(errno));
         Else;
           message = 'Read error: ' + %Str( strError(errno));
         EndIf;

         Dsply message;

       EndSr;

       // Routine calculates an epoch timestamp adjusted to account for
       //   the current time zone offset. This is then used to produce
       //   correct timestamps for dates in the directory entries.

       BegSr *InzSr;
       // Call CEEUTCO to obtain current time zone offset in seconds
          CEEUTCO( hours: minutes: offsetSeconds: *omit );
       // Then add them to the base date to form adjusted epoch
          adjustedEpoch = epoch + %seconds( %int( offsetSeconds ) );

       EndSr;
	

Program USESPECIAL - sample program that uses the DIRREADER special file


     FDirEntriesIF   F  732        SPECIAL PgmName('DIRREADER')
     F                                     PList(DirReaderParm)
     F                                     UsrOpn

     FQPrint    O    F  132        PRINTER

      /Copy DirData

     D directoryName   S            640a   Varying
     D                                     Inz('/Partner400')

     D message         S             52a
     D shortName       S             34a

      /Free
       Open(E) DirEntries;
       If %Error;
         message = 'Directory: ' + directoryName; // Report error and quit
         Dsply message;
         *InLR = *On;
         Return;
       EndIf;

       Dou %EOF(DirEntries);
         Read(E) DirEntries directoryData;
         If ( not %Error ) AND ( not %EOF(DirEntries) );
           shortName = name;
           except main;
         ElseIf %Error;
           message = directoryName; // Report (truncated) file name and quit
           Dsply message;
           Leave; // Exit read loop
         EndIf;

       EndDo;

       *InLR = *On;
      /End-free


      // SPECIAL files need a PList for extra parms. Sadly we
      //   have to code that in fixed form but we hide it down here!
     C     PListDummy    BegSr
     C     DirReaderParm PList
     C                   Parm                    directoryName
     C                   EndSr

     OQPrint    E            main
     O                       type                12
     O                       created             40
     O                       accessed            68
     O                       modified            96
     O                       shortName          132


Source IFSDIRPROT - prototypes for IFS routiines


      // IFSDIRPROT - Prototypes for IFS directory processing
      //            - Includes DS definitions for directory entry and
      //              stat() data

     D OpenDir         Pr              *   ExtProc('opendir')
     D
     D  ppath                          *   Value  Options(*String)

     D ReadDir         Pr              *   ExtProc('readdir')
     D  pdirectory                     *   Value

     D CloseDir        Pr            10I 0 ExtProc('closedir')
     D  pdirectory                     *   Value

     D Stat            Pr            10I 0 ExtProc('stat')
     D                                 *   Value Options(*String)
     D                                 *   Value

       // Function and data definitions for obtaining current errno value and string
     D GetPtr_errno    Pr              *   ExtProc('__errno')
     D

     D p_errno         S               *
     D p_errnoTxt      S               *
     D errno           S             10I 0 Based(p_errno)

     D strerror        Pr              *   extproc('strerror')
     D  errno                        10I 0 value


       // RPG Translation of C member STAT from file SYS in library QSYSINC
     D p_statDS        S               *   Inz(%addr(statDS))

     D statDS          DS
     D  st_mode                      10U 0
     D  st_ino                       10U 0
     D  st_nlink                      5U 0
     D  st_pad                        2A
     D  st_uid                       10U 0
     D  st_gid                       10U 0
     D  st_size                      10I 0
     D  st_atime                     10I 0
     D  st_mtime                     10I 0
     D  st_ctime                     10I 0
     D  st_dev                       10U 0
     D  st_blksize                   10U 0
     D  st_allocsize                 10U 0
     D  st_objtype                   12A
     D  st_codepage                   5U 0
     D  st_reserved1                 62A
     D  st_ino_gen_id                10U 0

       // DS for directory entry information retrieved by readdir
     D dirEnt          DS                  Based(p_dirEnt)
     D  dE_res1                      16a
     D  dE_genId                     10u 0
     D  dE_fileNo                    10u 0
     D  dE_recLen                    10u 0
     D  dE_res3                      10i 0
     D  dE_res4                       6a
     D  dE_res5                       2a
     D  dE_NLSinfo
     D   dE_CCSID                    10i 0 Overlay(dE_NLSInfo)
     D   dE_country                   2a   Overlay(dE_NLSInfo: *Next)
     D   dE_language                  3a   Overlay(dE_NLSInfo: *Next)
     D   dE_res6                      3a   Overlay(dE_NLSInfo: *Next)
     D  dE_nameLen                   10u 0
     D  dE_name                     640a

      // End of source IFSDIRPROT 	

Source DIRDATA Definition of data passed back from special program


     d directoryData   DS           732
     d   type                        12a
     d   name                       640a   Varying
     d   created                       z
     d   accessed                      z
     d   modified                      z

     d DIRECTORY       c                   '*DIR'
     d FILE            c                   '*FILE'
     d SYMLINK         c                   '*SYM'

     
Return to Home Page  

Want more information?
Got a question or comment about the site?
Please feel free to Contact Us at any time.}