-- File: PupErrors.mesa, Last Edit: BLyon January 16, 1981 2:50 PM DIRECTORY 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 EXPORTS BufferDefs, PupRouterDefs, PupStream, PupDefs SHARES BufferDefs = BEGIN OPEN DriverDefs, PupDefs; Network: PUBLIC TYPE = DriverDefs.Network; -- PktStream/ByteStream SIGNALs live here so they are defined only once StreamClosing: PUBLIC ERROR [why: PupStream.CloseReason, text: STRING] = CODE; RejectThisRequest: PUBLIC ERROR [error: STRING] = 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: STRING] = BEGIN IF BuildErrorPup[b, code, text] THEN PupRouterSendThis[b]; END; BuildErrorPup: PUBLIC PROCEDURE [ b: PupBuffer, code: PupTypes.PupErrorCode, text: STRING] RETURNS [ok: BOOLEAN] = BEGIN i: CARDINAL; 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"L; noProcessPupErrorCode => text _ "No such Port"L; resourceLimitsPupErrorCode => text _ "Buffers full"L; ENDCASE => NULL; IF text # NIL THEN BEGIN FOR i _ 0, i + 1 UNTIL i = text.length DO b.errorText[i] _ text[i]; ENDLOOP; END ELSE i _ 0; SetPupContentsBytes[b, 2*(10 + 1 + 1) + i]; -- Yetch IF CommFlags.doStats THEN StatsDefs.StatIncr[statErrorPupsSent]; RETURN[TRUE]; END; END.