[asterisk-commits] tilghman: trunk r114042 - /trunk/contrib/scripts/astcli
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Apr 10 14:04:30 CDT 2008
Author: tilghman
Date: Thu Apr 10 14:04:29 2008
New Revision: 114042
URL: http://svn.digium.com/view/asterisk?view=rev&rev=114042
Log:
The hydra grows yet another head...
(closes issue #12401)
Reported by: davevg
Patches:
astcli.diff2 uploaded by davevg (license 209)
Tested by: davevg, Corydon76
Modified:
trunk/contrib/scripts/astcli
Modified: trunk/contrib/scripts/astcli
URL: http://svn.digium.com/view/asterisk/trunk/contrib/scripts/astcli?view=diff&rev=114042&r1=114041&r2=114042
==============================================================================
--- trunk/contrib/scripts/astcli (original)
+++ trunk/contrib/scripts/astcli Thu Apr 10 14:04:29 2008
@@ -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 @@
#
# 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") if defined $ENV{HOME};
+GetOptions("username=s" => \$user, "secret=s" => \$pw, "host=s" => \$host, "port=s" => \$port, "readline" => \$interactive, "write" => \$save);
-process_credentials('/etc/astcli.conf');
-process_credentials("$ENV{HOME}/.astcli");
-GetOptions("username=s" => \$user, "secret=s" => \$pw, "host=s" => \$host, "port=s" => \$port);
-
+$|++; # 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;
+}
- $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 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;
+}
+
+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 @@
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 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;
}
More information about the asterisk-commits
mailing list