-- File: TrapBadPups.mesa -- Edit: HGM March 24, 1981 1:40 AM -- Edit: BLyon January 16, 1981 5:44 PM DIRECTORY Ascii USING [CR, SP], CmFile USING [OpenSection, NextItem, Close], Put USING [Text, Line], Runtime USING [IsBound], Storage USING [FreeString], String USING [ AppendChar, AppendDecimal, AppendNumber, AppendString, EquivalentString], Time USING [AppendCurrent], Indirect USING [GetParmFileName], Mailer USING [Level, SendMail], BufferDefs USING [PupBuffer], DriverDefs USING [Network], DriverTypes USING [Encapsulation], PupDefs USING [GetPupContentsBytes], ForwarderDefs USING [], PupRouterDefs USING [RejectPupWithBadChecksum, SetPupChecksum]; TrapBadPups: MONITOR IMPORTS CmFile, Put, Runtime, Storage, String, Time, Indirect, Mailer, PupDefs, PupRouterDefs EXPORTS BufferDefs, ForwarderDefs SHARES BufferDefs = BEGIN -- EXPORTed TYPEs Network: PUBLIC TYPE = DriverDefs.Network; to, cc: STRING ← NIL; troubles: STRING ← NIL; -- Also used as from badSequenceAppendNumber: CARDINAL ← 0; recent: CARDINAL ← 0; CollectInfo: PROCEDURE = BEGIN parmFileName: STRING ← NIL; sectionName: STRING = "TrapBadPups"L; token, arg: STRING ← NIL; IF Runtime.IsBound[Indirect.GetParmFileName] THEN parmFileName ← Indirect.GetParmFileName[]; IF parmFileName = NIL THEN RETURN; IF ~CmFile.OpenSection[parmFileName, sectionName] THEN BEGIN Problem["Can't find [TrapBadPups] section."L]; RETURN; END; DO [token, arg] ← CmFile.NextItem[]; SELECT TRUE FROM token = NIL => EXIT; String.EquivalentString[token, "Troubles"L] => BEGIN CheckForRegistry[arg]; Storage.FreeString[troubles]; troubles ← arg; END; String.EquivalentString[token, "To"L] => BEGIN CheckForRegistry[arg]; Storage.FreeString[to]; to ← arg; END; String.EquivalentString[token, "cc"L] => BEGIN CheckForRegistry[arg]; Storage.FreeString[cc]; cc ← arg; END; ENDCASE => BEGIN IF token[0] # '; THEN Problem["Unknown keyword: "L, token]; Storage.FreeString[arg]; END; Storage.FreeString[token]; ENDLOOP; CmFile.Close[parmFileName]; IF troubles = NIL THEN Problem["Please specify somebody in case of TROUBLES"L]; IF to = NIL THEN Problem["Please specify somebody to send the message to"L]; RETURN; END; CheckForRegistry: PROCEDURE [s: STRING] = BEGIN dot: BOOLEAN ← FALSE; FOR i: CARDINAL IN [0..s.length) DO SELECT s[i] FROM '. => dot ← TRUE; ', => BEGIN IF ~dot THEN BEGIN Problem["Registry expected in arg: "L, s]; RETURN; END; dot ← FALSE; END; ENDCASE => NULL; ENDLOOP; IF ~dot THEN BEGIN Problem["Registry expected in arg: "L, s]; RETURN; END; END; Problem: PROCEDURE [one, two, three: STRING ← NIL] = BEGIN text: STRING = [100]; Time.AppendCurrent[text]; String.AppendString[text, " TrapBadPups: "L]; String.AppendString[text, one]; IF two # NIL THEN String.AppendString[text, two]; IF three # NIL THEN String.AppendString[text, three]; LogString[text]; END; PrintBadPup: PUBLIC PROCEDURE [b: BufferDefs.PupBuffer] = BEGIN IF b = NIL THEN RETURN; IF troubles#NIL AND to#NIL THEN BEGIN badSequenceAppendNumber ← badSequenceAppendNumber + 1; IF recent < 30 THEN -- average of one every 10 min, but allow clumps of 3 BEGIN recent ← recent + 10; MailBadPup[b]; END; END; PupRouterDefs.RejectPupWithBadChecksum[b]; END; maxWords: CARDINAL = 300; maxBytes: CARDINAL = 500 + maxWords*8; MailBadPup: PUBLIC PROCEDURE [b: BufferDefs.PupBuffer] = BEGIN body: STRING = [maxBytes]; size: CARDINAL ← (b.pupLength - 1)/2; checksumLoc: LONG POINTER ← @b.pupLength + size; words: CARDINAL ← (PupDefs.GetPupContentsBytes[b] + 1)/2; i: CARDINAL; p: LONG POINTER; network: Network = b.network; Info: PROCEDURE [s: STRING, level: Mailer.Level] = {LogString[s]; }; O7: PROCEDURE [n: WORD] = BEGIN temp: STRING = [10]; String.AppendNumber[temp, n, 8]; THROUGH [temp.length..7) DO String.AppendChar[body, Ascii.SP]; ENDLOOP; String.AppendNumber[body, n, 8]; END; Time.AppendCurrent[body]; String.AppendString[body, " ***** Bad software checksum on Pup from net "L]; String.AppendNumber[body, network.netNumber.b, 8]; String.AppendChar[body, Ascii.CR]; String.AppendString[body, "Bad pup number "L]; String.AppendDecimal[body, badSequenceAppendNumber]; String.AppendString[body, " has a checksum of "L]; String.AppendNumber[body, checksumLoc↑, 8]; PupRouterDefs.SetPupChecksum[b]; -- Fix it up String.AppendString[body, ", but it should be "L]; String.AppendNumber[body, checksumLoc↑, 8]; String.AppendChar[body, Ascii.CR]; String.AppendString[body, "Encap: "L]; p ← @b.encapsulation; FOR i IN [0..SIZE[DriverTypes.Encapsulation]) DO O7[(p + i)↑]; ENDLOOP; String.AppendChar[body, Ascii.CR]; String.AppendString[body, "Header:"L]; p ← @b.bufferBody; FOR i IN [0..11 - 1) DO O7[(p + i)↑]; ENDLOOP; FOR i ← 0, i + 1 UNTIL i >= MIN[words, maxWords] DO IF (i MOD 10) = 0 THEN BEGIN String.AppendChar[body, Ascii.CR]; String.AppendString[body, IF i = 0 THEN "Body: "L ELSE " "L]; END; O7[b.pupWords[i]]; ENDLOOP; String.AppendChar[body, Ascii.CR]; Put.Text[NIL, body]; IF Runtime.IsBound[Mailer.SendMail] THEN [] ← Mailer.SendMail[ "TrapBadPups"L, "Bad Checksum info"L, to, cc, body, troubles, NIL, Info]; END; LogString: PROCEDURE [s: STRING] = {Put.Line[NIL, s]}; -- initialization CollectInfo[]; END.