-- Transport Mechanism: Maintain: Type Entry -- [Juniper]<Grapevine>maintain>MaintainType.mesa -- Andrew Birrell 14-Jan-82 13:08:17 -- Philip Karlton 15-May-81 16:51:40 DIRECTORY Ascii USING[ CR, SP ], BodyDefs USING[ Connect, maxConnectLength, maxRemarkLength, maxRNameLength, Password, Remark, RName, RNameSize, Timestamp ], GlassDefs USING[ Handle ], MaintainPrivate USING[ CopyName, Del, Handle, Operate, ReadWord, TypeType ], ProtocolDefs, Stream, String USING[ AppendNumber ], Time USING[ Append, Unpack ]; MaintainType: PROGRAM IMPORTS BodyDefs, MaintainPrivate, ProtocolDefs, Stream, String, Time EXPORTS MaintainPrivate = BEGIN OPEN MaintainPrivate; TypeEntry: PUBLIC PROCEDURE[handle: MaintainPrivate.Handle] = { DisplayEntry[handle, brief] }; TypeMembers: PUBLIC PROCEDURE[handle: MaintainPrivate.Handle] = BEGIN OPEN handle; rc: ProtocolDefs.ReturnCode; ReadWord[glass, " of group: "L, dName]; rc ← Operate[handle: handle, op: ReadMembers, name: dName]; IF rc.code = done THEN BEGIN [] ← ProtocolDefs.ReceiveTimestamp[str]; CopyName[from: dName, to: group]; TypeRList[glass, str, "Members:"L, contents]; END; END; TypeDetails: PUBLIC PROCEDURE[handle: MaintainPrivate.Handle] = { DisplayEntry[handle, full] }; Detail: TYPE = {brief, full}; DisplayEntry: PROC[handle: MaintainPrivate.Handle, amount: Detail ] = BEGIN OPEN handle; rc: ProtocolDefs.ReturnCode; items: CARDINAL; ReadWord[glass, " for R-Name: "L, dName]; rc ← Operate[handle: handle, op: ReadEntry, name: dName]; IF rc.code = done THEN [] ← ProtocolDefs.ReceiveTimestamp[str]; items ← IF rc.code = done THEN ProtocolDefs.ReceiveCount[str] ELSE 0; IF rc.code = done THEN TypeType[glass, rc.type]; SELECT rc.type FROM notFound => NULL; dead => TypePrefix[glass, str, amount]; individual => BEGIN CopyName[from: dName, to: individual]; TypePrefix[glass, str, amount]; TypePassword[glass, str, amount]; TypeConnect[glass, str, amount]; TypeRList[glass, str,"Forwarding:"L, contents]; TypeStampList[glass, str, amount]; TypeRList[glass, str, "DelForwarding:"L, IF amount=full THEN contents ELSE none]; TypeStampList[glass, str, amount]; TypeRList[glass, str, "Mailbox-sites:"L, contents]; TypeStampList[glass, str, amount]; TypeRList[glass, str, "DelMailboxSites:"L, IF amount=full THEN contents ELSE none]; TypeStampList[glass, str, amount]; END; group => BEGIN CopyName[from: dName, to: group]; TypePrefix[glass, str, amount ]; TypeRemark[glass, str, amount]; TypeRList[glass, str, "Members:"L, IF amount=brief THEN total ELSE contents]; TypeStampList[glass, str, amount]; TypeRList[glass, str, "DelMembers:"L, IF amount=full THEN contents ELSE none]; TypeStampList[glass, str, amount]; TypeRList[glass, str, "Owners:"L, contents]; TypeStampList[glass, str, amount]; TypeRList[glass, str, "DelOwners:"L, IF amount=full THEN contents ELSE none]; TypeStampList[glass, str, amount]; TypeRList[glass, str, "Friends:"L, contents]; TypeStampList[glass, str, amount]; TypeRList[glass, str, "DelFriends:"L, IF amount=full THEN contents ELSE none]; TypeStampList[glass, str, amount]; END; ENDCASE => ERROR; END; TypePrefix: PROC[glass: GlassDefs.Handle, str: ProtocolDefs.Handle, amount: Detail] = BEGIN -- type it iff amount = full OPEN glass; length: CARDINAL = ProtocolDefs.ReceiveCount[str]; type: ProtocolDefs.RNameType; name: BodyDefs.RName = [BodyDefs.maxRNameLength]; IF amount = full THEN { WriteChar[Ascii.CR]; WriteString["Prefix: "L]; }; TypeTimestamp[glass, str, amount]; type ← LOOPHOLE[ProtocolDefs.ReceiveCount[str]]; IF amount = full THEN TypeType[glass, type]; IF amount = full THEN WriteString[", "L]; [] ← TypeRName[glass, str, amount]; END; TypeRList: PROC[glass: GlassDefs.Handle, str: ProtocolDefs.Handle, text: STRING, amount: {contents, total, none}] = BEGIN OPEN glass; length: CARDINAL ← ProtocolDefs.ReceiveCount[str]; IF amount # none THEN{ WriteChar[Ascii.CR]; WriteString[text]; WriteChar[Ascii.SP] }; IF length = 0 THEN { IF amount # none THEN WriteString["none"L] } ELSE BEGIN count: CARDINAL ← 0; DO length ← length - TypeRName[glass, str, IF amount=contents THEN full ELSE brief]; count ← count+1; IF length = 0 THEN EXIT; IF amount = contents THEN WriteString[", "L]; ENDLOOP; IF amount=total THEN WriteDecimal[count]; END; END; TypeStampList: PROC[glass: GlassDefs.Handle, str: ProtocolDefs.Handle, amount: Detail] = BEGIN -- type it iff amount = full OPEN glass; length: CARDINAL ← ProtocolDefs.ReceiveCount[str]; IF amount = full THEN { WriteChar[Ascii.CR]; WriteString["Stamp-list: "] }; IF length = 0 THEN { IF amount = full THEN WriteString ["null"L] } ELSE DO TypeTimestamp[glass, str, amount]; length ← length - SIZE[BodyDefs.Timestamp]; IF length = 0 THEN EXIT; IF amount = full THEN WriteString[", "L]; ENDLOOP; END; TypeRName: PROC[glass: GlassDefs.Handle, str: ProtocolDefs.Handle, amount: Detail] RETURNS[length: CARDINAL] = BEGIN -- type it iff amount = full OPEN glass; rName: BodyDefs.RName = [BodyDefs.maxRNameLength]; ProtocolDefs.ReceiveRName[str, rName]; IF DelTyped[] THEN ERROR MaintainPrivate.Del[]; IF amount = full THEN WriteString[rName]; RETURN[BodyDefs.RNameSize[rName]] END; TypeTimestamp: PROC[glass: GlassDefs.Handle, str: ProtocolDefs.Handle, amount: Detail] = BEGIN -- type it iff amount = full OPEN glass; WriteOctal: PROC[n: CARDINAL] = BEGIN buffer: STRING = [6] --177777--; String.AppendNumber[buffer, n, 8]; WriteString[buffer]; END; stamp: BodyDefs.Timestamp; text: STRING = [50]; stamp ← ProtocolDefs.ReceiveTimestamp[str]; IF DelTyped[] THEN ERROR MaintainPrivate.Del[]; IF amount = full THEN BEGIN WriteChar['[]; WriteOctal[stamp.net]; WriteChar['#]; WriteOctal[stamp.host]; WriteChar[',]; Time.Append [text, Time.Unpack [LOOPHOLE[stamp.time]]]; WriteString[text]; WriteChar[']]; END; END; TypePassword: PROC[glass: GlassDefs.Handle, str: ProtocolDefs.Handle, amount: Detail] = BEGIN -- type it iff amount = full OPEN glass; length: CARDINAL = ProtocolDefs.ReceiveCount[str]; IF amount = full THEN { WriteChar[Ascii.CR]; WriteString["Password: "L]; }; IF amount = full THEN WriteString["(stamp="L]; TypeTimestamp[glass, str, amount]; IF amount = full THEN WriteString[") "L]; BEGIN pw: BodyDefs.Password = ProtocolDefs.ReceivePassword[str, [0,0,0,0]]; IF amount = full THEN FOR i: CARDINAL IN [0 .. LENGTH[pw]) DO WriteDecimal[pw[i]]; WriteChar[Ascii.SP] ENDLOOP; END; END; TypeConnect: PROC[glass: GlassDefs.Handle, str: ProtocolDefs.Handle, amount: Detail] = BEGIN -- type it always OPEN glass; length: CARDINAL = ProtocolDefs.ReceiveCount[str] - SIZE[BodyDefs.Timestamp]; WriteChar[Ascii.CR]; WriteString["Connect-site: "L]; IF amount = full THEN WriteString["(stamp="L]; TypeTimestamp[glass, str, amount]; IF amount = full THEN WriteString[") "L]; IF length = 0 THEN WriteString[ "null"L] ELSE BEGIN connect: BodyDefs.Connect = [BodyDefs.maxConnectLength]; connect.length ← ProtocolDefs.ReceiveCount[str]; GetBlock[ str, [@(connect.text), (1+connect.length)/2] ]; WriteString[connect]; END; END; TypeRemark: PROC[glass: GlassDefs.Handle, str: ProtocolDefs.Handle, amount: Detail] = BEGIN -- type it always OPEN glass; length: CARDINAL = ProtocolDefs.ReceiveCount[str] - SIZE[BodyDefs.Timestamp]; WriteChar[Ascii.CR]; WriteString["Remark: "L]; IF amount = full THEN WriteString["(stamp="L]; TypeTimestamp[glass, str, amount]; IF amount = full THEN WriteString[") "L]; IF length = 0 THEN WriteString[ "null"L] ELSE BEGIN remark: BodyDefs.Remark = [BodyDefs.maxRemarkLength]; remark.length ← ProtocolDefs.ReceiveCount[str]; GetBlock[ str, [@(remark.text), (1+remark.length)/2] ]; WriteString[remark]; END; END; GetBlock: PROC[str: ProtocolDefs.Handle, block: RECORD[where: POINTER, length: CARDINAL]] = BEGIN used: CARDINAL; why: Stream.CompletionCode; sst: Stream.SubSequenceType; [used, why, sst] ← Stream.GetBlock[str,[block.where, 0, 2*block.length]]; IF used # 2*block.length OR why = sstChange THEN ERROR ProtocolDefs.Failed[protocolError]; END; END.