-- Copyright (C) 1982  by Xerox Corporation. All rights reserved. 
-- PasswordTool.mesa, AOF,  3-Nov-84 12:24:03
-- Please don't forget to update the herald...

DIRECTORY
  Heap USING [systemZone],
  String USING [AppendChar, AppendNumber],

  Password USING [Check, Encrypted, Encrypt],

  FormSW USING [
    AllocateItemDescriptor, ClientItemsProcType, CommandItem, Display, newLine,
    ProcType, StringItem],
  Token USING [FreeStringHandle, Handle, Octal, StringToHandle, SyntaxError],
  Tool USING [Create, MakeSWsProc, MakeFormSW],
  ToolWindow USING [TransitionProcType],
  UserTerminal USING [BlinkDisplay],
  Window USING [Handle];

PasswordTool: PROGRAM
  IMPORTS Heap, String, Password, FormSW, Token, Tool, UserTerminal =
  BEGIN

  z: UNCOUNTED ZONE = Heap.systemZone;

  password, encrypted: LONG STRING ← NIL;
  form: Window.Handle;

  Init: FormSW.ProcType =
    BEGIN
    herald: STRING = "Password Tool of  3-Nov-84 12:24:08"L;
    [] ← Tool.Create[
      name: herald, makeSWsProc: MakeSWs, clientTransition: ClientTransition];
    END;

  Encrypt: FormSW.ProcType =
    BEGIN
    e: Password.Encrypted ← Password.Encrypt["Gateway"L, password];
    p: POINTER ← @e;
    encrypted.length ← 0;
    FOR i: CARDINAL IN [0..SIZE[Password.Encrypted]) DO
      IF i # 0 THEN String.AppendChar[encrypted, ' ];
      String.AppendNumber[encrypted, (p + i)↑, 8];
      ENDLOOP;
    FormSW.Display[form];
    END;

  Check: FormSW.ProcType =
    BEGIN
    e: Password.Encrypted;
    p: POINTER ← @e;
    token: Token.Handle;
    IF encrypted = NIL THEN BEGIN UserTerminal.BlinkDisplay[]; RETURN; END;
    token ← Token.StringToHandle[encrypted];
    BEGIN
    ENABLE Token.SyntaxError => BEGIN UserTerminal.BlinkDisplay[]; CONTINUE; END;
    FOR i: CARDINAL IN [0..SIZE[Password.Encrypted]) DO
      (p + i)↑ ← Token.Octal[token]; ENDLOOP;
    IF ~Password.Check[password, e] THEN UserTerminal.BlinkDisplay[];
    END;
    token ← Token.FreeStringHandle[token];
    END;


  MakeSWs: Tool.MakeSWsProc =
    BEGIN form ← Tool.MakeFormSW[window: window, formProc: MakeForm]; END;

  MakeForm: FormSW.ClientItemsProcType =
    BEGIN
    nParams: CARDINAL = 4;
    items ← FormSW.AllocateItemDescriptor[nParams];
    items[0] ← FormSW.CommandItem[
      tag: "Encrypt"L, proc: Encrypt, place: FormSW.newLine];
    items[1] ← FormSW.CommandItem[tag: "Check"L, proc: Check];
    items[2] ← FormSW.StringItem[
      tag: "Password"L, string: @password, place: FormSW.newLine,
      feedback: password];
    items[3] ← FormSW.StringItem[
      tag: "Encrypted"L, string: @encrypted, place: FormSW.newLine];
    RETURN[items, TRUE];
    END;

  ClientTransition: ToolWindow.TransitionProcType =
    BEGIN
    SELECT TRUE FROM
      old = inactive =>
        BEGIN
        password ← z.NEW[StringBody[20]];
        encrypted ← z.NEW[StringBody[10*8]];
        END;
      new = inactive =>
        BEGIN z.FREE[@password]; z.FREE[@encrypted]; END;
      ENDCASE;
    END;

  Init[];
  END.