#!/usr/bin/perl
# p. 350  Perl Programming

use Socket;
use Carp;
use FileHandle;
sub spawn;

my ($paddr,$addr);
my $port = 1153;
my $proto = getprotobyname('tcp');
socket(Server, PF_INET, SOCK_STREAM, $proto) or die "socket: $!";
setsockopt(Server,SOL_SOCKET,SO_REUSEADDR, pack("l",1)) or die "setsockopt: $!";
bind(Server, sockaddr_in($port,INADDR_ANY)) or die "bind: $!";
listen(Server, SOMAXCONN) or die "listen $!";
print "serverstarted on port $port";

for( ; $paddr = accept(Client, Server); close Client){

  my($port,$iaddr) =sockaddr_in($paddr);
  my $name=gethostbyaddr($iaddr,AF_INET);
  print "\nC. from $name [", inet_ntoa($iaddr), "] at port $port\n";

  spawn sub {
	print "hello\n";
        exec '/usr/local/bin/gnut -c /root/.gnutrc';
  };

}

sub spawn {
 my $coderef = shift;
 unless (@_ == 0 && $coderef && ref($coderef) eq 'CODE'){
      confess "usage: CODEREF";
 }

  my $pid;

  if(!defined($pid= fork)) {
	print "cannot fork $!";
	return;
  }elsif($pid){
        print "begat $pid";
	return;
  }

  open(STDIN,"<&Client") or die "Can't dup client to stdin";
  open(STDOUT,"<&Client") or die "Can't dup client to stdout";
  STDOUT->autoflush(); 

  exit &$coderef();
}
