-- file: IntUserCom.Mesa
-- edited by Brotz, April 1, 1981 5:24 PM
-- edited by Schroeder, March 14, 1981 1:21 PM
-- edited by Levin, August 19, 1980 1:05 PM

DIRECTORY
dsD: FROM "DisplayDefs",
exD: FROM "ExceptionDefs",
inD: FROM "InteractorDefs",
intCommon: FROM "IntCommon",
OsStaticDefs,
RetrieveDefs,
Storage,
StringDefs;

IntUserCom: PROGRAM
IMPORTS dsD, exD, inD, intC: intCommon, RetrieveDefs, Storage, StringDefs
EXPORTS inD =

BEGIN
OPEN inD, StringDefs;


LoginCommand: PUBLIC PROCEDURE [hp: HousePtr, confirmed: BOOLEAN] =
-- Prompts for name and password. Returns them in user.
-- Side effects: changes intC.user.
BEGIN

MakeNameDotRegistry: PROCEDURE[name, result: STRING] =
BEGIN
result.length ← 0;
AppendString[result, name];
AppendChar[result, ’.];
AppendString[result, intC.user.registry];
END; -- MakeNameDotRegistry --

UpdateOSPasswordIfDifferent: PROCEDURE =
BEGIN
MyBcplToMesaString[OsStaticDefs.OsStatics.UserPassword, string1];
-- now string1 is the OS user password --
IF NOT EquivalentString[string1, intC.user.password]
THEN BEGIN
StuffOsString[intC.user.password, OsStaticDefs.OsStatics.UserPassword];
exD.DisplayExceptionLine[exD.passwordWritten, 1];
END;
END; -- UpdateOSPasswordIfDifferent --

StuffOsString: PROCEDURE [mesa: STRING, os: POINTER TO BcplSTRING] =
BEGIN
bcplMaxChars: CARDINAL =
LOOPHOLE[os - 1, POINTER TO CARDINAL]↑ * 2 - BcplStringHeaderSize;
oldLength: CARDINAL ← mesa.length;
mesa.length ← MIN[mesa.length, bcplMaxChars];
MesaToBcplString[mesa, os];
mesa.length ← oldLength;
END; -- of StuffOsString --

-- The following procedure is needed because of a bug in the Mesa version --
MyBcplToMesaString: PROCEDURE[t: POINTER TO BcplSTRING, s: STRING] =
BEGIN
i: CARDINAL;
FOR i IN [0..(s.length ← MIN[t.length, s.maxlength])) DO
s[i] ← t.char[i]; ENDLOOP;
END;


i, saveLength: CARDINAL;
passwordString: STRING ← "Password "L;
string1: STRING ← [maxBracketStringLength];
string2: STRING ← [maxBracketStringLength];
newUser, newRegistry: STRING;
curX, rightX: ScreenXCoord;
userBracketsHouse: HousePtr = intC.userBracketsHouse;
userCommandHouse: HousePtr = intC.userCommandHouse;
aborted: BOOLEAN ← FALSE;

-- get new user name from brackets --
exD.ClearExceptionsRegion[];
dsD.ChangeCursor[invisibleCursor];
IF confirmed
THEN MakeNameDotRegistry[intC.user.name, string2]
ELSE BEGIN
AppendString[string1, userBracketsHouse.text];
[aborted, rightX] ← GetStringForBrackets
[hp: userBracketsHouse, leftX: userBracketsHouse.leftX,
rightX: userBracketsHouse.rightX, maxDeltaX: 128, bracketFace: boldFace,
displayChars: TRUE, initialDisplayString: string1, abortString: string1,
outputString: string2];
IF aborted THEN RETURN;
FOR i DECREASING IN [0 .. string2.length) DO
IF string2[i] = ’. THEN BEGIN
newUser ← Storage.String[i];
saveLength ← string2.length;
string2.length ← i;
AppendString[newUser, string2];
string2.length ← saveLength;
newRegistry ← Storage.String[saveLength-i-1];
FOR i IN [i+1..saveLength)
DO AppendChar[newRegistry, string2[i]] ENDLOOP;
Storage.FreeString[intC.user.registry];
intC.user.registry ← newRegistry;
EXIT
END;
REPEAT FINISHED =>
BEGIN
string2.length ← MIN[string2.length,
maxBracketStringLength-intC.user.registry.length-1];
newUser ← Storage.String[string2.length];
AppendString[newUser, string2];
MakeNameDotRegistry[newUser, string2];
END;
ENDLOOP;
Storage.FreeString[intC.user.name];
intC.user.name ← newUser;
userBracketsHouse.text.length ← 0;
AppendString[userBracketsHouse.text, string2];
userBracketsHouse.rightX ← rightX;
END;

-- get new password from brackets --
dsD.ClearRectangle[userCommandHouse.leftX, userBracketsHouse.rightX,
userCommandHouse.topY, intC.userCommandHouse.bottomY];
curX ← dsD.PutStringInBitMap[userCommandHouse.leftX, userCommandHouse.topY, passwordString, boldFace];
string1.length ← 0;
[ , curX] ← GetStringForBrackets[hp: userBracketsHouse, leftX: curX,
rightX: curX, maxDeltaX: 50, bracketFace: boldFace, displayChars: FALSE,
initialDisplayString: ""L, abortString: intC.user.password, outputString: string1];
dsD.ChangeCursor[hourGlass];
Storage.FreeString[intC.user.password];
intC.user.password ← Storage.String[string1.length];
AppendString[intC.user.password, string1];
dsD.ClearRectangle[userCommandHouse.leftX, curX, userBracketsHouse.topY,
userBracketsHouse.bottomY];
userCommandHouse.houseRefresher[userCommandHouse];
userBracketsHouse.houseRefresher[userBracketsHouse];
RetrieveDefs.NewUser[intC.retrieveHandle, string2, string1];

-- update the OS password if necessary --
-- string2 contains the new userName.registry --
MyBcplToMesaString[OsStaticDefs.OsStatics.UserName, string1];
-- now string1 is the OS user name --
FOR i DECREASING IN [0 .. string1.length) DO
IF string1[i] = ’.
THEN BEGIN -- OS user name includes the registry --
IF EquivalentString[string1, string2]
THEN UpdateOSPasswordIfDifferent[];
EXIT;
END;
REPEAT FINISHED => -- OS user name does not include registry --
IF EquivalentString[intC.user.name, string1]
AND EquivalentString[intC.user.registry, intC.profileRegistry]
THEN UpdateOSPasswordIfDifferent[];
ENDLOOP;

END; -- of LoginCommand --
END. -- of IntUserCom --