mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-25 07:01:09 +00:00
The hydra grows yet another head...
(closes issue #12401) Reported by: davevg Patches: astcli.diff2 uploaded by davevg (license 209) Tested by: davevg, Corydon76 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@114042 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use Net::Telnet;
|
use IO::Socket;
|
||||||
use Getopt::Long;
|
use Getopt::Long;
|
||||||
|
|
||||||
# Created by: David Van Ginneken
|
# Created by: David Van Ginneken
|
||||||
@@ -10,54 +10,104 @@ use Getopt::Long;
|
|||||||
#
|
#
|
||||||
# And distributed under the terms of the GPL
|
# And distributed under the terms of the GPL
|
||||||
#
|
#
|
||||||
my ($user, $pw, $host, $port) = (undef, undef, 'localhost', 5038);
|
my ($user, $pw, $host, $port, $interactive, $save) = (undef, undef, 'localhost', 5038, 0, 0);
|
||||||
|
my $EOL = "\r\n"; # Standard End of Line
|
||||||
process_credentials('/etc/astcli.conf');
|
process_credentials('/etc/astcli.conf');
|
||||||
process_credentials("$ENV{HOME}/.astcli");
|
process_credentials("$ENV{HOME}/.astcli") if defined $ENV{HOME};
|
||||||
GetOptions("username=s" => \$user, "secret=s" => \$pw, "host=s" => \$host, "port=s" => \$port);
|
GetOptions("username=s" => \$user, "secret=s" => \$pw, "host=s" => \$host, "port=s" => \$port, "readline" => \$interactive, "write" => \$save);
|
||||||
|
|
||||||
|
$|++; # Auto Flush Output
|
||||||
my $action = join(" ", @ARGV);
|
my $action = join(" ", @ARGV);
|
||||||
|
|
||||||
&usage if (!defined $user || !defined $pw);
|
&usage if (!defined $user || !defined $pw);
|
||||||
|
my $tc = new IO::Socket::INET(
|
||||||
|
PeerAddr => $host,
|
||||||
|
PeerPort => $port,
|
||||||
|
Timeout => 30,
|
||||||
|
Proto => 'tcp'
|
||||||
|
) or die "Could not connect to Host: $host on port $port\n";
|
||||||
|
if (my $error = login()) {
|
||||||
|
print STDERR $error;
|
||||||
|
exit 1;
|
||||||
|
};
|
||||||
|
|
||||||
my $tc = new Net::Telnet (Timeout => 10,
|
if ($save) {
|
||||||
Errmode => "die",
|
if (-d $ENV{HOME}) {
|
||||||
Host => $host,
|
open DEFAULT, ">$ENV{HOME}/.astcli";
|
||||||
Port => $port);
|
print DEFAULT "username=$user\n" if $user;
|
||||||
# Login with our username and secret.
|
print DEFAULT "password=$pw\n" if $pw;
|
||||||
$tc->open ();
|
print DEFAULT "hostname=$host\n" if $host;
|
||||||
$tc->print ("Action: Login");
|
print DEFAULT "portno=$port\n" if $port;
|
||||||
$tc->print ("Username: $user");
|
close DEFAULT;
|
||||||
$tc->print ("Secret: $pw");
|
}
|
||||||
$tc->print ("Events: off");
|
|
||||||
$tc->print ("");
|
|
||||||
# Check for login success.
|
|
||||||
my ($pre, $match) = $tc->waitfor ("/Message: .*/");
|
|
||||||
unless (($pre =~ m/Success/) && ($match =~ m/Authentication/)) {
|
|
||||||
print "Server Authentication failed.\n";
|
|
||||||
exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Send a single command to the manager connection handle (global $tc).
|
# Send a single command to the manager connection handle (global $tc).
|
||||||
# Assumes things always work well :-)
|
# Assumes things always work well :-)
|
||||||
sub send_command($) {
|
sub send_command($) {
|
||||||
my $command = shift;
|
my $command = shift;
|
||||||
|
$tc->send('Action: Command' . $EOL);
|
||||||
|
$tc->send("Command: $command" . $EOL);
|
||||||
|
$tc->send($EOL);
|
||||||
|
my $response = '';
|
||||||
|
while (<$tc>) {
|
||||||
|
last if $_ =~ /--END COMMAND--/;
|
||||||
|
$response .= $_;
|
||||||
|
}
|
||||||
|
$response =~ s/Privilege: Command$EOL//;
|
||||||
|
$response =~ s/Response: Follows$EOL//;
|
||||||
|
print $response;
|
||||||
|
}
|
||||||
|
|
||||||
$tc->print ("Action: Command");
|
sub login {
|
||||||
$tc->print ("Command: $command");
|
my ($response, $message);
|
||||||
$tc->print ("");
|
$tc->send("Action: Login" . $EOL);
|
||||||
my ($pre, undef) = $tc->waitfor ("/--END COMMAND--.*/");
|
$tc->send("Username: $user" . $EOL);
|
||||||
$pre =~ s/^\n\n//g;
|
$tc->send("Secret: $pw" . $EOL);
|
||||||
$pre =~ s/Privilege: Command\n//;
|
$tc->send("Events: off" . $EOL);
|
||||||
$pre =~ s/Response: Follows\n//;
|
$tc->send($EOL);
|
||||||
print $pre;
|
while (<$tc>) {
|
||||||
|
last if $_ eq $EOL;
|
||||||
|
$_ =~ s/$EOL//g;
|
||||||
|
($response) = $_ =~ /^Response: (.*?)$/ if $_ =~ /^Response:/;
|
||||||
|
($message) = $_ =~ /^Message: (.*?)$/ if $_ =~ /^Message:/;
|
||||||
|
}
|
||||||
|
return 0 if $response eq 'Success';
|
||||||
|
return $message;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub logoff {
|
||||||
|
my ($response, $message);
|
||||||
|
$tc->send("Action: Logoff" . $EOL . $EOL);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# If the user asked to send commands from standard input:
|
# If the user asked to send commands from standard input:
|
||||||
if ($action eq '-') {
|
if ($action eq '-' || !defined $action || $action eq '') {
|
||||||
while (<>) {
|
if ($interactive) {
|
||||||
chomp;
|
eval { require Term::ReadLine;};
|
||||||
send_command($_)
|
$interactive = scalar($@) ? 0 : 1;
|
||||||
|
print STDERR "Falling back to standard mode, Unable to load Term::Readline for readline mode\n" unless $interactive;
|
||||||
|
}
|
||||||
|
if ($interactive) {
|
||||||
|
my $term = new Term::ReadLine 'Command Line Interface';
|
||||||
|
my $prompt = "$host*CLI> ";
|
||||||
|
my $attribs = $term->Attribs;
|
||||||
|
$attribs->{completion_function} = sub {
|
||||||
|
my ($text, $line, $start) = @_;
|
||||||
|
# Stub function for tab auto completion for those feeling adventurous
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
while (defined($_ = $term->readline($prompt))) {
|
||||||
|
(logoff() and exit) if $_ =~ /exit|quit/; # Give them a way to exit the "terminal"
|
||||||
|
send_command($_);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (<>) {
|
||||||
|
chomp;
|
||||||
|
(logoff() and exit) if $_ =~ /exit|quit/; # If someone accidentally ends up here, let them exit
|
||||||
|
send_command($_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
exit 0;
|
exit 0;
|
||||||
}
|
}
|
||||||
@@ -69,7 +119,6 @@ send_command($action);
|
|||||||
sub process_credentials {
|
sub process_credentials {
|
||||||
# Process the credentials found..
|
# Process the credentials found..
|
||||||
my $file = shift;
|
my $file = shift;
|
||||||
|
|
||||||
# silently fail if we can't read the file:
|
# silently fail if we can't read the file:
|
||||||
return unless (-r $file);
|
return unless (-r $file);
|
||||||
open (my $fh, "<$file") or return;
|
open (my $fh, "<$file") or return;
|
||||||
@@ -84,8 +133,14 @@ sub process_credentials {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub usage {
|
sub usage {
|
||||||
print STDERR "astcli [-u <username> -s <passwd>] [-h host] [-p port] <cli-command>\n";
|
print STDERR "astcli [<options>] [<cli-command>|-]\n";
|
||||||
print STDERR " (command '-' - take commands from input)\n";
|
print STDERR " -u <name> - Connect as username <name>\n";
|
||||||
|
print STDERR " -s <pw> - Connect with secret <pw>\n";
|
||||||
|
print STDERR " -h <host> - Connect to host <host> [localhost]\n";
|
||||||
|
print STDERR " -p <port> - Connect on TCP port <port> [5038]\n";
|
||||||
|
print STDERR " -r - Start a readline session for interactivity\n";
|
||||||
|
print STDERR " -w - Save connection options in a configuration file\n";
|
||||||
|
print STDERR " You may specify the command as '-' to take commands from stdin.\n";
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user