In our last sample project, we created a program that assigned new access permissions to an IFS object. Now, let's update that example to allow "*SAME" to be specified.
This would, for example, allow you to change the permissions for the owner, without affecting the permissions for the group or anyone else.
To do that, what we'll do is retrieve the file's mode using stat(). Then, we'll preserve the bits from the original mode where *SAME is specified.
Here's the updated command source:
CMD PROMPT('Change File Mode') PARM KWD(OBJ) TYPE(*CHAR) LEN(640) MIN(1) + PROMPT('Object') PARM KWD(USER) TYPE(*CHAR) LEN(10) RSTD(*YES) + DFT(*SAME) VALUES(*NONE *R *RW *RX *RWX + *W *WX *X *SAME) PROMPT('Owner permissions') PARM KWD(GROUP) TYPE(*CHAR) LEN(10) RSTD(*YES) + DFT(*SAME) VALUES(*NONE *R *RW *RX *RWX + *W *WX *X *SAME) PROMPT('Group Permissions') PARM KWD(OTHER) TYPE(*CHAR) LEN(10) RSTD(*YES) + DFT(*SAME) VALUES(*NONE *R *RW *RX *RWX + *W *WX *X *SAME) PROMPT('Others Permissions')
And here's the new RPG source:
* CH3PERM2: Example of changing permissions of an IFS object w/*SAME * (From Chap 3) * * To compile: * CRTBNDRPG CH3PERM2 SRCFILE(xxx/QRPGLESRC) DBGVIEW(*LIST) * H DFTACTGRP(*NO) ACTGRP(*NEW) BNDDIR('QC2LE') D/copy IFSEBOOK/QRPGLESRC,IFSIO_H D/copy IFSEBOOK/QRPGLESRC,ERRNO_H D Path S 640A D UserPerm S 10A D GroupPerm S 10A D OtherPerm S 10A D MyStat S like(statds) D DS D Mode 10I 0 D CharMode3 1A overlay(Mode:3) D CharMode4 1A overlay(Mode:4) ** Warning: call this program from the command. If you call ** it directly, because "Path" is larger than 32 bytes. ** See http://faq.midrange.com/data/cache/70.html ** C *entry plist c parm Path c parm UserPerm c parm GroupPerm c parm OtherPerm C* Retrieve current file mode: c if stat(%trimr(path): %addr(mystat)) < 0 c callp die(%str(strerror(errno))) c endif c eval p_statds = %addr(mystat) c eval Mode = st_mode C* Calculate desired user permissions: c if UserPerm <> '*SAME' c bitoff x'FF' CharMode3 c bitoff x'C0' CharMode4 c if %scan('R': UserPerm) > 0 c eval Mode = Mode + S_IRUSR c endif c if %scan('W': UserPerm) > 0 c eval Mode = Mode + S_IWUSR c endif c if %scan('X': UserPerm) > 0 c eval Mode = Mode + S_IXUSR c endif c endif C* Calculate desired group permissions: c if GroupPerm <> '*SAME' c bitoff x'38' CharMode4 c if %scan('R': GroupPerm) > 0 c eval Mode = Mode + S_IRGRP c endif c if %scan('W': GroupPerm) > 0 c eval Mode = Mode + S_IWGRP c endif c if %scan('X': GroupPerm) > 0 c eval Mode = Mode + S_IXGRP c endif c endif C* Calculate desired permissions for everyone else: c if OtherPerm <> '*SAME' c bitoff x'07' CharMode4 c if %scan('R': OtherPerm) > 0 c eval Mode = Mode + S_IROTH c endif c if %scan('W': OtherPerm) > 0 c eval Mode = Mode + S_IWOTH c endif c if %scan('X': OtherPerm) > 0 c eval Mode = Mode + S_IXOTH c endif c endif C* Change the file's access mode: c if chmod(%trimr(path): Mode) < 0 c callp die(%str(strerror(errno))) c endif c eval *inlr = *on /DEFINE ERRNO_LOAD_PROCEDURE /COPY IFSEBOOK/QRPGLESRC,ERRNO_H
Note: We're using RPG's BITOFF operation to turn the bits from the original off before we set them. This ensures that they end up with the correct values, even if they were previously set to something.