Path: utzoo!attcan!uunet!lll-winken!lll-tis!helios.ee.lbl.gov!pasteur!ucbvax!CITHEX.CALTECH.EDU!carl From: carl@CITHEX.CALTECH.EDU (Carl J Lydick) Newsgroups: comp.os.vms Subject: Re: SUMMARY - How to find the next available uic Message-ID: <880704153636.132e@CitHex.Caltech.Edu> Date: 4 Jul 88 22:49:08 GMT Sender: daemon@ucbvax.BERKELEY.EDU Organization: The Internet Lines: 51 > Whenever we want to add new users to sysuaf.dat, we try to find > the next uic available for this new user. (For accounting reasons > we do NOT use any uic that has been used before). The only way I > could think of was to scan sysuaf.dat completely, using $IDTOASC > in a wildcard operation, translate the usernames back to individual > UIC's with $ASCTOID, then examining the group and member value, thus > finding the highest member value of the specified group. > But this takes about THIRTY times as much cpu time as does AUTHORIZE > with a SHOW [XXXX,*]/BRIEF > > Does anybody know which calls authorize might be using ? Since there's been one response to the net describing how to do this in C, and one in MACRO, I just thought I'd show how it's done in FORTRAN, viz., much more easily than in either of the other two languages. I tried doing it in DCL, which would have been as simple as the FORTRAN code, but the DCL read statement doesn't like the key value to have null bytes in it (It sees the null and decides that's the end of the command line! Is this a bug or a feature?). At any rate, here's the FORTRAN program: ******************************************************************************** PROGRAM NEXT_FREE_UIC CHARACTER*6 MEMBER INTEGER GROUP, KEYNUM, UIC, NEXT_UIC OPEN(UNIT=1,FILE='SYS$SYSTEM:RIGHTSLIST.DAT',SHARED,READONLY, 1 ACCESS='KEYED',STATUS='OLD',FORM='UNFORMATTED') TYPE 10 10 FORMAT(' GROUP: ',$) READ 20, GROUP 20 FORMAT(O6) KEYNUM = GROUP * '10000'X UIC = KEYNUM READ(1,KEYGE=KEYNUM,KEYID=0,ERR=900) NEXT_UIC 30 IF ((NEXT_UIC/'10000'X) .NE. GROUP) GOTO 900 IF (IAND(NEXT_UIC,'FFFF'X) .EQ. 'FFFF'X) GOTO 900 UIC = NEXT_UIC READ(1,ERR=900) NEXT_UIC GOTO 30 900 UIC = UIC + 1 IF (IAND(UIC,'FFFF'X) .EQ. 'FFFF'X) GOTO 950 TYPE 910, UIC/'10000'X, IAND(UIC,'FFFF'X) 910 FORMAT(1X,'THE NEXT UIC IN THE GROUP IS [',O6.6,',',O6.6,']') WRITE(MEMBER,920) IAND(UIC,'FFFF'X) 920 FORMAT(O6.6) CALL LIB$SET_SYMBOL('MEMBER', MEMBER) GOTO 999 950 TYPE 960, GROUP 960 FORMAT(' GROUP', O6.6, ' IS FULL') 999 END ******************************************************************************** If there were a KEYLT specifier, the loop could be eliminated, and it could all be done with a single read from the file, by setting KEYNUM equal to GROUP * '10000'X + 'FFFF'X.