Codebase list fusioninventory-agent / debian/2.2.1-1 fusioninventory-win32-service
debian/2.2.1-1

Tree @debian/2.2.1-1 (Download .tar.gz)

fusioninventory-win32-service @debian/2.2.1-1raw · history · blame

#!/usr/bin/perl

use strict;
use warnings;
use lib './lib';
use threads;
use threads::shared;
use constant SERVICE_SLEEP_TIME => 2000; # 20 milliseconds

use File::Spec;
use File::Basename;

use English qw(-no_match_vars);
use Win32;
use Win32::Daemon;

use FusionInventory::Agent;

delete($ENV{PERL5LIB});
delete($ENV{PERLLIB});

my $directory = dirname(File::Spec->rel2abs( __FILE__ ));
# on Win2k, Windows do not chdir to the bin directory
# we need to do it by ourself
chdir($directory);

Win32::Daemon::StartService();

my $thread;
my $state;
my $previousState = SERVICE_START_PENDING;

while (($state = Win32::Daemon::State()) != SERVICE_STOPPED) { 
    if ($state == SERVICE_START_PENDING) {
        # Initialization code
        startAgent();
        Win32::Daemon::State(SERVICE_RUNNING);
        $previousState = SERVICE_RUNNING;
    } elsif ($state == SERVICE_STOP_PENDING) {
        killAgent();
        Win32::Daemon::State(SERVICE_STOPPED);
    } elsif ($state == SERVICE_PAUSE_PENDING) {
        # "Pausing...";
        killAgent();
        Win32::Daemon::State(SERVICE_PAUSED);
        $previousState = SERVICE_PAUSED;
        killAgent();
        next;
    } elsif ($state == SERVICE_CONTINUE_PENDING) {
        # "Resuming...";
        startAgent();
        Win32::Daemon::State(SERVICE_RUNNING);
        $previousState = SERVICE_RUNNING;
        next;
    } elsif ($state == SERVICE_STOP_PENDING) {
        # "Stopping...";
        killAgent();
        Win32::Daemon::State(SERVICE_STOPPED);
        $previousState = SERVICE_STOPPED;
        next;
    } elsif ($state == SERVICE_RUNNING) {
        # The service is running as normal...
        # ...add the main code here...
        startAgent();
    } else {
        # Got an unhandled control message. Set the state to
        # whatever the previous state was.
        Win32::Daemon::State($previousState);
    }

    # Check for any outstanding commands. Pass in a non zero value
    # and it resets the Last Message to SERVICE_CONTROL_NONE.
    if (SERVICE_CONTROL_NONE != (my $message = getMessage())) {
        if (SERVICE_CONTROL_INTERROGATE == $message) {
            # Got here if the Service Control Manager is requesting
            # the current state of the service. This can happen for
            # a variety of reasons. Report the last state we set.
            Win32::Daemon::State($previousState);
        } elsif (SERVICE_CONTROL_SHUTDOWN == $message) {
            # Yikes! The system is shutting down. We had better clean up
            # and stop.
            # Tell the SCM that we are preparing to shutdown and that we expect
            # it to take 25 seconds, so don't terminate us for at least
            # 25 seconds...
            Win32::Daemon::State(SERVICE_STOP_PENDING, 25000);
        }
    }
    # Snoose for awhile so we don't suck up cpu time...
    Win32::Sleep(SERVICE_SLEEP_TIME);
}

sub getMessage {
    if ($Win32::Daemon::VERSION < 20101014) {
        return Win32::Daemon::LastControlMessage(1);
    } else {
        return Win32::Daemon::QueryLastMessage();
    }
}

sub startAgent {
    return if $thread;
    $thread = threads->create(sub {
        my $agent = FusionInventory::Agent->new(
            confdir => $directory . '/../../etc/fusioninventory',
            datadir => $directory . '/../../share',
            vardir  => $directory . '/../../var',
            libdir  => $directory . '/../../lib',
        );
        $agent->init(options => { service => 1 });
        $agent->run();
    });
}

sub killAgent {
    $thread->kill('KILL');
    $thread = undef;
}

__END__

=head1 NAME

fusioninventory-win32-service - FusionInventory Agent service for Windows