3 #$Id: serialmgrd,v 1.25 2009/06/27 18:24:33 staffcvs Exp $
15 my $consolidate_exe = "/usr/local/bin/consolidate";
16 my $sympathy_exe = "/usr/local/bin/sympathy";
18 my @keys = qw(host portcode baud task user password name options);
21 shedu => { offsets => [ 0, 7, 3, 11, 15 ], },
22 phoenix => { offsets => [ 0, 3, 11, 15 ], },
23 leprechaun => { offsets => [ 0, 3 ], },
24 imp => { offsets => [ 0, 3 ], },
25 pixie => { offsets => [ 0, 3, 11 ], },
26 basilisk => { offsets => [ 0, 3, 11, 7, 15 ], },
27 wyvern => { offsets => [ 0, 3, 11 ], },
28 goblin => { offsets => [ 0, 3 ], },
29 naga => { offsets => [ 0, 5 ], },
30 dragon => { offsets => [ 0, 3, 11 ], },
31 woking => { offsets => [ 0, 3, 11 ], },
35 my ( $host, $code ) = @_;
37 return "/dev/ttyS" . $code if ( $code =~ /^\d+$/ );
38 return "/dev/ttyUSB" . $1 if ( $code =~ /^u.(\d+)$/ );
39 return "/dev/ttyS" . ( $labeling->{$host}->{offsets}->[$1] + $2 )
40 if ( $code =~ /^(\d+)\.(\d+)$/ );
53 open FILE, "<" . "/etc/serialmgr/config";
56 next if ( $_ =~ /^#/ );
61 push @$lines, { map { $keys[ $c++ ] => $_ } @_ };
68 my ( $sysname, $nodename, $release, $version, $machine ) = POSIX::uname();
69 return $1 if ( $nodename =~ /([^.]+)\./ );
78 if ( $l->{task} eq "sympathy" ) {
79 $shell = "/usr/local/bin/run_sympathy";
82 $shell = "/usr/local/bin/run_conclient";
84 if ( not defined getpwnam( $l->{user} ) ) {
85 syslog( LOG_ERR, "creating an account for user " . $l->{user} );
87 mkdir "/export/home/colo";
90 push @cmd, "-d", "/export/home/colo/" . $l->{user};
91 if ( length( $l->{password} ) > 2 ) {
92 push @cmd, "-p", $l->{password};
94 push @cmd, "-s", $shell;
96 push @cmd, $l->{user};
98 #print join( ' ', @cmd ), "\n";
101 if ( not defined getgrnam( $l->{user} ) ) {
102 syslog( LOG_ERR, "need to create a group for " . $l->{user} );
105 my $current_shell = ( getpwnam( $l->{user} ) )[8];
106 my $uid = getpwnam( $l->{user} ) ;
108 if (( $uid > 0 ) and ( $current_shell ne $shell )) {
110 "changing shell for user " . $l->{user} . " to " . $shell );
112 push @cmd, "usermod";
113 push @cmd, "-s", $shell;
114 push @cmd, $l->{user};
119 if ( length( $l->{password} ) > 2 ) {
120 my $pwd = ( getpwnam( $l->{user} ) )[1];
121 if ( $l->{password} ne $pwd ) {
122 syslog( LOG_ERR, "changing password for user " . $l->{user} );
124 push @cmd, "usermod";
125 push @cmd, "-p", $l->{password};
126 push @cmd, $l->{user};
132 if ( $l->{user} eq 'root' ) {
134 elsif ( ! -d "/export/home/colo/".$l->{user} ) {
136 "need to create a home directory for " . $l->{user} );
139 elsif ( ( getpwnam( $l->{user} ) )[2] != ( stat _ )[4] ||
140 ( getpwnam( $l->{user} ) )[3] != ( stat _ )[5] ) {
142 "changing home directory ownership for user " . $l->{user} );
144 push @cmd, "chown", "-R";
145 push @cmd, $l->{user}.".".$l->{user};
146 push @cmd, "/export/home/colo/".$l->{user};
153 sub resolve_users($) {
156 my $host = hostname();
159 next if ( $l->{host} ne $host );
161 my $uid = $l->{user};
162 my $gid = $l->{user};
164 if ( $uid =~ /[^\d]/ ) {
165 $uid = getpwnam($uid);
166 if ( !defined($uid) ) {
167 syslog( LOG_ERR, "unknown user " . $l->{user} );
172 if ( $gid =~ /[^\d]/ ) {
173 $gid = getgrnam($gid);
174 if ( !defined($gid) ) {
175 syslog( LOG_ERR, "unknown group " . $l->{user} );
185 if ( $l->{uid} > 0 ) {
186 $l->{socket} = "/export/home/colo/" . $l->{user} . "/console-socket";
187 $l->{socket_dir} = "/export/home/colo/" . $l->{user};
188 $l->{log} = "/export/home/colo/" . $l->{user} . "/logs/console";
189 $l->{log_dir} = "/export/home/colo/" . $l->{user} . "/logs";
192 if ( $l->{task} eq "sympathy" ) {
193 $l->{socket} = "/root/sympathy/" . $l->{name};
194 $l->{socket_dir} = "/root/sympathy";
195 $l->{log} = "/root/sympathy/" . $l->{name} . ".log";
196 $l->{log_dir} = "/root/sympathy";
199 $l->{socket} = "/root/consoles/" . $l->{name};
200 $l->{socket_dir} = "/root/consoles";
201 $l->{log} = "/root/consoles/" . $l->{name} . ".log";
202 $l->{log_dir} = "/root/consoles";
212 my $cf = read_file();
214 # my $host = hostname();
217 # if ( $line->{host} eq $host ) {
218 $line->{device} = port_decode( $line->{host}, $line->{portcode} );
231 $t->{started} = time();
234 if ( !defined($pid) ) {
235 syslog( LOG_ERR, "fork failed" );
238 elsif ( $pid != 0 ) {
243 . $t->{task} . " for "
244 . $t->{name} . " on "
245 . $t->{device} . " ("
252 # use sympathy to clean up any old lock files whilst we're still root
253 system( $sympathy_exe, "-S", "-C", "-d", $t->{device} );
255 chown $t->{gid}, $t->{uid}, $t->{device};
256 $( = $) = $t->{gid} if ( $t->{gid} != 0 );
257 $< = $> = $t->{uid} if ( $t->{uid} != 0 );
259 mkdir $t->{socket_dir};
262 if ( $t->{task} eq "sympathy" ) {
268 push @args, $t->{device};
270 push @args, $t->{baud};
273 push @args, $t->{socket};
275 push @args, $t->{log};
277 push @args, $t->{options} if $t->{options};
279 $exe = $sympathy_exe;
285 push @args, $t->{baud} . ",n,8";
289 push @args, "1048576";
290 push @args, $t->{device};
291 push @args, $t->{log};
292 push @args, $t->{socket};
293 push @args, $t->{options} if $t->{options};
295 $exe = $consolidate_exe;
299 syslog(LOG_ERR, $exe. " ". join( ' ', @args ));
310 my $ranfor = $t->{ended} - $t->{started};
314 . $t->{task} . " for "
315 . $t->{name} . " on "
316 . $t->{device} . " ("
324 if ( $ranfor < 20 ) {
328 if ( $t->{badstarts} > 5 ) {
331 . $t->{task} . " for "
332 . $t->{name} . " on "
333 . $t->{device} . " ("
338 $t->{backoff} = time() + 5 * 60;
351 kill POSIX::SIGTERM, $t->{pid} if ( defined( $t->{pid} ) );
356 syslog( LOG_ERR, "shutting down on signal" );
363 if ( $t->{running} and ( $t->{pid} == waitpid( $t->{pid}, WNOHANG ) ) )
365 $t->{ended} = time();
371 openlog( "serialmgrd", "pid,console", LOG_LOCAL0 );
373 syslog( LOG_ERR, "starts" );
375 $stuff = get_config();
377 $stuff=resolve_users($stuff);
380 $SIG{INT} = $SIG{TERM} = \&terminate;
381 $SIG{CHLD} = \&sigchld;
389 if ( defined $t->{pid} ) {
390 if ( ( $t->{running} ) and ( kill( 0, $t->{pid} ) == 0 ) ) {
392 $t->{ended} = time();
395 if ( not $t->{running} ) {
400 if ( ( not defined( $t->{pid} ) ) and ( $t->{backoff} < $now ) ) {
407 if ( scalar(@$stuff) < 1 ) {
408 syslog( LOG_ERR, "Nothing to do - sleeping 3600s" );
413 syslog( LOG_ERR, "SIGHUP rereading config" );
416 $stuff = get_config();
418 $stuff=resolve_users($stuff);