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