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. ŽFile: PupErrors.mesa, Last Edit: BLyon January 16, 1981 2:50 PM PktStream/ByteStream SIGNALs live here so they are defined only once Êð˜JšœA™AJ˜šÏk ˜ Jšœœœ˜!Jšœ œ ˜Jšœœ˜)Jšœ œ˜J˜Jšœ œ˜#šœ œ˜J˜7—Jšœ Ïc ˜Jšœ œ'˜5Jšœ œ˜J˜—šœ ˜Jšœ4˜;Jšœ.˜5Jšœ ˜Jšœœ˜J˜Jšœ œœ˜*J˜JšœD™DJš œœœ)œœ˜QJš œœœœœ˜:J˜J˜Jšœœœ˜ Jšœœœ˜$J˜Jšœœœœ˜&Jšœœœœ˜'J˜šÏnœœ œœ˜AJšœ"œ˜+J˜—šŸœœ œ œ˜@Jšœ œ˜)J˜J˜—šŸœœ œ˜;Jšœ%œ˜.J˜—šŸœœ œ.˜FJš˜Jšœœœ%˜HJšœ˜J˜—šŸ œœ œ˜ Jšœ6œ˜=Jšœœœœ˜EJ˜—šŸ œœ œ˜!Jšœ6œ˜;Jšœœ˜Jš˜Jšœœœœœœœœ˜AJ˜J˜Jšœœ!œ˜Wšœ˜Jšœœ$œ ˜IJšœœ!˜-Jšœ%œœœ˜=—Jšœœ œœ˜EJšœœ'˜IJš œœœœœ˜>J˜J˜J˜J˜J˜J˜?šœœ˜šœ˜J˜:J˜/J˜4Jšœœ˜——šœœ˜Jš˜Jšœœ˜Jš œœœ œ!œ˜EJšœ0˜0Jš˜—Jšœ,˜0Jšœœ'˜@Jšœœ˜ Jšœ˜J˜—Jšœ˜J˜——…— ®,