!Set of routines for manipulating admin database
! FIND DIR: Returns the database entry for the specified directory
!J. Butler Oct 1984
!DAK 8/11/84 David A Kerr
!DAK Mods made to improve speed of access for more than one query
!DAK open admin db  - opens and reads in the index for database
!DAK close db       - closes the input opened above
!DAK search db      - same as find dir but no open/close file

%constinteger input stream = 1 ;!Routines open and close this input stream
!%include "managr:addefs.inc"
!%include "inc:fs.imp"
!%include "inc:util.imp"

%recordformat sf(%integer ptr,lim,server,extra)
{DAK}%recordformat tfm(%integer i %or %bytearray a(0:127))
{DAK}%ownrecord (tfm) t
{DAK}%owninteger len=0
%ownstring(5)block

%routine open admin db
  %integer i
  %if exists(adminfile) %then open input(input stream, adminfile) %c
  %else %start
    printstring("*WARNING* file ".adminfile." does not exist,")
    printstring(" trying for old version.")
    newline
    open input(input stream, adminold)
  %finish
  selectinput(input stream)
  %for i = 0, 1, 127 %cycle
     readsymbol(t_a(i))
  %repeat
  len = t_i
%end

%routine close db
  close input
%end

%predicate search db (%string(7) id, %record (admin fm) %name d)
   %integer cell, i, pos
   %record (tfm) tt
   to lower(id)
   %false %unless 'a' <= charno(id, 1) <= 'z'
!DAK assumes that admin.dat has been opened and that len and record t are set
!t!write(len, 3); newline
   pos = (charno(id, 1)-'a'+1)*4
   %for i = 0, 1, 3 %cycle
      tt_a(i) = t_a(pos+i)
   %repeat
!t!phex(tt_i); newline
   setinput(tt_i*128)
   %for cell = tt_i, 1, len %cycle
      readsymbol(byteinteger(addr(d)+i)) %for i = 0, 1, 7
      to lower(d_id)
!t!   write(length(d_id), 3); printstring(": ".d_id); newline
      -> found it %if d_id = id
      %exit %if d_id >= id
      skipsymbol %for i = 8,1,127
   %repeat
   %false

found it:
   read symbol(byteinteger(addr(d)+i)) %for i = 8,1,127
   %true
%end

%predicate find dir(%string (7) id, %record (admin fm) %name d)
   !Looks for id.  If it finds it it returns the information in D
   !result is TRUE if the user was found, FALSE otherwise.
   !D is undefined when result is FALSE.
   %integer cell, i, pos

!t!printstring(id); newline
   to lower(id)
   %false %unless 'a' <= charno(id, 1) <= 'z'
   open admin db
!t!write(len, 3); newline
   pos = (charno(id, 1)-'a'+1)*4
   %for i = 0, 1, 3 %cycle
      t_a(i) = t_a(pos+i)
   %repeat
!t!phex(t_i); newline
   setinput(t_i*128)
   %for cell = t_i, 1, len %cycle
      readsymbol(byteinteger(addr(d)+i)) %for i = 0, 1, 7
      to lower(d_id)
!t!   write(length(d_id), 3); printstring(": ".d_id); newline
      -> found it %if d_id = id
      %exit %if d_id >= id
      skipsymbol %for i = 8,1,127
   %repeat
   close db
   %false

found it:
   read symbol(byteinteger(addr(d)+i)) %for i = 8,1,127
   close db
   %true
%end


%routine show dir(%record (admin fm) %name d)
  !Print some of the admin database fields in a sensible format
  !Private dirs:   Fred Bloggs  (FB)   (Ex-Staff)
  !Systems dirs:   Magic Incantations (SPELLS) (Essential: Owner=Gandalf)
  %integer g
  %string (63) s

  %if charno(d_prenames, 1) # '!' %start
     !Privately owned directory
     printstring(d_prenames); space; printstring(d_surname)
  %else
     !Systems directory
     !strip the "! " off the front.
     %if length(d_description) >=2 %then %c
     s = substring(d_description, 3, length(d_description)) %else s = d_description
     printstring(s)
  %finish

  s = d_id; to upper(s)
  printstring("  (".s.")   (")
  g = d_group
  %if g & 1<<ex bit # 0 %then printstring(pref names(ex bit)."-")
  g = g & 255
  %if 1 <= g < dummy last grp %then printstring(grp names(g))
  %if charno(d_prenames, 1) = '!' %and d_supervisor # "" %start
     printstring(": Owner="); printstring(d_supervisor)
  %finish
  printstring(")")
  newline
%end

%endoffile
