From:	CSBVAX::MRGATE!INFO-VAX-RELAY@KL.SRI.COM@SMTP  8-JUL-1988 19:20
To:	ARISIA::EVERHART
Subj:	SUMMARY - How to find the next available uic


Received: from CUNYVM.CUNY.EDU by KL.SRI.COM with TCP; Thu, 30 Jun 88 07:48:02 PDT
Received: from HROEUR51.BITNET by CUNYVM.CUNY.EDU (IBM VM SMTP R1.1) with BSMTP id 2958; Thu, 30 Jun 88 10:45:40 EDT
Date:     Thu, 30 Jun 88 16:47 N
From:     <ARJAN%HROEUR51.BITNET@CUNYVM.CUNY.EDU>
Subject:  SUMMARY - How to find the next available uic
To:       INFO-VAX@KL.SRI.COM
X-Original-To:  INFO-VAX@KL.SRI.COM, ARJAN

My posting about scanning the rightsdatabase for finding
unused uic's in a given group has ripened for exacly two
months (posting of 29-apr-1988) before I received it back
myself via infovax, though some people must have received
it earlier (some reactions a few days after the posting),
but with the original posting yesterday (29-jun-1988) I
received another amount of reactions.
For all those people who sent me the key to the answer:
Thanks a lot.
For all those interested I'll give a short recipe plus the
code I knocked together.


First, one has to set up the FAB/RAB/XABKEY structures and
have them point to each other.
Since you'll be reading, the various fields in those structu-
res need not (all) be defined -RMS will handle that for you.
Open the file, start record stream, find the group uic
([xxx,177777]), using a sys$find (record access mode = KEYED).
(This is a check to be sure that the group exists.)
Then you sys$find [xxx,0] with record processing option
KEY GREATER THAN OR EQUAL TO. From there you sys$get the
next record with record access mode SEQUENTIAL i.o KEYED
and record processing option KEY GREATER THAN.
whenever you find [xxx,177777] again, you know that the
previous record was the record of the last uic in that group.

Follows the program.
(I know it's not not that elegant, but at least it
does what I want it to do, and it does so real fast)
-No privs needed, because rightslist.dat is protected w:re

------------------------------------------------------------------

/* FIND_UIC.C -- Find first free uic for a given group. */
/* and set symbol FULL_UIC to be this new uic.          */

# include rms         /* = fab + rab + nam + xab + rmsdef */
# include ssdef
# include stdio
# include descrip

int int_group, int_rec_mem_val, n, status, suc(), fail();
short int group[2], rec_grp_val[2];
int swtch;             /* for switching record buffers */

struct FAB rdbfab;    /* File access block */
struct XABKEY rdbxab_key_1; /* Extended attributes block */
struct RAB rdbrab;    /* Record access block */
static char filename[] = { "SYS$SYSTEM:RIGHTSLIST.DAT" };
char record[2][65];      /* The record(s) to find */

main()
{

rdbfab = cc$rms_fab;                    /* Initialize structures */
rdbrab = cc$rms_rab;
rdbxab_key_1 = cc$rms_xabkey;

rdbfab.fab$l_xab = &rdbxab_key_1;       /* Define fab's xab (key) pointer */
rdbrab.rab$l_fab = &rdbfab;             /* Rab's fab pointer */

rdbfab.fab$b_fac = FAB$M_GET;           /* File access: read only , share */
rdbfab.fab$b_shr = FAB$M_SHRGET;
rdbxab_key_1.xab$b_dtp = XAB$C_BN4;     /* Unsigned 4 byte binary ascending */
rdbfab.fab$l_fna = filename;            /* predefined file name */
rdbfab.fab$b_fns = strlen(filename);


printf("UIC group: ");
scanf("%o",&group[1]);                  /* Inquire for octal uic group */

int_group = group[1];
group[0] = -1;                          /* Group identifier */

status = sys$open(&rdbfab);             /* Opens for (shared) read only */
if(status!=RMS$_NORMAL) lib$stop(status);

rdbrab.rab$b_mbf = 5; /* Multibuffer count (?) (Minim. 2 for indexed files) */

status = sys$connect(&rdbrab);          /* Start record stream */
if(status!=RMS$_NORMAL) lib$stop(status);

find_highest_mem(group,record[swtch=0]);
}

