-- Transport Mechanism: Maintain: un-common commands

-- [Indigo]<Grapevine>Maintain>MaintainCommands.mesa

-- Andrew Birrell  13-Jan-82 16:18:58
-- Philip Karlton  15-May-81 16:09:26

DIRECTORY
Ascii		USING[ CR, DEL ],
BodyDefs	USING[ Connect, maxConnectLength, maxRemarkLength,
		       maxRNameLength, Password, Remark, RName ],
MaintainPrivate	USING[ CheckConnect, CheckMailName, CheckRealName, Confirm,
		       CopyName, Del, Handle, ReadPassword, ReadWord,
		       RemoveAllMemberships, Update],
ProtocolDefs	USING[ RegServerEnquirySocket],
PupDefs		USING[ GetPupAddress, PupAddress, PupNameTrouble ],
String		USING[ StringToNumber ];

MaintainCommands: PROGRAM
IMPORTS MaintainPrivate, ProtocolDefs, PupDefs, String
EXPORTS MaintainPrivate =

BEGIN

OPEN MaintainPrivate;

VerifyName: PUBLIC PROCEDURE[handle: MaintainPrivate.Handle] =
   BEGIN
   OPEN handle;
   ReadWord[glass, ": "L, dName];
   CheckMailName[dName];
   glass.WriteString[" ... ok"L];
   END;

DeleteIndividual: PUBLIC PROCEDURE[handle: MaintainPrivate.Handle] =
  BEGIN
  OPEN handle;
  ReadWord[glass, ": "L, individual];
  CopyName[from: individual, to: dName];
  IF Confirm[glass]
  THEN BEGIN
       Update[handle: handle, op: DeleteIndividual, name: individual];
       glass.WriteChar[Ascii.CR];
       glass.WriteString["--> Remove All Memberships"L];
       MaintainPrivate.RemoveAllMemberships[handle];
       END;
  END;

CreateGroup: PUBLIC PROCEDURE[handle: MaintainPrivate.Handle] = 
  BEGIN
  OPEN handle;
  ReadWord[glass, ": "L, group];
  CopyName[from: group, to: dName];
  Update[handle: handle, op: CreateGroup, name: group];
  END;

InitializeNewName: PUBLIC PROCEDURE[handle: MaintainPrivate.Handle] =
  BEGIN
  OPEN handle;
  ReadWord[glass, " from old name: "L, name];
  CheckRealName[name];
  ReadWord[glass, ", creating new name: "L, dName];
  Update[handle: handle, op: NewName, name: dName, value: name];
  END;

DeleteGroup: PUBLIC PROCEDURE[handle: MaintainPrivate.Handle] =
  BEGIN
  OPEN handle;
  ReadWord[glass, ": "L, group];
  CopyName[from: group, to: dName];
  IF Confirm[glass]
  THEN BEGIN
       Update[handle: handle, op: DeleteGroup, name: group];
       glass.WriteChar[Ascii.CR];
       glass.WriteString["--> Remove All Memberships"L];
       MaintainPrivate.RemoveAllMemberships[handle];
       END;
  END;

SetPassword: PUBLIC PROCEDURE[handle: MaintainPrivate.Handle] =
  BEGIN
  OPEN handle;
  pwstring: STRING = [32];
  pw: BodyDefs.Password;
  pw ← ReadPassword[glass, " to be: "L, pwstring];
  ReadWord[glass, " for individual: "L, individual];
  CopyName[from: individual, to: dName];
  Update[handle: handle, op: ChangePassword, name: individual, key: pw];
  END;

SetDecimalPassword: PUBLIC PROCEDURE[handle: MaintainPrivate.Handle] =
  BEGIN
  OPEN handle;
  buffer: STRING = [7] --177777B--;
  pw: BodyDefs.Password;
  glass.WriteString[" to be (4 numbers):"L];
  FOR i: CARDINAL IN [0..LENGTH[pw])
  DO ReadWord[glass, " "L, buffer];
     pw[i] ← String.StringToNumber[buffer, 10];
  ENDLOOP;
  ReadWord[glass, " for individual: "L, individual];
  CopyName[from: individual, to: dName];
  Update[handle: handle, op: ChangePassword, name: individual, key: pw];
  END;

SetConnect: PUBLIC PROCEDURE[handle: MaintainPrivate.Handle] =
  BEGIN
  OPEN handle;
  connect: BodyDefs.Connect = [BodyDefs.maxConnectLength];
  ReadWord[glass, " to be: "L, connect];
  IF connect.length > 0 THEN CheckConnect[connect];
  ReadWord[glass, " for individual: "L, individual];
  CopyName[from: individual, to: dName];
  Update[handle: handle, op: ChangeConnect, name: individual, connect: connect];
  END;

