require 'sys/socket.ph';
require 'fcntl.ph';

sub setup_sockets{
    # Open sockets on all the port numbers
    # that were gotten from the config files

    # This is what a socket looks like
    $sockaddr = 'S n a4 x8';
    ($name, $aliases, $proto) = getprotobyname('tcp');

    # Have the option of more than one port to listen on
    for $port (@port_numbers){
	$myfh = &checkout_filehandle();
	push(@ports, $myfh);	# Store it on my list

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

	# Make the socket
	socket($myfh, &AF_INET, &SOCK_STREAM, $proto) || die "socket: $!";
	bind($myfh,$this) || die "bind: $!";
	listen($myfh,5) || die "connect: $!";
	# And nuke the buffering
	select($myfh); $| = 1; select(STDOUT);
    }
}

sub checkout_filehandle {
    shift(@my_fh_list);
}

sub checkin_filehandle {
    local($fh) = @_;
    push(@my_fh_list, $fh);
}

sub new_connection {
    local($socketfh) = @_;

    # Connections have certain values associated with them:
    #
    # Filehandle -- This is what everything is indexed on.  All checked out
    #               filehandles will be in one of a few arrays depending
    #               what their status is.
    #               @talking_clients   New clients that we don't have a
    #                                  request from yet
    #               @waiting_clients   Clients waiting for a response
    #               (I think that's it)
    #
    # $fullrequest{} -- This is the full request, including all headers
    #                   and everything
    # $url{} -- The path associated with the request
    # $time{} -- Time the request was made
    # $host{} -- Host the request is coming from
    # $response{} -- The response for this request
    # $status{} -- 1 if the reply is complete

    # Accept the new connection and give it a fresh, brand new
    # usable filehandle for the client, if one is available, which one
    # always should be
    if($thisfh = &checkout_filehandle()){
	($addr = accept($thisfh, $socketfh)); # What if accept fails? Idunno.
	$now = time();

	# Yipee, we have a new client, we'll have to see what they want, but
	# for now we'll add them to the list, to be sure everyone gets dealt
	# with in order
	push(@talking_clients, $thisfh);
	print("New client: $thisfh\n\r") if $debug;

	# Set the connection to non buffering
	select($thisfh); $|=1;
	select(STDOUT);

	# Do yucky address stuff (inetaddr is the only important part)
	# (though, we may want to pay attention to port, I suppose)
	($af,$port,$inetaddr) = unpack($sockaddr,$addr);
	
	# Only use one of the next two options
	($hostname,$aliases,$addrtype,$length,@addrs) =   # This does
	    gethostbyaddr($inetaddr, 2);                  # name resolution

#	($hostname) = join('.', unpack('C4', $inetaddr)); # This doesn't

	$time{$thisfh} = $now;
	$host{$thisfh} = $hostname;
	$fullrequest{$thisfh} = '';

    }
    else{
	# This should never happen
    }
}
