/[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 386 - (show annotations) (download)
Mon Feb 3 20:12:24 2003 UTC (10 years, 4 months ago) by weasel
Original Path: trunk/pingd
File size: 20650 byte(s)
Prepare 2.0.10
1 #!/usr/bin/perl -w
2
3 $| = 1;
4
5 # (c) 2002 Peter Palfrader <peter@palfrader.org>
6 # $Id: pingd,v 1.93 2003/02/03 20:12:24 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::Stats;
290 use Echolot::Commands;
291 use Echolot::Thesaurus;
292 use Echolot::Log;
293 use POSIX qw(setsid);
294
295 delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
296
297
298 my $VERSION = '2.0.10';
299
300
301 my $redirected_stdio = 0;
302
303 sub setSigHandlers() {
304 $SIG{'HUP'} = sub {
305 Echolot::Log::info("Got SIGHUP. scheduling readcommands.");
306 Echolot::Globals::get()->{'scheduler'}->schedule('readcommands', 0, time() );
307 if ($redirected_stdio) {
308 close STDOUT;
309 close STDERR;
310 my $logfile = Echolot::Config::get()->{'logfile'};
311 open (STDOUT, ">>$logfile") or die ("Cannot open '$logfile' as STDOUT\n");
312 open (STDERR, ">&STDOUT") or die ("Cannot dup STDOUT as STDERR\n");
313 };
314 Echolot::Log::reopen();
315 };
316 $SIG{'INT'} = sub {
317 Echolot::Log::info("Got SIGINT. scheduling exit.");
318 Echolot::Globals::get()->{'scheduler'}->schedule('exit', 0, time() );
319 };
320 $SIG{'QUIT'} = sub {
321 Echolot::Log::info("Got SIGINT. scheduling exit.");
322 Echolot::Globals::get()->{'scheduler'}->schedule('exit', 0, time() );
323 };
324 $SIG{'TERM'} = sub {
325 Echolot::Log::info("Got SIGINT. scheduling exit.");
326 Echolot::Globals::get()->{'scheduler'}->schedule('exit', 0, time() );
327 };
328 };
329
330
331
332 sub commit_prospective_address() {
333 Echolot::Globals::get()->{'storage'}->commit_prospective_address();
334 };
335 sub expire() {
336 Echolot::Globals::get()->{'storage'}->expire();
337 };
338 sub metadata_backup() {
339 Echolot::Globals::get()->{'storage'}->metadata_backup();
340 };
341
342
343
344
345
346 sub command_adddelete(@) {
347 my $command = shift @_;
348 my @argv = @_;
349
350 die ("command_adddelete requires command\n") unless defined $command;
351 die ("add requires argument <address>\n") unless scalar @argv;
352 my @addresses;
353 for my $address (@argv) {
354 die ("argument <address> is not a valid email address\n") unless ($address =~ /^[a-zA-Z0-9+._-]+\@[a-zA-Z0-9+.-]+$/ );
355 push @addresses, $address;
356 };
357 for my $address (@addresses) {
358 Echolot::Commands::addCommand("$command $address");
359 };
360 };
361
362 sub command_set(@) {
363 my @argv = @_;
364
365 my @settings;
366 while (scalar @argv && $argv[0] =~ /^(showit|pingit|fetch)=(on|off)$/) {
367 push @settings, $argv[0];
368 shift @argv;
369 };
370
371 my @addresses;
372 for my $address (@argv) {
373 die ("argument $address is not a valid email address\n") unless ($address =~ /^[a-zA-Z0-9+._-]+\@[a-zA-Z0-9+.-]+$/ );
374 push @addresses, $address;
375 };
376
377 for my $address (@argv) {
378 for my $setting (@settings) {
379 Echolot::Commands::addCommand("set $address $setting");
380 };
381 };
382 };
383
384 sub command_setremailercaps(@) {
385 my @argv = @_;
386
387 my @caps;
388 for my $caps (@argv) {
389 my ($remailer_nick, $remailer_address) = ($caps =~ /^\s* \$remailer{"(.*)"} \s*=\s* "<(.*@.*)>.*"; \s*$/ix);
390 die ("caps '$caps' is not a valid remailer caps line\n") unless (defined $remailer_nick && defined $remailer_address);
391 push @caps, {
392 address => $remailer_address,
393 caps => $caps };
394 };
395 for my $caps (@caps) {
396 Echolot::Commands::addCommand("setremailercaps ".$caps->{'address'}." ".$caps->{'caps'});
397 };
398 };
399
400 sub command_deleteremailercaps(@) {
401 my @argv = @_;
402
403 my @addresses;
404 for my $address (@argv) {
405 die ("argument $address is not a valid email address\n") unless ($address =~ /^[a-zA-Z0-9+._-]+\@[a-zA-Z0-9+.-]+$/ );
406 push @addresses, $address;
407 };
408
409 for my $address (@addresses) {
410 Echolot::Commands::addCommand("deleteremailercaps $address");
411 };
412 };
413
414 sub command_getkeyconf(@) {
415 my @argv = @_;
416
417 my @addresses;
418 for my $address (@argv) {
419 die ("argument $address is not a valid email address\n") unless ($address =~ /^[a-zA-Z0-9+._-]+\@[a-zA-Z0-9+.-]+$/ );
420 push @addresses, $address;
421 };
422
423 push @addresses, 'all' unless (scalar @addresses);
424
425 for my $address (@addresses) {
426 Echolot::Commands::addCommand("getkeyconf $address");
427 };
428 };
429
430 sub command_sendpings(@) {
431 my @argv = @_;
432
433 my @addresses;
434 for my $address (@argv) {
435 die ("argument $address is not a valid email address\n") unless ($address =~ /^[a-zA-Z0-9+._-]+\@[a-zA-Z0-9+.-]+$/ );
436 push @addresses, $address;
437 };
438
439 push @addresses, 'all' unless (scalar @addresses);
440
441 for my $address (@addresses) {
442 Echolot::Commands::addCommand("sendpings $address");
443 };
444 };
445
446
447 sub pid_exists($) {
448 my ($remove_stale) = @_;
449
450 my $pidfile = Echolot::Config::get()->{'pidfile'};
451 if (! $remove_stale) {
452 return (-e $pidfile);
453 } else {
454 if (!-e $pidfile) {
455 return 0;
456 };
457
458 open (PIDFILE, $pidfile) or
459 die ("Cannot open pidfile '$pidfile': $!.\n");
460 my $line = <PIDFILE>;
461 close PIDFILE;
462
463 my ($pid, $host, $time) = $line =~ /^(\d+) \s+ (\S+) \s+ (\d+) \s* $/x or
464 die ("Cannot parse pidfile '$pidfile' line '$line'.\n");
465
466 (Echolot::Globals::get()->{'hostname'} eq $host) or
467 die ("Pidfile exists and is from another host.\n");
468 ($host ne 'unknown') or
469 die ("Pidfile exists and hostname is unknown.\n");
470 ($time < time()) or
471 die ("Pidfile exists and timestamp is in the future.\n");
472 my $sent = kill 0, $pid;
473 ($sent == 0) or
474 die ("Pidfile exists and process $pid running.\n");
475 warn ("Removing stale pidfile.\n");
476 unlink ($pidfile) or
477 die ("Removing stale pidfile $pidfile failed.\n");
478 return 0;
479 }
480
481
482 };
483
484 sub daemon_run($) {
485 my ($process) = @_;
486
487 Echolot::Log::logdie("Pidfile '".Echolot::Config::get()->{'pidfile'}."' exists\n")
488 if pid_exists(0);
489 open (PIDFILE, '>'.Echolot::Config::get()->{'pidfile'}) or
490 Echolot::Log::logdie("Cannot open pidfile '".Echolot::Config::get()->{'pidfile'}."': $!");
491 print PIDFILE "$PROCESS_ID ".Echolot::Globals::get()->{'hostname'}." ".time()."\n";
492 close PIDFILE;
493
494 Echolot::Globals::initStorage();
495 setSigHandlers();
496
497 Echolot::Globals::get()->{'scheduler'} = new Echolot::Scheduler;
498 my $scheduler = Echolot::Globals::get()->{'scheduler'};
499 $scheduler->add('exit' , -1 , 0, 'exit' );
500 $scheduler->add('readcommands' , -1 , 0, \&Echolot::Commands::processCommands );
501
502 $scheduler->add('processmail' , Echolot::Config::get()->{'processmail'} , 0, \&Echolot::Mailin::process );
503 $scheduler->add('ping' , Echolot::Config::get()->{'pinger_interval'} , 0, \&Echolot::Pinger::send_pings );
504 $scheduler->add('buildstats' , Echolot::Config::get()->{'buildstats'} , 0, \&Echolot::Stats::build_stats );
505 $scheduler->add('buildkeys' , Echolot::Config::get()->{'buildkeys'} , 0, \&Echolot::Stats::build_keys );
506 $scheduler->add('buildthesaurus' , Echolot::Config::get()->{'buildthesaurus'} , 0, \&Echolot::Thesaurus::build_thesaurus );
507
508 $scheduler->add('metadata_backup' , Echolot::Config::get()->{'metadata_backup'} , 0, \&metadata_backup );
509 $scheduler->add('commitprospectives' , Echolot::Config::get()->{'commitprospectives'} , 0, \&commit_prospective_address );
510 $scheduler->add('expire' , Echolot::Config::get()->{'expire'} , 0, \&expire );
511 $scheduler->add('getkeyconf' , Echolot::Config::get()->{'getkeyconf_interval'}, 0, \&Echolot::Conf::send_requests );
512 $scheduler->add('check_resurrection' , Echolot::Config::get()->{'check_resurrection'} , 0, \&Echolot::Conf::check_resurrection );
513
514 Echolot::Globals::get()->{'scheduler'}->schedule('readcommands', 0, time() )
515 if ($process);
516
517 $scheduler->run();
518
519 Echolot::Globals::get()->{'storage'}->commit();
520 Echolot::Globals::get()->{'storage'}->finish();
521
522 unlink (Echolot::Config::get()->{'pidfile'}) or
523 Echolot::Log::warn ("Cannot unlink pidfile ".Echolot::Config::get()->{'pidfile'}.".");
524 };
525
526 sub send_sig($) {
527 my ($sig) = @_;
528
529 die ("Pidfile '".Echolot::Config::get()->{'pidfile'}."' does not exist\n")
530 unless pid_exists(0);
531 open (PIDFILE, '<'.Echolot::Config::get()->{'pidfile'}) or
532 confess ("Cannot open pidfile '".Echolot::Config::get()->{'pidfile'}."': $!\n");
533 my $line = <PIDFILE>;
534 close PIDFILE;
535
536 my ($pid, $host, $time) = $line =~ /^(\d+) \s+ (\S+) \s+ (\d+) \s* $/x or
537 confess ("Cannot parse pidfile '$line'\n");
538 my $sent = kill $sig, $pid;
539 ($sent == 1) or
540 confess ("Did not send signal $sig to exactly one process but $sent. (pidfile reads $line)\n");
541 };
542
543 sub daemon_hup() {
544 send_sig(1);
545 };
546
547 sub daemon_stop() {
548 send_sig(15);
549 };
550
551 sub make_dirs() {
552 for my $dir (
553 Echolot::Config::get()->{'resultdir'},
554 Echolot::Config::get()->{'thesaurusdir'},
555 ) {
556 if ( ! -d $dir ) {
557 mkdir ($dir, 0755) or
558 confess ("Cannot create directory $dir: $!\n");
559 };
560 };
561 my @dirs = (
562 Echolot::Config::get()->{'private_resultdir'},
563 Echolot::Config::get()->{'gnupghome'},
564 Echolot::Config::get()->{'mixhome'},
565 Echolot::Config::get()->{'tmpdir'},
566 Echolot::Config::get()->{'storage'}->{'File'}->{'basedir'},
567 Echolot::Config::get()->{'mailerrordir'},
568 Echolot::Config::get()->{'mailerrordir'}.'/cur',
569 Echolot::Config::get()->{'mailerrordir'}.'/tmp',
570 Echolot::Config::get()->{'mailerrordir'}.'/new');
571 push @dirs, (
572 Echolot::Config::get()->{'mailin'}.'/cur',
573 Echolot::Config::get()->{'mailin'}.'/tmp',
574 Echolot::Config::get()->{'mailin'}.'/new' )
575 if (-d Echolot::Config::get()->{'mailin'});
576
577 for my $dir (@dirs) {
578 if ( ! -d $dir ) {
579 mkdir ($dir, 0700) or
580 confess ("Cannot create directory $dir: $!\n");
581 };
582 };
583 };
584
585 sub hup_if_wanted($) {
586 my ($nohup) = @_;
587 if (!$nohup && pid_exists(0)) {
588 daemon_hup()
589 } else {
590 print "Don't forget to run $PROGRAM_NAME process.\n";
591 };
592 };
593
594
595
596
597
598
599
600
601
602
603 my $params = { basedir => $Bin };
604 $params->{'basedir'} = $ENV{'ECHOLOT_HOME'} if (defined $ENV{'ECHOLOT_HOME'});
605
606 Getopt::Long::config('bundling');
607 if (!GetOptions (
608 'help' => \$params->{'help'},
609 'version' => \$params->{'version'},
610 'verbose+' => \$params->{'verbose'},
611 'nohup' => \$params->{'nohup'},
612 'detach' => \$params->{'detach'},
613 'process' => \$params->{'process'},
614 'basedir' => \$params->{'basedir'},
615 'quiet' => \$params->{'quiet'},
616 )) {
617 die ("$PROGRAM_NAME: Usage: $PROGRAM_NAME [-fwhv]\n");
618 };
619 if ($params->{'help'}) {
620 print ("Usage: $PROGRAM_NAME [options] command\n");
621 print ("See man pingd or perldoc pingd for more info.\n");
622 print ("echolot $VERSION - (c) 2002 Peter Palfrader <peter\@palfrader.org>\n");
623 print ("http://savannah.gnu.org/projects/echolot/\n");
624 print ("\n");
625 print ("Commands:\n");
626 print (" start starts echolot pingd\n");
627 print (" signals pingd to ... \n");
628 print (" stop ... shutdown\n");
629 print (" process ... reopen outfile and process commands\n");
630 print (" add ... add a remailer address\n");
631 print (" delete ... delete a remailer address\n");
632 print (" set ... set remailer options\n");
633 print (" setremailercaps ... set remailer capabilities manually\n");
634 print (" deleteremailercaps ... delete remailer capabilities manually\n");
635 print (" getkeyconf ... request remailer-xxx data immediatly\n");
636 print (" sendpings ... request immediate sending of pings\n");
637 print (" buildstats ... build remailer stats immediatly\n");
638 print (" buildkeys ... buid keyrings immediatly\n");
639 print (" buildthesaurus ... build thesaurus immediatly\n");
640 print (" dumpconf dump configuration\n");
641 exit 0;
642 };
643 if ($params->{'version'}) {
644 print ("echolot $VERSION\n");
645 print ("(c) 2002 Peter Palfrader <peter\@palfrader.org>\n");
646 print ("http://savannah.gnu.org/projects/echolot/\n");
647 exit 0;
648 };
649 $params->{'quiet'} = undef if ($params->{'verbose'});
650
651 my $COMMAND = shift @ARGV;
652 die ("command required\n") unless defined $COMMAND;
653
654
655 Echolot::Config::init( $params );
656 chdir( Echolot::Config::get()->{'homedir'} );
657 Echolot::Globals::init( version => $VERSION);
658
659
660 if ($COMMAND eq 'add' || $COMMAND eq 'delete') {
661 command_adddelete($COMMAND, @ARGV);
662 hup_if_wanted($params->{'nohup'});
663 } elsif ($COMMAND eq 'set') {
664 command_set(@ARGV);
665 hup_if_wanted($params->{'nohup'});
666 } elsif ($COMMAND eq 'deleteremailercaps') {
667 command_deleteremailercaps(@ARGV);
668 hup_if_wanted($params->{'nohup'});
669 } elsif ($COMMAND eq 'setremailercaps') {
670 command_setremailercaps(@ARGV);
671 hup_if_wanted($params->{'nohup'});
672 } elsif ($COMMAND eq 'getkeyconf') {
673 command_getkeyconf(@ARGV);
674 hup_if_wanted($params->{'nohup'});
675 } elsif ($COMMAND eq 'sendpings') {
676 command_sendpings(@ARGV);
677 hup_if_wanted($params->{'nohup'});
678 } elsif ($COMMAND eq 'buildstats') {
679 Echolot::Commands::addCommand("buildstats");
680 hup_if_wanted($params->{'nohup'});
681 } elsif ($COMMAND eq 'buildkeys') {
682 Echolot::Commands::addCommand("buildkeys");
683 hup_if_wanted($params->{'nohup'});
684 } elsif ($COMMAND eq 'buildthesaurus') {
685 Echolot::Commands::addCommand("buildthesaurus");
686 hup_if_wanted($params->{'nohup'});
687 } elsif ($COMMAND eq 'process') {
688 daemon_hup();
689 } elsif ($COMMAND eq 'stop') {
690 daemon_stop();
691 } elsif ($COMMAND eq 'start') {
692 # FIXME: remove stale pid files
693 die ("Pidfile '".Echolot::Config::get()->{'pidfile'}."' exists\n")
694 if pid_exists(1);
695 Echolot::Log::init();
696 make_dirs();
697 if ($params->{'detach'}) {
698 print "Detaching.\n" unless ($params->{'quiet'});
699 Echolot::Log::debug("Detaching.");
700 exit(0) if (fork());
701 POSIX::setsid();
702 exit(0) if (fork());
703 my $logfile = Echolot::Config::get()->{'logfile'};
704 open (STDOUT, ">>$logfile") or die ("Cannot open '$logfile' as STDOUT\n");
705 open (STDERR, ">&STDOUT") or die ("Cannot dup STDOUT as STDERR\n");
706 open (STDIN , "</dev/null") or die ("Cannot open /dev/null as STDIN\n");
707 $redirected_stdio = 1;
708 Echolot::Log::info "Starting up.";
709 daemon_run( $params->{'process'} );
710 Echolot::Log::info "Shutdown complete.";
711 } else {
712 daemon_run( $params->{'process'} );
713 };
714 } elsif ($COMMAND eq 'dumpconf') {
715 Echolot::Config::dump();
716 } elsif ($COMMAND eq 'convert') {
717 Echolot::Globals::initStorage();
718 setSigHandlers();
719
720 Echolot::Globals::get()->{'storage'}->convert();
721
722 Echolot::Globals::get()->{'storage'}->commit();
723 Echolot::Globals::get()->{'storage'}->finish();
724 } else {
725 die ("Command $COMMAND unknown");
726 };
727
728 exit 0;
729
730 # vim: set ts=4 shiftwidth=4:

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.5