#!/usr/bin/perl5.003 -T
#
#  Listing 1.
#
#  A simple Internet server that invokes finger and returns the
#  output to a Web browser. To access the server create a bit
#  of HTML that looks like this:
#
# <form method = GET action = http://HOSTNAME:7654/>
#   <input NAME = "user">
# </form>
#
#  where HOSTNAME is the name of the machine on which you're running
#  the server. Enter the name of the user that you want to finger in
#  the text input field and hit carriage return.
#
require 5.002;
use strict;
use Socket;

my( $proto, $port );

# Signal handler to get zombie processes.
$SIG{CHLD} = sub { wait };

# Untaint PATH
$ENV{PATH} = '/bin:/usr/bin';

# Create an Internet TCP socket.
$port  = 7654;
$proto = getprotobyname( 'tcp' );
socket( S, AF_INET, SOCK_STREAM, $proto )   or  die "socket:$!";

# Name the socket (bind it to an address).
bind( S, sockaddr_in( $port, INADDR_ANY))   or  die "bind:$!";

# Listen for client connections.
listen( S, 5 );

# Loop indefinitely, accepting connections
# as they arrive and forking a new process
# to handle the request.

for(; accept(NS,S); close NS ) {

    my $pid;
    if(!defined($pid = fork)) {
       die "Fork failed:$!";
    }

    if ($pid) {
       print "Fork worked\n";
    }
    elsif ($pid == 0) {

      # In the child process.
      close S;

      # Look for the user name in the HTTP GET request and
      # return the output of finger on this host for that
      # user.
      while (<NS>) {

        if($_ =~ /^GET/) {

           my($comm,$tag,$user,$http);
           ($comm,$tag,$user,$http) = split /[ =]/, $_;

           open(STDOUT, "+>&NS") || die "open:$!";
           select(STDOUT); $| = 1;

           print "HTTP/1.0 200 OK\n";
           print "MIME-Version: 1.0\n";
           print "Content-Type: text/plain\n\n";
           # Secure use of exec
           exec "/usr/bin/finger", $user;
        }
      }

      exit;   #Child process should exit
    }
}

exit;