// PupTestMisc.bcpl // Copyright Xerox Corporation 1980, 1982 // Last modified February 15, 1982 5:36 PM by Boggs get "pup.decl" get "puptest.decl" external [ // outgoing procedures MiscServices // incoming procedures Ws; Puts; Gets; PutTemplate; UNPACKDT; WRITEUDT GetPBI; ReleasePBI; CompletePup; AppendStringToPup OpenLevel1Socket; CloseLevel1Socket SetTimer; TimerHasExpired; Enqueue; Dequeue; Block; MultEq Confirm; GetString OpenPort; RTTitle; RTEntry; PrintPort OtherSpigot // incoming statics dsp; keys ] manifest [ // misc services protocols psMiscServ = 4 ptStringTimeRequest = 200b ptStringTimeReply = 201b ptTenexTimeRequest = 202b ptTenexTimeReply = 203b ptAltoTimeRequest = 206b ptAltoTimeReply = 207b ptMailCheckRequest = 214b ptMailCheckYes = 211b ptMailCheckNo = 212b ptMailCheckError = 213b ptNameRequest = 220b ptNameReply = 221b ptNameAddrError = 222b ptAddressRequest = 223b ptAddressReply = 224b ptNetDirVersion = 240b ptWhereUserRequest = 230b ptWhereUserReply = 231b ptWhereUserError = 232b ptAuthRequest = 250b ptAuthYes = 251b ptAuthNo = 252b ptValidRecipRequest = 266b ptValidRecipYes = 267b ptValidRecipNo = 270b // Routing info protocol psRouteInfo = 2 ptRouteInfoRequest = 200b ptRouteInfoReply = 201b ] static [ miscID; miscSoc ] //---------------------------------------------------------------------------- let MiscServices(quit) be //---------------------------------------------------------------------------- [ let soc = vec lenPupSoc; miscSoc = soc unless OpenPort("Misc services host: ", soc, 0, psMiscServ) return [ Ws("*N>>") switchon Gets(keys) into [ case $A: case $a: [ Authenticate(); endcase ] case $D: case $d: [ DateAndTime(); endcase ] case $H: case $h: [ quit = false; break ] case $N: case $n: [ NetDirectory(); endcase ] case $M: case $m: [ MailCheck(); endcase ] case $Q: case $q: [ quit = Confirm("Quit "); break ] case $R: case $r: [ RoutingInfo(); endcase ] case $V: case $v: [ ValidateRecip(); endcase ] case $W: case $w: [ WhereIsUser(); endcase ] case $?: [ Ws("? One of the following:") Ws("*nAuthenticate, Date and time, Host,") Ws("*nNet Directory, Mail check, Quit,") Ws("*nRouting info, Validate recipient, Where is User.") loop ] ] ] repeat CloseLevel1Socket(soc) ] repeatuntil quit //---------------------------------------------------------------------------- and DateAndTime() be //---------------------------------------------------------------------------- [ Ws("Date and time protocol ") [ let pbi = GetPBI(miscSoc) [ Ws("*N>>>") switchon Gets(keys) into [ case $T: case $t: [ Ws("Tenex format: ") pbi>>PBI.pup.type = ptTenexTimeRequest break ] case $A: case $a: [ Ws("Alto format: ") pbi>>PBI.pup.type = ptAltoTimeRequest break ] case $S: case $s: [ Ws("String format: ") pbi>>PBI.pup.type = ptStringTimeRequest break ] case $Q: case $q: Ws("Quit") //falls through case $*177: [ ReleasePBI(pbi); return ] case $?: [ Ws("Alto, Tenex, String: ") loop ] ] ] repeat pbi>>PBI.pup.length = pupOvBytes pbi = SendCommand(pbi); if pbi eq 0 loop switchon pbi>>PBI.pup.type into [ case ptStringTimeReply: [ PrintContents(pbi); endcase ] case ptTenexTimeReply: [ for i = 1 to pbi>>PBI.pup.length-pupOvBytes do PutTemplate(dsp,"$UO ", pbi>>PBI.pup.bytes^i) endcase ] case ptAltoTimeReply: [ for i = 1 to pbi>>PBI.pup.length-pupOvBytes do PutTemplate(dsp,"$UO ", pbi>>PBI.pup.bytes^i) let uv = vec 6 UNPACKDT(lv pbi>>PBI.pup.bytes^1, uv) Ws("= ") WRITEUDT(dsp, uv) endcase ] ] ReleasePBI(pbi) ] repeat ] //---------------------------------------------------------------------------- and NetDirectory() be //---------------------------------------------------------------------------- [ Ws("Net directory protocol ") [ let pbi = GetPBI(miscSoc) [ Ws("*N>>>") switchon Gets(keys) into [ case $A: case $a: [ break ] case $N: case $n: [ let string = vec 40 unless GetString("Name: ", string, true, false) return AppendStringToPup(pbi, 1, string) //sets Pup.length pbi>>PBI.pup.type = ptNameRequest break ] case $V: case $v: [ Ws("Version of net dir = ") pbi>>PBI.pup.words^1 = 1 pbi>>PBI.pup.words^2 = 0 pbi>>PBI.pup.type = ptNetDirVersion pbi>>PBI.pup.length = pupOvBytes+4 break ] case $Q: case $q: Ws("Quit") // falls through case $*177: [ ReleasePBI(pbi); return ] case $?: [ Ws("Name->Address, Version of NetDir: ") loop ] ] ] repeat pbi = SendCommand(pbi); if pbi eq 0 return switchon pbi>>PBI.pup.type into [ case ptNameAddrError: [ PrintContents(pbi); endcase ] case ptNameReply: [ for i = 1 to pbi>>PBI.pup.length-pupOvBytes by 6 do [ PrintPort(lv pbi>>PBI.pup.bytes^i); Ws(" ") ] endcase ] case ptNetDirVersion: [ PutTemplate(dsp, "$UD", pbi>>PBI.pup.words^1) endcase ] ] ReleasePBI(pbi) ] repeat ] //---------------------------------------------------------------------------- and WhereIsUser() be //---------------------------------------------------------------------------- [ let string = vec 40 unless GetString("Where is user: ", string, true, false) return let pbi = GetPBI(miscSoc) AppendStringToPup(pbi, 1, string) pbi = SendCommand(pbi, ptWhereUserRequest) if pbi eq 0 return switchon pbi>>PBI.pup.type into [ case ptWhereUserError: [ Ws("- No such user"); endcase ] case ptWhereUserReply: [ test pbi>>PBI.pup.length eq pupOvBytes ifso Ws("- Not logged in") ifnot for i = 1 to pbi>>PBI.pup.length-pupOvBytes by 2 do [ PutTemplate(dsp, "- Job $D", pbi>>PBI.pup.bytes^i) test pbi>>PBI.pup.bytes^(i+1) eq #377 ifso Ws(", Detached") ifnot PutTemplate(dsp, ", TTY $0", pbi>>PBI.pup.bytes^(i+1)) ] endcase ] ] ReleasePBI(pbi) ] //---------------------------------------------------------------------------- and RoutingInfo() be //---------------------------------------------------------------------------- // Note that this one goes to the gateway info socket instead of misc services [ let pbi = GetPBI(miscSoc) pbi>>PBI.pup.dPort.socket^1 = 0 pbi>>PBI.pup.dPort.socket^2 = psRouteInfo pbi = SendCommand(pbi, ptRouteInfoRequest, pupOvBytes, 1) if pbi then [ Enqueue(lv miscSoc>>PupSoc.iQ, pbi) RTTitle("Foreign routing table: ") ] let count = 0 let timer = nil; SetTimer(lv timer, 500) // 5 seconds [ Block() repeatuntil miscSoc>>PupSoc.iQ.head % TimerHasExpired(lv timer) let pbi = Dequeue(lv miscSoc>>PupSoc.iQ.head); if pbi eq 0 break if pbi>>PBI.pup.type eq ptRouteInfoReply then for i = 1 to pbi>>PBI.pup.length-pupOvBytes by 4 do RTEntry(pbi>>PBI.pup.bytes^i, pbi>>PBI.pup.bytes^(i+1), pbi>>PBI.pup.bytes^(i+2), pbi>>PBI.pup.bytes^(i+3), lv count) ReleasePBI(pbi) ] repeat ] //---------------------------------------------------------------------------- and Authenticate() be //---------------------------------------------------------------------------- [ let name = vec 40 unless GetString("Authenticate user: ", name, true, false) return let psw = vec 40 unless GetString(" password: ", psw, false, false) return let pbi = GetPBI(miscSoc) AppendMesaStringToPup(pbi, 1, name) AppendMesaStringToPup(pbi, (name>>String.length+7)/2, psw) pbi = SendCommand(pbi, ptAuthRequest) if pbi eq 0 return switchon pbi>>PBI.pup.type into [ case ptAuthYes: [ Ws("- Good"); endcase ] case ptAuthNo: [ Ws("- No "); PrintContents(pbi); endcase ] ] ReleasePBI(pbi) ] //---------------------------------------------------------------------------- and ValidateRecip() be //---------------------------------------------------------------------------- [ let string = vec 40 unless GetString("Validate recipient: ", string, true, false) return let pbi = GetPBI(miscSoc) AppendMesaStringToPup(pbi, 1, string) pbi = SendCommand(pbi, ptValidRecipRequest) if pbi eq 0 return switchon pbi>>PBI.pup.type into [ case ptValidRecipYes: [ Ws("- Good"); endcase ] case ptValidRecipNo: [ Ws("- Bad"); endcase ] ] ReleasePBI(pbi) ] //---------------------------------------------------------------------------- and MailCheck() be //---------------------------------------------------------------------------- [ let string = vec 40 unless GetString("Mail check for user: ", string, true, false) return let pbi = GetPBI(miscSoc) AppendStringToPup(pbi, 1, string) pbi = SendCommand(pbi, ptMailCheckRequest) if pbi eq 0 return switchon pbi>>PBI.pup.type into [ case ptMailCheckError: [ Ws("- No such user"); endcase ] case ptMailCheckNo: [ Ws("- No new mail"); endcase ] case ptMailCheckYes: [ Ws("- New mail waiting "); PrintContents(pbi); endcase ] ] ReleasePBI(pbi) ] //---------------------------------------------------------------------------- and SendCommand(opbi, type, length, retries; numargs na) = valof //---------------------------------------------------------------------------- // returns response pbi or 0 if timeout [ if na ls 4 then retries = 3 if na ge 3 then opbi>>PBI.pup.length = length if na ge 2 then opbi>>PBI.pup.type = type opbi>>PBI.pup.id^2 = miscID miscID = miscID+1 let soc = opbi>>PBI.socket let tQ = vec 1; tQ!0 = 0 opbi>>PBI.queue = tQ Enqueue(tQ, opbi) 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 opbi>>PBI.pup.id) then if ipbi>>PBI.pup.type ne typeError break OtherSpigot(ipbi); ipbi = 0 ] repeat if ipbi ne 0 break ] Block() repeatwhile tQ!0 eq 0 ReleasePBI(Dequeue(tQ)) resultis ipbi ] //---------------------------------------------------------------------------- and PrintContents(pbi) be //---------------------------------------------------------------------------- [ for i = 1 to pbi>>PBI.pup.length-pupOvBytes do Puts(dsp, pbi>>PBI.pup.bytes^i) ] //---------------------------------------------------------------------------- and AppendMesaStringToPup(pbi, firstWord, string) be //---------------------------------------------------------------------------- [ structure MesaString: [ length word maxLength word char^1,1 byte ] let ms = lv pbi>>PBI.pup.words + firstWord -1 ms>>MesaString.length = string>>String.length ms>>MesaString.maxLength = (string>>String.length+1) & -2 for i = 1 to string>>String.length do ms>>MesaString.char^i = string>>String.char^i pbi>>PBI.pup.length = pupOvBytes+firstWord*2+ms>>MesaString.maxLength+2 ]