Let's also include aclocal.m4
[asterisk-bristuff.git] / contrib / scripts / managerproxy.pl
blobcdf79a239e8b916a55f4c0691844802822d6c335
1 #!/usr/bin/perl -w
3 # Simple Asterisk Manager Proxy, Version 1.01
4 # 2004-09-26
5 # Copyright (c) 2004 David C. Troy <dave@popvox.com>
7 # This code is based on Flash Operator Panel 'op_server.pl'
8 # by Nicolas Gudino
9 #  Copyright (C) 2004.
11 # David C. Troy <dave@popvox.com>
12 # Nicolas Gudino <nicolas@house.com.ar>
14 # This program is free software, distributed under the terms of
15 # the GNU General Public License.
17 # Security consideration: This script will open your manager port
18 # for unauthenticated logins. Be careful out there :-)
19 #############################
21 #############################
22 # Perl Prerequisites
23 #############################
24 use strict;
25 use IO::Socket;
26 use IO::Select;
27 use POSIX qw(setsid);
29 #############################
30 # User Configurable Options
31 #############################
32 # Configuration for logging in to your asterisk server
33 # Check you Asterisk config file "manager.conf" for details
34 my $manager_host = '127.0.0.1';
35 my $manager_port = 5038;
36 my $manager_user = 'your_username';
37 my $manager_secret = 'your_secret';
38 # Port For this proxy
39 my $listen_port = 1234;
40 my $manager_pid = "/var/run/asterisk_managerproxy.pid";
42 #############################
43 # Declarations
44 #############################
45 my %proxy_clients;
46 my $O;
47 my $p;
48 my @S;
49 my %blocks;
50 my $debug = 0;
52 $SIG{PIPE} = 'IGNORE';
53 $SIG{INT} = 'close_all';
54 $SIG{USR1} = 'list_clients';
56 if (defined($ARGV[0]))
58 if ($ARGV[0] eq "-d")
60 defined(my $pid = fork) or die "Can't Fork: $!";
61 exit if $pid;
62 setsid or die "Can't start a new session: $!";
63 open MYPIDFILE, ">$manager_pid";
64 print MYPIDFILE $$;
65 close MYPIDFILE;
67 } else {
68 $debug = 1;
72 # Connect to manager
73 $p =
74 new IO::Socket::INET->new(
75 PeerAddr => $manager_host,
76 PeerPort => $manager_port,
77 Proto => "tcp",
78 Type => SOCK_STREAM
80 or die "\nCould not connect to Asterisk Manager Port at $manager_host\n";
82 $p->autoflush(1);
84 # Login to Manager
85 send_command_to_manager( "Action: Login\r\nUsername: $manager_user\r\nSecret: $manager_secret\r\n\r\n" );
87 # Start up listener for new connections
88 my $m =
89 new IO::Socket::INET(Listen => 1, LocalPort => $listen_port, ReuseAddr => 1)
90 or die "\nCan't listen to port $listen_port\n";
91 $O = new IO::Select();
92 $O->add($m);
93 $O->add($p);
94 $/ = "\0";
96 sub manager_reconnect()
98 my $attempt = 1;
99 my $total_attempts = 60;
103 log_debug("** Attempt reconnection to manager port # $attempt", 16);
104 $p =
105 new IO::Socket::INET->new(
106 PeerAddr => $manager_host,
107 PeerPort => $manager_port,
108 Proto => "tcp",
109 Type => SOCK_STREAM
111 $attempt++;
112 if ($attempt > $total_attempts)
114 die("!! Could not reconnect to Asterisk Manager port");
116 sleep(10); # wait 10 seconds before trying to reconnect
117 } until $p;
118 $O->add($p);
119 send_command_to_manager(
120 "Action: Login\r\nUsername: $manager_user\r\nSecret: $manager_secret\r\n\r\n"
124 # Loop, continuously processing new connections, input from those connections, and input from Manager conn
125 while (1)
127 while (@S = $O->can_read)
129 foreach (@S)
131 if ($_ == $m)
133 log_debug("** New client connection", 16);
134 my $C = $m->accept;
135 $proxy_clients{$C} = \$C;
136 print "New Connection: $C\n" if $debug;
137 $O->add($C);
138 } else {
139 # It's not a new client connection
140 my $i;
141 my $R = sysread($_, $i, 2); # 2048; interleave every two bytes?
142 if (defined($R) && $R == 0)
144 # Confirm it's really dead by trying to write to it?
145 my $T = syswrite($_, ' ', 2); # 2048
146 if (!defined($T))
148 # connection went away...
149 $O->remove($_);
150 $_->close;
152 # If we lost the socket for the Asterisk Mgr, then reconnect
153 if ($_ == $p)
155 log_debug(
156 "** Asterisk Manager connection lost!!!!!",
157 16);
158 manager_reconnect();
159 } else {
160 # Remove handle from proxy_clients hash
161 print "Closed Connection: $_\n" if $debug;
162 delete $proxy_clients{$_};
166 else # Socket is active and we are ready to read something from it
168 $blocks{$_} .= $i;
169 next if ($blocks{$_} !~ /\r\n\r\n$/);
170 # do a 'next' unless we have completed a block; we are not ready to continue
172 # Process the completed block
173 # If block is from asterisk, send to clients
174 if ($_ == $p) {
175 # block is from asterisk, send to clients
176 print "asterisk: $_\n$blocks{$_}" if $debug;
177 my $cnt = 0;
178 foreach my $client (values %proxy_clients) {
179 print "writing to $$client...\n" if $debug;
180 syswrite($$client, $blocks{$_});
181 $cnt++;
183 print "sent block to $cnt clients\n" if $debug;
184 } else {
185 # Blocks are from clients, send to asterisk
186 syswrite($p, $blocks{$_});
187 print "client: $_\n$blocks{$_}\n" if $debug;
189 delete $blocks{$_};
191 } # end if read succeeded
192 } # end if new client connection
193 } # end foreach @S -> can read
194 } # while can read
195 } # endless loop
197 sub close_all
199 log_debug("Exiting...", 0);
201 foreach my $hd ($O->handles)
203 $O->remove($hd);
204 close($hd);
207 exit(0);
210 sub send_command_to_manager
212 my $comando = shift;
213 if (defined $p)
215 my @lineas = split("\r\n", $comando);
216 foreach my $linea (@lineas)
218 syswrite($p, "$linea\r\n");
219 log_debug("-> $linea", 2);
221 log_debug(" ", 2);
222 syswrite($p, "\r\n");
226 sub log_debug
228 my $texto = shift;
229 $texto =~ s/\0//g;
230 print "$texto\n" if $debug;
233 sub list_clients()
235 my $cnt = 0;
236 foreach my $client (values %proxy_clients) {
237 print "client: $$client\n";
238 $cnt++;
240 print "$cnt clients.\n\n";