include  "managr:newadmin.inc"

begin ; ! Convert ADMIN database from human-readable to machine-readable

! RWT February 1990

! The human-readable form is not actually intended for human consumption,
! for this purpose the SHOW or LIST commands in the ADMIN program should
! be used.  Instead it is a debugging and rescue aid, and can be used to
! do nasty things the ADMIN program has not yet been taught, such as
! clearing out dead groups and flags.

! The human-readable form contains directory information one per line,
! and nothing else.  Each entry looks like this:
! ID Group{+Flag}* Date Prenames Surname
! That is to say, ID is followed by a space and then the name of the
! group to which that directory belongs, followed by any number of flags,
! each preceded by a plus sign.  The flags indicate membership of any
! number of classes (such as trusted, lasered, and the set of filestores
! on which the directory exists).  Each entry must belong to exactly one
! group, but may belong to any number of classes (even none).  The creation
! date, in standard dd/mm/yy form, follows this after a space.  There follows
! another space and then the name.  The name may contain any number of
! spaces, and whatever follows the last space is taken to be the surname.
! For non-person directories, the prenames should describe the purpose of
! the directory, and the surname should be the ID (not name) of the person
! responsible for its contents.

record (entry fm)name  list==nil,pred,this
string (255)line,l,r,x
integer  number
string (255)in="admin.dbh",out="admin.db"

on  9 start 
  selectoutput(1)
  write admin file(list)
  stop 
finish 
  
defineparam("Human readable input",in,0)
defineparam("Machine readable output",out,pamnewgroup)
processparameters(cliparam)
openinput(1,in); selectinput(1)
openoutput(1,out); selectoutput(0)
  
cycle 
  this == new(this); this = 0
  readline(line)
  unless  line -> l.(" ").r and  length(l)<7 start 
no: printstring("Faulty record ignored: "); printline(line)
    dispose(this)
    continue 
  finish 
  toupper(l); this_id = l
  ->no unless  r -> l.(" ").r and  l#""
  x = l and  l = "" unless  l -> x.("+").l; l = l."+"
  number = 0
  admingrouplist == lookup and add(admingrouplist,x,number) unless  x=""
  this_group = number
  while  l -> x.("+").l cycle 
    unless  x="" start 
      adminflaglist == lookup and add(adminflaglist,x,number)
      this_flags = this_flags!1<<(number-1)
    finish 
  repeat 
  ->no unless  r -> l.(" ").r
  this_created = packdate(l)
  ->no if  this_created=0
  ->no unless  r -> l.(" ").r and  r#""
  l = l." ".x while  r -> x.(" ").r
  this_sur == heapstring(r)
  this_pre == heapstring(l)
  this_next == nil
  if  list==nil then  list == this else  pred_next == this; pred == this
repeat 

end