# # Copyright (c) 2004-2007 - Consultas, PKG.fr # # This file is part of A2P. # # A2P is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # A2P is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with A2P; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # $Id: Client.pm 3 2007-10-18 16:20:19Z guillaume $ # # WARN SIGALRM is used to check time out, # so remember it can override a client definition package A2P::Client; use strict ; use Socket ; use IO::Socket ; use Time::HiRes qw(ualarm gettimeofday tv_interval); use A2P::Globals ; use A2P::Syslog ; use A2P::Com qw( IsCom GetCom comJOB comREQ comCOM comDONE comASK comUPD GetTmpFile comTEST ); use A2P::Tools qw( ShortID ); BEGIN { use Exporter () ; our ( $VERSION , @ISA , @EXPORT ); $VERSION = sprintf "%s", q$Rev: 415 $ =~ /(\d[0-9.]+)\s+/ ; @ISA = qw(Exporter); @EXPORT = qw(&TellListener &DoJob); } our $VERSION ; # Set OUTPUT_AUTOFLUSH $| = 1 ; # Last argument to TellListener can be a sub callback sub TellListener { my $which = shift ; $LISTENER = &GetTmpFile( $which . '-listener' ); my $callback = pop if ( ref($_[$#_]) =~ /^CODE$/ ); my @Default = ( "NO RESPONSE" ); my @Response = (); my $timer = [ &gettimeofday() ] ; my $shutdown = 0 ; my $response = 0 ; return ( "SERVICE NOT AVAILABLE" ) if ( ! -S $LISTENER ); return ( "NOTHING TO TELL" ) unless @_ ; $SIG{ALRM} = sub { # Check my time out return unless ( &tv_interval($timer) > $CLIENT_TIMEOUT ); push @Default , "TIME OUT" ; $shutdown ++ ; shutdown SOCK , 2 ; }; # Use ualarm to be advertize to check time-out &ualarm( 1000000 , 1000000 ); socket(SOCK, PF_UNIX, SOCK_STREAM, 0) or die "Can't open a socket: $!" ; SOCK->autoflush(1); connect(SOCK, pack_sockaddr_un($LISTENER)) or die "Can't connect to $LISTENER socket: $!" ; my $Question = &GetCom( comREQ , TODO , &GetCom( comASK , @_ )); &Debug("Asking '" . $Question . "' to $which service listener"); local $\ = "\n" ; # Talk now with service if ( print SOCK $Question ) { while ( my $line = ) { chomp $line ; next unless $line ; my @content = &IsCom( comCOM , $line ); my $info = @content ? $content[1] : $line ; # Update my time-out timer $timer = [ &gettimeofday() ] ; # Will leave loop if server answer COM is DONE, but keeping info if ( @content = &IsCom( comDONE , $info ) ) { $info = $content[1] ; } elsif ( $info =~ /^\d+$/ and $info == comTEST ) { print SOCK &GetCom( comCOM , $$ , comDONE ); next ; } # Call back to client if requested defined($callback) ? &$callback($info) : push @Response, $info ; $response ++ ; last if ( @content and $content[0] =~ /^done$/ ); } } &ualarm(0); @Response = @Default unless $response ; map { &Debug("Listener response: '" . $_ . "'") } @Response ; shutdown SOCK , 2 unless $shutdown ; return @Response ; } sub JustOutPut { local $\ = "\n" ; print @_ ; } sub DoJob { my $which = shift ; my $file = shift ; print "\nStarting job with [$which] service and '$file' file...\n"; # Find an suitable Id for the job my ( $jid ) = $file =~ m|.*/(.+)(\.\w+)?$| ; ( $jid ) = $file =~ m|/?(\w+)(\.\w+)+$| unless (defined($jid)); $jid = "JOB" . &ShortID(5) unless (defined($jid)); if ( $which and $file and $jid ) { print "A2P JobID = $jid\n" ; &TellListener( $which, JobManager => &GetCom( comJOB , $jid => $file ), \&JustOutPut ); } else { print "But it's impossible when an argument is missing\n" ; print "Tell me which service to ask as first argument\n" unless $which ; print "Tell me which file to compute as second argument\n" unless $file ; print "I can't compute Job ID with '$file'\n" unless $jid ; } } sub DoUpdate { my $service = shift ; my $module = shift ; my $varname = shift ; my $value = shift ; #print "\nUpdating value $varname on [$which-$module] service...\n"; if ( $service and $module and $varname and defined($value) ) { &TellListener( $service, $module => &GetCom( comUPD , $varname => $value ), \&JustOutPut ); } else { print "But it's impossible when an argument is missing\n" ; #print "Tell me which service to ask as first argument\n" unless $which ; #print "Tell me which file to compute as second argument\n" unless $file ; #print "I can't compute Job ID with '$file'\n" unless $jid ; } } &Debug("Module " . __PACKAGE__ . " v$VERSION loaded") unless ( $0 =~ /cgi/ ); 1;