Midrange News for the IBM i Community


Posted by: Bob Cozzi
Rogue Programmer
Cozzi Productions, Inc.
Chicagoland
How to retrieve USRPRF Home Directory Folder in CL
has no ratings.
Published: 03 Feb 2016
Revised: 04 Feb 2016 - 506 days ago
Last viewed on: 23 Jun 2017 (1568 views) 

Using IBM i? Need to create Excel, CSV, HTML, JSON, PDF, SPOOL reports? Learn more about the fastest and least expensive tool for the job: SQL iQuery.

How to retrieve USRPRF Home Directory Folder in CL Published by: Bob Cozzi on 03 Feb 2016 view comments(1)

I've had an issue in using the RTVUSRPRF in that it does not return the home folder for the user profile. So I use a technique in CL that I stole from my C++ code, used in our SQL Query File product. Basically it uses the PASE getpwnam function. Here's the code:

Retrieve User Profile Home Folder

DCL       VAR(&MYHOMEDIR) TYPE(*CHAR) LEN(640)

DCL        VAR(&UIDDEC) TYPE(*DEC) LEN(10 0)            
DCL        VAR(&UID) TYPE(*UINT) LEN(4)                 
DCL        VAR(&DIRLEN) TYPE(*UINT) LEN(4)              
                                                        
DCL        VAR(&RTNVAR) TYPE(*INT) LEN(4)               
DCL        VAR(&PWDPTR) TYPE(*PTR)                      
DCL        VAR(&PWDBUFFER) TYPE(*CHAR) LEN(641)         
DCL        VAR(&PWDBUFLEN) TYPE(*INT) LEN(4) VALUE(641) 
                                                        
DCL        VAR(&TEMPPWDPTR) TYPE(*PTR)                  
                                                        
DCL        VAR(&PASSWD) TYPE(*CHAR) LEN(64)             
DCL        VAR(&PW_NAME) TYPE(*PTR) STG(*DEFINED) +     
             DEFVAR(&PASSWD 1)                          
DCL        VAR(&PW_UID) TYPE(*UINT) STG(*DEFINED) +     
             LEN(4) DEFVAR(&PASSWD 17)                  
DCL        VAR(&PW_GID) TYPE(*UINT) STG(*DEFINED) +     
             LEN(4) DEFVAR(&PASSWD 21)                  
DCL        VAR(&PW_HOMEDIR) TYPE(*PTR) STG(*DEFINED) +  
             DEFVAR(&PASSWD 33)                         
DCL        VAR(&PW_INLPGM) TYPE(*PTR) STG(*DEFINED) + 
             DEFVAR(&PASSWD 49)                       
DCL        VAR(&HOMEDIR) TYPE(*CHAR) STG(*BASED) +    
             LEN(640) BASPTR(&PW_HOMEDIR)             

RTVUSRPRF  UID(&UIDDEC)                                   
CHGVAR     VAR(&UID) VALUE(&UIDDEC)                       
CHGVAR     VAR(&PWDPTR) VALUE(%ADDR(&PASSWD))             
CALLPRC    PRC('getpwuid_r') PARM((&UID *BYVAL) +         
             (&PWDPTR *BYVAL) (&PWDBUFFER) +              
             (&PWDBUFLEN *BYVAL) (&TEMPPWDPTR)) +         
             RTNVAL(&RTNVAR)                              
CALLPRC    PRC('strlen') PARM((&PW_HOMEDIR *BYVAL)) +     
             RTNVAL(&DIRLEN)                              
IF (&DIRLEN > 0) THEN(DO)                                 
  CHGVAR     VAR(&MYHOMEDIR) VALUE(%SST(&HOMEDIR 1 &DIRLEN)) 
enddo

Initially I use the legacy RTVUSRPRF command to retrieve the Unique ID for the user profile running the CL program. If you need other user's home directory, just specify their usrprf on the USRPRF parameter of the RTVUSRPRF command the UID for that user shall be returned. Then I call two proceddures: getpwuid_r and strlen.

getpwuid_r is a pase API and there are variations of it, but I settled on this version. It returns the Home Directory and Initial Program of the user profile, using the UID I retrieved from RTVUSRPRF. The returned information is very complex to traditional RPG/CL developers, so I've given you the data structure &PASSWD that receives the results. Note pointer subfields had to be aligned on a 16-byte boundary, so don't try to "fix" the structure when you copy it to your own systems, or it won't work.

Once we have the information returned, we have to extract it from the &PASSWD structure. The subfield &PW_HOMEDIR is a pointer to the user profile's home directory. The fun part is that it is a null-terminated string, so we can't just copy it using CHGVAR. To get the length of the home directory, I use the C runtime function strlen(). It returns to the CL program the number of bytes in the home directory. I use that length to issue the CHGVAR to extract the home directory into &MYHOMEDIR and everything is great.

You might ask, "Why not just use the QSYRUSRI API?" With that API, the user's home folder is returned in CCSID 1200 (Unicode) and I don't want to mess with calling iconv() to convert it to my job's CCSID simply to retrieve the home directory. So I'm avoiding it.

This may be a long-way around, but at least the PASE folks realized that it was silly to return the user's home folder in unicode when what you really want is it returned in the CCSID of your job. Now, we can do just that!

 

Return to midrangenews.com home page.
Sort Ascend | Descend

COMMENTS

(Sign in to Post a Comment)
Posted by: Ringer
Premium member *
Comment on: How to retrieve USRPRF Home Directory Folder in CL
Posted: 1 years 4 months 20 days 10 hours 8 minutes ago

RTVUSRPRF does not return that value? Weird. CHGUSRPRF lets you change it so you would think...