DIRECTORY IO USING [Close, EndOf, EndOfStream, Error, Flush, GetChar, PutFR, PutChar, PutRope, rope, RopeFromROS, ROS, STREAM], Rope USING [ROPE, Cat, Concat, Fetch, Find, Length, Substr], IPDefs USING [Address], IPName USING [LoadCacheFromName, NameToAddress], IPRouter USING [BestAddress], Process USING [SecondsToTicks], TCP USING [AbortTCPStream, CreateTCPStream, Error, ErrorFromStream, neverTimeout, Reason, Timeout, WaitForListenerOpen], QueryServices; QueryServicesImpl: CEDAR MONITOR IMPORTS IO, IPName, IPRouter, Process, Rope, TCP EXPORTS QueryServices = BEGIN whoIsSocket: INT = 43; fingerSocket: INT = 79; whoisServerName: Rope.ROPE = "SRI-NIC.ARPA"; nRetries: INT _ 4; seconds: CARDINAL _ 2; Whois: PUBLIC ENTRY PROC [pattern: Rope.ROPE] RETURNS[rope: Rope.ROPE] = { snooz: CONDITION _ [timeout: Process.SecondsToTicks[seconds]]; FOR i: INT IN [0..nRetries) DO rope _ QueryOnce[whoisServerName, pattern, whoIsSocket]; IF rope # NIL THEN RETURN[rope]; WAIT snooz; ENDLOOP; RETURN[IO.PutFR["Problems connecting to %g. Try again later.", IO.rope[whoisServerName]]]; }; Finger: PUBLIC ENTRY PROC [pattern: Rope.ROPE] RETURNS[rope: Rope.ROPE] = { snooz: CONDITION _ [timeout: Process.SecondsToTicks[seconds]]; host, user: Rope.ROPE _ NIL; IF Rope.Find[pattern,"@"] > -1 THEN [user, host] _ BreakName[pattern, '@] ELSE host _ pattern; IF host = NIL THEN RETURN["Please provide host name."]; IF Rope.Find[host, "."] = -1 THEN host _ Rope.Concat[host, ".ARPA"]; FOR i: INT IN [0..nRetries) DO rope _ QueryOnce[host, user, fingerSocket]; IF rope # NIL THEN RETURN[rope]; WAIT snooz; ENDLOOP; RETURN[IO.PutFR["Problems connecting to %g. Try again later.", IO.rope[host]]]; }; QueryOnce: PROC [host, pattern: Rope.ROPE, socket: INT] RETURNS[rope: Rope.ROPE_NIL] = { server: IO.STREAM; cr: TCP.Reason _ neverOpen; out: IO.STREAM _ IO.ROS[]; where: LIST OF IPDefs.Address; IF host = NIL THEN RETURN["Need host name."]; SELECT IPName.LoadCacheFromName[host, TRUE, TRUE] FROM bogus => RETURN[IO.PutFR["%g is not a valid name.", IO.rope[host]]]; down => RETURN[IO.PutFR["Name servers for %g are down. Try again later", IO.rope[host]]]; mxOk => { where _ IPName.NameToAddress[host]; IF where = NIL THEN RETURN[IO.PutFR["%g is for mail forwarding only. (Not on internet.)", IO.rope[host]]]; }; ENDCASE => {where _ IPName.NameToAddress[host];}; IF where = NIL THEN { RETURN[IO.PutFR["Can't find IP Address for %G.", IO.rope[host]]]; }; BEGIN ENABLE { TCP.Timeout => { out.PutRope["[TCP.Timeout.]\n"]; GO TO GiveUp; }; TCP.Error => { out.PutRope["[TCP.Error.]\n"]; cr _ reason; GO TO GiveUp; }; IO.Error => { out.PutRope["[IO.Error.]\n"]; cr _ TCP.ErrorFromStream[server]; GOTO GiveUp; }; }; server _ TCP.CreateTCPStream[[ matchLocalPort: FALSE, localPort: 0, matchForeignAddr: TRUE, foreignAddress: IPRouter.BestAddress[where], matchForeignPort: TRUE, foreignPort: socket, active: TRUE, timeout: 120000]]; TCP.WaitForListenerOpen[server, TCP.neverTimeout]; IF pattern # NIL THEN server.PutRope[pattern]; server.PutRope["\n\l"]; server.Flush[]; WHILE NOT server.EndOf[] DO c: CHAR _ server.GetChar[ ! IO.EndOfStream => EXIT]; IF c # '\l THEN out.PutChar[c] ENDLOOP; rope _ IO.RopeFromROS[out]; server.Close[]; out.Close[]; EXITS GiveUp => { IF server # NIL THEN TCP.AbortTCPStream[server]; SELECT cr FROM remoteAbort => RETURN[Rope.Cat[host, " refused connection.\n"]]; ENDCASE => RETURN[NIL]; }; END; }; BreakName: PROC[name: Rope.ROPE, char: CHAR _ '.] RETURNS[left, right: Rope.ROPE] = BEGIN length: INT = name.Length[]; FOR i: INT DECREASING IN [0..length) DO IF name.Fetch[i] = char THEN RETURN[ left: name.Substr[start: 0, len: i], right: name.Substr[start: i+1, len: length-(i+1)] ]; ENDLOOP; RETURN[left: NIL, right: NIL]; END; END. ฺQueryServicesImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Hal Murray May 16, 1985 3:20:40 am PDT John Larson, July 21, 1987 5:01:47 pm PDT Sharon Johnson, July 22, 1987 3:22:05 pm PDT ส– "cedar" style˜headšœ™Icodešœ ฯmœ1™šžœžœžœž˜Mšœ8˜8Mšžœžœžœžœ˜ Mšžœ˜ Mšžœ˜—Mšžœžœ6žœ˜ZMšœ˜M˜M˜—šŸœžœžœžœžœžœ žœ˜KMšœž œ.˜>Mšœžœžœ˜M˜Jšžœžœ&˜IJšžœ˜M˜Mšžœžœžœžœ˜7šžœžœ#˜DJ˜—šžœžœžœž˜Mšœ+˜+Mšžœžœžœžœ˜ Mšžœ˜ Mšžœ˜—Mšžœžœ6žœ˜OMšœ˜M˜M˜—šŸ œžœžœ žœžœ žœžœ˜XMšœžœžœ˜Mšœžœ˜Mš œžœžœžœžœ˜Mšœžœžœ˜Mšžœžœžœžœ˜-šžœ žœžœž˜6Jšœ žœžœ"žœ˜DJšœ žœžœ8žœ˜Zšœ ˜ Jšœ#˜#šžœ žœžœ˜Mšžœžœ=žœ˜VMšœ˜——Jšžœ*˜1—M˜šžœ žœžœ˜Mšžœžœ(žœ˜AMšœ˜—šž˜šžœ˜šžœ ˜Mšœ ˜ Mšžœžœ ˜—šžœ ˜Mšœ˜M˜ Mšžœžœ ˜—šžœ ˜ Mšœ˜Mšœžœ˜!Mšžœ ˜—M˜M˜——šœ žœ˜Mšœžœ˜Mšœ ˜ Mšœžœ˜Mšœ,˜,Mšœžœ˜Mšœ˜Mšœžœ˜ Mšœ˜—Mšžœžœ˜2M˜Mšžœ žœžœ˜.Mšœ˜M˜M˜šžœžœž˜Mšœžœžœžœ˜4Mšžœ žœ˜Mšžœ˜M˜—Mšœžœ˜Mšœ˜Mšœ ˜ Mšžœ ˜Mšžœ žœžœžœ˜0šžœž˜Mšœžœ+˜@Mšžœžœžœ˜—Mšœ˜Mšžœ˜Mšœ˜M˜M˜—š Ÿ œžœ žœžœžœžœ˜SJšž˜Jšœžœ˜š žœžœž œžœ ž˜'šžœžœžœ˜$Jšœ$˜$Jšœ4˜4—Jšžœ˜—Jšžœžœ žœ˜Jšžœ˜J˜—M˜Mšžœ˜——…—ฎ™