-- Copyright (C) 1981, 1983, 1984 by Xerox Corporation. All rights reserved. -- ReceiveInput.mesa, Transport Mechanism Mail Server - input from other GV servers -- -- HGM, 10-Dec-85 22:12:37 -- Andrew Birrell 12-Jan-81 16:09:58 -- -- Mike Schroeder 25-Jan-83 16:11:56 -- DIRECTORY BodyDefs USING [maxRNameLength, RName, Timestamp], Heap USING [systemZone], HeapDefs USING [ ObjectNumber, HeapAbandonWrite, HeapStartWrite, HeapWriteData, ReceiveObj, HeapEndWrite, GetWriterOffset, WriterHandle], LogDefs USING [ShowRejection, WriteChar, WriteLogEntry], NameInfoDefs USING [IsMemberDirect], PolicyDefs USING [CheckOperation, EndOperation], ProtocolDefs USING [ AppendTimestamp, Failed, Handle, mailServerServerSocket, ReceiveRName, ReceiveTimestamp, SendAck, SendNow], PupDefs USING [AppendHostName, PupAddress, SecondsToTocks], PupStream USING [CreatePupByteStreamListener, RejectThisRequest], RestartDefs USING [] --EXPORT only-- , SLDefs USING [SLHeader, SLWrite], String USING [AppendLongDecimal, AppendString], Time USING [Current]; ReceiveInput: PROGRAM IMPORTS Heap, HeapDefs, LogDefs, NameInfoDefs, PolicyDefs, ProtocolDefs, PupDefs, PupStream, SLDefs, String, Time EXPORTS RestartDefs --PROGRAM-- = BEGIN Filter: PROCEDURE [from: PupDefs.PupAddress] = BEGIN IF NOT PolicyDefs.CheckOperation[serverInput] THEN BEGIN LogDefs.ShowRejection["ServerInput", from]; -- No L ERROR PupStream.RejectThisRequest["Server full"L] END; END; Receiver: PROCEDURE [str: ProtocolDefs.Handle, fromAddr: PupDefs.PupAddress] = BEGIN OPEN ProtocolDefs; fromName: BodyDefs.RName = [BodyDefs.maxRNameLength]; express: BOOLEAN ← FALSE; ReceiveRName[str, fromName ! Failed => GOTO badName]; IF NameInfoDefs.IsMemberDirect["*.MS"L, fromName] # yes THEN GOTO badName; IF FinkyGGW[fromName] THEN express ← TRUE; DO BEGIN bodyHandle: HeapDefs.WriterHandle = HeapDefs.HeapStartWrite[body]; SLhandle: HeapDefs.WriterHandle = HeapDefs.HeapStartWrite[SLinput]; Accept: PROCEDURE [obj: HeapDefs.ObjectNumber] = BEGIN IF express THEN SLDefs.SLWrite[obj, SLhandle, express] ELSE SLDefs.SLWrite[obj, SLhandle, input]; END; header: SLDefs.SLHeader; header.received.host ← fromAddr.host; header.received.net ← fromAddr.net; header.received.time ← Time.Current[]; header.server ← NIL; BEGIN ENABLE Failed => GOTO bad; header.created ← ProtocolDefs.ReceiveTimestamp[str]; HeapDefs.HeapWriteData[SLhandle, [@header, SIZE[SLDefs.SLHeader]]]; HeapDefs.ReceiveObj[SLhandle, str]; HeapDefs.ReceiveObj[bodyHandle, str]; LogReceived[header.created, fromName, HeapDefs.GetWriterOffset[bodyHandle], express]; LogDefs.WriteChar['S]; HeapDefs.HeapEndWrite[bodyHandle, Accept]; EXITS bad => BEGIN HeapDefs.HeapAbandonWrite[bodyHandle]; HeapDefs.HeapAbandonWrite[SLhandle]; EXIT END; END; END; BEGIN ENABLE ProtocolDefs.Failed => EXIT; ProtocolDefs.SendAck[str]; -- all is on disk -- ProtocolDefs.SendNow[str]; END; -- wait for sender to start a new message, possibly -- ENDLOOP; PolicyDefs.EndOperation[serverInput]; str.delete[str]; EXITS badName => BEGIN PolicyDefs.EndOperation[serverInput]; str.delete[str]; LogBad[fromAddr]; END; END; -- Record ugly hackery: This depends upon GGWs, and only GGWs, being named with a dash: -- PA-Gateway.ms, WBST-Gateway.ms .... but ArpaGateway.ms FinkyGGW: PROC [name: LONG STRING] RETURNS [fink: BOOL] = BEGIN FOR i: CARDINAL IN [0..name.length) DO IF name.text[i] = '- THEN RETURN[TRUE]; ENDLOOP; RETURN[FALSE]; END; LogReceived: PROC [ created: BodyDefs.Timestamp, from: BodyDefs.RName, words: LONG CARDINAL, express: BOOL] = BEGIN log: LONG STRING ← Heap.systemZone.NEW[StringBody[200]]; String.AppendString[log, "Server input from "L]; String.AppendString[log, from]; String.AppendString[log, ": "L]; ProtocolDefs.AppendTimestamp[log, created]; String.AppendString[log, "; "L]; String.AppendLongDecimal[log, words]; String.AppendString[log, " words"L]; IF express THEN String.AppendString[log, ", express"L]; LogDefs.WriteLogEntry[log]; Heap.systemZone.FREE[@log]; END; LogBad: PROC [fromAddr: PupDefs.PupAddress] = BEGIN log: LONG STRING ← Heap.systemZone.NEW[StringBody[200]]; String.AppendString[log, "Illegal MS-input request from host "L]; PupDefs.AppendHostName[log, fromAddr]; LogDefs.WriteLogEntry[log]; Heap.systemZone.FREE[@log]; END; [] ← PupStream.CreatePupByteStreamListener[ ProtocolDefs.mailServerServerSocket, Receiver, PupDefs.SecondsToTocks[60], Filter]; END.