-- Transport mechanism: Maintain: raw communications
-- [Juniper]<Grapevine>Maintain>MaintainComm.mesa
-- Andrew Birrell 14-Jan-82 9:37:23
DIRECTORY
BodyDefs USING[ Connect, oldestTime, Password, Remark, RName ],
LocateDefs USING[ FindRegServer, FoundServerInfo ],
MaintainPrivate USING[ Failed, Handle, TypeRC ],
ProtocolDefs,
PupDefs USING[ AppendPupAddress, PupAddress ];
MaintainComm: PROGRAM
IMPORTS LocateDefs, MaintainPrivate, ProtocolDefs, PupDefs
EXPORTS MaintainPrivate =
BEGIN
OPEN MaintainPrivate;
-- Actual communication with the registration servers --
Update: PUBLIC PROC[handle: MaintainPrivate.Handle,
op: ProtocolDefs.RSOperation, name: BodyDefs.RName,
value: BodyDefs.RName ← NIL,
connect: BodyDefs.Connect ← NIL,
remark: BodyDefs.Remark ← NIL,
key: BodyDefs.Password ← [0,0,0,0],
sendRList: PROC[ProtocolDefs.Handle] ← NIL ] =
BEGIN
rc: ProtocolDefs.ReturnCode =
Operate[handle, op, name, value, connect, remark, key];
END;
Operate: PUBLIC PROC[handle: MaintainPrivate.Handle,
op: ProtocolDefs.RSOperation, name: BodyDefs.RName,
value: BodyDefs.RName ← NIL,
connect: BodyDefs.Connect ← NIL,
remark: BodyDefs.Remark ← NIL,
key: BodyDefs.Password ← [0,0,0,0],
sendRList: PROC[ProtocolDefs.Handle] ← NIL ]
RETURNS[ rc: ProtocolDefs.ReturnCode ] =
BEGIN
OPEN ProtocolDefs;
TryUpdate: PROC[str: ProtocolDefs.Handle] =
BEGIN
SendRSOperation[str, op];
IF op # NoOp THEN SendRName[str, name];
SELECT op FROM
IN [Expand..ReadEntry] =>
SendTimestamp[str, BodyDefs.oldestTime];
IdentifyCaller =>
SendPassword[str:str, pw: key, key: [0,0,0,0]];
IN [AddMember..DeleteFriend], NewName,
IN [IsMemberDirect..IsFriendClosure] =>
{ IF value = NIL THEN ERROR; SendRName[str, value] };
Authenticate, CreateIndividual, ChangePassword =>
SendPassword[str:str, pw: key, key: handle.callerKey];
ChangeConnect =>
{ IF connect = NIL THEN ERROR; SendConnect[str, connect] };
ChangeRemark =>
{ IF remark = NIL THEN ERROR; SendRemark[str, remark] };
AddListOfMembers =>
{ IF sendRList = NIL THEN ERROR; sendRList[str] };
ENDCASE => NULL;
SendNow[str];
IF op # NoOp THEN rc ← ReceiveRC[str];
END;
oldBad: BOOLEAN ← FALSE;
Create: PROC =
BEGIN
serverSite: STRING = [21] --377#377#177777|177777--;
PupDefs.AppendPupAddress[serverSite, handle.serverAddr];
handle.glass.WriteString[serverSite];
handle.glass.WriteString[" ... "L];
handle.glass.SendNow[];
handle.str ← ProtocolDefs.CreateStream[handle.serverAddr];
IF handle.authenticated
THEN BEGIN
SendRSOperation[handle.str, IdentifyCaller];
ProtocolDefs.SendRName[handle.str, handle.caller];
ProtocolDefs.SendPassword[str:handle.str,
pw: handle.callerKey,
key:[0,0,0,0]];
ProtocolDefs.SendNow[handle.str];
rc ← ReceiveRC[handle.str];
IF rc.code # done
THEN BEGIN
handle.authenticated ← FALSE;
handle.glass.WriteString[
"your name/password is not valid! ... "L];
END;
END;
END;
Destroy: PROC =
BEGIN
IF handle.str # NIL THEN DestroyStream[handle.str];
handle.str ← NIL;
END;
Accept: PROC[addr: PupDefs.PupAddress]RETURNS[BOOLEAN] =
BEGIN
addr.socket ← RegServerEnquirySocket;
IF handle.str # NIL AND handle.serverAddr # addr THEN Destroy[];
IF handle.str = NIL
THEN BEGIN
handle.serverAddr ← addr;
Create[ ! Failed => GOTO failed];
handle.addrKnown ← TRUE;
END;
RETURN[TRUE];
EXITS failed => RETURN[FALSE]
END;
handle.glass.WriteString[" ... "L]; handle.glass.SendNow[];
SELECT op FROM
NoOp, CheckStamp, Authenticate, IdentifyCaller =>
NULL;
ENDCASE =>
IF NOT handle.authenticated
THEN { handle.glass.WriteString["please login first"L];
ERROR MaintainPrivate.Failed[] };
BEGIN
IF handle.str # NIL
THEN BEGIN
TryUpdate[ handle.str ! Failed => GOTO streamGone ];
EXITS streamGone => Destroy[];
END;
IF handle.str = NIL
THEN BEGIN
IF handle.addrKnown
THEN Create[ ! Failed => GOTO notThere]
ELSE BEGIN
[] ← LocateDefs.FindRegServer["x.GV"L, Accept];
IF handle.str = NIL THEN GOTO notThere;
END;
TryUpdate[handle.str ! Failed => GOTO notThere];
END;
IF rc.code = WrongServer
THEN oldBad ← TRUE
ELSE oldBad ← FALSE;
EXITS notThere => { Destroy[]; oldBad ← TRUE };
END;
IF oldBad
THEN BEGIN -- need to find the correct R-Server --
foundInfo: LocateDefs.FoundServerInfo;
handle.glass.WriteString["Locating registration server ... "L];
foundInfo ← LocateDefs.FindRegServer[name, Accept];
WITH foundInfo SELECT FROM
notFound => rc ← [BadRName, notFound];
allDown => rc ← [AllDown, notFound];
found =>
BEGIN
TryUpdate[ handle.str ! Failed => GOTO down ];
EXITS down =>
{ Destroy[]; rc ← [AllDown, notFound] };
END;
ENDCASE => ERROR;
END;
IF rc.code = done
THEN handle.glass.WriteString["done"L]
ELSE MaintainPrivate.TypeRC[handle, op, rc, name, value];
END;
END.