#!/usr/bin/perl -w

=head1 NAME

dh_installinit - install init scripts and/or upstart jobs into package build directories

=cut

use strict;
use Debian::Debhelper::Dh_Lib;

=head1 SYNOPSIS

B<dh_installinit> [S<I<debhelper options>>] [B<--name=>I<name>] [B<-n>] [B<-R>] [B<-r>] [B<-d>] [S<B<--> I<params>>]

=head1 DESCRIPTION

B<dh_installinit> is a debhelper program that is responsible for installing
init scripts with associated defaults files, as well as upstart job files
into package build directories.

It also automatically generates the F<postinst> and F<postrm> and F<prerm>
commands needed to set up the symlinks in F</etc/rc*.d/> to start and stop
the init scripts.

=head1 FILES

=over 4

=item debian/I<package>.init

If this exists, it is installed into etc/init.d/I<package> in the package
build directory.

=item debian/I<package>.default

If this exists, it is installed into etc/default/I<package> in the package
build directory.

=item debian/I<package>.upstart

If this exists, it is installed into etc/init/I<package>.conf in the package
build directory.

=back

=head1 OPTIONS

=over 4

=item B<-n>, B<--noscripts>

Do not modify F<postinst>/F<postrm>/F<prerm> scripts.

=item B<-o>, B<--onlyscripts>

Only modify F<postinst>/F<postrm>/F<prerm> scripts, do not actually install any init
script, default files, or upstart job. May be useful if the init script or
upstart job is shipped and/or installed by upstream in a way that doesn't
make it easy to let B<dh_installinit> find it.

=item B<-R>, B<--restart-after-upgrade>

Do not stop the init script until after the package upgrade has been
completed. This is different than the default behavior, which stops the
script in the F<prerm>, and starts it again in the F<postinst>.

This can be useful for daemons that should not have a possibly long
downtime during upgrade. But you should make sure that the daemon will not
get confused by the package being upgraded while it's running before using
this option.

=item B<-r>, B<--no-restart-on-upgrade>

Do not stop init script on upgrade.

=item B<--no-start>

Do not start the init script on install or upgrade, or stop it on removal.
Only call B<update-rc.d>. Useful for rcS scripts.

=item B<-d>, B<--remove-d>

Remove trailing B<d> from the name of the package, and use the result for the
filename the upstart job file is installed as in F<etc/init/> , and for the
filename the init script is installed as in etc/init.d and the default file
is installed as in F<etc/default/> . This may be useful for daemons with names
ending in B<d>. (Note: this takes precedence over the B<--init-script> parameter
described below.)

=item B<-u>I<params> B<--update-rcd-params=>I<params>

=item B<--> I<params>

Pass I<params> to L<update-rc.d(8)>. If not specified, B<defaults> will be
passed to L<update-rc.d(8)>.

=item B<--name=>I<name>

Install the init script (and default file) as well as upstart job file
using the filename I<name> instead of the default filename, which is
the package name. When this parameter is used, B<dh_installinit> looks
for and installs files named F<debian/package.name.init>,
F<debian/package.name.default> and F<debian/package.name.upstart>
instead of the usual F<debian/package.init>, F<debian/package.default> and
F<debian/package.upstart>.

=item B<--init-script=>I<scriptname>

Use I<scriptname> as the filename the init script is installed as in
F<etc/init.d/> (and also use it as the filename for the defaults file, if it
is installed). If you use this parameter, B<dh_installinit> will look to see
if a file in the F<debian/> directory exists that looks like
F<package.scriptname> and if so will install it as the init script in
preference to the files it normally installs.

This parameter is deprecated, use the B<--name> parameter instead. This
parameter is incompatible with the use of upstart jobs.

=item B<--error-handler=>I<function>

Call the named shell I<function> if running the init script fails. The
function should be provided in the F<prerm> and F<postinst> scripts, before the
B<#DEBHELPER#> token.

=back

=head1 NOTES

Note that this command is not idempotent. L<dh_prep(1)> should be called
between invocations of this command. Otherwise, it may cause multiple
instances of the same text to be added to maintainer scripts.

=cut

init(options => {
	"r" => \$dh{R_FLAG},
	"no-restart-on-upgrade" => \$dh{R_FLAG},
	"no-start" => \$dh{NO_START},
	"R|restart-after-upgrade" => \$dh{RESTART_AFTER_UPGRADE},
	"init-script=s" => \$dh{INIT_SCRIPT},
	"update-rcd-params=s", => \$dh{U_PARAMS},
	"remove-d" => \$dh{D_FLAG},
});

