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+.*/++ ; |
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"); |