BadRemark: PUBLIC ERROR[bad: CHARACTER] = CODE;

SetRemark: PUBLIC PROCEDURE[handle: MaintainPrivate.Handle] =
  BEGIN
  OPEN handle;
  remark: BodyDefs.Remark = [BodyDefs.maxRemarkLength];
  IF glass.ReadString[" to be: "L, remark, line] = Ascii.DEL
  THEN ERROR MaintainPrivate.Del[];
  FOR index: CARDINAL IN [0..remark.length)
  DO SELECT remark[index] FROM
       ' ,
       '!, '#, '$, '%, '&, '(, '), '*, '+, ',, '-, '., '/,
       IN ['0..'9],
       '<, '=, '>, '?, '@,
       IN ['A..'Z],
       '[, ("\\"L)[0]--for cedar escapes!--, '], '↑, '←,
       IN ['a..'z],
       '{, '|, '}, '~ => NULL;
     ENDCASE => ERROR BadRemark[remark[index]];
  ENDLOOP;
  ReadWord[glass, " for group: "L, group];
  CopyName[from: group, to: dName];
  Update[handle: handle, op: ChangeRemark, name: group, remark: remark];
  END;

RemoveMailbox: PUBLIC PROCEDURE[handle: MaintainPrivate.Handle] =
  BEGIN
  OPEN handle;
  ReadWord[glass, " at server: "L, name];
  ReadWord[glass, " from individual: "L, individual];
  CopyName[from: individual, to: dName];
  Update[handle: handle, op: DeleteMailBox, name: individual, value: name];
  END;

AddForward: PUBLIC PROCEDURE[handle: MaintainPrivate.Handle] = 
  BEGIN
  OPEN handle;
  ReadWord[glass, " to destination recipient: "L, name];
  CheckMailName[name];
  ReadWord[glass, " for individual: "L, individual];
  CopyName[from: individual, to: dName];
  Update[handle: handle, op: AddForward, name: individual, value: name];
  END;

RemoveForward: PUBLIC PROCEDURE[handle: MaintainPrivate.Handle] =
  BEGIN
  OPEN handle;
  ReadWord[glass, " to destination recipient: "L, name];
  ReadWord[glass, " from individual: "L, individual];
  CopyName[from: individual, to: dName];
  Update[handle: handle, op: DeleteForward, name: individual, value: name]
  END;

AddOwner: PUBLIC PROCEDURE[handle: MaintainPrivate.Handle] = 
  BEGIN
  OPEN handle;
  ReadWord[glass, ": "L, name];
  CheckMailName[name];
  ReadWord[glass, " to group: "L, group];
  CopyName[from: group, to: dName];
  Update[handle: handle, op: AddOwner, name: group, value: name]
  END;

RemoveOwner: PUBLIC PROCEDURE[handle: MaintainPrivate.Handle] =
  BEGIN
  OPEN handle;
  ReadWord[glass, ": "L, name];
  ReadWord[glass, " from group: "L, group];
  CopyName[from: group, to: dName];
  Update[handle: handle, op: DeleteOwner, name: group, value: name];
  END;

AddFriend: PUBLIC PROCEDURE[handle: MaintainPrivate.Handle] = 
  BEGIN
  OPEN handle;
  ReadWord[glass, ": "L, name];
  IF name.length = 0 OR name[0] # '*
  THEN CheckMailName[name];
  ReadWord[glass, " to group: "L, group];
  CopyName[from: group, to: dName];
  Update[handle: handle, op: AddFriend, name: group, value: name];
  END;

RemoveFriend: PUBLIC PROCEDURE[handle: MaintainPrivate.Handle] =
  BEGIN
  OPEN handle;
  ReadWord[glass, ": "L, name];
  ReadWord[glass, " from group: "L, group];
  CopyName[from: group, to: dName];
  Update[handle: handle, op: DeleteFriend, name: group, value: name];
  END;

SetServer: PUBLIC PROCEDURE[handle: MaintainPrivate.Handle] =
  BEGIN
  OPEN handle;
  serverSite: BodyDefs.RName = [BodyDefs.maxRNameLength];
  addr: PupDefs.PupAddress ← serverAddr;
  addr.socket ← [0,0];
  ReadWord[glass, " to be NLS-name or addr: "L, serverSite];
  PupDefs.GetPupAddress[@addr, serverSite !
                        PupDefs.PupNameTrouble => GOTO bad ];
  addr.socket ← ProtocolDefs.RegServerEnquirySocket;
  IF str # NIL THEN str.delete[str];
  str ← NIL; serverAddr ← addr; addrKnown ← TRUE;
  EXITS bad => handle.glass.WriteString[" ... Bad NLS-name"L];
  END;

END.