// GateConNet.bcpl -- miscellaneous network-related stuff
// Last modified July 2, 1983 10:19 PM by Boggs
get "Pup0.decl"
get "Pup1.decl"
get "GateConServ.decl"
external
[
// outgoing procedures
SendCommand; MiscCmd; Gateway; PrintPort
OtherPup; OtherPupCtx; GetBuf
// incoming procedures
MoveBlock; MultEq; Enqueue; Dequeue; FlushQueue
SetTimer; TimerHasExpired; Block
GetPBI; ReleasePBI; CompletePup
GetPartner; OpenLevel1Socket; CloseLevel1Socket
Ws; Puts; PutTemplate; GetString; Error
ExtractSubstring; Free
RestartGateConUser; RestartRoute; RestartEcho
RestartName; RestartTime; RestartBoot; TopLevel
// outgoing statics
gcNet; gcHost; gcName; otherPupQ
// incoming statics
dsp; errorDsp; sysZone
]
static [ gcNet; gcHost; gcName; gcID; otherPupQ ]
//----------------------------------------------------------------------------
let SendCommand(pbi, type, length, retries; numargs na) = valof
//----------------------------------------------------------------------------
// returns response pbi or 0
[
if na ls 4 then retries = 3
if na ge 3 then pbi>>PBI.pup.length = length
if na ge 2 then pbi>>PBI.pup.type = type
if pbi>>PBI.pup.dPort.net eq 0 & pbi>>PBI.pup.dPort.host eq 0 then
[
pbi>>PBI.pup.dPort.net = gcNet
pbi>>PBI.pup.dPort.host = gcHost
]
if pbi>>PBI.pup.dPort.socket↑1 eq 0 & pbi>>PBI.pup.dPort.socket↑2 eq 0 then
[
pbi>>PBI.pup.dPort.socket↑1 = gcSocket1
pbi>>PBI.pup.dPort.socket↑2 = gcSocket2
]
pbi>>PBI.pup.id↑1 = gcPassword
pbi>>PBI.pup.id↑2 = gcID
gcID = gcID+1
let soc = pbi>>PBI.socket
let tQ = vec 1; tQ!0 = 0
pbi>>PBI.queue = tQ
Enqueue(tQ, pbi)
let ipbi = 0
for i = 1 to retries do
[
Block() repeatwhile tQ!0 eq 0
CompletePup(Dequeue(tQ))
let timer = nil; SetTimer(lv timer, 200) //2 sec
[
Block() repeatuntil TimerHasExpired(lv timer) % soc>>PupSoc.iQ.head ne 0
ipbi = Dequeue(lv soc>>PupSoc.iQ)
if ipbi eq 0 break //timeout - retransmit
if MultEq(lv ipbi>>PBI.pup.id, lv pbi>>PBI.pup.id) then
if ipbi>>PBI.pup.type ne typeError break
test ipbi ne 0
ifso OtherPup(ipbi)
ifnot ReleasePBI(ipbi)
ipbi = 0
] repeat
if ipbi ne 0 break
]
Block() repeatwhile tQ!0 eq 0
ReleasePBI(Dequeue(tQ))
resultis ipbi
]
//----------------------------------------------------------------------------
and MiscCmd(requestType, replyType, Proc, data, length; numargs na) be
//----------------------------------------------------------------------------
[
if na ls 5 then length = 0
let soc = vec lenPupSoc; OpenLevel1Socket(soc)
let pbi = GetBuf(soc)
pbi>>PBI.pup.dPort.socket↑2 = 4 // psMiscServ
if length ne 0 then MoveBlock(lv pbi>>PBI.pup.words, data, (length+1)/2)
pbi = SendCommand(pbi, requestType, pupOvBytes+length)
test pbi ne 0 & pbi>>PBI.pup.type eq replyType
ifso Proc(pbi)
ifnot Ws(" - the server doesn't answer")
if pbi then ReleasePBI(pbi)
CloseLevel1Socket(soc)
]
//---------------------------------------------------------------------------
and GetBuf(soc, returnIfNone; numargs na) = valof
//---------------------------------------------------------------------------
[
let pbi = GetPBI(soc, true)
if pbi ne 0 resultis pbi
if na eq 2 & returnIfNone resultis 0
FlushQueue(lv soc>>PupSoc.iQ)
Block()
] repeat
//---------------------------------------------------------------------------
and OtherPup(pbi) be Enqueue(otherPupQ, pbi)
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
and OtherPupCtx(ctx) be
//---------------------------------------------------------------------------
[
Block() repeatuntil otherPupQ!0 ne 0
let pbi = Dequeue(otherPupQ)
if pbi>>PBI.pup.type eq typeError then
[
Error("Error Pup from ")
PutTemplate(errorDsp, "$P: ", PrintPort, lv pbi>>PBI.pup.sPort)
for i = 25 to pbi>>PBI.pup.length-pupOvBytes do
Puts(errorDsp, pbi>>PBI.pup.bytes↑i)
]
ReleasePBI(pbi)
] repeat
//----------------------------------------------------------------------------
and PrintPort(stream, port) be
//----------------------------------------------------------------------------
PutTemplate(stream, "[$UO#$UO#$UEO]", port>>Port.net, port>>Port.host,
lv port>>Port.socket)
//----------------------------------------------------------------------------
and Gateway() be
//----------------------------------------------------------------------------
[
let doTopLevel = gcHost eq 0
let name = vec 128
if GetString("*NGateway: ", name) then
[
let port = vec lenPort
if GetPartner(name, dsp, port, gcSocket1, gcSocket2) then
[
gcNet = port>>Port.net
gcHost = port>>Port.host
if gcName ne 0 then Free(sysZone, gcName)
gcName = ExtractSubstring(name)
RestartGateConUser()
RestartRoute()
RestartEcho()
RestartName()
RestartTime()
RestartBoot()
if doTopLevel then TopLevel()
FlushQueue(otherPupQ)
]
]
]