-- Transport Mechanism Mail Server - Miscellaneous socket communication -- -- [Ivy]<DMS>MS>MiscSoc.mesa -- Randy Gobbel 29-May-81 14:44:13 -- -- Andrew Birrell 13-Jan-81 11:15:27 -- -- Mark Johnson May 28, 1981 2:29 PM -- DIRECTORY BodyDefs USING[ maxRNameLength, RName ], BufferDefs, Inline USING[ LongCOPY ], MailboxDefs USING[ Poll ], PolicyDefs USING[ ProdServersPause ], Process USING[ Detach ], ProtocolDefs USING[ Init, mailServerPollingSocket ], PupDefs USING[ GetFreePupBuffer, GetPupContentsBytes, PupBuffer, PupRouterSendThis, PupSocket, PupSocketMake, ReturnFreePupBuffer, SetPupContentsWords, SwapPupSourceAndDest, veryLongWait ], PupTypes USING[ echoSoc, fillInSocketID, PupAddress, PupType ], RestartDefs, --EXPORT only-- ServerDefs USING[ EnumerateAll, NoSuchServer, ServerAddr, ServerHandle, ServerNotUp, ServerUp, UpServer ], SiteCacheDefs USING[ SingleFlush ], Storage USING[ FreeString, String ], String USING[ WordsForString]; MiscSoc: MONITOR IMPORTS Inline, MailboxDefs, PolicyDefs, Process, ProtocolDefs, PupDefs, ServerDefs, SiteCacheDefs, Storage, String EXPORTS RestartDefs--PROGRAM-- = BEGIN poll: PupDefs.PupSocket = PupDefs.PupSocketMake[ ProtocolDefs.mailServerPollingSocket, , PupDefs.veryLongWait ]; prod: PupDefs.PupSocket = PupDefs.PupSocketMake[ PupTypes.fillInSocketID, , PupDefs.veryLongWait ]; echo: PupDefs.PupSocket = PupDefs.PupSocketMake[ PupTypes.echoSoc, , PupDefs.veryLongWait ]; UnexpectedTimeout: ERROR = CODE; AcceptPoll: PROCEDURE = BEGIN DO BEGIN b: PupDefs.PupBuffer = poll.get[]; IF b = NIL THEN ERROR UnexpectedTimeout[]; SELECT b.pupType FROM mailCheckLaurel => BEGIN client: BodyDefs.RName = [BodyDefs.maxRNameLength]; pLength: CARDINAL = PupDefs.GetPupContentsBytes[b]; IF pLength > BodyDefs.maxRNameLength THEN b.pupType ← mailNotNew ELSE BEGIN Inline.LongCOPY[from: @(b.pupString), to: @(client.text), nwords: (1+pLength)/2 ]; client.length ← pLength; b.pupType ← IF MailboxDefs.Poll[client] THEN mailIsNew ELSE mailNotNew; END; PupDefs.SwapPupSourceAndDest[b]; PupDefs.SetPupContentsWords[b,0]; PupDefs.PupRouterSendThis[b]; END; echoMe => BEGIN PupDefs.SwapPupSourceAndDest[b]; b.pupType ← iAmEcho; PupDefs.PupRouterSendThis[b]; END; LOOPHOLE[215B] => -- LOOPHOLE to get around difference in Pilot/Alto PupTypes -- BEGIN-- cache-flush request from other M-Server -- nameString: LONG STRING = IF SIZE[PupDefs.PupBuffer] = 1 THEN LONG[LOOPHOLE[@(b.pupWords)]] ELSE LOOPHOLE[@(b.pupWords)]; name: BodyDefs.RName = Storage.String[nameString.length]; Inline.LongCOPY[from: nameString, to: name, nwords: String.WordsForString[name.length]]; IF name.length <= BodyDefs.maxRNameLength THEN SiteCacheDefs.SingleFlush[name]; PupDefs.ReturnFreePupBuffer[b]; Storage.FreeString[name]; END; ENDCASE => PupDefs.ReturnFreePupBuffer[b]; END; ENDLOOP; END; PollForUpServer: PROCEDURE[ server: ServerDefs.ServerHandle ] = BEGIN ENABLE BEGIN ServerDefs.NoSuchServer => GOTO notFound; ServerDefs.ServerNotUp => GOTO notUp; END; IF NOT ServerDefs.ServerUp[server] THEN BEGIN dest: PupTypes.PupAddress ← ServerDefs.ServerAddr[server]; b: PupDefs.PupBuffer ← PupDefs.GetFreePupBuffer[]; PupDefs.SetPupContentsWords[b, 0]; b.pupType ← echoMe; b.pupID ← [a: LOOPHOLE[server], b: 0]; dest.socket ← SELECT server.type FROM mail => ProtocolDefs.mailServerPollingSocket, foreign => PupTypes.echoSoc, ENDCASE => ERROR; prod.setRemoteAddress[dest]; prod.put[b]; END; EXITS notFound => -- no such server -- NULL; notUp => -- R-Servers not up, etc -- NULL; END; ProdServers: PROC = BEGIN DO PolicyDefs.ProdServersPause[]; ServerDefs.EnumerateAll[PollForUpServer]; ENDLOOP; END; ProdReply: PROCEDURE = BEGIN DO BEGIN b: PupDefs.PupBuffer = prod.get[]; IF b = NIL THEN ERROR UnexpectedTimeout[]; SELECT b.pupType FROM iAmEcho, --MTP (IFS doesn't echo)-- error => BEGIN maybe: ServerDefs.ServerHandle = LOOPHOLE[b.pupID.a]; Work: PROCEDURE[ really: ServerDefs.ServerHandle ] = BEGIN IF really = maybe AND( b.pupType = iAmEcho OR really.type = foreign ) THEN ServerDefs.UpServer[really]; END; PupDefs.ReturnFreePupBuffer[b]; ServerDefs.EnumerateAll[Work]; END; ENDCASE => PupDefs.ReturnFreePupBuffer[b]; END; ENDLOOP; END; Echo: PROCEDURE = BEGIN DO BEGIN b: PupDefs.PupBuffer = echo.get[]; IF b = NIL THEN ERROR UnexpectedTimeout[]; SELECT b.pupType FROM echoMe => BEGIN PupDefs.SwapPupSourceAndDest[b]; b.pupType ← iAmEcho; PupDefs.PupRouterSendThis[b]; END; ENDCASE => PupDefs.ReturnFreePupBuffer[b]; END; ENDLOOP; END; ProtocolDefs.Init[]; Process.Detach[ FORK AcceptPoll[] ]; Process.Detach[ FORK ProdReply[] ]; Process.Detach[ FORK Echo[] ]; Process.Detach[ FORK ProdServers[] ]; END.