Index: astcli
===================================================================
--- astcli	(revision 113923)
+++ astcli	(working copy)
@@ -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,55 +10,88 @@
 #
 # And distributed under the terms of the GPL
 #
-my ($user, $pw, $host, $port) = (undef, undef, 'localhost', 5038);
-
+my ($user, $pw, $host, $port, $interactive) = (undef, undef, 'localhost', 5038, 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, "interactive" => \$interactive);
 
+
+$|++; # 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'
+);
+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;
-}
-
 # 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 {
+	$tc->send("Action: Login" . $EOL);
+	$tc->send("Username: $user" . $EOL);
+	$tc->send("Secret: $pw" . $EOL);
+	$tc->send("Events: off" . $EOL);
+	$tc->send($EOL);
+	my $response = '';
+	my $message = '';
+	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;
 }
-
 # If the user asked to send commands from standard input:
 if ($action eq '-') {
-	while (<>) {
-		chomp;
-		send_command($_)
+	if ($interactive){
+		eval { require Term::ReadLine;};
+		$interactive = ($@?0:1);
+		print STDERR "Falling back to standard mode, Unable to load Term::Readline for interactive 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)) ) {
+			exit if $_ =~ /exit|quit/; # Give them a way to exit the "terminal"
+			send_command($_);
+		}	
+	} else {
+		while (<>) {
+			chomp;
+			send_command($_);
+		}
+	}
 	exit 0;
 }
 
@@ -69,7 +102,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,7 +116,7 @@
 }
 
 sub usage {
-	print STDERR "astcli [-u <username> -s <passwd>] [-h host] [-p port] <cli-command>\n";
+	print STDERR "astcli [-u <username> -s <passwd>] [-h host] [-p port] [-i interactive] <cli-command>\n";
 	print STDERR "       (command '-' - take commands from input)\n";
 	exit;
 }
