-- 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.