The "Generic Ping Thing" can be used to connect to a site at a port,
send one line, and echo back the results. The "Owl" is an example
of a Generic Ping Thing for Finger and Whois.

The Generic: All the work is done by GetData. There's a "GetUser_Host"
verb which you can call to separate host from search term. It looks for
either [t--m] at [site], or "site term" in the dobjstr.

You'll probably want to override the "inform" verb so that your object
actually does something useful. See the Hoois Owl for an example.

@dump #338 with create
@create $thing named Generic Ping Thing:Generic Ping Thing,Ping Thing,pingthing
@prop #338."error_msg" "Sorry, ran into a problem. Error:" rc
@prop #338."start_inform_msg" "" rc
@prop #338."end_inform_msg" "" rc
;;#338.("aliases") = {"Generic Ping Thing", "Ping Thing", "pingthing"}
;;#338.("object_size") = {0, 0}

@verb #338:"GetData" this none this rx
@program #338:GetData
"Syntax: GetData(host,port,line_to_send);";
Host = args[1];
Port = args[2];
line_to_send = args[3];
Connection = $network:open(Host, Port);
if (typeof(Connection) == ERR)
  player:tell(this.error_msg, tostr(Connection));
  return;
endif
notify(Connection, line_to_send);
player:tell(this.start_inform_msg);
while (typeof(line = read(Connection)) == STR)
  fork (0)
    this:inform(line);
  endfork
endwhile
suspend(2);
player:tell(this.end_inform_msg);
$network:close(Connection);
.

@verb #338:"GetUser_Host" this none this
@program #338:GetUser_Host
"Syntax: GetUser_Host(hostname,username);";
"        Where hostname may be either a host, or a [u--r] at [host.]";
if (At_Place = index(args[1], "@"))
  host = args[1][At_Place + 1..length(args[1])];
  user = args[1][1..At_Place - 1];
else
  host = args[1];
  if (length($string_utils:words(dobjstr)) > 1)
    user = $string_utils:words(dobjstr)[2];
  else
    user = "";
  endif
endif
return {host, user};
.

@verb #338:"inform" this none this
@program #338:inform
player:tell(@args);
.

"***finished***



And, here's the Owl. Use "finger [h--p] at [nspace.cts.com] on owl" or
"whois rs.internic.net USD on owl".

@dump #339 with create
@create #338 named Owl:Owl
@prop #339."looking_msg" "Whoo! Searching for " rc
@prop #339."finger_msg" "The owl turns and gives the finger to " rc
@prop #339."tome" {} rc
;;#339.("tome") = {"Cerebus has been idle since Sunday, October 2, 1994, 3:27:04 PM (1d 18:09:42)", "Local time is Tuesday, October 4, 1994, 9:36:46 AM,", "which is 0:00 hours off of GMT.", "", "", "Ain't nobody here but us non-aligned chickens.", "Try \"finger [h--p] at [nspace.cts.com]\"", "", "", "FURTHER QUESTIONS", "For more information about nspace.cts.com, contact Jerry Stratton at", "[j--r--y] at [teetot.acusd.edu]", "", "\"The rifle of all descriptions, the shot gun, the musket and repeater", " are such arms; and that under the Constitution the right to keep and", " bear arms cannot be infringed or forbidden by the legislature.\"", "              -- ANDREWS v. STATE; 50 Tenn. 165,179,8 Am. Rep. 8, 14", "                                   (Tennessee Supreme Court, 1871)"}
@prop #339."help_msg" "You can _whois site search_word on %t_ or _finger site username on %t_." rc
;;#339.("error_msg") = "Thud. The owl falls over. Why?"
;;#339.("start_inform_msg") = "Flap, Flap, Flap. Whoo!"
;;#339.("end_inform_msg") = "Screech! The owl chomps on a tin mouse."
;;#339.("key") = #78
;;#339.("aliases") = {"Owl"}
;;#339.("description") = "A forbidding owl with golden eyes, one wing holds a dusty bronze tome, and the other is doing its best to give you the finger. You can use this owl to do fingers and whois."
;;#339.("object_size") = {0, 0}

@verb #339:"search whois" any on this
@program #339:search
Stuff = this:GetUser_Host(args[1], args[2]);
Whois = 43;
player.location:announce_all(this.looking_msg, (Stuff[2] == "") ? "nothing" | Stuff[2], " on ", Stuff[1], ".");
this.tome = {};
this:GetData(Stuff[1], Whois, Stuff[2]);
.

@verb #339:"finger" any on this
@program #339:finger
Stuff = this:GetUser_Host(args[1], args[2]);
Finger = 79;
player.location:announce_all(this.finger_msg, (Stuff[2] == "") ? "nothing" | Stuff[2], " on ", Stuff[1], ".");
this.tome = {};
this:GetData(Stuff[1], Finger, Stuff[2]);
.

@verb #339:"description" this none this
@program #339:description
WhatYouSee = pass(@args);
if (length(this.tome))
  WhatYouSee = {WhatYouSee, "", @this.tome};
endif
return WhatYouSee;
.

@verb #339:"inform" this none this
@program #339:inform
pass(@args);
this.tome = {@this.tome, @args};
.

@verb #339:"erase" this none none
@program #339:erase
player:tell("You erase the ", this.name, ".");
this.tome = {};
.

"***finished***