ljr/ljcom/bin/ljrpc

165 lines
3.8 KiB
Perl
Executable File

#!/usr/bin/perl -w
#
# LiveJournal Remote Procedure Call Client (ljrpc)
# Copyright 2001 Dormando (dormando@rydia.net)
# Going to add a license (GPL?) later.
#
#
# This client runs commands you give it at the prompt through the RPC
# system. By default, first it sends out a 'ping', then sends the
# command to any machine that replies to it. Prints out replies it
# gets, too. It can also be invoked with --now, in which case it
# broadcasts the command and exits immediately.
#
# <LJDEP>
# lib: IO::Socket, Getopt::Long
# </LJDEP>
use strict;
use IO::Socket;
use Getopt::Long;
use constant SEC_SLAVE_WAIT => 4;
use lib "$ENV{'LJHOME'}/cgi-bin";
require "ljconfig.pl";
$SIG{CHLD} = 'IGNORE';
my $MAXLEN = 512;
my $PORTNO = 6100;
if ($LJ::BCAST_ADDR) { } # shutup warning
my $bcastaddr = $LJ::BCAST_ADDR || '10.0.0.255';
my ($cmdmsg, $remhost, @hosts);
### option processing
my $timeout = 0;
my $quick = 0;
my $server = "web";
my $ping = 0;
my $delay = 0;
my $serialized = 0;
exit 1 unless
GetOptions('timeout=i' => \$timeout,
'now' => \$quick,
'server=s' => \$server,
'ping' => \$ping,
'serialized|s' => \$serialized,
'dest=s' => \$bcastaddr,
'delay|d=i' => \$delay,
);
my $msg = "@ARGV";
$msg = "cmd: " . $msg;
# Creat socket. Shoot the broadcast off.
my $sock = IO::Socket::INET->new(Proto => 'udp') or die "Creating socket: $!\n";
$sock->sockopt(SO_BROADCAST, 1);
my $ipaddr = inet_aton($bcastaddr);
my $portaddr = sockaddr_in($PORTNO, $ipaddr);
print STDERR "Broadcasting.\n";
if ($quick) {
$sock->send($msg, 0, $portaddr) or die "send: $!\n";
exit 0;
} else {
$sock->send("marco $server", 0, $portaddr) or die "send: $!\n";
}
my $count = 0;
$| = 1;
# First loop, grabs machines that are up.
my %mark;
if ($server eq "web") {
open (O, "$ENV{LJHOME}/cgi-bin/pool_int_web.txt");
while (<O>) {
chomp;
$mark{$_} = 1;
}
close O;
}
eval {
local $SIG{ALRM} = sub { die "timeout" };
alarm(SEC_SLAVE_WAIT);
while ($sock->recv($cmdmsg, $MAXLEN)) {
my ($port, $ipaddr) = sockaddr_in($sock->peername);
$remhost = gethostbyaddr($ipaddr, AF_INET) || "";
my $remip = inet_ntoa($ipaddr);
if ($cmdmsg eq "pollo") {
alarm(SEC_SLAVE_WAIT);
$count++;
print "$count: $remhost [$remip]\n";
delete $mark{$remip};
push(@hosts, $remhost);
}
}
alarm(0);
};
print "\n";
if ($ping) {
print "Unreported int_web nodes:\n" if %mark;
foreach (keys %mark) {
print " $_\n";
}
exit;
}
if ($serialized) {
foreach my $host (@hosts) {
printf "Sending: %-30s", "$host ...";
my $ipaddr = inet_aton($host);
my $portaddr = sockaddr_in($PORTNO, $ipaddr);
if ($sock->send($msg, 0, $portaddr)) {
print "sent.\n";
} else {
print "failed.\n";
}
if ($delay) {
sleep $delay;
} else {
$sock->recv($cmdmsg, $MAXLEN);
my ($port, $remipaddr) = sockaddr_in($sock->peername);
$remhost = gethostbyaddr($remipaddr, AF_INET);
print "Server $remhost:\n===============================\n";
print $cmdmsg;
print "\n\n";
}
}
exit;
}
foreach my $host (@hosts) {
printf "Sending: %-30s", "$host ...";
my $ipaddr = inet_aton($host);
my $portaddr = sockaddr_in($PORTNO, $ipaddr);
if ($sock->send($msg, 0, $portaddr)) {
print "sent.\n";
} else {
print "failed.\n";
}
sleep $timeout;
}
print "\n\n";
# Loop receiving command stuffs.
for (my $i = 0; $i < @hosts; $i++) {
$sock->recv($cmdmsg, $MAXLEN);
my ($port, $ipaddr) = sockaddr_in($sock->peername);
$remhost = gethostbyaddr($ipaddr, AF_INET);
# Parse thing.
print "Server $remhost:\n===============================\n";
print $cmdmsg;
print "\n\n";
}