IFS Path Validation

Discussions relating to writing software in ILE RPG (RPG IV). This includes both fixed and free format RPG.
Post Reply
bbunney
Posts: 45
Joined: Wed Jul 06, 2022 7:52 pm

IFS Path Validation

Post by bbunney »

Can I use the access API to verify that an IFS Path exists as opposed to verifying a path and file exists? If not should I use the CHDIR command instead or maybe use the open source CHKLNK command? Thanks.

Code: Select all

Dcl-Pr access     Int(10:0) ExtProc('access');
   pathptr          Pointer Value;              
   mode             Int(10:0) Value;            
End-Pr;                                         

pathname = '/home/property/documents' + x'00';
pathptr = %addr(pathname);         
pathok = 0;

Path_Exists = access(pathptr:pathok);

If Path_Exists = 0;
// Path Found
Else;
// Path not Found
EndIf;
jonboy49
Posts: 205
Joined: Wed Jul 28, 2021 8:18 pm

Re: IFS Path Validation

Post by jonboy49 »

Personally, I would use opendir() for this task as it checks for both existence and premissions.
bbunney
Posts: 45
Joined: Wed Jul 06, 2022 7:52 pm

Re: IFS Path Validation

Post by bbunney »

Thank you! I will do that. I'm assuming that if the path is found that I would need to execute a closedir then. My program uses the open, write, close and unlink API's to write a file to the IFS if the path is valid.
jonboy49
Posts: 205
Joined: Wed Jul 28, 2021 8:18 pm

Re: IFS Path Validation

Post by jonboy49 »

The other option would be stat() - which would avoid the close but may have a higher overhead.

From googling around, there appear to be some versions of access() that will work with directories but it is unclear to me which is what! Scott probably knows - he is far more knowledgeable about all things C than I am.
Scott Klement
Site Admin
Posts: 652
Joined: Sun Jul 04, 2021 5:12 am

Re: IFS Path Validation

Post by Scott Klement »

access() should work fine. Not sure that I understand what is being asked... what is the difference between a "path exists" vs "path and file exists"?

If its important to determine if the object is a directory (vs. a file) then I would use stat() and check the IS_DIR bit of the mode. (Which will cover all of the "directory-like" objects, such as *DIR, *DDIR, *FLR and *FILE)

I wouldn't use anything that creates an object like mkdir or open, or anything that changes your current state like chdir unless you actually want to create an object or change your current state, respectively. These add overhead, its just a waste if you don't need it. Plus... why? Checking existence with access() is actually easier to code -- and stat() is also relatively easy and much more powerful. Why use something not designed for the purpose?

Also, your RPG code that calls stat could be much simpler, unless you need to run it on V3R2/V3R7? Why aren't you taking advantage of options(*string)?
bbunney
Posts: 45
Joined: Wed Jul 06, 2022 7:52 pm

Re: IFS Path Validation

Post by bbunney »

The code I put in my post isn't my code. It was code I googled before I wrote my code. I'm developing a program that will be passed an IFS Path, document type (JSON, XML, TXT or PDF), file name prefix and a data string. I want to validate the path first, the file name will be unique as a sequence number is generated for each file from a data area. I coded jonboy's first suggestion because I have to code to V7.2 even thought the development box is on V7.4 as I have to wait until over 60 production LPAR's are upgraded or I would have used a SQL Table for this. A will replace opendir() and closedir() with access() then. Thank you! But I have another issue now. When I go to write an XML string to the IFS, two characters are added to the front of the string causing 2 characters what appears to be a tab and a ' '. So something must be wrong with either my open() or write() statement. Could you take a look please? Thanks!

Code: Select all

Dcl-S l_fd              Int(10:0);     
Dcl-S l_data          VarChar(64512);
Dcl-S l_IFSFile        VarChar(200);

Dcl-C O_WRONLY           2;       
Dcl-C O_CREAT              8;       
Dcl-C O_TRUNC            64;      
Dcl-C O_CCSID              32;      
Dcl-C O_TEXTDATA        16777216;
Dcl-C O_TEXT_CREAT    33554432;
                        
Dcl-C RW          6;       
Dcl-C R             4;       
Dcl-C OWNER   64;      
Dcl-C GROUP      8;         

Dcl-Pr OpenFile       Int(10:0) ExtProc('open');       
   FileName             Pointer   Value Options(*string);
   OpenFlags            Int(10:0) Value;                 
   Mode                    Uns(10:0) Value Options(*nopass);
   Ccsid                    Uns(10:0) Value Options(*nopass);
   TxtCreatId            Uns(10:0) Value Options(*nopass);
End-Pr;                                                
                                                       
Dcl-Pr WriteFile         Int(10:0) Extproc('write');      
   Fildes                     Int(10:0) Value;                 
   Buf                         Pointer   Value;                 
   Nbyte                     Uns(10:0) Value;                 
End-Pr;                                                
                                                       
Dcl-Pr CloseFile          Int(10:0) ExtProc('close');      
   Fildes                      Int(10:0) Value;                 
End-Pr;   

l_IFSFile = %Trim(Ds_IFSParm.IFSPath) + '/' +                     
   l_PropCodeLower + %Trim(Ds_IFSParm.DocPrefix) +                
   %Trim(%Editc(DocSeqNbr:'Z')) + '.' + %Trim(Ds_IFSParm.DocType);

l_fd = OpenFile(%Trim(l_IFSFile):                   
   O_CREAT+O_WRONLY+O_TEXTDATA+O_CCSID+O_TEXT_CREAT:
   RW*OWNER + RW*GROUP + R:819:37);                 

l_Data = %Trim(Ds_IFSParm.DocData);   

WriteFile(l_fd:%Addr(l_Data):%Len(l_Data));      

CloseFile(l_fd);

EVAL l_Data                                                            
L_DATA =                                                               
          ....5...10...15...20...25...30...35...40...45...50...55...60 
     1   '<ns2:responsibleGamingResponse version="1.0" xmlns:xxx="xxxx'
    61   'xxx" xmlns:ns2="rgrsp"><xxx:header><xxx:communications><xxxr:'
    
 On my PC:
 '	Á<ns2:responsibleGamingResponse version="1.0" xmlns:xxx="xxxxxxx"'   
                                                
msddcb
Posts: 21
Joined: Wed Jul 28, 2021 5:12 am

Re: IFS Path Validation

Post by msddcb »

Change you write to only write the data portion of the variable length field

WriteFile(l_fd:%Addr(l_Data : *DATA):%Len(l_Data));

The first 2 characters you are seeing is the length of the variable length field.

See ... https://www.ibm.com/docs/en/i/7.4?topic ... s-variable

Cheers
bbunney
Posts: 45
Joined: Wed Jul 06, 2022 7:52 pm

Re: IFS Path Validation

Post by bbunney »

msddcb, that worked. Thank you so much!!
Post Reply