Retrieving the name of a file from object links

690 pts.
We are receiving a Daily file containing Chassis information via FTP at a scheduled time in the early morning. I have written a process to automatically retrieve this file, CPYFRMIMPF to my Physical File, then process the data into our Chassis Master. Originally, I was told it would be a specific and constant name so I could retrieve it, copy it then delete it. The problem is, I am now told that the name isn't always going to be the same. They are still figuring out how to do that. The file is coming over as "daily_file_201332074926.csv". I can account for the date in my program and modify the name of the file I'm retrieving, but I don't see how I can get the exact time for the filename. My Question is this: Is there a way for me to somehow retrieve the name of that file from the directory in the object links within a CLLE program?

Software/Hardware used:

Answer Wiki

Thanks. We'll let you know when a new response is added.

you can create a file for your program to process.   QFTPSRC is a regular source file (PF-SRC) that we store ftp scripts and logs you can use any source file you want (you will specify it in the OVRDBF commands).  In your CL you would:

  • process QTEMP/LSOUTPUT

Member GETLIST would contain the following:

  • open target_site
  • user username password
  • cd library
  • lcd qtemp
  • ls * (DISK
  • close
  • quit

Discuss This Question: 7  Replies

There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when members answer or reply to this question.
  • Eric Witham
    I'm not entirely sure this is something that would work. The system I'm on is where the file is, so i can't very well FTP to the same system.This is in the IFS and I get to the file using the WRKLNK '/' command. One of the directories holds a .CSV file and i'm just trying to retrieve the name of the .CSV file. The only option i can think of is to do a DSPLNK and mark the output as *PRINT, then copy the spooled file to a physical flat file and read that. Since there's only going to be 1 file in there at a time per day, this might be one of the few workarounds without having to use API's, which, i'm not entirely opposed to. It just seems that there should be an easier way to deal with the IFS.
    690 pointsBadges:
  • TomLiotta i can’t very well FTP to the same system.   Why not? Is it restricted?   FTP to/from same system might be the easiest way to do it. It's certainly possible to read directory entries, but it's a little more complicated.   Tom
    125,585 pointsBadges:
  • Eric Witham
    Interesting. I guess it just seemed illogical to me to have to ftp the system you're already on. I dunno haha. But i did find a solution at the following url: solution was done by a Developer named Scott Klement. I modified it for what I needed.Basically the CLLE handles the QSHELL command to retrieve the full path into the record of the file declared. You can see i'm substringing the filename because there could be 3 variations of the name.Anyway, here's the code:             PGM                                                                                                                                             DCL        VAR(&FILENAME) TYPE(*CHAR) LEN(30)                           DCL        VAR(&FILE_EXT) TYPE(*CHAR) LEN(04) VALUE('.csv')             DCLF       FILE(EWITHAM/IFSDCLI00)                                                                                                              OVRDBF     FILE(STDOUT) TOFILE(DIROUTPUT)                               QSH        CMD('ls /depotsystems/chassis/dcli*')                                                                                    #READ:      RCVF                                                                    MONMSG     MSGID(CPF0864) EXEC(GOTO CMDLBL(#EOF))                                                                                               SELECT                                                                  WHEN       COND(%SST(&FULLPATH 46 4) *EQ &FILE_EXT)                     CHGVAR     VAR(&FILENAME) VALUE(%SST(&FULLPATH 23 27))                  WHEN       COND(%SST(&FULLPATH 47 4) *EQ &FILE_EXT)                     CHGVAR     VAR(&FILENAME) VALUE(%SST(&FULLPATH 23 28))                  WHEN       COND(%SST(&FULLPATH 48 4) *EQ &FILE_EXT)                     CHGVAR     VAR(&FILENAME) VALUE(%SST(&FULLPATH 23 29))                  ENDSELECT                                                                                                                                       GOTO       CMDLBL(START)                                    #EOF:       ENDPGM
    690 pointsBadges:
  • TomLiotta
    If you prefer an actual programmed solution, Qshell isn't necessary. ILE CL can read directories directly:
    pgm    ( +
             &DirName     +
       dcl   &DirName     *char  128
       dcl   &FName       *char  640
       dcl   &x00         *char    1     value( x'00' )
       dcl   &rc          *int
       dcl   &subrc       *int
       dcl   &Dir         *char  128
       dcl   &Link        *char  640
       dcl   &BUF         *char 4096
       dcl   &mtime       *int           stg( *defined ) defvar( &BUF    29 )
       dcl   &oType       *char   10     stg( *defined ) defvar( &BUF    49 )
       dcl   &pCTime      *ptr
       dcl   &CTime       *char   24     +
                             stg( *BASED )  +
                             basptr( &pCTime )
       dcl   &pDir        *ptr
       dcl   &DirDS       *char    1     +
                             stg( *BASED )  +
                             basptr( &pDir )
     /* Directory entry DS */
       dcl   &pDirEnt     *ptr
       dcl   &DirEnt      *char 1024     +
                             stg( *BASED )  +
                             basptr( &pDirEnt )
       dcl   &res1        *char   16     stg( *defined ) defvar( &DirEnt  1 )
       dcl   &sgenid      *uint          stg( *defined ) defvar( &DirEnt 17 )
       dcl   &sfileno     *int           stg( *defined ) defvar( &DirEnt 21 )
       dcl   &sreclen     *uint          stg( *defined ) defvar( &DirEnt 25 )
       dcl   &res2        *int           stg( *defined ) defvar( &DirEnt 29 )
       dcl   &res3        *char    8     stg( *defined ) defvar( &DirEnt 33 )
       dcl   &snlsinf     *char   12     stg( *defined ) defvar( &DirEnt 41 )
       dcl   &snamlen     *uint          stg( *defined ) defvar( &DirEnt 53 )
       dcl   &sfname      *char  640     stg( *defined ) defvar( &DirEnt 57 )
       dcl   &nullptr     *ptr
       monmsg    ( cpf0000 mch0000 cpf9999 ) exec( goto StdErr )
       chgvar            &Dir         ( &DirName *tcat &x00 )
       callprc     'opendir'          ( &Dir ) rtnval( &pDir )
       if ( &pDir *eq &nullptr )  +
          goto  Close_Dir
       dountil  ( &pDirEnt *eq &nullptr )
          callprc     'readdir'       ( &DirDS ) rtnval( &pDirEnt )
          if ( &pDirEnt *ne &nullptr )  +
             callsubr    OutEntry     rtnval( &subrc )
       goto  Close_Dir
       monmsg (cpf0000 cpf9999 mch0000)
       callprc     'closedir'         ( &DirDS ) rtnval( &rc )
       monmsg (cpf0000 cpf9999 cee0000 mch0000)
    subr     OutEntry
       if ( &snamlen *gt 0 )  do
          chgvar        &FName    %sst( &sfname 1 &snamlen )
          chgvar        &Link         ( +
                                        &DirName *tcat '/' *cat +
                                        &FName   *tcat +
                                        &x00  +
          callprc     'stat'          ( &Link &BUF ) rtnval( &rc )
          if ( &rc *eq 0 )  do
             callprc  'ctime'         ( &mtime ) rtnval( &pCTime )
             sndpgmmsg   msgid( CPF9898 ) msgf( QCPFMSG ) +
                           msgdta( +
                                   'Object Found'   *bcat +
                                   &CTime           *bcat +
                                   &FName           *bcat +
                                   &oType                 +
                                 ) +
                           msgtype( *INFO )
          else  +
             rtnsubr rtnval( -1 )
    The program accepts a 128-char directory and lists its contents via messages. Note that the directory name parm value must be padded with blanks if it's shorter than 128 characters.   Compile as a *MODULE. Then use CRTPGM to create the program from the *MODULE and specify BNDDIR(QC2LE) to pull in the APIs.   Modify it to cut out the stuff for sending the messages. It's just an example program, so it can simply return a file name as an output parm. Use this version just to see how opendir(), readdir() and closedir() work.   Note that all directories include the [.] and [..] entries. Simple IF-tests can skip those.   Tom
    125,585 pointsBadges:
  • BigKat
    oh, I thought the files were still on the other system when you had to determine the dynamic name.  Although as Tom mentioned, you can FTP back to yourself and it shouldn't be restricted, as the data is already being FTP'd to you.
    9,460 pointsBadges:
  • Eric Witham
    BigKat, agreed. My mistake. Company is sending us the file, i just have to retrieve it and don't know the name. But i found the code that completely helps.Tom, thanks. I think the resolution i posed with the clle code is an actual programmed solutions. I'm using code within a source member to retrieve information. i can make it a dynamic process for other programs to use, but i didn't because this isn't a common issue.I appreciate the help from both though!
    690 pointsBadges:
  • TomLiotta
    Re BigKat's FTP: Essentially all network functions can be routed right back to the originating server. It's a very useful testing technique to remember for the future. Testing can be done even when you only have a single server simply by using appropriate host names (or IP addresses or even APPN control point names).   Re "programmed solution": Yes, Scott Klement's method is indeed. To clarify, I was referring to FTP and supplying an alternative to that. Other members following the thread might not allow FTP to be active on their server. Your acceptance of Scott's work indicated that you were wanting direct programming rather than something of a workaround (i.e., FTP). So, I was showing the basics that was even more direct and that didn't require an optional OS component. I use Qshell regularly on my own systems just as you're using it.   But because I also work on many other systems, I know that lots of members need alternatives. Qshell won't be available for some others, and PTF issues might cause trouble for some in production environments.   Qshell interaction with QSYS.LIB features does get a little twisted from time to time. If direct access to /root via APIs is understood, or at least working examples are available, some members will get use out of it.   Tom
    125,585 pointsBadges:

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to:

To follow this tag...

There was an error processing your information. Please try again later.

Thanks! We'll email you when relevant content is added and updated.


Share this item with your network: