/[webpac2]/trunk/run.pl
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/run.pl

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 389 by dpavlin, Sun Jan 22 13:38:17 2006 UTC revision 790 by dpavlin, Wed Dec 13 10:08:27 2006 UTC
# Line 4  use strict; Line 4  use strict;
4    
5  use Cwd qw/abs_path/;  use Cwd qw/abs_path/;
6  use File::Temp qw/tempdir/;  use File::Temp qw/tempdir/;
 use Data::Dumper;  
7  use lib './lib';  use lib './lib';
8    
9  use WebPAC::Common 0.02;  use WebPAC::Common 0.02;
10  use WebPAC::Lookup;  use WebPAC::Parser 0.08;
11  use WebPAC::Input 0.03;  use WebPAC::Input 0.16;
12  use WebPAC::Store 0.03;  use WebPAC::Store 0.14;
13  use WebPAC::Normalize::XML;  use WebPAC::Normalize 0.22;
14  use WebPAC::Output::TT;  use WebPAC::Output::TT;
15  use WebPAC::Output::Estraier 0.08;  use WebPAC::Validate 0.06;
16  use YAML qw/LoadFile/;  use WebPAC::Output::MARC;
17    use WebPAC::Config;
18  use Getopt::Long;  use Getopt::Long;
19  use File::Path;  use File::Path;
20  use Time::HiRes qw/time/;  use Time::HiRes qw/time/;
21    use File::Slurp;
22    use Data::Dump qw/dump/;
23    use Storable qw/dclone/;
24    use Pod::Usage qw/pod2usage/;
25    
26    use Proc::Queue size => 1;
27    use POSIX ":sys_wait_h"; # imports WNOHANG
28    
29  =head1 NAME  =head1 NAME
30    
# Line 25  run.pl - start WebPAC indexing Line 32  run.pl - start WebPAC indexing
32    
33  B<this command will probably go away. Don't get used to it!>  B<this command will probably go away. Don't get used to it!>
34    
35  Options:  =head1 OPTIONS
36    
37  =over 4  =over 4
38    
# Line 41  limit loading to 100 records Line 48  limit loading to 100 records
48    
49  remove database and Hyper Estraier index before indexing  remove database and Hyper Estraier index before indexing
50    
51  =item --one=database_name  =item --only=database_name/input_filter
52    
53    reindex just single database (legacy name is --one)
54    
55  reindex just single database  C</input_filter> is optional part which can be C<name>
56    or C<type> from input
57    
58  =item --config conf/config.yml  =item --config conf/config.yml
59    
60  path to YAML configuration file  path to YAML configuration file
61    
62    =item --stats
63    
64    disable indexing, modify_* in configuration and dump statistics about field
65    and subfield usage for each input
66    
67    =item --validate path/to/validation_file
68    
69    turn on extra validation of imput records, see L<WebPAC::Validation>
70    
71    =item --marc-lint
72    
73    By default turned on if normalisation file has C<marc*> directives. You can disable lint
74    messages with C<--no-marc-lint>.
75    
76    =item --marc-dump
77    
78    Force dump or input and marc record for debugging.
79    
80    =item --parallel 4
81    
82    Run databases in parallel (aproximatly same as number of processors in
83    machine if you want to use full load)
84    
85    =item --only-links
86    
87    Create just links
88    
89    =item --merge
90    
91    Create merged index of databases which have links
92    
93  =back  =back
94    
95  =cut  =cut
# Line 57  my $offset; Line 98  my $offset;
98  my $limit;  my $limit;
99    
100  my $clean = 0;  my $clean = 0;
101  my $config = 'conf/config.yml';  my $config_path;
102  my $debug = 0;  my $debug = 0;
103  my $one_db_name;  my $only_filter;
104    my $stats = 0;
105    my $validate_path;
106    my $marc_lint = 1;
107    my $marc_dump = 0;
108    my $parallel = 0;
109    my $only_links = 0;
110    my $merge = 0;
111    my $help;
112    
113    my $log = _new WebPAC::Common()->_get_logger();
114    
115  GetOptions(  GetOptions(
116          "limit=i" => \$limit,          "limit=i" => \$limit,
117          "offset=i" => \$offset,          "offset=i" => \$offset,
118          "clean" => \$clean,          "clean" => \$clean,
119          "one=s" => \$one_db_name,          "one=s" => \$only_filter,
120          "config" => \$config,          "only=s" => \$only_filter,
121          "debug" => \$debug,          "config" => \$config_path,
122            "debug+" => \$debug,
123            "stats" => \$stats,
124            "validate=s" => \$validate_path,
125            "marc-lint!" => \$marc_lint,
126            "marc-dump!" => \$marc_dump,
127            "parallel=i" => \$parallel,
128            "only-links!" => \$only_links,
129            "merge" => \$merge,
130            "help" => \$help,
131  );  );
132    
133  $config = LoadFile($config);  pod2usage(-verbose => 2) if ($help);
134    
135    my $config = new WebPAC::Config( path => $config_path );
136    
137    #print "config = ",dump($config) if ($debug);
138    
139    die "no databases in config file!\n" unless ($config->databases);
140    
141    $log->info( "-" x 79 );
142    
143    my $log_file = 'log';
144    
145    if (-e $log_file ) {    # && -s $log_file > 5 * 1024 * 1024) {
146            $log->info("moved old log with ", -s $log_file, " bytes to '${log_file}.old'");
147            rename $log_file, "${log_file}.old" || $log->logwarn("can't rename $log_file to ${log_file}.old: $!");
148    }
149    
150    my $estcmd_fh;
151    my $estcmd_path = './estcmd-merge.sh';
152    if ($merge) {
153            open($estcmd_fh, '>', $estcmd_path) || $log->logdie("can't open $estcmd_path: $!");
154            print $estcmd_fh 'cd /data/estraier/_node/ || exit 1',$/;
155            print $estcmd_fh 'sudo /etc/init.d/hyperestraier stop',$/;
156            $log->info("created merge batch file $estcmd_path");
157    }
158    
159    
160    my $validate;
161    $validate = new WebPAC::Validate(
162            path => $validate_path,
163    ) if ($validate_path);
164    
165    
166    my $use_indexer = $config->use_indexer;
167    $stats ||= $validate;
168    if ($stats) {
169            $log->debug("disabled indexing for stats collection");
170            $use_indexer = undef;
171    } else {
172            $log->info("using $use_indexer indexing engine...");
173    }
174    
175  print "config = ",Dumper($config) if ($debug);  # parse normalize files and create source files for lookup and normalization
176    
177  die "no databases in config file!\n" unless ($config->{databases});  my $parser = new WebPAC::Parser( config => $config );
178    
179  my $total_rows = 0;  my $total_rows = 0;
180  my $start_t = time();  my $start_t = time();
181    
182  while (my ($database, $db_config) = each %{ $config->{databases} }) {  my @links;
183    
184          next if ($one_db_name && $database !~ m/$one_db_name/i);  if ($parallel) {
185            $log->info("Using $parallel processes for speedup");
186            Proc::Queue::size($parallel);
187    }
188    
189    sub create_ds_config {
190            my ($db_config, $database, $input, $mfn) = @_;
191            my $c = dclone( $db_config );
192            $c->{_} = $database || $log->logconfess("need database");
193            $c->{_mfn} = $mfn || $log->logconfess("need mfn");
194            $c->{input} = $input || $log->logconfess("need input");
195            return $c;
196    }
197    
198    while (my ($database, $db_config) = each %{ $config->databases }) {
199    
200            my ($only_database,$only_input) = split(m#/#, $only_filter) if ($only_filter);
201            next if ($only_database && $database !~ m/$only_database/i);
202    
203            if ($parallel) {
204                    my $f=fork;
205                    if(defined ($f) and $f==0) {
206                            $log->info("Created processes $$ for speedup");
207                    } else {
208                            next;
209                    }
210            }
211    
212            my $indexer;
213            if ($use_indexer && $parser->have_rules( 'search', $database )) {
214    
215                    my $cfg_name = $use_indexer;
216                    $cfg_name =~ s/\-.*$//;
217    
218                    my $indexer_config = $config->get( $cfg_name ) || $log->logdie("can't find '$cfg_name' part in confguration");
219                    $indexer_config->{database} = $database;
220                    $indexer_config->{clean} = $clean;
221                    $indexer_config->{label} = $db_config->{name};
222    
223                    # force clean if database has links
224                    $indexer_config->{clean} = 1 if ($db_config->{links});
225    
226                    if ($use_indexer eq 'hyperestraier') {
227    
228                            # open Hyper Estraier database
229                            use WebPAC::Output::Estraier '0.10';
230                            $indexer = new WebPAC::Output::Estraier( %{ $indexer_config } );
231                    
232                    } elsif ($use_indexer eq 'hyperestraier-native') {
233    
234                            # open Hyper Estraier database
235                            use WebPAC::Output::EstraierNative;
236                            $indexer = new WebPAC::Output::EstraierNative( %{ $indexer_config } );
237    
238                    } elsif ($use_indexer eq 'kinosearch') {
239    
240                            # open KinoSearch
241                            use WebPAC::Output::KinoSearch;
242                            $indexer_config->{clean} = 1 unless (-e $indexer_config->{index_path});
243                            $indexer = new WebPAC::Output::KinoSearch( %{ $indexer_config } );
244    
245                    } else {
246                            $log->logdie("unknown use_indexer: $use_indexer");
247                    }
248    
249                    $log->logide("can't continue without valid indexer") unless ($indexer);
250            }
251    
         my $log = _new WebPAC::Common()->_get_logger();  
252    
253          #          #
254          # open Hyper Estraier database          # store Hyper Estraier links to other databases
255          #          #
256            if (ref($db_config->{links}) eq 'ARRAY' && $use_indexer) {
257                    foreach my $link (@{ $db_config->{links} }) {
258                            if ($use_indexer eq 'hyperestraier') {
259                                    if ($merge) {
260                                            print $estcmd_fh 'sudo -u www-data estcmd merge ' . $database . ' ' . $link->{to},$/;
261                                    } else {
262                                            $log->info("saving link $database -> $link->{to} [$link->{credit}]");
263                                            push @links, sub {
264                                                    $log->info("adding link $database -> $link->{to} [$link->{credit}]");
265                                                    $indexer->add_link(
266                                                            from => $database,
267                                                            to => $link->{to},
268                                                            credit => $link->{credit},
269                                                    );
270                                            };
271                                    }
272                            } else {
273                                    $log->warn("NOT IMPLEMENTED WITH $use_indexer: adding link $database -> $link->{to} [$link->{credit}]");
274                            }
275                    }
276            }
277            next if ($only_links);
278    
         my $est_config = $config->{hyperestraier} || $log->logdie("can't find 'hyperestraier' part in confguration");  
         $est_config->{database} = $database;  
         $est_config->{clean} = $clean;  
   
         my $est = new WebPAC::Output::Estraier( %{ $est_config } );  
279    
280          #          #
281          # now WebPAC::Store          # now WebPAC::Store
# Line 101  while (my ($database, $db_config) = each Line 283  while (my ($database, $db_config) = each
283          my $abs_path = abs_path($0);          my $abs_path = abs_path($0);
284          $abs_path =~ s#/[^/]*$#/#;          $abs_path =~ s#/[^/]*$#/#;
285    
286          my $db_path = $config->{webpac}->{db_path} . '/' . $database;          my $db_path = $config->webpac('db_path');
287    
288          if ($clean) {          if ($clean) {
289                  $log->info("creating new database $database in $db_path");                  $log->info("creating new database '$database' in $db_path");
290                  rmtree( $db_path ) || $log->warn("can't remove $db_path: $!");                  rmtree( $db_path ) || $log->warn("can't remove $db_path: $!");
291          } else {          } else {
292                  $log->info("working on $database in $db_path");                  $log->info("working on database '$database' in $db_path");
293          }          }
294    
295          my $db = new WebPAC::Store(          my $store = new WebPAC::Store(
296                  path => $db_path,                  path => $db_path,
                 database => $database,  
297                  debug => $debug,                  debug => $debug,
298          );          );
299    
# Line 130  while (my ($database, $db_config) = each Line 311  while (my ($database, $db_config) = each
311                  $log->info("database $database doesn't have inputs defined");                  $log->info("database $database doesn't have inputs defined");
312          }          }
313    
         my @supported_inputs = keys %{ $config->{webpac}->{inputs} };  
   
314          foreach my $input (@inputs) {          foreach my $input (@inputs) {
315    
316                    my $input_name = $input->{name} || $log->logdie("input without a name isn't valid: ",dump($input));
317    
318                    next if ($only_input && ($input_name !~ m#$only_input#i && $input->{type} !~ m#$only_input#i));
319    
320                  my $type = lc($input->{type});                  my $type = lc($input->{type});
321    
322                  die "I know only how to handle input types ", join(",", @supported_inputs), " not '$type'!\n" unless (grep(/$type/, @supported_inputs));                  die "I know only how to handle input types ", join(",", $config->webpac('inputs') ), " not '$type'!\n" unless (grep(/$type/, $config->webpac('inputs')));
323    
324                  my $lookup = new WebPAC::Lookup(                  my $input_module = $config->webpac('inputs')->{$type};
325                          lookup_file => $input->{lookup},  
326                  );                  my @lookups = $parser->have_lookup_create($database, $input);
327    
328                  my $input_module = $config->{webpac}->{inputs}->{$type};                  $log->info("working on input '$input_name' in $input->{path} [type: $input->{type}] using $input_module",
329                            @lookups ? " creating lookups: ".join(", ", @lookups) : ""
330                    );
331    
332                  $log->info("working on input $input->{path} [$input->{type}] using $input_module");                  if ($stats) {
333                            # disable modification of records if --stats is in use
334                            delete($input->{modify_records});
335                            delete($input->{modify_file});
336                    }
337    
338                  my $input_db = new WebPAC::Input(                  my $input_db = new WebPAC::Input(
339                          module => $input_module,                          module => $input_module,
340                          code_page => $config->{webpac}->{webpac_encoding},                          encoding => $config->webpac('webpac_encoding'),
341                          limit => $limit || $input->{limit},                          limit => $limit || $input->{limit},
342                          offset => $offset,                          offset => $offset,
343                          lookup => $lookup,                          recode => $input->{recode},
344                            stats => $stats,
345                            modify_records => $input->{modify_records},
346                            modify_file => $input->{modify_file},
347                  );                  );
348                  $log->logdie("can't create input using $input_module") unless ($input);                  $log->logdie("can't create input using $input_module") unless ($input);
349    
350                    if (defined( $input->{lookup} )) {
351                            $log->warn("$database/$input_name has depriciated lookup definition, removing it...");
352                            delete( $input->{lookup} );
353                    }
354    
355                    my $lookup_coderef;
356    
357                    if (@lookups) {
358    
359                            my $rules = $parser->lookup_create_rules($database, $input) || $log->logdie("no rules found for $database/$input");
360    
361                            $lookup_coderef = sub {
362                                    my $rec = shift || die "need rec!";
363                                    my $mfn = $rec->{'000'}->[0] || die "need mfn in 000";
364    
365                                    WebPAC::Normalize::data_structure(
366                                            row => $rec,
367                                            rules => $rules,
368                                            config => create_ds_config( $db_config, $database, $input, $mfn ),
369                                    );
370    
371                                    #warn "current lookup: ", dump(WebPAC::Normalize::_get_lookup());
372                            };
373    
374                            WebPAC::Normalize::_set_lookup( undef );
375    
376                            $log->debug("created lookup_coderef using:\n$rules");
377    
378                    };
379    
380                    my $lookup_jar;
381    
382                  my $maxmfn = $input_db->open(                  my $maxmfn = $input_db->open(
383                          path => $input->{path},                          path => $input->{path},
384                          code_page => $input->{encoding},        # database encoding                          code_page => $input->{encoding},        # database encoding
385                  );                          lookup_coderef => $lookup_coderef,
386                            lookup => $lookup_jar,
387                            %{ $input },
388                            load_row => sub {
389                                    my $a = shift;
390                                    return $store->load_row(
391                                            database => $database,
392                                            input => $input_name,
393                                            id => $a->{id},
394                                    );
395                            },
396                            save_row => sub {
397                                    my $a = shift;
398                                    return $store->save_row(
399                                            database => $database,
400                                            input => $input_name,
401                                            id => $a->{id},
402                                            row => $a->{row},
403                                    );
404                            },
405    
                 my $n = new WebPAC::Normalize::XML(  
                 #       filter => { 'foo' => sub { shift } },  
                         db => $db,  
                         lookup_regex => $lookup->regex,  
                         lookup => $lookup,  
                         prefix => $input->{name},  
406                  );                  );
407    
408                  my $normalize_path = $input->{normalize}->{path};                  my $lookup_data = WebPAC::Normalize::_get_lookup();
409    
410                  if ($normalize_path =~ m/\.xml$/i) {                  if (defined( $lookup_data->{$database}->{$input_name} )) {
411                          $n->open(                          $log->debug("created following lookups: ", sub { dump( $lookup_data ) } );
412                                  tag => $input->{normalize}->{tag},  
413                                  xml_file => $input->{normalize}->{path},                          foreach my $key (keys %{ $lookup_data->{$database}->{$input_name} }) {
414                          );                                  $store->save_lookup(
415                  } elsif ($normalize_path =~ m/\.(?:yml|yaml)$/i) {                                          database => $database,
416                          $n->open_yaml(                                          input => $input_name,
417                                  path => $normalize_path,                                          key => $key,
418                                  tag => $input->{normalize}->{tag},                                          data => $lookup_data->{$database}->{$input_name}->{$key},
419                                    );
420                            }
421                    }
422    
423                    my $report_fh;
424                    if ($stats || $validate) {
425                            my $path = "out/report/${database}-${input_name}.txt";
426                            open($report_fh, '>', $path) || $log->logdie("can't open $path: $!");
427    
428                            print $report_fh "Report for database '$database' input '$input_name' records ",
429                                    $offset || 1, "-", $limit || $input->{limit} || $maxmfn, "\n\n";
430                            $log->info("Generating report file $path");
431                    }
432    
433                    my $marc;
434                    if ($parser->have_rules( 'marc', $database, $input_name )) {
435                            $marc = new WebPAC::Output::MARC(
436                                    path => "out/marc/${database}-${input_name}.marc",
437                                    lint => $marc_lint,
438                                    dump => $marc_dump,
439                          );                          );
440                  }                  }
441    
442                    my $rules = $parser->normalize_rules($database,$input_name) || $log->logdie("no normalize rules found for $database/$input_name");
443                    $log->debug("parsed normalize rules:\n$rules");
444    
445                    # reset position in database
446                    $input_db->seek(1);
447    
448                    # generate name of config key for indexer (strip everything after -)
449                    my $indexer_config = $use_indexer;
450                    $indexer_config =~ s/^(\w+)-?.*$/$1/g if ($indexer_config);
451    
452                    my $lookup_hash;
453                    my $depends = $parser->depends($database,$input_name);
454            
455                    if ($depends) {
456                            $log->debug("$database/$input_name depends on: ", dump($depends)) if ($depends);
457                            $log->logdie("parser->depends didn't return HASH") unless (ref($depends) eq 'HASH');
458    
459                            foreach my $db (keys %$depends) {
460                                    foreach my $i (keys %{$depends->{$db}}) {
461                                            foreach my $k (keys %{$depends->{$db}->{$i}}) {
462                                                    my $t = time();
463                                                    $log->debug("loading lookup $db/$i");
464                                                    $lookup_hash->{$db}->{$i}->{$k} = $store->load_lookup(
465                                                            database => $db,
466                                                            input => $i,
467                                                            key => $k,
468                                                    );
469                                                    $log->debug(sprintf("lookup $db/$i took %.2fs", time() - $t));
470                                            }
471                                    }
472                            }
473    
474                            $log->debug("lookup_hash = ", sub { dump( $lookup_hash ) });
475                    }
476    
477    
478                  foreach my $pos ( 0 ... $input_db->size ) {                  foreach my $pos ( 0 ... $input_db->size ) {
479    
480                          my $row = $input_db->fetch || next;                          my $row = $input_db->fetch || next;
481    
482                            $total_rows++;
483    
484                          my $mfn = $row->{'000'}->[0];                          my $mfn = $row->{'000'}->[0];
485    
486                          if (! $mfn || $mfn !~ m#^\d+$#) {                          if (! $mfn || $mfn !~ m#^\d+$#) {
# Line 194  while (my ($database, $db_config) = each Line 489  while (my ($database, $db_config) = each
489                                  push @{ $row->{'000'} }, $pos;                                  push @{ $row->{'000'} }, $pos;
490                          }                          }
491    
                         my $ds = $n->data_structure($row);  
492    
493                          $est->add(                          if ($validate) {
494                                  id => $input->{name} . "/" . $mfn,                                  if ( my $errors = $validate->validate_rec( $row, $input_db->dump_ascii ) ) {
495                                  ds => $ds,                                          $log->error( "MFN $mfn validation error:\n",
496                                  type => $config->{hyperestraier}->{type},                                                  $validate->report_error( $errors )
497                                            );
498                                    }
499                                    next;   # validation doesn't create any output
500                            }
501    
502                            my $ds = WebPAC::Normalize::data_structure(
503                                    row => $row,
504                                    rules => $rules,
505                                    lookup => $lookup_hash,
506                                    config => create_ds_config( $db_config, $database, $input, $mfn ),
507                                    marc_encoding => 'utf-8',
508                                    load_row_coderef => sub {
509                                            my ($database,$input,$mfn) = @_;
510                                            return $store->load_row(
511                                                    database => $database,
512                                                    input => $input,
513                                                    id => $mfn,
514                                            );
515                                    },
516                          );                          );
517    
518                          $total_rows++;                          $log->debug("ds = ", sub { dump($ds) }) if ($ds);
519    
520                            $store->save_ds(
521                                    database => $database,
522                                    input => $input_name,
523                                    id => $mfn,
524                                    ds => $ds,
525                            ) if ($ds && !$stats);
526    
527                            $indexer->add(
528                                    id => "${input_name}/${mfn}",
529                                    ds => $ds,
530                                    type => $config->get($indexer_config)->{type},
531                            ) if ($indexer && $ds);
532    
533                            if ($marc) {
534                                    my $i = 0;
535    
536                                    while (my $fields = WebPAC::Normalize::_get_marc_fields( fetch_next => 1 ) ) {
537                                            $marc->add(
538                                                    id => $mfn . ( $i ? "/$i" : '' ),
539                                                    fields => $fields,
540                                                    leader => WebPAC::Normalize::marc_leader(),
541                                                    row => $row,
542                                            );
543                                            $i++;
544                                    }
545    
546                                    $log->info("Created $i instances of MFN $mfn\n") if ($i > 1);
547                            }
548                  }                  }
549    
550          };                  if ($validate) {
551                            my $errors = $validate->report;
552                            if ($errors) {
553                                    $log->info("validation errors:\n$errors\n" );
554                                    print $report_fh "$errors\n" if ($report_fh);
555                            }
556                    }
557    
558                    if ($stats) {
559                            my $s = $input_db->stats;
560                            $log->info("statistics of fields usage:\n$s");
561                            print $report_fh "Statistics of fields usage:\n$s" if ($report_fh);
562                    }
563    
564                    # close MARC file
565                    $marc->finish if ($marc);
566    
567                    # close report
568                    close($report_fh) if ($report_fh)
569    
570            }
571    
572            eval { $indexer->finish } if ($indexer && $indexer->can('finish'));
573    
574          my $dt = time() - $start_t;          my $dt = time() - $start_t;
575          $log->info("$total_rows records indexed in " .          $log->info("$total_rows records ", $indexer ? "indexed " : "",
576                  sprintf("%.2f sec [%.2f rec/sec]",                  sprintf("in %.2f sec [%.2f rec/sec]",
577                          $dt, ($total_rows / $dt)                          $dt, ($total_rows / $dt)
578                  )                  )
579          );          );
580    
581          #  
582          # add Hyper Estraier links to other databases          # end forked process
583          #          if ($parallel) {
584          if (ref($db_config->{links}) eq 'ARRAY') {                  $log->info("parallel process $$ finished");
585                  foreach my $link (@{ $db_config->{links} }) {                  exit(0);
                         $log->info("adding link $database -> $link->{to} [$link->{credit}]");  
                         $est->add_link(  
                                 from => $database,  
                                 to => $link->{to},  
                                 credit => $link->{credit},  
                         );  
                 }  
586          }          }
587    
588  }  }
589    
590    if ($parallel) {
591            # wait all children to finish
592            sleep(1) while wait != -1;
593            $log->info("all parallel processes finished");
594    }
595    
596    #
597    # handle links or merge after indexing
598    #
599    
600    if ($merge) {
601            print $estcmd_fh 'sudo /etc/init.d/hyperestraier start',$/;
602            close($estcmd_fh);
603            chmod 0700, $estcmd_path || $log->warn("can't chmod 0700 $estcmd_path: $!");
604            system $estcmd_path;
605    } else {
606            foreach my $link (@links) {
607                    $log->logdie("coderef in link ", Dumper($link), " is ", ref($link), " and not CODE") unless (ref($link) eq 'CODE');
608                    $link->();
609            }
610    }

Legend:
Removed from v.389  
changed lines
  Added in v.790

  ViewVC Help
Powered by ViewVC 1.1.26