-- Copyright (C) 1981, 1984 by Xerox Corporation. All rights reserved. -- ReadForward.mesa, Transport Mechanism Mail Server - algorithm to process forward queue -- -- HGM: 15-Dec-84 22:46:03 -- Randy Gobbel 19-May-81 11:57:02 -- -- Andrew Birrell 29-Dec-81 14:53:38 -- -- Hankins 30-Jul-84 14:22:52 Klamath update (BufferDefs) DIRECTORY BodyDefs USING [RName], Buffer, HeapDefs USING [ ObjectNumber, HeapReadData, HeapStartRead, ReaderHandle, HeapEndRead, SendObj], LocalNameDefs USING [ReadMSName], LogDefs USING [WriteLogEntry], PolicyDefs USING [EndOperation, WaitOperation], Process USING [Detach], ProtocolDefs USING [ AppendTimestamp, CreateStream, DestroyStream, Failed, Handle, Password, ReceiveAck, SendRName, SendTimestamp], RestartDefs USING [], ServerDefs USING [ ServerAddr, ServerHandle, ServerNotUp, ServerUp, DownServer, NoSuchServer], SLDefs USING [ GetCount, SLHeader, SLStartRead, SLReadHandle, SLEndRead, SLTransfer], String USING [AppendString]; ReadForward: PROGRAM IMPORTS HeapDefs, LocalNameDefs, LogDefs, PolicyDefs, Process, ProtocolDefs, ServerDefs, SLDefs, String EXPORTS RestartDefs --PROGRAM-- = BEGIN NoRecipients: ERROR = CODE; --not caught; should not occur-- ForwardMain: PROCEDURE = BEGIN -- multiple instantiations of this procedure are allowed -- DO BEGIN str: ProtocolDefs.Handle ¬ NIL; SLobj: HeapDefs.ReaderHandle; SLhandle: SLDefs.SLReadHandle; bodyObj: HeapDefs.ObjectNumber; slHeader: SLDefs.SLHeader; outcome: {ok, down} ¬ ok; [SLhandle, bodyObj, SLobj] ¬ SLDefs.SLStartRead[forward]; PolicyDefs.WaitOperation[readForward]; BEGIN -- read SL header -- ended: BOOLEAN; used: CARDINAL; [ended, used] ¬ HeapDefs.HeapReadData[ SLobj, [@slHeader, SIZE[SLDefs.SLHeader]]]; IF ended THEN ERROR NoRecipients[]; END; IF NOT ServerDefs.ServerUp[slHeader.server] THEN { HeapDefs.HeapEndRead[SLobj]; outcome ¬ down} ELSE BEGIN str ¬ ProtocolDefs.CreateStream[ ServerDefs.ServerAddr[ slHeader.server ! ServerDefs.ServerNotUp, ServerDefs.NoSuchServer => GOTO noAddr] ! ProtocolDefs.Failed => GOTO noStr]; BEGIN ENABLE ProtocolDefs.Failed => {HeapDefs.HeapEndRead[SLobj]; GOTO wentDown}; myName: BodyDefs.RName; myKey: ProtocolDefs.Password; [name: myName, key: myKey, password:] ¬ LocalNameDefs.ReadMSName[]; ProtocolDefs.SendRName[str, myName]; ProtocolDefs.SendTimestamp[str, slHeader.created]; END; BEGIN ENABLE ProtocolDefs.Failed => GOTO wentDown; HeapDefs.SendObj[SLobj, str]; HeapDefs.SendObj[HeapDefs.HeapStartRead[bodyObj], str]; ProtocolDefs.ReceiveAck[str]; END; ProtocolDefs.DestroyStream[str]; EXITS noAddr => {HeapDefs.HeapEndRead[SLobj]; outcome ¬ down}; noStr => BEGIN HeapDefs.HeapEndRead[SLobj]; ServerDefs.DownServer[slHeader.server]; outcome ¬ down; END; wentDown => BEGIN ProtocolDefs.DestroyStream[str]; ServerDefs.DownServer[slHeader.server]; outcome ¬ down; END; END; BEGIN log: STRING = [128]; String.AppendString[log, "Forwarded "L]; ProtocolDefs.AppendTimestamp[log, slHeader.created]; String.AppendString[log, " to "L]; WITH slHeader.server.name SELECT FROM rName => String.AppendString[log, value]; ENDCASE; IF outcome # ok THEN String.AppendString[log, ": failed"L]; LogDefs.WriteLogEntry[log]; END; SELECT outcome FROM ok => SLDefs.SLEndRead[SLhandle]; down => SLDefs.SLTransfer[SLhandle, input]; ENDCASE => ERROR; END; PolicyDefs.EndOperation[readForward]; ENDLOOP; END; ForwardRestart: PROCEDURE = BEGIN -- on restart, must transfer everything to input, since ServerHandles -- are no longer valid -- THROUGH [0..SLDefs.GetCount[forward]) DO handle: SLDefs.SLReadHandle; body: HeapDefs.ObjectNumber; SL: HeapDefs.ReaderHandle; [handle, body, SL] ¬ SLDefs.SLStartRead[forward]; HeapDefs.HeapEndRead[SL]; SLDefs.SLTransfer[handle, input]; ENDLOOP; END; ForwardRestart[]; Process.Detach[FORK ForwardMain[]]; END.