diff options
author | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-04-10 19:04:29 +0000 |
---|---|---|
committer | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-04-10 19:04:29 +0000 |
commit | b64b1c598733aa853e3d7e80dd110017fdca647e (patch) | |
tree | 4d19d0f5ed6b454b1f470e4b4ad5ff5a97d1d26e /contrib | |
parent | 76c6b355080abf62df0b523f7c942c7131154f55 (diff) |
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: http://svn.digium.com/svn/asterisk/trunk@114042 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'contrib')
-rwxr-xr-x | contrib/scripts/astcli | 127 |
1 files changed, 91 insertions, 36 deletions
diff --git a/contrib/scripts/astcli b/contrib/scripts/astcli index ed942eeed..cf0ebdf15 100755 --- a/contrib/scripts/astcli +++ b/contrib/scripts/astcli @@ -1,7 +1,7 @@ #!/usr/bin/perl -w use strict; -use Net::Telnet; +use IO::Socket; use Getopt::Long; # Created by: David Van Ginneken @@ -10,54 +10,104 @@ use Getopt::Long; # # 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("$ENV{HOME}/.astcli"); -GetOptions("username=s" => \$user, "secret=s" => \$pw, "host=s" => \$host, "port=s" => \$port); +process_credentials("$ENV{HOME}/.astcli") if defined $ENV{HOME}; +GetOptions("username=s" => \$user, "secret=s" => \$pw, "host=s" => \$host, "port=s" => \$port, "readline" => \$interactive, "write" => \$save); +$|++; # Auto Flush Output my $action = join(" ", @ARGV); &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, - Errmode => "die", - Host => $host, - Port => $port); -# Login with our username and secret. -$tc->open (); -$tc->print ("Action: Login"); -$tc->print ("Username: $user"); -$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; +if ($save) { + if (-d $ENV{HOME}) { + open DEFAULT, ">$ENV{HOME}/.astcli"; + print DEFAULT "username=$user\n" if $user; + print DEFAULT "password=$pw\n" if $pw; + print DEFAULT "hostname=$host\n" if $host; + print DEFAULT "portno=$port\n" if $port; + close DEFAULT; + } } # Send a single command to the manager connection handle (global $tc). # Assumes things always work well :-) sub send_command($) { 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; +} + +sub login { + my ($response, $message); + $tc->send("Action: Login" . $EOL); + $tc->send("Username: $user" . $EOL); + $tc->send("Secret: $pw" . $EOL); + $tc->send("Events: off" . $EOL); + $tc->send($EOL); + 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; +} - $tc->print ("Action: Command"); - $tc->print ("Command: $command"); - $tc->print (""); - my ($pre, undef) = $tc->waitfor ("/--END COMMAND--.*/"); - $pre =~ s/^\n\n//g; - $pre =~ s/Privilege: Command\n//; - $pre =~ s/Response: Follows\n//; - print $pre; +sub logoff { + my ($response, $message); + $tc->send("Action: Logoff" . $EOL . $EOL); + return 1; } # If the user asked to send commands from standard input: -if ($action eq '-') { - while (<>) { - chomp; - send_command($_) +if ($action eq '-' || !defined $action || $action eq '') { + if ($interactive) { + eval { require Term::ReadLine;}; + $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; } @@ -69,7 +119,6 @@ send_command($action); sub process_credentials { # Process the credentials found.. my $file = shift; - # silently fail if we can't read the file: return unless (-r $file); open (my $fh, "<$file") or return; @@ -84,8 +133,14 @@ sub process_credentials { } sub usage { - print STDERR "astcli [-u <username> -s <passwd>] [-h host] [-p port] <cli-command>\n"; - print STDERR " (command '-' - take commands from input)\n"; + print STDERR "astcli [<options>] [<cli-command>|-]\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; } |