-- File: PasswordTool.mesa - last edit:
-- AOF                  3-Nov-84 12:24:03
-- WIrish               5-Feb-88 12:39:51
-- Copyright (C) 1982, 1984, 1988 by Xerox Corporation. All rights reserved. 

DIRECTORY
  Heap USING [systemZone],
  Runtime USING [GetBcdTime],
  String USING [AppendChar, AppendNumber, AppendString],

  Password USING [Check, Encrypted, Encrypt],

  FormSW USING [
    AllocateItemDescriptor, ClientItemsProcType, CommandItem, Display, newLine,
    ProcType, StringItem],
  Time USING [Append, Unpack],
  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, Runtime, String, Password, FormSW, Time, Token, Tool, UserTerminal =
  BEGIN

  z: UNCOUNTED ZONE = Heap.systemZone;

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

  Init: FormSW.ProcType =
    BEGIN
    herald: LONG STRING = [100];
    String.AppendString[herald, "Password Tool of "L];
    Time.Append[herald, Time.Unpack[Runtime.GetBcdTime[]]];
    [] ← 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.