#!/usr/bin/perl use Socket; use strict; use FileHandle; use lib "/clients/users/acinael/perl"; use Webthread; my @connections; my (@message, @requests, @storage); my $dir="/Users/micahaci/www/"; my ($server, $nfound, $file, $handle, $rdset, $wtset); my ($port, $proto, $paddr, $iaddr, $name); my ($rdout,$ebits,$wtout,$note,$hdr,$last,$newhand); my @rdq; my @wtq; #socket stuff $port = shift || 50005; 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: $!"; &logmsg("server started on port $port, type ^c to terminate"); push @rdq, $server; #add service port to read queue print "sfno: " . fileno($server) . "hand: $server \n"; while (1) #main loop { print "*************BEGIN*************\n"; #print "fo: " . fileno($handle) . "hand: " . $handle ."\n"; #debug #get connection bits $rdset = $wtset = ""; $rdset = &fhbits(@rdq); $wtset = &fhbits(@wtq); &fhtst($rdset); #debug #select ready handle $rdout=$wtout=$last=$note=""; $nfound = select($rdset,$wtset,undef,undef); print "$nfound sets: " . vec($rdset,0,1) . "s $wtout \n";#debug print "rdsize: ". @rdq ."\twtsize: " . @wtq . "\n"; #dispaly && dispatch &fhtst($rdset); #debug &dispatchr($rdset); &dispatchw($wtset); print "*************$note***END****************88\n"; } #end of program, start of subroutines sub logmsg{ print "$0 $$: @_ at ", scalar localtime, "\n"; } sub acpt { $paddr = accept($handle, $server); #accept connection / handshake ($port, $iaddr) = sockaddr_in($paddr); #new data port $name = gethostbyaddr($iaddr, AF_INET); #create new thread and add it to the list of connections push @connections, webthread::new(\*handle,$port,$name,$paddr,$iaddr); #logging to console &logmsg("connection from $name [", inet_ntoa($iaddr), "] at port $port"); @connections[-1]->webthread::disp; push @rdq, @connections[-1]->webthread::hand; #add new connection to rdq } sub fhbits { #turnes handles into bit values and packs them into bit vector my(@arr) = @_; my($bits); foreach (@arr) { vec($bits,fileno($_),1) = 1; } return $bits; } sub fhtst { #displays bit vectors (debugging function) my $test_counter=0; while($test_counter<5) { print "testvec: " . vec($_[0],$test_counter,1) . "\n"; $test_counter++; } $test_counter=0; } sub dispatchr { #deal with set bits my $bits = $_; my $offset = 3; my $counter = 0; while ($counter < @rdq) { if( vec($bits,$offset,1) == 1) { #$_[0] = $rdset, $wtset $newhand = $_; print "rvec: off: $offset :" . vec($_[0],$offset,1) . "\n"; #debug if($offset == 3) { #service port &acpt(); } else {#service data port &readsvc($rdq[$counter]->webthread::hand); } $offset++; } else { $offset++; } $counter++; } } sub dispatchw { #deal with set bits my($bits) = $_; my $offset = 3; my $counter =0; while ($counter < @wtq) { if( vec($bits,$offset,1) == 1) { #$_[0] = $rdset, $wtset $newhand = $_; print "rvec: off: $offset :" . vec($_[0],$offset,1) . "\n"; #debug if($offset == 3) { #service port &acpt(); } else { &writesvc($wtq[$counter]); } $offset++; } else { $offset++; } $counter++; } } sub process{#works, but not yet in conjunction with the new multi threading if($note eq 'GET') { if (@requests[1] eq '/') #if whole directory is requested { $dir="/Users/micahaci/www/"; opendir DH, $dir; foreach $file (readdir DH) { if ($file =~ /^\./){} #no files that start with . else { open PAGE, $dir.$file or die "couln't open " . $file;; print "1File: " . $file . "\n"; while() { print Client $_; } close PAGE; push(@storage,$file); } } } else #if a specific file is requested { open $file, $dir . @requests[1]; print "2File: " . @requests[1] . "\n"; if ($file==undef) {print Client "HTTP/1.0: 404 Page not found\r\n";} while(<$file>) { print Client $_; } close $file; push(@storage,$file); } shutdown(Client,2); } } sub readsvc { my $note; &recv($_,$note,128,undef); print $note; } sub writesvc{} { #print {$_}, $_->hdr; #print {$_}, $_-filex; }