rt/msrserv.pl
changeset 195 674071846ee3
parent 28 801dc7eabf51
child 197 b9a6e2c22745
equal deleted inserted replaced
194:c21e7c12dd50 195:674071846ee3
     1 #!/usr/bin/perl -w
     1 #!/usr/bin/perl -w
     2 #------------------------------------------------------------
     2 #------------------------------------------------------------
     3 #
     3 #
     4 # (C) Copyright
     4 # (C) Copyright
     5 #     Diese Software ist geistiges Eigentum der 
       
     6 #     Ingenieurgemeinschaft IgH. Sie darf von 
       
     7 #     Toyota Motorsport GmbH
       
     8 #     beliebig kopiert und veraendert werden. 
       
     9 #     Die Weitergabe an Dritte ist untersagt.
       
    10 #     Dieser Urhebrrechtshinweis muss erhalten
       
    11 #     bleiben.
       
    12 #
       
    13 #     Ingenieurgemeinschaft IgH
     5 #     Ingenieurgemeinschaft IgH
    14 #     Heinz-Baecker-Strasse 34
     6 #     Heinz-Baecker-Strasse 34
    15 #     D-45356 Essen
     7 #     D-45356 Essen
    16 #     Tel.:  +49-201/61 99 31
     8 #     Tel.:  +49-201/61 99 31
    17 #     Fax.:  +49-201/61 98 36
     9 #     Fax.:  +49-201/61 98 36
    18 #     WWW:   http://www.igh-essen.com
    10 #     WWW:   http://www.igh-essen.com
    19 #     Email: msr@igh-essen.com
    11 #     Email: msr@igh-essen.com
    20 #
    12 #
    21 #------------------------------------------------------------
    13 #------------------------------------------------------------
    22 #
    14 #
    23 # Multithreaded Server 
    15 # Multithreaded Server
    24 # according to the example from "Programming Perl"
    16 # according to the example from "Programming Perl"
    25 # this code is improved according to the example from 
    17 # this code is improved according to the example from
    26 # perldoc perlipc, so now safely being usable under Perl 5.8 
    18 # perldoc perlipc, so now safely being usable under Perl 5.8
    27 # (see note (*))
    19 # (see note (*))
    28 #
    20 #
    29 # works with read/write on a device-file  
    21 # works with read/write on a device-file
    30 #
    22 #
    31 # $Revision: 1.1 $
    23 # $Revision: 1.1 $
    32 # $Date: 2004/10/01 16:00:42 $
    24 # $Date: 2004/10/01 16:00:42 $
    33 # $RCSfile: msrserv.pl,v $
    25 # $RCSfile: msrserv.pl,v $
    34 #
    26 #
    38 use strict;
    30 use strict;
    39 BEGIN { $ENV{PATH} = '/opt/msr/bin:/usr/bin:/bin' }
    31 BEGIN { $ENV{PATH} = '/opt/msr/bin:/usr/bin:/bin' }
    40 use Socket;
    32 use Socket;
    41 use Carp;
    33 use Carp;
    42 use FileHandle;
    34 use FileHandle;
    43 use Getopt::Std; 
    35 use Getopt::Std;
    44 
    36 
    45 use Sys::Syslog qw(:DEFAULT setlogsock); 
    37 use Sys::Syslog qw(:DEFAULT setlogsock);
    46 
    38 
    47 use vars qw (
    39 use vars qw (
    48 	     $self $pid $dolog $port $dev %opts $selfbase
    40 	     $self $pid $dolog $port $dev %opts $selfbase
    49 	     $len $offset $stream $written $read $log $blksize
    41 	     $len $offset $stream $written $read $log $blksize
    50 	     $instdir
    42 	     $instdir
    51 	     $authfile %authhosts
    43 	     $authfile %authhosts
    52 	     );
    44 	     );
    53 
    45 
    54 
    46 
    55 # Do logging to local syslogd by unix-domain socket instead of inetd
    47 # Do logging to local syslogd by unix-domain socket instead of inetd
    56 setlogsock("unix");  
    48 setlogsock("unix");
    57 
    49 
    58 # Prototypes and some little Tools
    50 # Prototypes and some little Tools
    59 sub spawn;
    51 sub spawn;
    60 sub logmsg { 
    52 sub logmsg {
    61   my ($level, $debug, @text) = @_;
    53   my ($level, $debug, @text) = @_;
    62   syslog("daemon|$level", @text) if $debug > $dolog;
    54   syslog("daemon|$level", @text) if $debug > $dolog;
    63 #  print STDERR "daemon|$level", @text, "\n" if $dolog;
    55 #  print STDERR "daemon|$level", @text, "\n" if $dolog;
    64 }
    56 }
    65 sub out {
    57 sub out {
    66   my $waitpid = wait; 
    58   my $waitpid = wait;
    67   logmsg("notice", 2, "$waitpid exited");
    59   logmsg("notice", 2, "$waitpid exited");
    68   unlink "$selfbase.pid";
    60   unlink "$selfbase.pid";
    69   exit 0;
    61   exit 0;
    70 }
    62 }
    71 
    63 
    72 sub help {
    64 sub help {
    73   print "\n  usage: $0 [-l og] [-h elp] [-p port] [-d device]\n"; 
    65   print "\n  usage: $0 [-l og] [-h elp] [-p port] [-d device]\n";
    74   exit; 
    66   exit;
    75 }
    67 }
    76 
    68 
    77 # Process Options
    69 # Process Options
    78 %opts = (
    70 %opts = (
    79 	 "l" => 1,
    71 	 "l" => 1,
    80 	 "h" => 0,
    72 	 "h" => 0,
    81 	 "p" => 2345,
    73 	 "p" => 2345,
    82 	 "d" => "/dev/msr"
    74 	 "d" => "/dev/msr"
    83 	 );
    75 	 );
    84   
    76 
    85 getopts("lhp:d:", \%opts);
    77 getopts("lhp:d:", \%opts);
    86 
    78 
    87 help if $opts{"h"};
    79 help if $opts{"h"};
    88 
    80 
    89 ( $self =  $0 ) =~ s+.*/++ ;
    81 ( $self =  $0 ) =~ s+.*/++ ;
    92 $dolog = $opts{"l"};
    84 $dolog = $opts{"l"};
    93 $port = $opts{"p"};
    85 $port = $opts{"p"};
    94 $dev = $opts{"d"};
    86 $dev = $opts{"d"};
    95 $blksize = 1024; # try to write as much bytes
    87 $blksize = 1024; # try to write as much bytes
    96 $instdir = "/opt/msr";
    88 $instdir = "/opt/msr";
    97 $authfile = "$instdir/etc/hosts.auth"; 
    89 $authfile = "$instdir/etc/hosts.auth";
    98 
    90 
    99 # Start logging
    91 # Start logging
   100 openlog($self, 'pid');
    92 openlog($self, 'pid');
   101 
    93 
   102 # Flush Output, dont buffer
    94 # Flush Output, dont buffer
   125 socket(Server, PF_INET, SOCK_STREAM, $proto) or die "socket: $!";
   117 socket(Server, PF_INET, SOCK_STREAM, $proto) or die "socket: $!";
   126 setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, pack("l", 1))
   118 setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, pack("l", 1))
   127   or die "setsocketopt: $!";
   119   or die "setsocketopt: $!";
   128 bind (Server, sockaddr_in($port, INADDR_ANY))
   120 bind (Server, sockaddr_in($port, INADDR_ANY))
   129   or die "bind: $!";
   121   or die "bind: $!";
   130 listen (Server, SOMAXCONN) 
   122 listen (Server, SOMAXCONN)
   131   or die "listen: $!";
   123   or die "listen: $!";
   132 
   124 
   133 %authhosts = ();
   125 %authhosts = ();
   134 # get authorized hosts
   126 # get authorized hosts
   135 open (AUTH, $authfile) 
   127 open (AUTH, $authfile)
   136   or logmsg ("notice", 2, "Could not read allowed hosts file: $authfile");
   128   or logmsg ("notice", 2, "Could not read allowed hosts file: $authfile");
   137 while (<AUTH>) {
   129 while (<AUTH>) {
   138     chomp;
   130     chomp;
   139     my $host = lc $_;
   131     my $host = lc $_;
   140      if ($host =~ /^[\d\w]/) {
   132      if ($host =~ /^[\d\w]/) {
   174     next if $waitedpid and not $paddr;
   166     next if $waitedpid and not $paddr;
   175     my ($port, $iaddr) = sockaddr_in($paddr);
   167     my ($port, $iaddr) = sockaddr_in($paddr);
   176     my $name = lc gethostbyaddr($iaddr, AF_INET);
   168     my $name = lc gethostbyaddr($iaddr, AF_INET);
   177     my $ipaddr = inet_ntoa($iaddr);
   169     my $ipaddr = inet_ntoa($iaddr);
   178     my $n = 0;
   170     my $n = 0;
   179     
   171 
   180 # tell about the requesting client
   172 # tell about the requesting client
   181     logmsg ("info", 2, "Connection from >$ipaddr< ($name) at port $port");
   173     logmsg ("info", 2, "Connection from >$ipaddr< ($name) at port $port");
   182     
   174 
   183     spawn sub {
   175     spawn sub {
   184       my ($head, $hlen, $pos, $pegel, $typ, $siz, $nch, $nrec, $dat, $i, $j, $n, $llen); 
   176       my ($head, $hlen, $pos, $pegel, $typ, $siz, $nch, $nrec, $dat, $i, $j, $n, $llen); 
   185       my ($watchpegel, $shmpegel);
   177       my ($watchpegel, $shmpegel);
   186       my ($rin, $rout, $in, $line, $data_requested, $oversample);
   178       my ($rin, $rout, $in, $line, $data_requested, $oversample);
   187       my (@channels);
   179       my (@channels);
   188       
   180 
   189 #   to use stdio on writing to Client
   181 #   to use stdio on writing to Client
   190       Client->autoflush();
   182       Client->autoflush();
   191       
   183 
   192 #   Open Device 
   184 #   Open Device
   193       sysopen (DEV, "$dev", O_RDWR | O_NONBLOCK, 0666) or die("can't open $dev");
   185       sysopen (DEV, "$dev", O_RDWR | O_NONBLOCK, 0666) or die("can't open $dev");
   194       
   186 
   195 #   Bitmask to check for input on stdin
   187 #   Bitmask to check for input on stdin
   196       $rin = "";
   188       $rin = "";
   197       vec($rin, fileno(Client), 1) = 1; 
   189       vec($rin, fileno(Client), 1) = 1;
   198       
   190 
   199 #   check for authorized hosts
   191 #   check for authorized hosts
   200       my $access = 'deny';
   192       my $access = 'deny';
   201       $access = 'allow' if $authhosts{$ipaddr};
   193       $access = 'allow' if $authhosts{$ipaddr};
   202       $line = "<remote_host host=\"$ipaddr\" access=\"$access\">\n";
   194       $line = "<remote_host host=\"$ipaddr\" access=\"$access\">\n";
   203       logmsg ("info", 2, $line);
   195       logmsg ("info", 2, $line);
   206       while ($len) {
   198       while ($len) {
   207 	$written = syswrite (DEV, $line, $len, $offset);
   199 	$written = syswrite (DEV, $line, $len, $offset);
   208 	$len -= $written;
   200 	$len -= $written;
   209 	$offset += $written;
   201 	$offset += $written;
   210       }
   202       }
   211       
   203 
   212       while ( 1 ) {
   204       while ( 1 ) {
   213 	$in = select ($rout=$rin, undef, undef, 0.0); # poll client
   205 	$in = select ($rout=$rin, undef, undef, 0.0); # poll client
   214 #     look for any Input from Client
   206 #     look for any Input from Client
   215 	if ($in) {
   207 	if ($in) {
   216 #       exit on EOF
   208 #       exit on EOF
   217 	  $len = sysread (Client, $line, $blksize) or exit;
   209 	  $len = sysread (Client, $line, $blksize) or exit;
   218 	  logmsg("info", 0, "got $len bytes: \"$line\""); 
   210 	  logmsg("info", 0, "got $len bytes: \"$line\"");
   219 	  $offset = 0;
   211 	  $offset = 0;
   220 #       copy request to device
   212 #       copy request to device
   221 	  while ($len) {
   213 	  while ($len) {
   222 	    $written = syswrite (DEV, $line, $len, $offset);
   214 	    $written = syswrite (DEV, $line, $len, $offset);
   223 	    $len -= $written;
   215 	    $len -= $written;
   237   logmsg("info", 2, "server loop\n");
   229   logmsg("info", 2, "server loop\n");
   238 }
   230 }
   239 
   231 
   240 sub spawn {
   232 sub spawn {
   241   my $coderef = shift;
   233   my $coderef = shift;
   242   
   234 
   243   unless (@_ == 0 && $coderef && ref($coderef) eq 'CODE') {
   235   unless (@_ == 0 && $coderef && ref($coderef) eq 'CODE') {
   244     confess "usage: spawn CODEREF";
   236     confess "usage: spawn CODEREF";
   245   }
   237   }
   246   my $pid; 
   238   my $pid;
   247   if (!defined($pid = fork)) {
   239   if (!defined($pid = fork)) {
   248     logmsg ("notice", 2, "fork failed: $!");
   240     logmsg ("notice", 2, "fork failed: $!");
   249     return;
   241     return;
   250   } elsif ($pid) {
   242   } elsif ($pid) {
   251     logmsg ("notice", 2, "Request $pid");
   243     logmsg ("notice", 2, "Request $pid");
   256 # open (STDIN, "<&Client") or die "Can't dup client to stdin";
   248 # open (STDIN, "<&Client") or die "Can't dup client to stdin";
   257 # open (STDOUT, ">&Client") or die "Can't dup client to stdout";
   249 # open (STDOUT, ">&Client") or die "Can't dup client to stdout";
   258 # STDOUT->autoflush();
   250 # STDOUT->autoflush();
   259   exit &$coderef();
   251   exit &$coderef();
   260 }
   252 }
   261 
       
   262 
       
   263 
       
   264 
       
   265 
       
   266 
       
   267 
       
   268 
       
   269 
       
   270 
       
   271 
       
   272