source: A2P/a2p/A2P/Infos.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: 8.8 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: Infos.pm 3 2007-10-18 16:20:19Z guillaume $
21#
22# Class to report any usefull information
23#
24
25package A2P::Infos ;
26
27use strict;
28use A2P::Globals ;
29use A2P::Globals qw( get_default_lockid );
30use A2P::Syslog ;
31use A2P::Init ;
32use A2P::Init qw( ResetInit );
33
34BEGIN {
35    our $VERSION = sprintf "%s", q$Rev: 1185 $ =~ /(\d[0-9.]+)\s+/ ;
36}
37our $VERSION ;
38
39sub new {
40    my $class  = shift ;
41    my $self = {
42       LOCKID_LIST  => []
43       } ;
44    bless $self , $class ;
45    &Debug("new ".__PACKAGE__." object v$VERSION created");
46    return $self ;
47}
48
49my $default_lockid = &get_default_lockid() ;
50my $config ;
51
52sub _get_local_servicename {
53    my $lockid = shift ;
54    my $service = shift ;
55
56    my @confs ;
57    my @found = () ;
58
59    # If one more argument, it's directly the local service name
60    if (defined($service)) {
61        @confs = ( '/etc/afp2print/' . $service . '.conf' ) ;
62
63    } else {
64        # Get all local configuration files
65        @confs = glob( '/etc/afp2print/*.conf' ) ;
66    }
67
68    foreach my $conf (@confs) {
69        my ( $name ) = $conf =~ m|^/etc/afp2print/([^/]+)\.conf$| ;
70        # Skip other configurations
71        next if ( $name =~ /^destid|documents|afpds2tex|stat|e-service/ );
72
73        &Debug("Checking '$conf' configuration") if ($ADVANCED_DEBUGGING);
74
75        # Initialize Init module
76        &ResetInit ;
77        &Init( "$A2P_SYS_CONF" , $conf );
78
79        # Requested values must be specified here
80        my @env = &Init(
81            '$TEXSPOOL'       => '',
82            '$AFPSPOOL'       => '',
83            '$ERRORSPOOL'     => '',
84            '$DONESPOOL'      => '',
85            '$LOCKID'         => $default_lockid,
86            '$SCAN_SPOOL'     => 0,
87            '$KEEP_JOBSTATUS' => 0
88            );
89        my %env = () ;
90        foreach my $env ( @env ) {
91            $env =~ s|ENV\{(\w+)\}|env{$1}| ;
92            eval $env ;
93        }
94
95        next unless ( $env{LOCKID} eq $lockid
96            and $env{SCAN_SPOOL} and $env{KEEP_JOBSTATUS});
97
98        &Debug("Service '$name' uses '$env{LOCKID}' LOCKID")
99             if ($ADVANCED_DEBUGGING);
100
101        # Keep config for other API
102        $config = \%env ;
103
104        push @found, $name ;
105    }
106
107    return @found ;
108}
109
110sub _recursive_serviceid_table_check {
111    my $ref = shift ;
112    my $depth = shift || 0 ;
113    return &Error("Not a hash ref at depth $depth in services id list")
114        unless (ref($ref) =~ /^HASH/);
115    if ($depth<2) {
116        map {
117            unless(&_recursive_serviceid_table_check($ref->{$_},$depth+1)) {
118            delete $ref->{$_} ;
119            &Error("Key '$_' deleted at depth $depth in services id list");
120            }
121        } keys(%{$ref}) ;
122
123    } elsif (!exists($ref->{serviceid}) or !defined($ref->{serviceid})
124        or !$ref->{serviceid}) {
125            return &Error("'serviceid' key not found");
126    }
127    return scalar(keys(%{$ref})) ;
128}
129
130sub get_lockid_list {
131    return @{$_[0]->{LOCKID_LIST}} ;
132}
133
134sub get_serviceid_of {
135    my $self = shift ;
136    my $object = shift ;
137
138    my $lockids = $self->{LOCKID} ;
139    $lockids = $self->{LOCKID} = {} unless (defined($lockids));
140
141    # Services table is transmitted by A2P::DB as hash to initialize our list
142    if (ref($object) =~ /^HASH/) {
143        if (&_recursive_serviceid_table_check($object)) {
144            my @services = () ;
145            $self->{LOCKID_ERROR} = 0 ;
146
147            # Scan hash to get any (lockid,serviceid) pair
148            foreach my $name (keys(%{$object})) {
149                foreach my $lockid (keys(%{$object->{$name}})) {
150                    my $serviceid =
151                        exists($object->{$name}->{$lockid}->{serviceid})
152                        ?
153                        $object->{$name}->{$lockid}->{serviceid}
154                        :
155                        &Error("No serviceid found for '$name-$lockid'")
156                        ;
157                    #&Debug("Keeping serviceid $serviceid for '$name-$lockid'");
158                    push @services, [ $lockid , $serviceid , $name ] ;
159                }
160            }
161
162            # Scan each pair to get conflicting ones
163            while (@services) {
164                my ( $lockid, $serviceid, $name ) = @{ shift @services } ;
165                my @match = () ;
166                if (@match = grep { $_->[0] eq $lockid } @services) {
167                    &Debug("Found services with same LOCKID for this server");
168
169                    # 0. Still strip conflicting from list
170                    @services = grep { $_->[0] ne $lockid } @services ;
171
172                    # 1. Search available LOCKID in local configurations
173                    my @localname = &_get_local_servicename($lockid);
174                    if (!@localname) {
175                        &Debug("No local service with $lockid LOCKID found, skipping it");
176                        next ;
177
178                    } elsif (@localname == 1 and $localname[0] eq $name) {
179                        # This lockid is in fact the only one used today, so
180                        # just remove the others
181                        &Debug("Found '$lockid' is managed by service '$name'");
182
183                    } elsif (@localname == 1) {
184                        # Only local service really use this lockid but it should
185                        # be in @match others list
186                        my @realone = grep { $_->[2] eq $localname[0] } @match ;
187                        &Debug("Not installed locally"),next unless (@realone);
188                        &Debug("Found '$lockid' is managed by service '$localname[0]'");
189                        &Warn("Found many local service '$name-$lockid', please update your confs")
190                            if (@realone>1);
191                        ( $lockid, $serviceid, $name ) = @{$realone[0]} ;
192
193                    } else {
194                        # Found many local running service with the same LOCKID, we need to
195                        # say something is bad in configurations
196                        &Warn("Bad server configuration found: ".
197                            "many service seems to have the same LOCKID",
198                            "So I will associating serviceid $serviceid to only service $name",
199                            "You should check configuration files, and set different LOCKID for each one",
200                            map { "'$_' service configuration is to check"} @localname
201                            );
202                    }
203                }
204
205                if ( ! defined($lockids->{$lockid}) or
206                    $lockids->{$lockid} != $serviceid ) {
207                    &Debug("Setting serviceid to $serviceid for lockid $lockid as service $name");
208                    $lockids->{$lockid} = $serviceid ;
209                }
210            }
211
212            # Update lockid list
213            $self->{LOCKID_LIST} = [ keys(%{$lockids}) ] ;
214
215            # And return ourself
216            return $self ;
217
218        } else {
219            return &Error("No serviceid table found in '$object'");
220        }
221
222    }
223
224    return (defined($lockids->{$object}) and $lockids->{$object}) ?
225        $lockids->{$object} : 0 ;
226}
227
228sub get_servicename_of {
229    my $self = shift ;
230    my @name = &_get_local_servicename(@_) ;
231    my $name = shift @name ;
232    return '' unless ( defined($name) and $name );
233    #&Debug("Servicename of '@_' is '$name'");
234    return $name ;
235}
236
237sub get_afpspool_of {
238    my $self = shift ;
239    my $lockid = shift ;
240    my $service = shift || 'afpds2tex' ;
241    my @name = &_get_local_servicename($lockid,$service) ;
242    my $name = shift @name ;
243    return &Error("No conf found for $service service (Got '$name')")
244        unless ( $name eq $service );
245    #&Debug("Servicename of '@_' is '$name'");
246    return exists($config->{'AFPSPOOL'}) ? $config->{'AFPSPOOL'} :
247        &Error("AFPSPOOL not found for $service service") ;
248}
249
250sub get_spools_of {
251    my $self = shift ;
252    my $lockid = shift ;
253    my $service = shift || 'afpds2tex' ;
254    my @name = &_get_local_servicename($lockid,$service) ;
255    my $name = shift @name ;
256    return &Error("No conf found for $service service (Got '$name')")
257        unless ( $name eq $service );
258    #&Debug("Servicename of '@_' is '$name'");
259    return map { exists($config->{$_}) ? $config->{$_} : '' }
260        qw( DONESPOOL ERRORSPOOL ) ;
261}
262
263&Debug("Module " . __PACKAGE__ . " v$VERSION loaded");
264
2651;
266
Note: See TracBrowser for help on using the repository browser.