foreach my $package (@{$dh{DOPACKAGES}}) {
	my $tmp=tmpdir($package);

	# Figure out what filename to install it as.
	my $script;
	my $jobfile=$package;
	if (defined $dh{NAME}) {
		$jobfile=$script=$dh{NAME};
	}
	elsif ($dh{D_FLAG}) {
		# -d on the command line sets D_FLAG. We will 
		# remove a trailing 'd' from the package name and 
		# use that as the name.
		$script=$package;
		if ($script=~m/(.*)d$/) {
			$jobfile=$script=$1;
		}
		else {
			warning("\"$package\" has no final d' in its name, but -d was specified.");
		}
	}       
	elsif ($dh{INIT_SCRIPT}) {
		$script=$dh{INIT_SCRIPT};
	}
	else {
		$script=$package;
	}       

	my $job=pkgfile($package,"upstart");

	if ($job ne '' && ! $dh{ONLYSCRIPTS}) {
		if (! -d "$tmp/etc/init") {
			doit("install","-d","$tmp/etc/init");
		}
		
		doit("install","-p","-m644",$job,"$tmp/etc/init/$jobfile.conf");
	}

	my $default=pkgfile($package,'default');
	if ($default ne '' && ! $dh{ONLYSCRIPTS}) {
		if (! -d "$tmp/etc/default") {
			doit("install","-d","$tmp/etc/default");
		}
		doit("install","-p","-m644",$default,"$tmp/etc/default/$script");
	}

	my $init=pkgfile($package,$script) || pkgfile($package,"init") ||
		pkgfile($package,"init.d");
	if ($init ne '' && ! $dh{ONLYSCRIPTS}) {
		if (! -d "$tmp/etc/init.d") {
			doit("install","-d","$tmp/etc/init.d");
		}
		
		doit("install","-p","-m755",$init,"$tmp/etc/init.d/$script");
	}

	if ($dh{INIT_SCRIPT} && $job ne '' && $init ne '') {
		error("Can't use --init-script with an upstart job");
	}

	if ($job ne '' || $init ne '' || $dh{ONLYSCRIPTS}) {
		# This is set by the -u "foo" command line switch, it's
		# the parameters to pass to update-rc.d. If not set,
		# we have to say "defaults".
		my $params='';
		if (defined($dh{U_PARAMS})) {
			$params=join(' ',@{$dh{U_PARAMS}});
		}	
		if ($params eq '') {
			$params="defaults";
		}
		
		if (! $dh{NOSCRIPTS}) {
			if (! $dh{NO_START}) {
				if ($dh{RESTART_AFTER_UPGRADE}) {
					# update-rc.d, and restart (or
					# start if new install) script
					autoscript($package,"postinst", "postinst-init-restart",
						"s/#SCRIPT#/$script/;s/#INITPARMS#/$params/;s/#ERROR_HANDLER#/$dh{ERROR_HANDLER}/");
				}
				else {
					# update-rc.d, and start script
					autoscript($package,"postinst", "postinst-init",
						"s/#SCRIPT#/$script/;s/#INITPARMS#/$params/;s/#ERROR_HANDLER#/$dh{ERROR_HANDLER}/");
				}
			
				if ($dh{R_FLAG} || $dh{RESTART_AFTER_UPGRADE}) {
					# stops script only on remove
					autoscript($package,"prerm","prerm-init-norestart",
						"s/#SCRIPT#/$script/;s/#INITPARMS#/$params/;s/#ERROR_HANDLER#/$dh{ERROR_HANDLER}/");
				}
				else {
					# always stops script
					autoscript($package,"prerm","prerm-init",
						"s/#SCRIPT#/$script/;s/#INITPARMS#/$params/;s/#ERROR_HANDLER#/$dh{ERROR_HANDLER}/");
				}
			}
			else {
				# just update-rc.d
				autoscript($package,"postinst", "postinst-init-nostart",
					"s/#SCRIPT#/$script/;s/#INITPARMS#/$params/;s/#ERROR_HANDLER#/$dh{ERROR_HANDLER}/");
			}

			# removes rc.d links
			autoscript($package,"postrm","postrm-init",
				"s/#SCRIPT#/$script/;s/#INITPARMS#/$params/;s/#ERROR_HANDLER#/$dh{ERROR_HANDLER}/");
		}
	}
}

=head1 SEE ALSO

L<debhelper(7)>

This program is a part of debhelper.

=head1 AUTHORS

Joey Hess <joeyh@debian.org>

Steve Langasek <steve.langasek@canonical.com>

=cut
