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