/[echolot]/branches/snapshot-2003-02-17-branch/pingd
ViewVC logotype

Contents of /branches/snapshot-2003-02-17-branch/pingd

Parent Directory Parent Directory | Revision Log Revision Log


Revision 406 - (show annotations) (download)
Sun Feb 16 05:46:54 2003 UTC (10 years, 3 months ago) by weasel
Original Path: trunk/pingd
File size: 20922 byte(s)
Check mixmaster binary on startup
1 #!/usr/bin/perl -w
2
3 $| = 1;
4
5 # (c) 2002, 2003 Peter Palfrader <peter@palfrader.org>
6 # $Id: pingd,v 1.97 2003/02/16 05:46:54 weasel Exp $
7 #
8
9 =pod
10
11 =head1 NAME
12
13 pingd - echolot ping daemon
14
15 =head1 SYNOPSIS
16
17 =over
18
19 =item B<pingd> B<start>
20
21 =item B<pingd> B<stop>
22
23 =item B<pingd> B<process>
24
25 =item B<pingd> B<add> I<address> [I<address> ...]
26
27 =item B<pingd> B<delete> I<address> [I<address> ...]
28
29 =item B<pingd> B<set> option=value [option=value..] I<address> [I<address> ...]
30
31 =item B<pingd> B<setremailercaps> I<capsstring>
32
33 =item B<pingd> B<deleteremailercaps> I<address>
34
35 =item B<pingd> B<getkeyconf> [I<address> [I<address> ...]]
36
37 =item B<pingd> B<sendpings> [I<address> [I<address> ...]]
38
39 =item B<pingd> B<buildstats>
40
41 =item B<pingd> B<buildkeys>
42
43 =item B<pingd> B<buildthesaurus>
44
45 =item B<pingd> B<dumpconf>
46
47 =back
48
49 =head1 DESCRIPTION
50
51 pingd is the heart of echolot. Echolot is a pinger for anonymous remailers.
52
53 A Pinger in the context of anonymous remailers is a program that regularily
54 sends messages through remailers to check their reliability. It then calculates
55 reliability statistics which are used by remailer clients to choose the chain
56 of remailers to use.
57
58 Additionally it collects configuration parameters and keys of all remailers and
59 offers them in a format readable by remailer clients.
60
61 When called without parameters pingd schedules tasks like sending pings,
62 processing incoming mail and requesting remailer-xxx data and runs them at
63 configurable intervalls.
64
65 =head1 COMMANDS
66
67 =over
68
69 =item B<start>
70
71 Start the ping daemon.
72
73 =item B<stop>
74
75 Send the running pingd process a SIGTERM.
76
77 =item B<process>
78
79 Sends a HUP signal to the daemon which instructs it to process the commands.
80
81 For other effects of sending the HUP Signal see the SIGNALS section below.
82
83 =item B<add> I<address> [I<address> ...]
84
85 Add I<address> to the list of remailers to query for
86 keys and confs.
87
88 =item B<delete> I<address> [I<address> ...]
89
90 Delete I<address> from the list of remailers to query for
91 keys and confs. Delete all statistics and keys for that remailer.
92
93 =item B<set> option=value [option=value..] I<address> [I<address> ...]
94
95 Possible options and values:
96
97 =over
98
99 =item B<showit=>{B<on>,B<off>}
100
101 Set B<showit> (show remailer in mlist, rlist etc.) for remailer I<address> to
102 either B<on> or B<off>.
103
104 =item B<pingit=>{B<on>,B<off>}
105
106 Set B<pingit> (send out pings to that remailer) for remailer I<address> to
107 either B<on> or B<off>.
108
109 =item B<fetch=>{B<on>,B<off>}
110
111 Set B<fetch> (fetch remailer-key and remailer-conf) for remailer I<address> to
112 either B<on> or B<off>.
113
114 =back
115
116 =item B<setremailercaps> I<capsstring>
117
118 Some remailers (Mixmaster V2 - currently lcs and passthru2) don't return a
119 useable remailer-conf message. For such remailers you need to set it manually.
120
121 For instance:
122
123 ./pingd setremailercaps '$remailer{"passthru2"} = "<mixer@immd1.informatik.uni-erlangen.de> mix middle";'
124 ./pingd setremailercaps '$remailer{"lcs"} = "<mix@anon.lcs.mit.edu> mix klen1000";'
125
126 =item B<deleteremailercaps> I<address>
127
128 Delete remailer-conf data for I<address>. The config data will be reset from
129 the next valid remailer-conf reply by the remailer.
130
131 =item B<getkeyconf> [I<address> [I<address> ...]]
132
133 Send a command to immediatly request keys and configuration from remailers.
134 If no addresses are given requests will be sent to all remailers.
135
136 =item B<sendpings> [I<address> [I<address> ...]]
137
138 Send a command to immediatly send pings to the given remailers.
139 If no addresses are given requests will be sent to all remailers.
140
141 =item B<buildstats>
142
143 Send a command to immediatly rebuild stats.
144
145 =item B<buildkeys>
146
147 Send a command to immediatly rebuild the keyrings.
148
149 =item B<buildthesaurus>
150
151 Send a command to immediatly rebuild the Thesaurus.
152
153 =item B<dumpconf>
154
155 Dumps the current configuration to standard output.
156
157 =back
158
159 =head1 OPTIONS
160
161 =over
162
163 =item B<--basedir>
164
165 The home directory to which everything else is relative. See the BASE
166 DIRECTORY section below.
167
168 =item B<--verbose>
169
170 Verbose mode. Causes B<pingd> to print debugging messages about its progress.
171
172 =item B<--quiet>
173
174 Quiet mode. Be even quieter than normal.
175
176 =item B<--help>
177
178 Print a short help message and exit sucessfully.
179
180 =item B<--version>
181
182 Print version number and exit sucessfully.
183
184 =item B<--nohup>
185
186 Usefull only with the B<add>, B<set>, B<setremailercaps>,
187 B<deleteremailercaps>, B<getkeyconf>, B<sendpings>, B<buildstats>,
188 B<buildkeys>, or B<buildthesaurus> command.
189
190 Don't send a HUP signal to the daemon which instructs it to process the
191 commands after adding the command to the task list.
192
193 By default such a signal is sent.
194
195 =item B<--process>
196
197 Usefull only with the B<start> command.
198
199 Read and process the commands file on startup.
200
201 =item B<--detach>
202
203 Usefull only with the B<start> command.
204
205 Tell B<pingd> to detach.
206
207 =back
208
209 =head1 BASE DIRECTORY
210
211 The home directory to which everything else is relative.
212
213 Basedir defaults to whatever directory the B<pingd> binary is located. It can
214 be overridden by the B<ECHOLOT_HOME> environment variable which in turn is
215 weaker than the B<--basedir> setting.
216
217 This directory is then used to locate the configuration file B<pingd.conf> (see
218 FILES below).
219
220 The B<homedir> setting in B<pingd.conf> finally sets the base directory.
221
222 =head1 FILES
223
224 The configuration file is searched in these places in this order:
225
226 =over
227
228 =item the file pointed to by the B<ECHOLOT_CONF> environment variable
229
230 =item <basedir>/pingd.conf
231
232 =item $HOME/echolot/pingd.conf
233
234 =item $HOME/pingd.conf
235
236 =item $HOME/.pingd.conf
237
238 =item /etc/echolot/pingd.conf
239
240 =item /etc/pingd.conf
241
242 =back
243
244 =head1 ENVIRONMENT
245
246 =over
247
248 =item ECHOLOT_CONF echolot config file (see section FILES)
249
250 =item ECHOLOT_HOME echolot base directory (see section BASE DIRECTORY)
251
252 =back
253
254 =head1 SIGNALS
255
256 On B<SIGINT>, B<SIGQUIT>, and B<SIGTERM> B<pingd> will schedule a shutdown
257 for as soon as the current actions are finished or immediatly if no actions are
258 currently being processed. It will then write all metadata and pingdata to
259 disk and close all files cleanly before exiting.
260
261 On B<SIGHUP> <pingd> will execute any pending commands from the commands file
262 (B<commands.txt> by default). It also closes and reopens the file 'output'
263 which is used for stdout and stderr when the daemon is running detached.
264 This can be used if you want to rotate that file.
265
266 =head1 AUTHOR
267
268 Peter Palfrader E<lt>peter@palfrader.orgE<gt>
269
270 =head1 BUGS
271
272 Please report them at E<lt>URL:http://savannah.gnu.org/bugs/?group=echolotE<gt>
273
274 =cut
275
276 use strict;
277 use FindBin qw{ $Bin };
278 use lib ( $Bin, "$Bin/lib" );
279 use Getopt::Long;
280 use English;
281 use Carp;
282 use Echolot::Config;
283 use Echolot::Globals;
284 use Echolot::Storage::File;
285 use Echolot::Scheduler;
286 use Echolot::Conf;
287 use Echolot::Mailin;
288 use Echolot::Pinger;
289 use Echolot::Chain;
290 use Echolot::Stats;
291 use Echolot::Commands;
292 use Echolot::Thesaurus;
293 use Echolot::Log;
294 use POSIX qw(setsid);
295
296 delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
297
298
299 my $VERSION = '2.0.10';
300
301
302 my $redirected_stdio = 0;
303
304 sub setSigHandlers() {
305 $SIG{'HUP'} = sub {
306 Echolot::Log::info("Got SIGHUP. scheduling readcommands.");
307 Echolot::Globals::get()->{'scheduler'}->schedule('readcommands', 0, time() );
308 if ($redirected_stdio) {
309 close STDOUT;
310 close STDERR;
311 my $logfile = Echolot::Config::get()->{'logfile'};
312 open (STDOUT, ">>$logfile") or die ("Cannot open '$logfile' as STDOUT\n");
313 open (STDERR, ">&STDOUT") or die ("Cannot dup STDOUT as STDERR\n");
314 };
315 Echolot::Log::reopen();
316 };
317 $SIG{'INT'} = sub {
318 Echolot::Log::info("Got SIGINT. scheduling exit.");
319 Echolot::Globals::get()->{'scheduler'}->schedule('exit', 0, time() );
320 };
321 $SIG{'QUIT'} = sub {
322 Echolot::Log::info("Got SIGINT. scheduling exit.");
323 Echolot::Globals::get()->{'scheduler'}->schedule('exit', 0, time() );
324 };
325 $SIG{'TERM'} = sub {
326 Echolot::Log::info("Got SIGINT. scheduling exit.");
327 Echolot::Globals::get()->{'scheduler'}->schedule('exit', 0, time() );
328 };
329 };
330
331
332
333 sub commit_prospective_address() {
334 Echolot::Globals::get()->{'storage'}->commit_prospective_address();
335 };
336 sub expire() {
337 Echolot::Globals::get()->{'storage'}->expire();
338 };
339 sub metadata_backup() {
340 Echolot::Globals::get()->{'storage'}->metadata_backup();
341 };
342
343
344
345
346
347 sub command_adddelete(@) {
348 my $command = shift @_;
349 my @argv = @_;
350
351 die ("command_adddelete requires command\n") unless defined $command;
352 die ("add requires argument <address>\n") unless scalar @argv;
353 my @addresses;
354 for my $address (@argv) {
355 die ("argument <address> is not a valid email address\n") unless ($address =~ /^[a-zA-Z0-9+._-]+\@[a-zA-Z0-9+.-]+$/ );
356 push @addresses, $address;
357 };
358 for my $address (@addresses) {
359 Echolot::Commands::addCommand("$command $address");
360 };
361 };
362
363 sub command_set(@) {
364 my @argv = @_;
365
366 my @settings;
367 while (scalar @argv && $argv[0] =~ /^(showit|pingit|fetch)=(on|off)$/) {
368 push @settings, $argv[0];
369 shift @argv;
370 };
371
372 my @addresses;
373 for my $address (@argv) {
374 die ("argument $address is not a valid email address\n") unless ($address =~ /^[a-zA-Z0-9+._-]+\@[a-zA-Z0-9+.-]+$/ );
375 push @addresses, $address;
376 };
377
378 for my $address (@argv) {
379 for my $setting (@settings) {
380 Echolot::Commands::addCommand("set $address $setting");
381 };
382 };
383 };
384
385 sub command_setremailercaps(@) {
386 my @argv = @_;
387
388 my @caps;
389 for my $caps (@argv) {
390 my ($remailer_nick, $remailer_address) = ($caps =~ /^\s* \$remailer{"(.*)"} \s*=\s* "<(.*@.*)>.*"; \s*$/ix);
391 die ("caps '$caps' is not a valid remailer caps line\n") unless (defined $remailer_nick && defined $remailer_address);
392 push @caps, {
393 address => $remailer_address,
394 caps => $caps };
395 };
396 for my $caps (@caps) {
397 Echolot::Commands::addCommand("setremailercaps ".$caps->{'address'}." ".$caps->{'caps'});
398 };
399 };
400
401 sub command_deleteremailercaps(@) {
402 my @argv = @_;
403
404 my @addresses;
405 for my $address (@argv) {
406 die ("argument $address is not a valid email address\n") unless ($address =~ /^[a-zA-Z0-9+._-]+\@[a-zA-Z0-9+.-]+$/ );
407 push @addresses, $address;
408 };
409
410 for my $address (@addresses) {
411 Echolot::Commands::addCommand("deleteremailercaps $address");
412 };
413 };
414
415 sub command_getkeyconf(@) {
416 my @argv = @_;
417
418 my @addresses;
419 for my $address (@argv) {
420 die ("argument $address is not a valid email address\n") unless ($address =~ /^[a-zA-Z0-9+._-]+\@[a-zA-Z0-9+.-]+$/ );
421 push @addresses, $address;
422 };
423
424 push @addresses, 'all' unless (scalar @addresses);
425
426 for my $address (@addresses) {
427 Echolot::Commands::addCommand("getkeyconf $address");
428 };
429 };
430
431 sub command_sendpings(@) {
432 my @argv = @_;
433
434 my @addresses;
435 for my $address (@argv) {
436 die ("argument $address is not a valid email address\n") unless ($address =~ /^[a-zA-Z0-9+._-]+\@[a-zA-Z0-9+.-]+$/ );
437 push @addresses, $address;
438 };
439
440 push @addresses, 'all' unless (scalar @addresses);
441
442 for my $address (@addresses) {
443 Echolot::Commands::addCommand("sendpings $address");
444 };
445 };
446
447
448 sub pid_exists($) {
449 my ($remove_stale) = @_;
450
451 my $pidfile = Echolot::Config::get()->{'pidfile'};
452 if (! $remove_stale) {
453 return (-e $pidfile);
454 } else {
455 if (!-e $pidfile) {
456 return 0;
457 };
458
459 open (PIDFILE, $pidfile) or
460 die ("Cannot open pidfile '$pidfile': $!.\n");
461 my $line = <PIDFILE>;
462 close PIDFILE;
463
464 my ($pid, $host, $time) = $line =~ /^(\d+) \s+ (\S+) \s+ (\d+) \s* $/x or
465 die ("Cannot parse pidfile '$pidfile' line '$line'.\n");
466
467 (Echolot::Globals::get()->{'hostname'} eq $host) or
468 die ("Pidfile exists and is from another host.\n");
469 ($host ne 'unknown') or
470 die ("Pidfile exists and hostname is unknown.\n");
471 ($time < time()) or
472 die ("Pidfile exists and timestamp is in the future.\n");
473 my $sent = kill 0, $pid;
474 ($sent == 0) or
475 die ("Pidfile exists and process $pid running.\n");
476 warn ("Removing stale pidfile.\n");
477 unlink ($pidfile) or
478 die ("Removing stale pidfile $pidfile failed.\n");
479 return 0;
480 }
481
482
483 };
484
485 sub daemon_run($) {
486 my ($process) = @_;
487
488 Echolot::Log::logdie("Pidfile '".Echolot::Config::get()->{'pidfile'}."' exists\n")
489 if pid_exists(0);
490 open (PIDFILE, '>'.Echolot::Config::get()->{'pidfile'}) or
491 Echolot::Log::logdie("Cannot open pidfile '".Echolot::Config::get()->{'pidfile'}."': $!");
492 print PIDFILE "$PROCESS_ID ".Echolot::Globals::get()->{'hostname'}." ".time()."\n";
493 close PIDFILE;
494
495 Echolot::Globals::initStorage();
496 setSigHandlers();
497
498 Echolot::Globals::get()->{'scheduler'} = new Echolot::Scheduler;
499 my $scheduler = Echolot::Globals::get()->{'scheduler'};
500 $scheduler->add('exit' , -1 , 0, 'exit' );
501 $scheduler->add('readcommands' , -1 , 0, \&Echolot::Commands::processCommands );
502
503 $scheduler->add('processmail' , Echolot::Config::get()->{'processmail'} , 0, \&Echolot::Mailin::process );
504 $scheduler->add('ping' , Echolot::Config::get()->{'pinger_interval'} , 0, \&Echolot::Pinger::send_pings );
505 $scheduler->add('chainping' , Echolot::Config::get()->{'chainpinger_interval'} , 0, \&Echolot::Chain::send_pings )
506 if Echolot::Config::get()->{'do_chainpings'};
507 $scheduler->add('buildstats' , Echolot::Config::get()->{'buildstats'} , 0, \&Echolot::Stats::build_stats );
508 $scheduler->add('buildkeys' , Echolot::Config::get()->{'buildkeys'} , 0, \&Echolot::Stats::build_keys );
509 $scheduler->add('buildthesaurus' , Echolot::Config::get()->{'buildthesaurus'} , 0, \&Echolot::Thesaurus::build_thesaurus );
510
511 $scheduler->add('metadata_backup' , Echolot::Config::get()->{'metadata_backup'} , 0, \&metadata_backup );
512 $scheduler->add('commitprospectives' , Echolot::Config::get()->{'commitprospectives'} , 0, \&commit_prospective_address );
513 $scheduler->add('expire' , Echolot::Config::get()->{'expire'} , 0, \&expire );
514 $scheduler->add('getkeyconf' , Echolot::Config::get()->{'getkeyconf_interval'} , 0, \&Echolot::Conf::send_requests );
515 $scheduler->add('check_resurrection' , Echolot::Config::get()->{'check_resurrection'} , 0, \&Echolot::Conf::check_resurrection );
516
517 Echolot::Globals::get()->{'scheduler'}->schedule('readcommands', 0, time() )
518 if ($process);
519
520 $scheduler->run();
521
522 Echolot::Globals::get()->{'storage'}->commit();
523 Echolot::Globals::get()->{'storage'}->finish();
524
525 unlink (Echolot::Config::get()->{'pidfile'}) or
526 Echolot::Log::warn ("Cannot unlink pidfile ".Echolot::Config::get()->{'pidfile'}.".");
527 };
528
529 sub send_sig($) {
530 my ($sig) = @_;
531
532 die ("Pidfile '".Echolot::Config::get()->{'pidfile'}."' does not exist\n")
533 unless pid_exists(0);
534 open (PIDFILE, '<'.Echolot::Config::get()->{'pidfile'}) or
535 confess ("Cannot open pidfile '".Echolot::Config::get()->{'pidfile'}."': $!\n");
536 my $line = <PIDFILE>;
537 close PIDFILE;
538
539 my ($pid, $host, $time) = $line =~ /^(\d+) \s+ (\S+) \s+ (\d+) \s* $/x or
540 confess ("Cannot parse pidfile '$line'\n");
541 my $sent = kill $sig, $pid;
542 ($sent == 1) or
543 confess ("Did not send signal $sig to exactly one process but $sent. (pidfile reads $line)\n");
544 };
545
546 sub daemon_hup() {
547 send_sig(1);
548 };
549
550 sub daemon_stop() {
551 send_sig(15);
552 };
553
554 sub make_dirs() {
555 for my $dir (
556 Echolot::Config::get()->{'resultdir'},
557 Echolot::Config::get()->{'thesaurusdir'},
558 ) {
559 if ( ! -d $dir ) {
560 mkdir ($dir, 0755) or
561 confess ("Cannot create directory $dir: $!\n");
562 };
563 };
564 my @dirs = (
565 Echolot::Config::get()->{'private_resultdir'},
566 Echolot::Config::get()->{'gnupghome'},
567 Echolot::Config::get()->{'mixhome'},
568 Echolot::Config::get()->{'tmpdir'},
569 Echolot::Config::get()->{'storage'}->{'File'}->{'basedir'},
570 Echolot::Config::get()->{'mailerrordir'},
571 Echolot::Config::get()->{'mailerrordir'}.'/cur',
572 Echolot::Config::get()->{'mailerrordir'}.'/tmp',
573 Echolot::Config::get()->{'mailerrordir'}.'/new');
574 push @dirs, (
575 Echolot::Config::get()->{'mailin'}.'/cur',
576 Echolot::Config::get()->{'mailin'}.'/tmp',
577 Echolot::Config::get()->{'mailin'}.'/new' )
578 if (-d Echolot::Config::get()->{'mailin'});
579
580 for my $dir (@dirs) {
581 if ( ! -d $dir ) {
582 mkdir ($dir, 0700) or
583 confess ("Cannot create directory $dir: $!\n");
584 };
585 };
586 };
587
588 sub hup_if_wanted($) {
589 my ($nohup) = @_;
590 if (!$nohup && pid_exists(0)) {
591 daemon_hup()
592 } else {
593 print "Don't forget to run $PROGRAM_NAME process.\n";
594 };
595 };
596
597
598
599
600
601
602
603
604
605
606 my $params = { basedir => $Bin };
607 $params->{'basedir'} = $ENV{'ECHOLOT_HOME'} if (defined $ENV{'ECHOLOT_HOME'});
608
609 Getopt::Long::config('bundling');
610 if (!GetOptions (
611 'help' => \$params->{'help'},
612 'version' => \$params->{'version'},
613 'verbose+' => \$params->{'verbose'},
614 'nohup' => \$params->{'nohup'},
615 'detach' => \$params->{'detach'},
616 'process' => \$params->{'process'},
617 'basedir' => \$params->{'basedir'},
618 'quiet' => \$params->{'quiet'},
619 )) {
620 die ("$PROGRAM_NAME: Usage: $PROGRAM_NAME [-fwhv]\n");
621 };
622 if ($params->{'help'}) {
623 print ("Usage: $PROGRAM_NAME [options] command\n");
624 print ("See man pingd or perldoc pingd for more info.\n");
625 print ("echolot $VERSION - (c) 2002, 2003 Peter Palfrader <peter\@palfrader.org>\n");
626 print ("http://savannah.gnu.org/projects/echolot/\n");
627 print ("\n");
628 print ("Commands:\n");
629 print (" start starts echolot pingd\n");
630 print (" signals pingd to ... \n");
631 print (" stop ... shutdown\n");
632 print (" process ... reopen outfile and process commands\n");
633 print (" add ... add a remailer address\n");
634 print (" delete ... delete a remailer address\n");
635 print (" set ... set remailer options\n");
636 print (" setremailercaps ... set remailer capabilities manually\n");
637 print (" deleteremailercaps ... delete remailer capabilities manually\n");
638 print (" getkeyconf ... request remailer-xxx data immediatly\n");
639 print (" sendpings ... request immediate sending of pings\n");
640 print (" buildstats ... build remailer stats immediatly\n");
641 print (" buildkeys ... buid keyrings immediatly\n");
642 print (" buildthesaurus ... build thesaurus immediatly\n");
643 print (" dumpconf dump configuration\n");
644 exit 0;
645 };
646 if ($params->{'version'}) {
647 print ("echolot $VERSION\n");
648 print ("(c) 2002, 2003 Peter Palfrader <peter\@palfrader.org>\n");
649 print ("http://savannah.gnu.org/projects/echolot/\n");
650 exit 0;
651 };
652 $params->{'quiet'} = undef if ($params->{'verbose'});
653
654 my $COMMAND = shift @ARGV;
655 die ("command required\n") unless defined $COMMAND;
656
657
658 Echolot::Config::init( $params );
659 chdir( Echolot::Config::get()->{'homedir'} );
660 Echolot::Globals::init( version => $VERSION);
661
662
663 if ($COMMAND eq 'add' || $COMMAND eq 'delete') {
664 command_adddelete($COMMAND, @ARGV);
665 hup_if_wanted($params->{'nohup'});
666 } elsif ($COMMAND eq 'set') {
667 command_set(@ARGV);
668 hup_if_wanted($params->{'nohup'});
669 } elsif ($COMMAND eq 'deleteremailercaps') {
670 command_deleteremailercaps(@ARGV);
671 hup_if_wanted($params->{'nohup'});
672 } elsif ($COMMAND eq 'setremailercaps') {
673 command_setremailercaps(@ARGV);
674 hup_if_wanted($params->{'nohup'});
675 } elsif ($COMMAND eq 'getkeyconf') {
676 command_getkeyconf(@ARGV);
677 hup_if_wanted($params->{'nohup'});
678 } elsif ($COMMAND eq 'sendpings') {
679 command_sendpings(@ARGV);
680 hup_if_wanted($params->{'nohup'});
681 } elsif ($COMMAND eq 'buildstats') {
682 Echolot::Commands::addCommand("buildstats");
683 hup_if_wanted($params->{'nohup'});
684 } elsif ($COMMAND eq 'buildkeys') {
685 Echolot::Commands::addCommand("buildkeys");
686 hup_if_wanted($params->{'nohup'});
687 } elsif ($COMMAND eq 'buildthesaurus') {
688 Echolot::Commands::addCommand("buildthesaurus");
689 hup_if_wanted($params->{'nohup'});
690 } elsif ($COMMAND eq 'process') {
691 daemon_hup();
692 } elsif ($COMMAND eq 'stop') {
693 daemon_stop();
694 } elsif ($COMMAND eq 'start') {
695 # FIXME: remove stale pid files
696 die ("Pidfile '".Echolot::Config::get()->{'pidfile'}."' exists\n")
697 if pid_exists(1);
698 Echolot::Log::init();
699 make_dirs();
700 Echolot::Config::check_binaries();
701 if ($params->{'detach'}) {
702 print "Detaching.\n" unless ($params->{'quiet'});
703 Echolot::Log::debug("Detaching.");
704 exit(0) if (fork());
705 POSIX::setsid();
706 exit(0) if (fork());
707 my $logfile = Echolot::Config::get()->{'logfile'};
708 open (STDOUT, ">>$logfile") or die ("Cannot open '$logfile' as STDOUT\n");
709 open (STDERR, ">&STDOUT") or die ("Cannot dup STDOUT as STDERR\n");
710 open (STDIN , "</dev/null") or die ("Cannot open /dev/null as STDIN\n");
711 $redirected_stdio = 1;
712 Echolot::Log::info "Starting up.";
713 daemon_run( $params->{'process'} );
714 Echolot::Log::info "Shutdown complete.";
715 } else {
716 daemon_run( $params->{'process'} );
717 };
718 } elsif ($COMMAND eq 'dumpconf') {
719 Echolot::Config::dump();
720 } elsif ($COMMAND eq 'convert') {
721 Echolot::Globals::initStorage();
722 setSigHandlers();
723
724 Echolot::Globals::get()->{'storage'}->convert();
725
726 Echolot::Globals::get()->{'storage'}->commit();
727 Echolot::Globals::get()->{'storage'}->finish();
728 } else {
729 die ("Command $COMMAND unknown");
730 };
731
732 exit 0;
733
734 # vim: set ts=4 shiftwidth=4:

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.5