|
|
Hi,
as announced yesterday here is my way of executing remotely commands
on a Windows machine:
- Win32ForkServer.pl
- Win32Client.pl
#----------------------------------------------------------
# Name : Win32ForkServer.pl
# Author : Axel Mock
#
# Description:
# PERL script implementing the socket server for the RCMD service
# on Windows Remote Target Compile machines allowing commands to be
# executed on that machine from a remote client.
# Specialty: DOES FORKING using Win32 PERL Pseudo-Fork (PERL
threads)
# one time directly using fork and another time indirectly using IO:PIPE
# for capturing the output.
#
# Should be installed on the target as a service using
# srvany.exe and instsrv.exe from the Windows Resource Kit
#
#
#
#----------------------------------------------------------
use IO::Socket;
use IO::Pipe;
use IO::Select;
use POSIX 'WNOHANG';
use Net::hostent;
use constant PORT => 2222;
my $DEBUG;
sub TimeStamp {
my (@t) = localtime (time());
#$dt becomes DDMMYYhhmmss
return (sprintf ("%02d-%02d-%04d %02d:%02d:%02d", $t[3],$t[4]+1,
$t[5]+1900, $t[2],$t[1], $t[0]));
}
sub interact {
my ($sock) = shift;
# part of child process
$sock->autoflush (1);
while (defined ($request = <$sock>)) {
# do something with $buf ....
if ($request =~ /exec:(.+)/ ) {
$request = $1;
print STDERR "\t\t\tRequest: $request\n" if $DEBUG;
my ($pipe) = new IO::Pipe;
$pipe->reader ("$request 2>&1");
while ($line = <$pipe>) {
print $sock $line;
}
$answer = "\n\n$request .. handled\n";
print $sock $answer;
}
else {
print $sock "\n\nUnknown request: $request ..handled\n" if
$DEBUG;
}
}
return (0);
}
sub ReapChildren {
while ( waitpid (-1, WNOHANG) > 0) {} ;
}
# ---------- M A I N ------------
if (scalar (@ARGV) > 0) {
$DEBUG = grep (/^-D\s*(\d*)?$/i, @ARGV);
}
# Signal handler for CHILD process
$SIG{CHLD} = sub { ReapChildren () };
$listen_socket = new IO::Socket::INET (LocalPort => PORT,
Listen => 20,
Proto => 'tcp',
Reuse => 1,
Timeout
=> 60*60,
);
unless ($listen_socket) {
die "Listening socket could not be created. Reason: $@\n";
}
$listen_socket->blocking (0); # make the socket non-blocking
my $listener = IO::Select->new ($listen_socket);
warn ("Server started, Listening on port " . PORT. "\n") if $DEBUG;
while (1) {
my $ready = $listener->can_read;
if ($ready) {
next unless (my $client = $listen_socket->accept());
$client->blocking (1);
ReapChildren ();
# print STDERR "Connect \n";
defined (my $child = fork ()) || (die "Cannot fork: $!");
if ($child == 0) {
$listen_socket->close;
my $hostinfo = gethostbyaddr($client->peeraddr);
my $hostname = $hostinfo->name || $client-
>peerhost;
$msg = sprintf "[%s # Connect from %s (%s:%4d)
]\n", TimeStamp (), $hostname, $client->peerhost, $client->peerport;
print STDERR $msg if $DEBUG;
my $result = interact ($client);
$msg = sprintf "[%s # Closing %s:%4d ]\n",
TimeStamp (), $client->peerhost, $client->peerport;
print STDERR $msg if $DEBUG;
exit (0);
}
# parent process does not need this connection, so close it
$client->close ();
}
else {
sleep ();
}
}
# main server finishes : close the socket
close ($listen_socket);
__END__
#----------------------------------------------------------
# Name : Win32Client.pl
# Author : Axel Mock
#
# Description:
# PERL script implementing the socket client for the RCMD service.
# To be used interactively for testing purposes.
#
#
#----------------------------------------------------------
use IO::Socket;
my ($request, $answer);
unless (@ARGV > 1) {
die "usage: $0 host $request ..."
}
$host = shift(@ARGV);
$request = join (' ', @ARGV);
$remote = IO::Socket::INET->new( Proto => "tcp",
PeerAddr
=> $host,
PeerPort
=> 2222,
);
unless ($remote) {
die "cannot connect to server port 2222 daemon on $host"
}
$remote->autoflush(1);
#setsockopt ($remote, IPPROTO_TCP, TCP_NODELAY, 1);
print "requesting : $request\n";
print $remote "exec: $request\n";
while (1) {
if (defined ($answer = <$remote>) ) {
print $answer;
if ($answer =~ /\.\.\s*handled/) {
last ();
}
}
else {
sleep (1);
}
}
close $remote;
__END__
Usage:
Install Win32ForkServer via InstSrv / InstAny on the remote machine.
Do NOT forget to open the corresponding port in the Windows firewall.
For test
Run Win32Client on the controlling machine:
perl win32client remotemachine COMMAND
e.g.
perl win32client 192.168.10.25 dir C:\W*
Please postpone any questions to next week...
Good luck,
Axel
----------------------------------------------------------------------
S y s K o n n e c t G m b H
A Marvell Company
Siemensstr. 23
D-76275 Ettlingen
----------------------------------------------------------------------
Axel Mock
Software Engineer
phone: +49 7243 502 319
fax: +49 7243 502 931
email: amock@xxxxxxxxxxxxx
http://www.syskonnect.de
-----------------------------------------------------------------------
_______________________________________________
ActivePerl mailing list
ActivePerl@xxxxxxxxxxxxxxxxxxxxxxxx
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
|
|