It turns out that there is no simple way of generating a list of files currently residing in a folder on the IBM i IFS. Simple, in this case, would be a command like DSPLNK OUTPUT(*FILE). An API does exist, but a combination of not enough time and too much lazy proved to be quite a disincentive for me going down that route.
The issue was that we recieve a number of very big files and, to save a bit of bandwidth, these files were being zipped before being sent to the IBM i. Dropping the file into the IFS and unzipping it was easy enough but then I found myself with an archive folder containing one of more files. While I can set the name of the folder into which the files should be extracted, I have no way of determining beforehand what the file names will be.
Here’s a solution:
/* -------------------------------------------------------------------------- */ /* Program : EXTRACTZIP */ /* Description : Retrieve and unpack a zipped archive */ /* Written by : Paul Pritchard */ /* Date : 27/05/2015 */ /* -------------------------------------------------------------------------- */ pgm dcl &library *char 10 value('MYLIB') dcl &fromfile *char 50 dcl &tombr *char 50 value('/qsys.lib/qtemp.lib/IMPORTP.file/IMPORTP.mbr') dcl &dltfile *char 50 dclf EXTRACTP /* Retrieve and the zipped file and unzip it. */ /* I won't bore you with the details here, but the the production program is */ /* retriving the ZIP file from an FTP server and using PKZIP to unzip it. */ /* The extract directory is /home/EXPATPAUL/EXTRACTFLR which now contains one */ /* or more stream files */ /* Retrieve a list of extracted files */ /* First, I use QShell to list the files in EXTRACTFLR. The output of this is */ /* redirected to ExtractedFiles.TXT. */ /* In order to use this information, I copy the ExtractedFiles.TXT stream */ /* to an ad-hoc physical file (QTEMP/EXTRACTP) */ qsh cmd('ls /home/EXPATPAUL/EXTRACTFLR/ > /home/EXPATPAUL/ExtractedFiles.TXT') crtpf file(QTEMP/EXTRACTP) rcdlen(20) cpyfrmstmf fromstmf('/home/EXPATPAUL/ExtractedFiles.TXT') + tombr('/qsys.lib/qtemp.lib/EXTRACTP.file/EXTRACTP.mbr') + mbropt(*REPLACE) /* And now I can use QTEMP/EXTRACTP to drive my way through EXTRACTFLR and */ /* copy each of the files in the archive into the IMPORTP physical file. */ dowhile '1' rcvf monmsg msgid(CPF0864) exec(LEAVE) /* Copy the next sream file from the archive */ chgvar &fromfile value('/home/EXPATPAUL/EXTRACTFLR/' *tcat &EXTRACTP) cpyfrmstmf fromstmf(&fromfile) tombr(&tombr) mbropt(*add) + STMFCCSID(*PCASCII) /* and then delete the stream file */ chgvar &dltfile value('rm /home/EXPATPAUL/EXTRACTFLR/' *tcat &EXTRACTP) qsh cmd(&dltfile) enddo /* Clean up and exit */ qsh cmd('rm /home/EXPATPAUL/ExtractedFiles.TXT') dltf qtemp/EXTRACTP endpgm
It should go without saying that some of the names have been changed and that the above program should be treated as a sample only.
Being able to move information between the QShell/IFS and traditional i5/OS environments is both useful and (in my experience) increasingly important. Although it does take a bit of thinking about, it isn’t difficult which is why I find that the oft-seen solution of “buy this tool” is both disappointing and (often) overkill.