#!@l_prefix@/bin/perl

##
##  Copyright (c) 2004  Klaraelvdalens Datakonsult AB
##  Copyright (c) 2003  Code Fusion cc
##
##    Writen by Stuart Bing?<s.binge@codefusion.co.za>
##    Portions based on work by the following people:
##
##      (c) 2003  Tassilo Erlewein  <tassilo.erlewein@erfrakon.de>
##      (c) 2003  Martin Konold     <martin.konold@erfrakon.de>
##      (c) 2003  Achim Frank       <achim.frank@erfrakon.de>
##
##
##  This  program is free  software; you can redistribute  it and/or
##  modify it  under the terms of the GNU  General Public License as
##  published by the  Free Software Foundation; either version 2, or
##  (at your option) any later version.
##
##  This program is  distributed in the hope that it will be useful,
##  but WITHOUT  ANY WARRANTY; without even the  implied warranty of
##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
##  General Public License for more details.
##
##  You can view the  GNU General Public License, online, at the GNU
##  Project's homepage; see <http://www.gnu.org/licenses/gpl.html>.
##

#
#  Module prefixes in the logs:
#    K: kolabd
#    C: Config
#    T: Templates
#    L: LDAP
#    Y: Cyrus
#    B: Backend
#    KC: kolabconf
#    DS: DirServ
#    Anything else: the various backends
#

use strict;
use Sys::Syslog;
use IO::File;
use Kolab;
use Kolab::Util;
use Kolab::DirServ;
use Kolab::LDAP;
use Kolab::LDAP::Backend;
use vars qw(%pids);

openlog('kolabd', 'cons, pid', 'user');

my $prefix = $Kolab::config{'prefix'};
my $pidfile = IO::File->new("$prefix/var/kolab/kolab.pid", 'w+')
    || die "Unable to open PID file `$prefix/var/kolab/kolab.pid'";
print $pidfile $$;
undef $pidfile;

sub sigInt
{
    Kolab::Util::superLog('Kolab is shutting down');

    Kolab::log('K', 'SIGINT/SIGTERM detected, kill()ing children');

    foreach my $pid (keys %pids) {
        kill('INT', $pid);
        waitpid($pid, 0);
    }

    Kolab::LDAP::shutdown;

    Kolab::log('K', 'Exiting');
    exit(0);
}

sub sigHup
{
    Kolab::log('K', 'Refreshing configuration');
    foreach my $pid (keys %pids) {
        kill('INT', $pid);
        waitpid($pid, 0);
    }
    %pids = ();
    Kolab::reloadConfig;
    Kolab::log('K', 'Synchronising');
    Kolab::LDAP::sync;
    Kolab::log('K', 'Reloading addressbook.peers');
    Kolab::DirServ::reloadPeers;
    Kolab::log('K', 'Finished refresh');
    &run;
}

sub sigDie {
  Kolab::log( 'K', $_[0], KOLAB_ERROR );
}

sub run
{
    my $pid;
    my $finished = 0;
    foreach my $backend (keys %Kolab::LDAP::Backend::backends) {
        Kolab::log('K', "Forking `$backend' listener");
        $pid = fork;
        if (!defined($pid)) {
	    Kolab::log('K', "Unable to fork `$backend' listener", KOLAB_ERROR);
            exit(1);
        }

        if ($pid) {
            $pids{$pid} = 1;
            $finished++;
            next;
        }
        Kolab::LDAP::Backend::run($backend);

        Kolab::log('K', "`$backend' returned");
	# exit with 0 status to avoid killing daemon
	exit(0);
    }

    $SIG{'INT'} = \&sigInt;
    $SIG{'TERM'} = \&sigInt;
    $SIG{'HUP'} = \&sigHup;
    $SIG{__DIE__} = \&sigDie;

    Kolab::log('K', 'Listeners spawned, wait()ing');

    while ($finished > 0) {
        wait;
        if ($?) {
            Kolab::log('K', 'Abnormal child exit status encountered, aborting');
            kill('INT', $$);
        } else {
            Kolab::log('K', 'Child terminated normally');
        }
    }
}

print 'kolabd - Kolab Backend Daemon

  Copyright (c) 2004  Klaraelvdalens Datakonsult AB
  Copyright (c) 2003  Code Fusion cc
  Copyright (c) 2003  Tassilo Erlewein, Martin Konold, Achim Frank

This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
';

Kolab::Util::superLog('Kolab is starting up');

eval {
  Kolab::LDAP::startup;

  Kolab::log('K', 'Loading backends');
  Kolab::LDAP::Backend::load;
  Kolab::LDAP::Backend::load('user');
  Kolab::LDAP::Backend::load('sf');
  Kolab::LDAP::Backend::load('dirservd',1);
  
  Kolab::log('K', 'Performing backend startup');
  &Kolab::LDAP::Backend::startup;
  
  Kolab::log('K', 'Synchronising');
  Kolab::LDAP::sync;
  
  Kolab::log('K', 'Synchronisation complete, starting up daemon');
  run;
}; Kolab::log( 'K', $@, KOLAB_ERROR ) if $@;

