lpmoo-1.2/etc/
lpmoo-1.2/mudlib/
lpmoo-1.2/mudlib/etc/
lpmoo-1.2/mudlib/include/
lpmoo-1.2/mudlib/include/moo/
lpmoo-1.2/mudlib/lpc/
lpmoo-1.2/mudlib/std/auto/
lpmoo-1.2/mudlib/std/bfuns/
#
#  Name/Address Translation Daemon
#
###############################################################################

$host  = "localhost";
$port  = 9990;

$name  = "DNS";
$pass  = "password";

$login = "connect $name $pass\n";

###############################################################################

require 'getopts.pl';

package network;

require 'sys/socket.ph';

$sockaddr = 'S n a4 x8';
chop($hostname = `hostname`);

$next      = 'netsocket000000';
%listening = ();

sub hostname
{
  local($who) = @_ || $hostname;

  local($name, $aliases, $type, $len, $addr) = gethostbyname($who);

  return $name;
}

sub ipaddr
{
  local($who) = @_;
  $who = $hostname if (! $who);

  local($name, $aliases, $type, $len, $addr) = gethostbyname($who);

  return join('.', unpack('C4', $addr));
}

sub resolveaddr
{
  local($addr) = @_;

  if ($addr =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/)
    {
      return gethostbyaddr(pack('C4', $1, $2, $3, $4), &AF_INET);
    }
  else
    {
      return gethostbyname($addr);
    }
}

sub name2addr
{
  local($name) = @_;

  local($addr) = &ipaddr($name);

  return $addr;
}

sub addr2name
{
  local($addr) = @_;

  local($name, $aliases, $type, $len, $addr) = &resolveaddr($addr);

  return $name;
}

sub open
{
  local($them, $port) = @_;
  local($name, $aliases, $proto, $type, $len, $thisaddr);

  if ($listening{$them})
    {
      local(*S) = $them;
      *NS = ++$next;

      (local($addr) = accept(NS, S)) || return undef;
      select((select(NS), $| = 1)[0]);

      return $next;
    }

  $port = 'telnet'    unless $port;
  $them = 'localhost' unless $them;

  ($name, $aliases, $proto) = getprotobyname('tcp');
  ($name, $aliases, $port)  = getservbyname($port, 'tcp')
      unless $port =~ /^\d+$/;
  ($name, $aliases, $type, $len, $thisaddr) = gethostbyname($hostname);
  ($name, $aliases, $type, $len, $thataddr) = &resolveaddr($them);

  $this = pack($sockaddr, &AF_INET, 0,     $thisaddr);
  $that = pack($sockaddr, &AF_INET, $port, $thataddr);

  *S = ++$next;

  socket(S, &PF_INET, &SOCK_STREAM, $proto) || return undef;
  bind(S, $this) || return undef;
  connect(S, $that) || return undef;

  select((select(S), $| = 1)[0]);

  return $next;
}

sub listen
{
  local($port) = @_;
  local($name, $aliases, $proto, $type, $len, $this, $addr);

  ($name, $aliases, $proto) = getprotobyname('tcp');
  ($name, $aliases, $port)  = getservbyname($port, 'tcp')
      unless $port =~ /^\d+$/;

  $this = pack($sockaddr, &AF_INET, $port, "\0\0\0\0");

  *S = ++$next;

  socket(S, &PF_INET, &SOCK_STREAM, $proto) || return undef;
  bind(S, $this) || return undef;
  listen(S, 5) || return undef;

  select((select(S), $| = 1)[0]);

  $listening{$next} = 1;

  return $next;
}

sub read
{
  local(*S, $bsize) = @_;

  return undef if (sysread(S, $_, $bsize) == 0);

  return $_;
}

sub readline
{
  local(*S) = @_;

  return scalar(<S>);
}

sub write
{
  local(*S, $data) = @_;

  return syswrite(S, $data, length($data));
}

sub close
{
  local(*S)    = @_;
  local($sock) = @_;

  close(S);

  delete $listening{$sock} if ($listening{$sock});
}

package main;

&Getopts('d');

$sock = &network'open($host, $port);

while (! defined($sock))
  {
    sleep(10);
    $sock = &network'open($host, $port);
  }

&network'write($sock, $login);

sub send
{
  local($_) = @_;

  print if ($opt_d);
  &network'write($sock, $_);
}

while ($_ = &network'readline($sock))
  {
    print if ($opt_d);
    s/\r?\n?$//;

    if (/^NAME\? (.*)/)
      {
        $name = &network'addr2name($1);
        if ($name eq "")
          { &send("NONAME $1\n"); }
        else
          { &send("HOST $name = $name = $1\n"); }
      }
    elsif (/^ADDR\? (.*)/)
      {
        $addr = &network'name2addr($1);
        $name = &network'addr2name($addr);
        if ($name eq "")
          { &send("NOADDR $1\n"); }
        else
          { &send("HOST $1 = $name = $addr\n"); }
      }
  }