Merge "sip_to_pjsip: Write media_encryption."
[asterisk/asterisk.git] / contrib / scripts / astcli
1 #!/usr/bin/perl -w
2
3 use strict;
4 use IO::Socket;
5 use Getopt::Long;
6
7 # Created by: David Van Ginneken
8 # Bird's the Word Technologies
9 # davevg@btwtech.com
10 #
11 # And distributed under the terms of the GPL
12 #
13 my ($user, $pw, $host, $port, $interactive, $save) = (undef, undef, 'localhost', 5038, 0, 0);
14 my $EOL = "\r\n"; # Standard End of Line
15 my @commands;
16 process_credentials('/etc/astcli.conf');
17 process_credentials("$ENV{HOME}/.astcli") if defined $ENV{HOME};
18 GetOptions("username=s" => \$user, "secret=s" => \$pw, "host=s" => \$host, "port=s" => \$port, "readline" => \$interactive, "write" => \$save);
19
20 $|++; # Auto Flush Output
21 my $action = join(" ", @ARGV);
22
23 &usage if (!defined $user || !defined $pw);
24 my $tc = new IO::Socket::INET(
25                 PeerAddr => $host,
26                 PeerPort => $port,
27                 Timeout => 30,
28                 Proto => 'tcp'
29 ) or die "Could not connect to Host: $host on port $port\n";
30 if (my $error = login()) {
31         print STDERR $error;
32         exit 1;
33 };
34
35 if ($save) {
36         if (-d $ENV{HOME}) {
37                 open DEFAULT, ">$ENV{HOME}/.astcli";
38                 print DEFAULT "username=$user\n" if $user;
39                 print DEFAULT "password=$pw\n" if $pw;
40                 print DEFAULT "hostname=$host\n" if $host;
41                 print DEFAULT "portno=$port\n" if $port;
42                 close DEFAULT;
43         }
44 }
45
46 # Send a single command to the manager connection handle (global $tc).
47 # Assumes things always work well :-)
48 sub send_command($) {
49         my $command = shift;
50         $tc->send('Action: Command' . $EOL);
51         $tc->send("Command: $command" . $EOL);
52         $tc->send($EOL);
53         my $response = '';
54         while (<$tc>) {
55                 if ($_ =~ /--END COMMAND--/) {
56                         $_ =~ s/--END COMMAND--\s*//;
57                         $response .= $_;
58                         last;
59                 }
60                 $response .= $_;
61         }
62         $response =~ s/Privilege: Command$EOL//;
63         $response =~ s/Response: Follows$EOL//;
64         return $response;
65 }
66
67 sub login {
68         my ($response, $message);
69         $tc->send("Action: Login" . $EOL);
70         $tc->send("Username: $user" . $EOL);
71         $tc->send("Secret: $pw" . $EOL);
72         $tc->send("Events: off" . $EOL);
73         $tc->send($EOL);
74         while (<$tc>) {
75                 last if $_ eq $EOL;
76                 $_ =~ s/$EOL//g;
77                 ($response) = $_ =~ /^Response: (.*?)$/ if $_ =~ /^Response:/;
78                 ($message) = $_ =~ /^Message: (.*?)$/ if $_ =~ /^Message:/;
79         }
80         return 0 if $response eq 'Success';
81         return $message;
82 }
83
84 sub logoff {
85         my ($response, $message);
86         $tc->send("Action: Logoff" . $EOL . $EOL);
87         return 1;
88 }
89
90 # If the user asked to send commands from standard input:
91 if ($action eq '-' || !defined $action || $action eq '') {
92         if ($interactive) {
93                 eval { require Term::ReadLine;};
94                 $interactive = scalar($@) ? 0 : 1;
95                 print STDERR "Falling back to standard mode, Unable to load Term::Readline for readline mode\n" unless $interactive;
96         }
97         if ($interactive) {
98                 my $term = new Term::ReadLine 'Command Line Interface';
99                 my $prompt = "$host*CLI> ";
100                 my $attribs = $term->Attribs;
101                 $attribs->{completion_function} = \&tab_completion;
102                 while (defined($_ = $term->readline($prompt))) {
103                         (logoff() and exit) if $_ =~ /exit|quit/; # Give them a way to exit the "terminal"
104                         print send_command($_) if $_ !~ m/^\s*$/;
105                 }       
106         } else {
107                 while (<>) {
108                         chomp;
109                         (logoff() and exit) if $_ =~ /exit|quit/; # If someone accidentally ends up here, let them exit
110                         print send_command($_);
111                 }
112         }
113         exit 0;
114 }
115
116 # Otherwise just send the command:
117 print send_command($action);
118
119 # parses a configuration file into the global $user and $pw.
120 sub process_credentials {
121         # Process the credentials found..
122         my $file = shift;
123         # silently fail if we can't read the file:
124         return unless (-r $file);
125         open (my $fh, "<$file") or return;
126         while (<$fh>) {
127                 chomp;
128                 (undef,$user) = split(/[,=]/, $_) if $_ =~ /user(name)?[,=]/i;
129                 (undef,$pw) = split(/[,=]/, $_) if $_ =~ /(secret|passw(or)?d|pwd?)[,=]/i;
130                 (undef,$host) = split(/[,=]/, $_) if $_ =~ /host(name)?[,=]/i;
131                 (undef,$port) = split(/[,=]/, $_) if $_ =~ /port(num|no)?[,=]/i;
132         }
133         close ($fh);
134 }
135
136 sub usage {
137         print STDERR "astcli [<options>] [<cli-command>|-]\n";
138         print STDERR "       -u <name> - Connect as username <name>\n";
139         print STDERR "       -s <pw>   - Connect with secret <pw>\n";
140         print STDERR "       -h <host> - Connect to host <host> [localhost]\n";
141         print STDERR "       -p <port> - Connect on TCP port <port> [5038]\n";
142         print STDERR "       -r        - Start a readline session for interactivity\n";
143         print STDERR "       -w        - Save connection options in a configuration file\n";
144         print STDERR "   You may specify the command as '-' to take commands from stdin.\n";
145         exit;
146 }
147
148 sub tab_completion {
149     my ($word, $buffer, $offset) = @_;
150         my %items;
151         my $lastword = '';
152         if ($word eq '') {
153                 $buffer =~ m/(\S+)\s?$/;
154                 $lastword = $1;
155                 #print STDERR "\n\nlastword=\"$lastword\"\n";
156         }
157
158         my $res = send_command("_command matchesarray \"$buffer\" \"$word\"");
159         foreach my $item (split /\s+/, $res) {
160                 $items{$item}++ unless ($item eq '_EOF_' or $item eq '' or $item eq $lastword);
161         }
162                 
163         #print STDERR "\nword=\"$word\" buffer=\"$buffer\" offset=\"$offset\" res=\"$res\"\n";
164
165         return sort keys %items;
166 }
167