crossroads

Git mirror of https://crossroads.e-tunity.com/
git clone git://git.finwo.net/app/crossroads
Log | Files | Refs

server (2288B)


      1 #!/usr/bin/perl
      2 
      3 use strict;
      4 use Socket;
      5 use POSIX;
      6 
      7 # Verbose messaging
      8 sub msg {
      9     # print STDERR ("server: ", @_);
     10 }
     11 
     12 # Child process catcher
     13 sub reaper {
     14     while ((my $waitedpid = waitpid(-1,WNOHANG)) > 0) {
     15         msg ("Child $waitedpid done",
     16              ($? ? " with exit $?" : ''),
     17              "\n");
     18     }
     19     $SIG{CHLD} = \&reaper;
     20 }
     21 
     22 # Connection handler
     23 sub handleconnection () {
     24     my $pid;
     25 
     26     # Daemonize
     27     if (!defined ($pid = fork())) {
     28         msg ("Can't fork: $!\n");
     29         return;
     30     } elsif ($pid) {
     31         # Parent branch
     32         msg ("Connection handler started as pid $pid\n");
     33         return;
     34     }
     35 
     36     # Child branch
     37     while (defined (my $line = <Client>)) {
     38 	chomp ($line);
     39 	$line =~ s/\r//;
     40 	last if ($line eq '');
     41 	msg ("Client says: [$line]\n");
     42     }
     43 
     44     msg ("Sending response\n");
     45     my $msg = "Hello World!\n";
     46     print Client ("HTTP/1.0 200 OK\r\n",
     47 		  "Content-length: ", length($msg), "\r\n",
     48 		  "\r\n",
     49 		  $msg);
     50     exit (0);
     51 }
     52 
     53 # Daemon server
     54 sub serve ($) {
     55     my $port = shift;
     56     
     57     # Create the tcp service.
     58     socket (Server, PF_INET, SOCK_STREAM, getprotobyname ('tcp'))
     59       or die ("Can't create server socket: $!\n");
     60     setsockopt (Server, SOL_SOCKET, SO_REUSEADDR, pack("l", 1))
     61       or die ("Can't set socket options: $!\n");
     62     bind (Server, sockaddr_in ($port, INADDR_ANY))
     63       or die ("Can't bind to port: $!\n");
     64     listen (Server, SOMAXCONN)
     65       or die ("Can't listen to socket: $!\n");
     66     msg ("Server started on port $port.\n");
     67     
     68     $SIG{CHLD} = \&reaper;
     69     $SIG{INT} = sub {
     70         msg ("Interrupt caught, terminating..\n");
     71         exit(0);
     72     };
     73     
     74     while (1) {
     75         for (my $waitedpid = 0;
     76              (my $paddr = accept (Client, Server)) || $waitedpid;
     77              $waitedpid = 0, close (Client)) {
     78             next if ($waitedpid and not $paddr);
     79             my ($port, $iaddr) = sockaddr_in ($paddr);
     80             my $name = gethostbyaddr ($iaddr, AF_INET);
     81             
     82             msg ("Connection from $name/", inet_ntoa ($iaddr), ":$port\n");
     83             
     84             handleconnection ();
     85         }
     86     }
     87 }
     88 
     89 # Main starts here
     90 if ($#ARGV != 1) {
     91     die <<"ENDUSAGE";
     92    
     93 Usage: server nsec portnr
     94 
     95 ENDUSAGE
     96 }
     97 
     98 alarm (shift (@ARGV));
     99 serve (shift (@ARGV));
    100