source: A2P/a2p/A2P/BackEnd.pm @ 3

Last change on this file since 3 was 3, checked in by guillaume, 17 years ago
  • AUTHORS: Ajout des différents contributeurs
  • COPYING: Ajout de la licence GPL v3
  • a2p: Préparation des sources pour leur publication sous GPL
  • Property svn:keywords set to Id
File size: 5.9 KB
Line 
1#
2# Copyright (c) 2004-2007 - Consultas, PKG.fr
3#
4# This file is part of A2P.
5#
6# A2P is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# A2P is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with A2P; if not, write to the Free Software
18# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19#
20# $Id: BackEnd.pm 3 2007-10-18 16:20:19Z guillaume $
21#
22
23package A2P::BackEnd ;
24
25# Derived class from Thread.pm
26use base qw(A2P::Thread);
27
28use strict ;
29use integer ;
30use Time::HiRes qw( usleep ) ;
31use A2P::Globals ;
32use A2P::Syslog ;
33use A2P::Com qw( IsCom comJOB comZIP comFILE );
34
35BEGIN {
36    our $VERSION = sprintf "%s", q$Rev: 955 $ =~ /(\d[0-9.]+)\s+/ ;
37}
38our $VERSION ;
39
40################################################################################
41##             BackEnd code                                                   ##
42################################################################################
43sub Do {
44    my $self = shift ;
45    my $ref  = shift ;
46
47    my $Ret = 0 ;
48
49    my @Job = &IsCom( comJOB , $$ref );
50
51    if ( @Job == 2 ) {
52        my ( $Job , $Cmd ) = @Job ;
53
54        my ( $SigPipe , $SigChild ) = ( 0 , 0 );
55        $SIG{PIPE}  = sub { $SigPipe  ++ ; };
56        $SIG{CHILD} = sub { $SigChild ++ ; };
57
58        my $ThisCmdId = sprintf("%s-T%sCMD%03d", $Job, $$, $self->{CmdIndex});
59        $self->{CmdIndex} = 1 if ( ++ $self->{CmdIndex} > 999 );
60        &Debug("Set Id $ThisCmdId to this command");
61
62        # Keep internal stats
63        &UPSTAT('CMD-EXEC');
64
65        my $try = 0 ;
66
67        if ( @Job = &IsCom( comZIP , $Cmd ) ) {
68            # If we are cleaning making a zip file, we should process differen-
69            # tly as file list to zip can be too long for zip command line
70
71            my $command = 'zip -@' .
72                ( $COMPRESSFILES ?
73                    ( $COMPRESSFILES > 0 and
74                        $COMPRESSFILES <= 9 ? $COMPRESSFILES : 1 ) : 0 ) .
75                $ZIPOPTIONS . ' ' . $Job[0] ;
76
77            &Debug("Setting $ThisCmdId to '$command'");
78
79            my @files = split( /(?<=file>)(?=<file)/, $Job[1] );
80
81            if ( @files ) {
82                &Debug("Sending '$Job[1]' to $ThisCmdId zip process");
83                if (defined(open(*CMD , '|' . $command))) {
84                    local $\ = "\n" ;
85                    foreach my $rawfile ( @files ) {
86                        my $file = "" ;
87                        unless (( $file ) = &IsCom( comFILE , $rawfile )) {
88                            $self->ThisError("Bad file format in file list '" .
89                                $Job[1] ."'");
90                            $Ret = 260 ; # Ret will be evaluated to 5 later
91                            last ;
92                        }
93                        unless ( $file and print CMD $file ) {
94                            $self->ThisError("Can't send '$file' to " .
95                                $ThisCmdId . " zip command: $! $?");
96                            $Ret = 257 ; # Ret will be evaluated to 2 later
97                            last ;
98                        }
99                    }
100                    close(CMD);
101
102                } else {
103                    $self->ThisError("Can't open $ThisCmdId: $!");
104                    $Ret = 258 ; # Ret will be evaluated to 3 later
105                }
106
107            } else {
108                $self->ThisError("Bad to zip list format in '$Job[1]'");
109                $Ret = 259 ; # Ret will be evaluated to 4 later
110            }
111
112        } else {
113            &Debug("Starting $ThisCmdId");
114
115            # Try to do command
116            my $timeout = time + $BACKEND_RETRYTIMEOUT ;
117            while ( $try ++ < $BACKEND_RETRY ) {
118                $! = 0 ;
119                # Don't retry if command returns as expected
120                last unless ( $Ret = system( $Cmd ) );
121                &Debug("Try #$try '$Cmd' as it returned $Ret ($!)");
122                &UPSTAT('CMD-EXEC-ERR-'.$Ret);
123                last if ( time > $timeout );
124                usleep $try * $USLEEP ;
125            }
126        }
127
128        if ($Ret) {
129            # update try to real count
130            $try -- ;
131
132            &Warn("$Job: $ThisCmdId core dumped") if ($Ret & 128);
133            &Info("$Job: $ThisCmdId received signal " . ($Ret & 127))
134                if ($Ret & 127);
135            $Ret = $Ret >> 8 ;
136            $self->ThisError("$ThisCmdId returned with value $Ret after " .
137                $try . ($try<2?" try":" tries").(($!)?": '$!'":""));
138
139            # Keep internal stats
140            &UPSTAT('CMD-EXEC-FAILED');
141            $STATS{'CMD-EXEC-LAST-FAILED'} = $Job . ': ' . $Cmd ;
142
143        } else {
144            &Debug("$ThisCmdId received signal " . ($Ret & 127))
145                if ($Ret & 127);
146            $Ret = DONE ;
147
148            # Keep internal stats
149            &UPSTAT('CMD-EXEC-DONE');
150
151        }
152
153        &Debug("SIGPIPE received: $! $? $@") if $SigPipe ;
154        wait ;
155        &Debug("SIGCHLD received: $! $? $@") if $SigChild ;
156
157        &Debug("$ThisCmdId status = " .
158            (defined($means{$Ret}) ? $means{$Ret} : $Ret));
159        $self->Return( $Job , $Ret );
160        $self->AnswerDone( $Job );
161
162    } else {
163        $self->ThisError("Got bad command request '$$ref'");
164
165        $Ret = 9 ;
166
167        if (@Job) {
168            # Return exec status even for bad format to not break job processing
169            $self->Return( $Job[0] , $Ret );
170            $self->AnswerDone( $Job[0] );
171        }
172
173        # Keep internal stats
174        &UPSTAT('BA-CMD-FORMAT');
175    }
176
177    return $Ret == DONE ? 1 : 0 ;
178}
179
180sub ThreadInit {
181    $_[0]->{CmdIndex} = 1 ;
182}
183
184&Debug("Module " . __PACKAGE__ . " v$VERSION loaded");
185
1861;
Note: See TracBrowser for help on using the repository browser.