1. Working with the IFS on System i
What is the IFS
What is a Stream File ?
Stream File processing
The IFS and Navigator
System i IFS Commands in the OS
Working with IFS Directories
On the CD
Presented by : Chuck Walker
The System Solutions Group, llc
2. What is the IFS ?
The Integrated File System
The Integrated File System is a part of the System i OS that supports stream file input / output
and storage management similar to DOS, Windows, Linux, and Unix platforms.
Different file systems in the OS are geared towards processing different kinds of files. Here are a
few examples:
File System / Path Description File Type
QSYS.LIB System I Library file system DB2 400
QDLS Document Library Service DOS
QOpenSys The Open System file system Unix
Root The root file system Windows
You can see these file systems in the Navigator tree.
The QNTC file system provides access to data and objects that are stored on an Integrated
xSeries® Server (IXS) running Windows NT 4.0 or later, or Linux® operating system.
The QNTC file system is part of the base i5/OS operating system. QOPT is the Optical File
System.
3. Common Uses for IFS processing
The IFS is commonly used as a platform to exchange data with other systems. We have all
generated CSV files to be used in spreadsheets or to be imported into other database systems.
It’s not uncommon as well to use the IFS as an FTP server to collect data from business partners.
The possibilities are almost endless. Consider the possibility of writing a CGI file or HTML code
to the IFS for use by a web server. Or exporting data in an xml file used by a web server or
picked up by a business partner.
The IFS provides an easy access platform to the different file types we might need to import or
export without using ODBC drivers.
IBM has supplied plenty of tools to access these file systems.
What is a Stream File?
As System I programmers we are used to working with strongly typed files that have a structure
of strongly typed fields. A copy of this structure is included in our program objects when they are
compiled. Unless you are using embedded SQL if the file structure changes the program needs
to be re-compiled. Although we may work with multiple members the file structure remains the
same.
In other operating systems such as Unix, Linux, and Windows a file is simply a collection of bytes.
Instead of being strongly typed they are loosely defined. There are typically characters within the
stream of bytes that trigger events. In a CSV file a comma dictates a different column and a
CR/LF character triggers a new row. The file extension often defines the rules for processing
these Stream files.
Rules for naming files are different depending on what type of file it is. DOS allows 8 characters
with a 3 byte extension (no spaces). Windows allows a much longer name and now allows
spaces. Unix & Linux allows spaces but is case sensitive. In these environments myfile.txt and
MYFILE.TXT are different files.
These are typically known as Stream files because they are a constant stream of bytes. Once
again, how the collection of bytes are processed and by what program is dictated by the
extension.
The IFS was created as an extension to OS/400 to work with stream files. We can access all of
these different file types with a common interface.
4. Stream File Processing
Using built in System i commands :
IBM has supplied commands to import / export stream files. A couple that are very handy are
these.
Copy From Stream File
/* Build the IFS path/file name .................... */
CHGVAR VAR(&Path) VALUE('/PUBLIC/PPL/XML/' +
|| &FILENAME)
/* Copy the IFS file to the PPXMLIN file ........... */
CPYFRMSTMF FROMSTMF(&Path) +
TOMBR('/QSYS.LIB/SPPLIB.LIB/PPXMLIN.FILE/PPXMLI+
N.MBR') MBROPT(*REPLACE)
The above Control Language code copies the contents of the file in the variable &FILENAME on
the IFS into a file named PPXMLIN member PPXMLIN).
A couple of things to remember when using this command. This file path is actually
root/public/ppl/xml. Typically root is the current folder so you only need to spell out the path after
root. The target file cannot be a regular physical file. It must be a source file.
The beauty of using this method is that you can read the target source file with an RPG program
just like you do any other file. If your data is a fixed length fixed format text record you can simply
plug it into a data structure. If your incoming data is xml you can read the record from the source
file and parse the line with the built in XML operation codes.
Copy To Stream File
CHGVAR VAR(&Path) VALUE('/PUBLIC/PPL/MRI/out/' +
|| &FILENAME)
CHGVAR VAR(&FROM) VALUE('/QSYS.LIB/' +
|| 'SPPLIB.LIB/' +
|| 'PPXMLOUT.FILE/' +
|| 'PPXMLOUT.MBR')
CPYTOSTMF FROMMBR(&FROM) TOSTMF(&PATH) +
STMFCODPAG(*PCASCII)
CHGAUT OBJ(&PATH) USER(*PUBLIC) DTAAUT(*RWX) +
OBJAUT(*ALL)
Likewise we can copy a files contents to a stream file. In this case the source or From file must
be a source file. In the event you are putting the stream file on your IFS for someone to consume
you may need to change the authority. In this scenario you could write xml or fixed format
records to you source file in an RPG program and then transfer it to the IFS in a Control
Language program.
We will look at some other available commands a little later in the presentation.
5. Reading / Writing Stream files directly from RPG:
IBM supplies a series of Unix type APIs used for manipulating stream files from RPG.
To do this from an RPG program we need to use the Open(), Read() Write(), and Close() APIs.
The following code snippets are taken from Accessing the IFS with RPG IV by Scott Klement. A
copy of this PDF is included on the CD.
The OPEN()Prototype :
D open PR 10I 0 extproc('open')
D path * value options(*string)
D oflag
10I 0 value
D mode 10U 0 value options(*nopass)
D codepage 10U 0 value options(*nopass)
Open Flag values :
D**********************************************************************
D* Flags for use in open()
D*More than one can be used -- add them together.
D**********************************************************************
D* Reading Only
D O_RDONLY C 1
D* Writing Only
D O_WRONLY C 2
D* Reading & Writing
D O_RDWR C 4
D* Create File if not
exist
D O_CREAT C 8
D* Exclusively create
D O_EXCL C 16
D* Truncate File to 0
bytes
D O_TRUNC C 64
D* Append to File
D O_APPEND C 256
D* Convert text by
code-page
D O_CODEPAGE C 8388608
D* Open in text-mode
D O_TEXTDATA C 16777216
Mode is used to specify the access rights that this file will give to
users who want to work with it. Like the "oflag" parameter, this
parameter is treated as a series of bits. The rightmost 9 bits are the
ones that we're concerned with, and they're laid out like this:
user: owner group other
access: R W X R W X R W X
bit: 9 8 7 6 5 4 3 2 1
6. D**********************************************************************
D* Mode Flags.
D* basically, the mode parm of open(), creat(),
D* chmod(),etc
D* uses 9 least significant bits to determine the
D* file's mode. (peoples access rights to the file)
D*
D* user: owner group other
D* access: R W X R W X R W X
D* bit: 8 7 6 5 4 3 2 1 0
D*
D* (This is accomplished by adding the flags below to get the
D* mode)
D***************************************************************
D* owner authority
D S_IRUSR C 256
D S_IWUSR C 128
D S_IXUSR C 64
D S_IRWXU C 448
D* group authority
D S_IRGRP C 32
D S_IWGRP C 16
D S_IXGRP C 8
D S_IRWXG C 56
D* other people
D S_IROTH C 4
D S_IWOTH C 2
D S_IXOTH C 1
D S_IRWXO C 7
Code snippet showing the use of the open() API
c eval path = '/QIBM/UserData/OS400/DirSrv'
+
c '/slapd.conf'
c eval flags = O_WRONLY + O_CREAT + O_TRUNC
c eval mode = S_IRUSR + S_IWUSR
c + S_IRGRP
c eval fd = open(%trimr(path): flags: mode)
c if fd < 0
c goto bomb_out
c endif
The READ()Prototype :
D read PR 10I 0 extproc('read')
D fildes 10I 0 value
D buf * value
D nbyte 10U 0 value
Code snipet to Read a stream file :
c eval len = read(fd: ptr2buf: %size(buf))
c if len < 1
c goto no_more_to_read
c endif
7. FTP and stream files :
userid password
namefmt 1
cd in
mget *.zip /PUBLIC/PPL/direct/in/
mget *.xml /PUBLIC/PPL/direct/in/
mget *.zip /PUBLIC/PPL/Direct/arc
mget *.xml /PUBLIC/PPL/Direct/arc
quit
Namefmt 1 is needed when Getting or Putting files on the IFS.
8. The IFS and Navigator :
Things you can do with Navigator :
To check in a file, follow these steps.
1. In iSeries Navigator, right-click the file that you want to check in.
2. Select Properties.
3. Select File Properties → Use Page.
4. Click Check In.
To check out a file, follow these steps.
1. In iSeries Navigator, right-click the file that you want to check out.
2. Select Properties.
3. Click File Properties → Use Page.
4. Click Check Out.
If you check out a file others cannot update an AS/400 IFS stream file while you are working on
it. This comes in handy when several people may be updating IFS data for a project and you
want to ensure that no one overwrites another person's changes.
9. To create a folder, follow these steps.
1. Expand the system that you want to use in iSeries Navigator → File Systems → Integrated File
System.
2. Right-click the file system to which you want to add the new folder and select New Folder.
3. Type a new name for the object in the New Folder dialog. 4. Click OK. When you create a
folder on the System i platform, you need to consider whether you want to protect the new folder
(or object) with journal management. You also need to consider whether you want objects created
in this folder to be scanned or not. Related tasks “Setting whether objects should be scanned or
not” on page 125Follow these steps to set whether an object should be scanned or not. Related
information Journal managementRemoving a folder To remove a folder, follow these steps. 1.
Expand the system that you want to use in iSeries Navigator → File Systems → Integrated File
System. Continue to expand until the file or folder that you want to remove is visible. 2. Right-
click the file or folder and select Delete.
Moving Files or Folders to another File System.
You may also use Navigator with Windows explorer. Example : You may use the Copy option in
Explorer and the Paste option in Navigator to copy a file from Windows.
Be aware though that Not all characteristics are supported by all file systems. For example, the
QSYS.LIB or independent ASP QSYS.LIB file systems support storing and retrieving only a few
extended attributes, whereas the “root” (/) and QOpenSys file systems support storing and
retrieving all extended attributes. Therefore QSYS.LIB and independent ASP QSYS.LIB are not
good candidates for storing objects that have extended attributes.
To send a file or folder to another system, follow these steps.
1. Expand the system that you want to use in iSeries Navigator → File Systems →
Integrated File System. Continue to expand until the file or folder that you want to send is
visible.
2. Right-click the file or folder and select Send. The file or folder appears in the Selected
Files and Folders list of the Send Files from dialog.
3. Expand the list of available systems and groups.
4. Select a system and click Add to add the system to the Target systems and groups list.
Repeat this step for all the systems you want to send this file or folder.
5. Click OK to send the file or folder with the current default package definitions and
schedule information. When you create a package definition, it is saved and can be reused
at any time to send the defined set of files and folders to multiple endpoint systems or
system groups. If you choose to create a snapshot of your files, you can keep more than
one version of copies of the same set of files. Sending a snapshot ensures that no updates
are made to the files during the distribution, so that the last target system receives the
same objects as the first target system.
10. System i IFS Commands in the OS :
Command Description
ADDLNK Add Link.
ADDMFS Add Mounted File System.
CHGAUD Change Auditing Value.
CHGAUT Change Authority.
CHGCURDIR Change Current Directory.
CHGNFSEXP Change Network
CHGOWN Change Owner.
CHGPGP Change Primary Group.
CHKIN Check in a file.
CHKOUT Check out a file.
CPY Copy a file.
CPYFRMSTMF Copy from Stream File.
CPYTOSTMF Copy to Stream File.
CRTDIR Create Directory.
CRTUDFS Create UDFS.
CVTRPCSRC Convert RPC Source.
DLTUDFS Delete UDFS.
DSPAUT Display Authority.
DSPCURDIR Display Current Directory.
DSPLNK Display Object Links.
DSPF Display Stream File.
DSPMFSIN Display Mounted File System Information.
DSPUDFS Display UDFS.
EDTF Edit Stream File.
ENDNFSSVR End Network File System Server.
ENDRPCBIND End RPC Binder Daemon.
MOV Moves an object to a different directory
RLSIFSLCK Release Integrated File System Locks.
RMVDIR Remove Directory from the system
RMVLNK Remove Link Removes the link to an object
RMVMFS Remove Mounted File System. Removes exported,
RNM Rename an object in a directory
RPCBIND Start RPC Binder Daemon.
RST Restore Copies an object or group of objects from a backup
device to the system
RTVCURDIR Retrieve Current Directory Retrieves the name of the
current directory and puts it into a specified variable.
SAV Save Copies an object or group of objects from the system
to a backup device
SAVDLO Save Document Library Objects. (QDLS)
STRNFSSVR Start Network File System Server. Starts one or all of the
NFS daemons on the server and client.
11. WRKAUT Work with Authority Shows a list of users and their
authorities and provides options for adding a user, changing
a user authority, or removing a user
WRKLNK Work with Object Links Shows a list of objects in a
directory and provides options for performing actions on the
objects
WRKOBJOWN1 Work with Objects by Owner Shows a list of objects owned
by a user profile and provides options for performing
actions on the objects
WRKOBJPGP1 Work with Objects by Primary Group Shows a list of
objects controlled by a primary group and provides options
for performing actions on the objects
A few notes :
If you would like to give your users access and some control over the files in an IFS
directory then you can simply use the WRKLNK command in a menu option. This will
give them the standard Work options to delete, copy, etc.
If you use the IFS other than QDLS and you are not using the SAV command in your
backup routine you may not be saving all of your files. I have seen a couple of situations
where the company was using the SAVDLO command in their backup routine and they
thought they where backing up their IFS. They where not. They where only backing up
the files in QDLS.
It’s not uncommon to need to use the CHGAUT command to to change the permissions
on an object if it is an outgoing file that someone else needs to access.
12. When files and directories are created on the IFS the OS creates links that point to these
objects. An easy way to give your users easy access to content on the IFS is the
WRKLNK command.
If you don’t want your users to have copy, remove, rename and edit options use the
DSPLNK command.
13. Working with IFS Directories:
Processing all of the files in an IFS folder
This program uses IFS C++ API’s included in the QSYSINCLUDE objects. All you
have to do is prototype and use them. No additional binding directories are needed. For
more information on these API’s see
http://publib.boulder.ibm.com/infocenter/iseries/v5r4/index.jsp?topic=/apis/unix2.htm
I have included a document with these APIs listed in the Integrated File System APIs.pdf.
This program also includes use of C++ API’s from the QC2LE binding directory. I use
the System() api to execute AS400 commands instead of calling QCMDEXEC. For more
information on the C++ API’s provided in these service programs refer to the
C-Functions.pdf included with this presentation .
H DEBUG OPTION(*SRCSTMT)
H DFTACTGRP(*NO) ACTGRP(*NEW) BNDDIR('QC2LE': 'SSPC')
* ----------------------------------------------------------------
* PROCEDURE PROTOTYPES
* ----------------------------------------------------------------
D System pr 10i 0 extproc('system')
D command * value options(*string)
D OpenDir pr * extproc('opendir')
D dirName * value options(*string)
D ReadDir pr * extproc('readdir')
D dirPtr * value
D p_DirEnt s *
D dsDirEnt ds based(p_DirEnt)
D d_Resrv1 16
D d_FGenId 10u 0
D d_FileNo 10u 0
D d_RcdLen 10u 0
D d_Resrv2 10i 0
D d_Resrv3 8
D d_NLSData 12
D nls_ccsid 10i 0 overlay(d_NLSData: 1)
D nls_cntry 2 overlay(d_NLSData: 5)
D nls_lang 3 overlay(d_NLSData: 7)
D nls_resrv 3 overlay(d_NLSData: 10)
D d_NameLen 10u 0
D d_FilName 640
D CloseDir pr 10i 0 extproc('closedir')
D dirPtr * value
14. /free
// Open the designated IFS directory
p_Dir = OpenDir(rptPath);
if p_Dir <> *null;
// Read and process each file found in the directory
p_DirEnt = readdir(p_Dir);
dow p_DirEnt <> *null;
if %subst(d_filName: 1: d_NameLen) <> '.' and
%subst(d_filName: 1: d_NameLen) <> '..';
file = %subst(d_FilName: 1: d_NameLen);
dec = %scan('.': file: 1);
if dec > 0;
extn = %subst(file: dec+1: d_NameLen-dec);
if extn = *blanks;
%subst(file: dec: 1) = ' ';
endif;
else;
extn = *blanks;
endif;
// Process zipped file Unzip or just copy…..
Uppercase(extn);
zipFile = %trim(rptPath) + file;
if %trimr(extn) = 'ZIP';
command = ('JAVA CLASS(JvUnZip) PARM(' + apos +
%trimr(zipFile) + apos + ' ' + apos +
%trimr(xmlPath) + apos + ') CLASSPATH(' +
apos + clsPath + apos + ')');
result = System(%trimr(command));
// Process unzipped station report file by copying it
// directly into the XML directory
elseif %trimr(extn) = 'XML';
command = ('CPY OBJ(' + apos + %trimr(zipFile) +
apos + ') TODIR(' + apos + %trimr(xmlPath) +
apos + ') DTAFMT(*TEXT) OWNER(*KEEP)');
result = System(%trimr(command));
EndIf;
EndIf;
EndDo;
EndIf;
15. On the CD
File Name Description
Working with the IFS on System i.PDF This document in PDF Format.
Integrated File System APIs.pdf This document is a list of the API’s IBM
supplies for IFS processing and access.
This is information from an IBM website
complete with links to API detail pages.
IntegratedFileSystem.pdf This is an IBM PDF file that covers the IFS
from start to finish.
Accessing the IFS with RPG IV.pdf A presentation document on accessing the
IFS with RPG by Scott Klement
Working With the IFS in RPG IV.pdf An e-book by Scott Klement.
C-Functions.pdf C Runtime Library Functions included in
the OS by IBM.