Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Duncan White
client-server-runcommand
Commits
40b46a3f
Commit
40b46a3f
authored
Nov 30, 2017
by
Duncan White
Browse files
first version..
parents
Changes
3
Hide whitespace changes
Inline
Side-by-side
README
0 → 100644
View file @
40b46a3f
The need came up to run a particular performance gathering
command on a server as root, but record the output somewhere
else.
Sounds like a very simple client/server. So here I've adapted
the pre-existing raspberry-pi-phonehome listener daemon to be a
command-listener. The command is a variable inside the script
of course.
In addition, I wrote a very simple cat-client that connects to
a server (like telnet) and grabs the output..
cat-client
0 → 100755
View file @
40b46a3f
#!/usr/bin/perl
use
strict
;
use
warnings
;
use
Data::
Dumper
;
use
IO::
Socket
;
my
$host
=
shift
@ARGV
||
"
146.169.22.26
";
# shell4..
my
$port
=
shift
@ARGV
||
55001
;
#
# my $socket = connect_server();
# connect to our server (trying several times if
# necessary), return the socket we receive.
# In case of repeated failure, return undef.
#
sub
connect_server
()
{
warn
"
trying to connect to
$host
:
$port
\n
";
foreach
(
1
..
5
)
{
my
$socket
=
new
IO::Socket::
INET
('
PeerAddr
'
=>
$host
,
'
PeerPort
'
=>
$port
,
'
Proto
'
=>
'
tcp
');
return
$socket
if
$socket
;
warn
"
trying again...
\n
";
sleep
1
;
}
return
undef
;
}
my
$socket
=
connect_server
();
die
"
can't connect to
$host
:
$port
\n
"
unless
$socket
;
warn
"
connected to
$host
..
\n
";
while
(
<
$socket
>
)
{
print
;
}
command-listener
0 → 100755
View file @
40b46a3f
#!/usr/bin/perl
#
# command-listener: daemon that listens for a connection on a
# port and runs a single specific command, sending the
# results of running that command back to the client.
#
use
strict
;
use
warnings
;
use
Data::
Dumper
;
use
IO::
Socket
;
use
POSIX
'
WNOHANG
';
use
csglib::
Log
;
# important constants
# think about logging later..
my
$logfile
=
"
/tmp/command-listener.log
";
# command to run..
my
$command
=
"
/bin/date
";
# example:-)
my
$port
=
shift
@ARGV
||
55001
;
my
$quit
=
0
;
my
$log
=
new
csglib::
Log
(
scriptname
=>
"
command-listener
",
file
=>
$logfile
,
level
=>
LOG_INFO
)
||
die
"
command-listener: can't create
$logfile
\n
";
#
# my $socket = initialize_listener( $port );
# start listening server on port $port..
# return the socket we receive. In case of
# total failure, return undef.
#
sub
initialize_listener
($)
{
my
(
$port
)
=
@_
;
# signal handler for child die events
$SIG
{
CHLD
}
=
sub
{
while
(
waitpid
(
-
1
,
WNOHANG
)
>
0
)
{}
};
# signal handle for being interrupted
$SIG
{
INT
}
=
sub
{
$quit
++
};
$log
->
info
(
"
trying to listen on port
$port
"
);
foreach
(
1
..
5
)
{
my
$socket
=
new
IO::Socket::
INET
(
'
LocalPort
'
=>
$port
,
'
Listen
'
=>
20
,
'
Proto
'
=>
'
tcp
',
'
Reuse
'
=>
1
,
'
Timeout
'
=>
3600
);
return
$socket
if
$socket
;
$log
->
info
(
"
trying again...
"
);
sleep
1
;
}
return
undef
;
}
#
# connection_loop( $listensocket, $callback );
# take the listening socket $listensocket
# and a callback function $callback.
# forever wait for connections, forking
# a child for each connection, and making
# the child call the callback function $callback
# to handle one conversation with one client.
#
sub
connection_loop
($$)
{
my
(
$listensocket
,
$callback
)
=
@_
;
while
(
!
$quit
)
{
next
unless
my
$conn
=
$listensocket
->
accept
;
defined
(
my
$child
=
fork
())
||
$log
->
fatal
(
"
can't fork: $!
"
);
if
(
$child
==
0
)
# child
{
$listensocket
->
close
;
my
$peer
=
getpeername
(
$conn
);
my
(
$port
,
$iaddr
)
=
sockaddr_in
(
$peer
);
my
$peerhostname
=
gethostbyaddr
(
$iaddr
,
AF_INET
);
my
$peeraddr
=
inet_ntoa
(
$iaddr
);
$log
->
info
(
"
accepted connection from
$peeraddr
, host
$peerhostname
"
);
STDIN
->
fdopen
(
$conn
,'
<
')
||
$log
->
fatal
(
"
can't reopen STDIN: $!
"
);
STDOUT
->
fdopen
(
$conn
,'
>
')
||
$log
->
fatal
(
"
can't reopen STDOUT: $!
"
);
#STDERR->fdopen($conn,'>') ||
# $log->fatal( "can't reopen STDERR: $!" );
$|
=
1
;
# auto flush
$callback
->
();
exit
0
;
}
$conn
->
close
;
}
}
#
# converse();
# handle one client<->server conversation,
# there's no from-client data needed (if there was,
# it would be on STDIN), simply run $command which
# will produce output on STDOUT, which will be
# automatically sent back to the client.
#
sub
converse
()
{
system
(
$command
);
}
# stage 1: initialize the listener
my
$socket
=
initialize_listener
(
$port
);
$log
->
fatal
(
"
can't create listening socket
$port
"
)
unless
$socket
;
# stage 2: connection loop
$log
->
warn
(
"
server listening on port
$port
, ready for connections
"
);
connection_loop
(
$socket
,
\
&converse
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment