DIRECTORY Rope USING [Fetch, Length, ROPE], StatsDefs USING [StatIncr], PupRouterDefs USING [SneakySendUnlocked], PupStream USING [CloseReason], PupDefs, CommFlags USING [doStats, doDebug], DriverDefs USING [Glitch, Network, PutOnGlobalDoneQueue, GetDeviceChain], BufferDefs, -- SHARES PupTypes USING [allHosts, PupErrorCode, PupSocketID], DriverTypes USING [bufferSeal]; PupErrors: PROGRAM IMPORTS StatsDefs, PupRouterDefs, DriverDefs, PupDefs, Rope EXPORTS BufferDefs, PupRouterDefs, PupStream, PupDefs SHARES BufferDefs = BEGIN OPEN DriverDefs, PupDefs; Network: PUBLIC TYPE = DriverDefs.Network; StreamClosing: PUBLIC ERROR [why: PupStream.CloseReason, text: Rope.ROPE] = CODE; RejectThisRequest: PUBLIC ERROR [error: Rope.ROPE] = CODE; suppressErrors: BOOLEAN _ FALSE; suppressBufferFull: BOOLEAN _ FALSE; BufferSealBroken: PUBLIC ERROR = CODE; BufferDidntArrive: PUBLIC ERROR = CODE; SetErrorSuppression: PUBLIC PROCEDURE [dontSendErrors: BOOLEAN] = BEGIN suppressErrors _ dontSendErrors; END; SetBufferFullSuppression: PUBLIC PROCEDURE [dontSend: BOOLEAN] = BEGIN suppressBufferFull _ dontSend; END; RejectPupWithBadChecksum: PUBLIC PROCEDURE [b: PupBuffer] = BEGIN Reject[b, badChecksumPupErrorCode]; END; Reject: PUBLIC PROCEDURE [b: PupBuffer, code: PupTypes.PupErrorCode] = BEGIN IF BuildErrorPup[b, code, NIL] THEN PupRouterDefs.SneakySendUnlocked[b]; END; SendErrorPup: PUBLIC PROCEDURE [ b: PupBuffer, code: PupTypes.PupErrorCode, text: Rope.ROPE] = BEGIN IF BuildErrorPup[b, code, text] THEN PupRouterSendThis[b]; END; BuildErrorPup: PUBLIC PROCEDURE [ b: PupBuffer, code: PupTypes.PupErrorCode, text: Rope.ROPE] RETURNS [ok: BOOLEAN] = BEGIN p: LONG POINTER TO ARRAY [0..9] OF WORD = LOOPHOLE[@b.pupLength]; temp: PupTypes.PupSocketID; network: Network _ b.network; IF CommFlags.doDebug AND b.seal # DriverTypes.bufferSeal THEN Glitch[BufferSealBroken]; IF suppressErrors OR (suppressBufferFull AND code = resourceLimitsPupErrorCode) OR b.pupType = error OR b.dest.host = PupTypes.allHosts THEN BEGIN DriverDefs.PutOnGlobalDoneQueue[b]; RETURN[FALSE]; END; IF CommFlags.doDebug AND network= NIL THEN Glitch[BufferDidntArrive]; IF network.netNumber.b > 377B THEN network _ DriverDefs.GetDeviceChain[]; FOR i: CARDINAL IN [0..9] DO b.errorHeader[i] _ p[i]; ENDLOOP; b.pupType _ error; b.errorCode _ code; b.errorOptions _ 0; temp _ b.dest.socket; b.dest _ b.source; b.source _ [[network.netNumber.b], [network.hostNumber], temp]; IF text = NIL THEN SELECT code FROM badChecksumPupErrorCode => text _ "Bad Software Checksum"; noProcessPupErrorCode => text _ "No such Port"; resourceLimitsPupErrorCode => text _ "Buffers full"; ENDCASE => NULL; IF text # NIL THEN BEGIN length: INT = text.Length[]; FOR i: INT IN [0..length) DO b.errorText[i] _ text.Fetch[i]; ENDLOOP; SetPupContentsBytes[b, 2*(10 + 1 + 1) + length]; END ELSE SetPupContentsBytes[b, 2*(10 + 1 + 1) + 0]; IF CommFlags.doStats THEN StatsDefs.StatIncr[statErrorPupsSent]; RETURN[TRUE]; END; END. ìPupErrors.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. BLyon January 16, 1981 2:50 PM Russ Atkinson (RRA) February 4, 1985 12:37:16 pm PST PktStream/ByteStream SIGNALs live here so they are defined only once ʘcodešœ™Kšœ Ïmœ1™K˜K˜K˜K˜K˜K˜?šžœžœž˜šžœž˜K˜:K˜/K˜4Kšžœžœ˜——šžœžœž˜Kšž˜Kšœžœ˜Kš žœžœžœ žœ!žœ˜EKšœ0˜0Kšž˜—Kšžœ,˜0Kšžœžœ'˜@Kšžœžœ˜ Kšžœ˜K˜—Kšžœ˜K˜——…— ®¢