servderive commit fix
[freeside.git] / torrus / bin / configsnapshot.in
1 #!@PERL@
2 #  Copyright (C) 2002  Stanislav Sinyagin
3 #
4 #  This program is free software; you can redistribute it and/or modify
5 #  it under the terms of the GNU General Public License as published by
6 #  the Free Software Foundation; either version 2 of the License, or
7 #  (at your option) any later version.
8 #
9 #  This program is distributed in the hope that it will be useful,
10 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 #  GNU General Public License for more details.
13 #
14 #  You should have received a copy of the GNU General Public License
15 #  along with this program; if not, write to the Free Software
16 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
17
18 # $Id: configsnapshot.in,v 1.1 2010-12-27 00:04:01 ivan Exp $
19 # Stanislav Sinyagin <ssinyagin@yahoo.com>
20
21 BEGIN { require '@torrus_config_pl@'; }
22
23 use strict;
24 use Getopt::Long;
25
26 use Torrus::Log;
27 use Torrus::ConfigTree;
28 use Torrus::SiteConfig;
29 use Torrus::ConfigBuilder;
30
31 exit(1) if not Torrus::SiteConfig::verify();
32
33 my $tree;
34 my $help_needed;
35 my $verbose = 0;
36
37 my $outfile = 'snapshot.xml';
38
39 my $filter_param;
40 my $filter_value;
41 my $filter_op = '=';
42
43 my $creator = "Torrus version @VERSION@\n" .
44     "This file was generated by command:\n" .
45     $0 . " \\\n";
46 foreach my $arg ( @ARGV )
47 {
48     if( $arg =~ /^--/ )
49     {
50         $creator .= ' ' . $arg . ' ';
51     }
52     else
53     {
54         $creator .= "\'" . $arg . "\'\\\n";
55     }
56 }
57 $creator .= "\nOn " . scalar(localtime(time));
58
59 my $ok = GetOptions('tree=s'   => \$tree,
60                     'out=s'    => \$outfile,
61                     'param=s'  => \$filter_param,
62                     'value=s'  => \$filter_value,
63                     'op=s'     => \$filter_op,
64                     'verbose'  => \$verbose,
65                     'help'     => \$help_needed);
66
67 if( not $ok or not $tree or $help_needed or
68     ( defined($filter_param) + defined($filter_value) == 1 ) or
69     ( $filter_op ne '=' and $filter_op ne 'eq' and $filter_op ne 're' ) or
70     scalar(@ARGV) > 0 )
71 {
72     print STDERR "Usage: $0 --tree=NAME [options...]\n",
73     "Options:\n",
74     "  --tree=NAME     tree name\n",
75     "  --out=filename  output file [".$outfile."]\n",
76     "  --param=PARAM --value=VALUE \n",
77     "                  filter the output by leaves with specified value\n",
78     "  --op=OP         filter operation [=|eq|re], default: [=]\n",
79     "  --verbose       print extra information\n",
80     "  --help          this help message\n";
81     exit 1;
82 }
83
84 if( $verbose )
85 {
86     Torrus::Log::setLevel('verbose');
87 }
88
89 if( not Torrus::SiteConfig::treeExists( $tree ) )
90 {
91     Error('Tree ' . $tree . ' does not exist');
92     exit 1;
93 }
94
95 &Torrus::DB::setSafeSignalHandlers();
96
97 my $config_tree = new Torrus::ConfigTree( -TreeName => $tree, -Wait => 1 );
98 if( not defined( $config_tree ) )
99 {
100     exit 1;
101 }
102
103
104 my $filter_match = sub {return $_[0] == $filter_value};
105
106 if(defined($filter_param))
107 {
108     if( $filter_op eq 'eq' )
109     {
110         $filter_match = sub {return $_[0] eq $filter_value};
111     }
112     elsif( $filter_op eq 're' )
113     {
114         $filter_match = sub {return $_[0] =~ $filter_value};
115     }
116 }
117
118
119         
120 my $cb = new Torrus::ConfigBuilder;
121
122 $cb->addCreatorInfo( $creator );
123
124 # We don't collect views, since they are in defaults.xml which is always
125 # included
126
127 collect_monitors( $config_tree, $cb );
128 collect_tokensets( $config_tree, $cb );
129 collect_definitions( $config_tree, $cb );
130 collect_datasources( $config_tree, $cb );
131
132 my $ok = $cb->toFile( $outfile );
133 if( $ok )
134 {
135     Verbose('Wrote ' . $outfile);
136 }
137 else
138 {
139     Error('Cannot write ' . $outfile . ': ' . $!);
140 }
141
142 exit($ok ? 0:1);
143
144 sub collect_monitors
145 {
146     my $config_tree = shift;
147     my $cb = shift;
148
149     my $monitorsNode = $cb->startMonitors();
150
151     foreach my $action ( $config_tree->getActionNames() )
152     {
153         &Torrus::DB::checkInterrupted();
154         
155         my $params = $config_tree->getParams( $action );
156         $cb->addMonitorAction( $monitorsNode, $action, $params );
157     }
158
159     foreach my $monitor ( $config_tree->getMonitorNames() )
160     {
161         &Torrus::DB::checkInterrupted();
162         
163         my $params = $config_tree->getParams( $monitor );
164         $cb->addMonitor( $monitorsNode, $monitor, $params );
165     }
166 }
167
168 sub collect_tokensets
169 {
170     my $config_tree = shift;
171     my $cb = shift;
172
173     my $tsetsNode = $cb->startTokensets();
174
175     foreach my $tset ( $config_tree->getTsets() )
176     {
177         &Torrus::DB::checkInterrupted();
178         
179         my $params = $config_tree->getParams( $tset );
180         my $name = $tset;
181         $name =~ s/^S//;
182         $cb->addTokenset( $tsetsNode, $name, $params );
183     }
184 }
185
186
187 sub collect_definitions
188 {
189     my $config_tree = shift;
190     my $cb = shift;
191
192     my $definitionsNode = $cb->startDefinitions();
193
194     foreach my $defName ( sort $config_tree->getDefinitionNames() )
195     {
196         &Torrus::DB::checkInterrupted();
197
198         my $value = $config_tree->getDefinition( $defName );
199         $cb->addDefinition( $definitionsNode, $defName, $value );
200     }
201
202     my $propsNode = $cb->startParamProps();
203     my $props = $config_tree->getParamProperties();
204
205     &Torrus::DB::checkInterrupted();
206
207     foreach my $prop ( sort keys %{$props} )
208     {
209         foreach my $param ( sort keys %{$props->{$prop}} )
210         {
211             $cb->addParamProp( $propsNode, $param, $prop,
212                                $props->{$prop}{$param} );
213         }
214     }
215 }
216
217
218 my %filterTokens;
219
220
221 sub collect_datasources
222 {
223     my $config_tree = shift;
224     my $cb = shift;
225     
226     my $topNode = $cb->getTopSubtree();
227     my $topToken = $config_tree->token('/');
228     
229     my $params = prepare_params( $config_tree, $topToken );
230     $cb->addParams( $topNode, $params );
231
232     if( defined($filter_param) )
233     {
234         $filterTokens{$topToken} = apply_filter( $config_tree, $topToken );
235     }
236     
237     collect_subtrees( $config_tree, $cb, $topToken, $topNode );
238 }
239         
240
241
242 sub apply_filter
243 {
244     my $config_tree = shift;
245     my $token = shift;
246
247     $filterTokens{$token} = 0;
248     
249     foreach my $ctoken ( $config_tree->getChildren( $token ) )
250     {
251         &Torrus::DB::checkInterrupted();
252         
253         if( $config_tree->isSubtree( $ctoken ) )
254         {
255             $filterTokens{$token} += apply_filter( $config_tree, $ctoken );
256         }
257         elsif( $config_tree->isLeaf( $ctoken ) )
258         {
259             my $val = $config_tree->getNodeParam( $ctoken, $filter_param );
260             if( defined($val) and &{$filter_match}($val) )
261             {
262                 $filterTokens{$ctoken} = 1;
263                 $filterTokens{$token}++;
264             }                
265         }
266     }
267
268     return $filterTokens{$token};
269 }
270         
271
272
273 sub collect_subtrees
274 {
275     my $config_tree = shift;
276     my $cb = shift;
277     my $token = shift;
278     my $parentNode = shift;
279     
280     foreach my $ctoken ( $config_tree->getChildren( $token ) )
281     {
282         &Torrus::DB::checkInterrupted();
283         
284         if( not defined($filter_param) or $filterTokens{$ctoken} )
285         {
286             my $childName =
287                 $config_tree->nodeName( $config_tree->path($ctoken) );
288             my $params = prepare_params( $config_tree, $ctoken );
289         
290             if( $config_tree->isSubtree( $ctoken ) )
291             {
292                 my $subtreeNode =
293                     $cb->addSubtree( $parentNode, $childName, $params );
294                 collect_subtrees( $config_tree, $cb, $ctoken, $subtreeNode );
295             }
296             elsif( $config_tree->isLeaf( $ctoken ) )
297             {
298                 $cb->addLeaf( $parentNode, $childName, $params );
299             }
300             
301             foreach my $aliasToken ( $config_tree->getAliases( $ctoken ) )
302             {
303                 $cb->addAlias( $parentNode,
304                                $config_tree->path( $aliasToken ) );
305             }
306         }
307     }
308 }
309
310
311 sub prepare_params
312 {
313     my $config_tree = shift;
314     my $token = shift;
315     
316     my $params = $config_tree->getParams( $token, 1 );
317
318     # Remove linebreaks
319     while( my( $param, $value ) = each %{$params} )
320     {
321         $value =~ s/\s+/ /gm;
322         $params->{$param} = $value;
323     }
324
325     return $params;
326 }
327
328 # Local Variables:
329 # mode: perl
330 # indent-tabs-mode: nil
331 # perl-indent-level: 4
332 # End: