-- Any old test program -- Test2.mesa -- Andrew Birrell 4-Feb-81 16:45:19 DIRECTORY BodyDefs, IODefs, LocateDefs USING[ FindRegServer, FoundServerInfo ], NameInfoDefs, ProtocolDefs, PupDefs, StringDefs, TimeDefs; Test2: PROGRAM IMPORTS IODefs, LocateDefs, NameInfoDefs, ProtocolDefs, PupDefs, StringDefs, TimeDefs = BEGIN OPEN BodyDefs, IODefs, NameInfoDefs, ProtocolDefs, PupDefs; serverAddr: PupDefs.PupAddress; -- other server's address -- addrKnown: BOOLEAN ← FALSE; -- validity of serverAddr -- str: Handle ← NIL; -- stream to other server -- -- "Operate" procedure stolen from Maintain Operate: PUBLIC PROC[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: [0,0,0,0]]; 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, serverAddr]; WriteString[serverSite]; WriteString[" ... "L]; str ← ProtocolDefs.CreateStream[serverAddr]; END; Destroy: PROC = BEGIN IF str # NIL THEN DestroyStream[str]; str ← NIL; END; Accept: PROC[addr: PupDefs.PupAddress]RETURNS[BOOLEAN] = BEGIN addr.socket ← RegServerEnquirySocket; IF str # NIL AND serverAddr # addr THEN Destroy[]; IF str = NIL THEN BEGIN serverAddr ← addr; Create[ ! Failed => GOTO failed]; addrKnown ← TRUE; END; RETURN[TRUE]; EXITS failed => RETURN[FALSE] END; BEGIN IF str # NIL THEN BEGIN TryUpdate[ str ! Failed => GOTO streamGone ]; EXITS streamGone => Destroy[]; END; IF str = NIL THEN BEGIN IF addrKnown THEN Create[ ! Failed => GOTO notThere] ELSE BEGIN [] ← LocateDefs.FindRegServer["x.GV"L, Accept]; IF str = NIL THEN GOTO notThere; END; TryUpdate[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; 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[ str ! Failed => GOTO down ]; EXITS down => { Destroy[]; rc ← [AllDown,notFound] }; END; ENDCASE => ERROR; END; END; WriteStamp: PROC[stamp: Timestamp] = BEGIN text: STRING = [30]; WriteOctal: PROC[n: CARDINAL] = BEGIN buffer: STRING = [6] --177777--; StringDefs.AppendNumber[buffer, n, 8]; WriteString[buffer]; END; WriteChar['[]; WriteOctal[stamp.net]; WriteChar['#]; WriteOctal[stamp.host]; WriteChar[',]; TimeDefs.AppendDayTime [text, TimeDefs.UnpackDT [stamp.time]]; WriteString[text]; WriteChar[']]; END; WriteType: PROC[type: RNameType] = BEGIN WriteString[SELECT type FROM group => "group"L, individual => "individual"L, notFound => "not found"L, dead => "dead"L, ENDCASE => ERROR]; END; WriteRC: PROC[rc: ReturnCode] = BEGIN WriteString[SELECT rc.code FROM done => "ok"L, noChange => "no change"L, outOfDate => "out of date"L, NotAllowed => "not allowed"L, BadOperation => "bad operation"L, BadProtocol => "bad protocol"L, BadRName => "bad R-Name: "L, BadPassword => "bad password"L, WrongServer => "wrong server"L, AllDown => "all suitable R-Servers down"L, ENDCASE => ERROR]; IF rc.code = BadRName THEN WriteType[rc.type]; END; LookEither: PROC[name: RName, work: PROC[RName]]RETURNS[done: BOOLEAN] = BEGIN stamp: Timestamp; rc: ReturnCode; WriteChar[CR]; WriteString[name]; WriteString[": "L]; rc ← Operate[op: Expand, name: name]; IF rc.code = done THEN stamp ← ReceiveTimestamp[str]; IF rc.code = done THEN BEGIN THROUGH [name.length..16] DO WriteChar[SP] ENDLOOP; ProtocolDefs.ReceiveRList[str, work]; END ELSE WriteRC[rc]; done ← ( rc.code=WrongServer OR rc.code=AllDown); END; -- Look at all individuals in some registry; NIL if not wanted -- LookIndividual: PROC[name: RName]RETURNS[done: BOOLEAN] = BEGIN first: BOOLEAN ← TRUE; LookAt: PROC[given: RName] = BEGIN IF first THEN first ← FALSE ELSE WriteString[", "L]; WriteString[given]; END; done ← LookEither[name, LookAt]; IF NOT done AND first THEN WriteString["none"L]; END; -- Look at all groups in some registry; NIL if not wanted -- LookGroup: PROC[name: RName]RETURNS[done: BOOLEAN] = BEGIN first: BOOLEAN ← TRUE; count: CARDINAL ← 0; LookAt: PROC[given: RName] = BEGIN FOR i: CARDINAL IN [0..given.length) DO IF given[i] = '↑ THEN BEGIN IF first THEN first ← FALSE ELSE WriteString[", "L]; WriteString[given]; EXIT END; ENDLOOP; count ← count + 1; END; done ← LookEither[name, LookAt]; IF NOT first THEN WriteString[". "L]; WriteDecimal[count]; WriteString[" member"L]; IF count # 1 THEN WriteChar['s]; END; -- Look at all dead entries in some registry; NIL if not wanted -- LookDead: PROC[name: RName]RETURNS[done: BOOLEAN] = NIL; -- Look at all entries of given type in given registry -- LookEnum: PROC[type: RNameType, registry: STRING, work: PROC[RName]RETURNS[done: BOOLEAN] ] = BEGIN enumName: RName = [maxRNameLength]; memberInfo: MemberInfo; StringDefs.AppendString[enumName, SELECT type FROM individual => "Individuals."L, group => "Groups."L, dead => "Dead."L, ENDCASE => ERROR]; StringDefs.AppendString[enumName, registry]; WriteChar[CR]; WriteChar[CR]; WriteString[enumName]; memberInfo ← GetMembers[enumName]; WITH memberInfo SELECT FROM group => BEGIN ENABLE UNWIND => Close[members]; Enumerate[members, work]; Close[members]; END; allDown => WriteString[": all R-Servers down!"L]; notFound => WriteString[": not found!"L]; ENDCASE => ERROR; END; -- Look at all entries in registry with R-Name "regGroup" -- LookAtRegistry: PROC[regGroup: RName] RETURNS[done: BOOLEAN] = BEGIN FOR i: CARDINAL DECREASING IN [0..regGroup.length) DO regGroup.length ← regGroup.length-1; IF regGroup[i] = '. THEN EXIT; ENDLOOP; IF LookGroup # NIL THEN LookEnum[group, regGroup, LookGroup]; IF LookIndividual # NIL THEN LookEnum[individual, regGroup, LookIndividual]; IF LookDead # NIL THEN LookEnum[dead, regGroup, LookDead]; done ← FALSE; END; ProtocolDefs.Init[]; LookEnum[group, "GV"L, LookAtRegistry ! ProtocolDefs.Failed => { WriteString["ProtocolDefs.Failed"L]; CONTINUE } ]; IF str # NIL THEN DestroyStream[str]; END.