use Socket; use strict; use POSIX qw(setsid); my @hosts = ('foo.com', 'bar.org'); my $host; my $kidpid; # daemonize the program &daemonize; foreach $host (@hosts){ sshPush( $host ); } sub sshPush { my $host = shift; my $cmd = "/opt/local/bin/hg push --ssh \"/opt/local/bin/ossh -i /path/to/id_dsa\" ssh://UserName@".$host."/TWiki"; chdir '/path/to/TWiki' or die "Can't chdir to /: $!"; if (TryConnect( $host )) { if (!defined($kidpid = fork())) { # fork returned undef, so failed die "cannot fork: $!"; } elsif ($kidpid == 0) { # fork returned 0, so this branch is the child exec($cmd); # if the exec fails, fall through to the next statement die "can't exec push: $!"; } } chdir '/' or die "Can't chdir to /: $!"; } sub TryConnect { my $port = 22; my $host = shift || 'localhost'; my $iaddr; if (!($iaddr = inet_aton($host))) { return 0; } my $paddr = sockaddr_in($port, $iaddr); my $result; eval { local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required alarm 7; socket(SOCK, &AF_INET, &SOCK_STREAM, 0) || die "socket: $!"; $result = connect(SOCK, $paddr); close(SOCK); alarm 0; }; if ($@) { die "$@" unless $@ eq "alarm\n"; # timed out } return $result; } sub daemonize { chdir '/' or die "Can't chdir to /: $!"; open STDIN, '/dev/null' or die "Can't read /dev/null: $!"; open STDOUT, '>>/zstore/timpush.log' or die "Can't write to /dev/null: $!"; open STDERR, '>>/zstore/timpush.log' or die "Can't write to /dev/null: $!"; defined(my $pid = fork) or die "Can't fork: $!"; exit if $pid; setsid or die "Can't start a new session: $!"; umask 0; }