find_highest_mem(gr,rc)
int *gr;
char *rc;
{

rdbrab.rab$b_krf = 0;  /* Key of referece; - Identifier field (Okay, default) */
rdbrab.rab$l_kbf = gr; /* Key value of the key of reference - (Identifier) */
rdbrab.rab$b_ksz = 4;
rdbrab.rab$b_rac = RAB$C_KEY; /* record access mode: random access by key */
rdbrab.rab$l_ubf = rc; /* record buffer address */
rdbrab.rab$w_usz = 64; /* record length */

if(int_group!=1) /* No group identifier for [1,*] */
  {
   sys$clref(1);
   status = sys$find(&rdbrab,&fail,&suc);
   if(status!=RMS$_NORMAL && status!=RMS$_PENDING)
     {
      puts("%FIND_NEW_UIC-F-NOGRP, specified group does not exist");
      exit();
     }
   sys$waitfr(1);
  }

group[0] = 0;                 /* Group exists */
rdbrab.rab$l_rop = RAB$M_KGE; /* Rec. proc. opt: key gr than or eq. to */

sys$clref(1);

status = sys$find(&rdbrab,&fail,&suc);
if(status!=RMS$_NORMAL && status!=RMS$_PENDING)
  {
   puts("%FIND_NEW_UIC-W-UNKNWN, unknown error");
   exit();
  }

sys$waitfr(1);

rdbrab.rab$l_ubf = record[swtch=1]; /* second record buffer address */

while(1)
 {
  sys$clref(1);
  rdbrab.rab$b_rac = RAB$C_SEQ; /* Found first record, now read seqential. */
  rdbrab.rab$l_rop = RAB$M_KGT; /* Rec. processing option: key greater than */
  rdbrab.rab$l_ubf = record[swtch]; /* one of the  two record buff addresses */

  status = sys$get(&rdbrab,&fail,&suc);
  if(status!=RMS$_NORMAL && status!=RMS$_PENDING) lib$stop(status);
  sys$waitfr(1);
 }

status = sys$close(&rdbfab);
if(status!=RMS$_NORMAL) lib$stop(status);
}

suc() /* RMS completed (successfully) -- AST success routine */
{
 int n;
 rec_grp_val[0] = record[swtch][0] + record[swtch][1]*256;
 rec_grp_val[1] = record[swtch][2] + record[swtch][3]*256;
 if(rec_grp_val[0]==-257)
   {
    if(swtch==0) swtch=1; else swtch=0;
    int_rec_mem_val = record[swtch][0] + record[swtch][1]*256 + 1;
    set_uic_symbol();
    exit();
   }
 if(swtch==0) swtch=1; else swtch=0;
 sys$setef(1);
}

fail() /* RMS completed (unsuccessfully) -- AST error routine */
  {
   puts("%FIND_NEW_UIC-F-NOGRP, specified group does not exist");
   exit();
  }

set_uic_symbol()
{
int global=2;
char newuic[16], memnum[7], grpnum[7];
struct  dsc$descriptor_s uic_desc, symbol_desc;
static char brace[]={ "]" }, comma[]={ "," }, uic_symbol[]={ "FULL_UIC" };

 otoa(int_group,&grpnum);
 otoa(int_rec_mem_val,&memnum);
 newuic[0]='['; newuic[1]='\0';
 strcat(newuic,grpnum);
 strcat(newuic,comma);
 strcat(newuic,memnum);
 strcat(newuic,brace);

 uic_desc.dsc$w_length=strlen(uic_symbol);     /* Symbol name length */
 uic_desc.dsc$b_dtype=DSC$K_DTYPE_T;
 uic_desc.dsc$b_class=DSC$K_CLASS_S;
 uic_desc.dsc$a_pointer=uic_symbol;

 symbol_desc.dsc$w_length=strlen(newuic);           /* Symbol length */
 symbol_desc.dsc$b_dtype=DSC$K_DTYPE_T;
 symbol_desc.dsc$b_class=DSC$K_CLASS_S;
 symbol_desc.dsc$a_pointer=newuic;

 status=lib$set_symbol(&uic_desc,&symbol_desc,&global); /* set global symbol */
 if (status!=SS$_NORMAL) lib$stop(status);
}
