Current Dir: /snap/core22/2955/usr/sbin/

[FILE] aa-remove-unknown [ edit | delete | rename ]
[FILE] aa-status [ edit | delete | rename ]
[FILE] aa-teardown [ edit | delete | rename ]
[FILE] add-shell [ edit | delete | rename ]
[FILE] addgroup [ edit | delete | rename ]
[FILE] adduser [ edit | delete | rename ]
[FILE] agetty [ edit | delete | rename ]
[FILE] apparmor_parser [ edit | delete | rename ]
[FILE] apparmor_status [ edit | delete | rename ]
[FILE] arpd [ edit | delete | rename ]
[FILE] arptables [ edit | delete | rename ]
[FILE] arptables-nft [ edit | delete | rename ]
[FILE] arptables-nft-restore [ edit | delete | rename ]
[FILE] arptables-nft-save [ edit | delete | rename ]
[FILE] arptables-restore [ edit | delete | rename ]
[FILE] arptables-save [ edit | delete | rename ]
[FILE] badblocks [ edit | delete | rename ]
[FILE] blkdeactivate [ edit | delete | rename ]
[FILE] blkdiscard [ edit | delete | rename ]
[FILE] blkid [ edit | delete | rename ]
[FILE] blkzone [ edit | delete | rename ]
[FILE] blockdev [ edit | delete | rename ]
[FILE] bridge [ edit | delete | rename ]
[FILE] capsh [ edit | delete | rename ]
[FILE] cfdisk [ edit | delete | rename ]
[FILE] chcpu [ edit | delete | rename ]
[FILE] chgpasswd [ edit | delete | rename ]
[FILE] chmem [ edit | delete | rename ]
[FILE] chpasswd [ edit | delete | rename ]
[FILE] chroot [ edit | delete | rename ]
[FILE] cpgr [ edit | delete | rename ]
[FILE] cppw [ edit | delete | rename ]
[FILE] cryptdisks_start [ edit | delete | rename ]
[FILE] cryptdisks_stop [ edit | delete | rename ]
[FILE] cryptsetup [ edit | delete | rename ]
[FILE] cryptsetup-reencrypt [ edit | delete | rename ]
[FILE] cryptsetup-ssh [ edit | delete | rename ]
[FILE] ctrlaltdel [ edit | delete | rename ]
[FILE] dcb [ edit | delete | rename ]
[FILE] debugfs [ edit | delete | rename ]
[FILE] delgroup [ edit | delete | rename ]
[FILE] deluser [ edit | delete | rename ]
[FILE] depmod [ edit | delete | rename ]
[FILE] devlink [ edit | delete | rename ]
[FILE] dhclient [ edit | delete | rename ]
[FILE] dhclient-script [ edit | delete | rename ]
[FILE] dmsetup [ edit | delete | rename ]
[FILE] dmstats [ edit | delete | rename ]
[FILE] dosfsck [ edit | delete | rename ]
[FILE] dosfslabel [ edit | delete | rename ]
[FILE] dumpe2fs [ edit | delete | rename ]
[FILE] e2freefrag [ edit | delete | rename ]
[FILE] e2fsck [ edit | delete | rename ]
[FILE] e2image [ edit | delete | rename ]
[FILE] e2label [ edit | delete | rename ]
[FILE] e2mmpstatus [ edit | delete | rename ]
[FILE] e2scrub [ edit | delete | rename ]
[FILE] e2scrub_all [ edit | delete | rename ]
[FILE] e2undo [ edit | delete | rename ]
[FILE] e4crypt [ edit | delete | rename ]
[FILE] e4defrag [ edit | delete | rename ]
[FILE] ebtables [ edit | delete | rename ]
[FILE] ebtables-nft [ edit | delete | rename ]
[FILE] ebtables-nft-restore [ edit | delete | rename ]
[FILE] ebtables-nft-save [ edit | delete | rename ]
[FILE] ebtables-restore [ edit | delete | rename ]
[FILE] ebtables-save [ edit | delete | rename ]
[FILE] faillock [ edit | delete | rename ]
[FILE] fatlabel [ edit | delete | rename ]
[FILE] fdisk [ edit | delete | rename ]
[FILE] filefrag [ edit | delete | rename ]
[FILE] findfs [ edit | delete | rename ]
[FILE] fsck [ edit | delete | rename ]
[FILE] fsck.cramfs [ edit | delete | rename ]
[FILE] fsck.ext2 [ edit | delete | rename ]
[FILE] fsck.ext3 [ edit | delete | rename ]
[FILE] fsck.ext4 [ edit | delete | rename ]
[FILE] fsck.fat [ edit | delete | rename ]
[FILE] fsck.minix [ edit | delete | rename ]
[FILE] fsck.msdos [ edit | delete | rename ]
[FILE] fsck.vfat [ edit | delete | rename ]
[FILE] fsfreeze [ edit | delete | rename ]
[FILE] fstab-decode [ edit | delete | rename ]
[FILE] fstrim [ edit | delete | rename ]
[FILE] genl [ edit | delete | rename ]
[FILE] getcap [ edit | delete | rename ]
[FILE] getpcaps [ edit | delete | rename ]
[FILE] getty [ edit | delete | rename ]
[FILE] groupadd [ edit | delete | rename ]
[FILE] groupdel [ edit | delete | rename ]
[FILE] groupmems [ edit | delete | rename ]
[FILE] groupmod [ edit | delete | rename ]
[FILE] grpck [ edit | delete | rename ]
[FILE] grpconv [ edit | delete | rename ]
[FILE] grpunconv [ edit | delete | rename ]
[FILE] halt [ edit | delete | rename ]
[FILE] hwclock [ edit | delete | rename ]
[FILE] iconvconfig [ edit | delete | rename ]
[FILE] init [ edit | delete | rename ]
[FILE] insmod [ edit | delete | rename ]
[FILE] installkernel [ edit | delete | rename ]
[FILE] integritysetup [ edit | delete | rename ]
[FILE] invoke-rc.d [ edit | delete | rename ]
[FILE] ip [ edit | delete | rename ]
[FILE] ip6tables [ edit | delete | rename ]
[FILE] ip6tables-apply [ edit | delete | rename ]
[FILE] ip6tables-legacy [ edit | delete | rename ]
[FILE] ip6tables-legacy-restore [ edit | delete | rename ]
[FILE] ip6tables-legacy-save [ edit | delete | rename ]
[FILE] ip6tables-nft [ edit | delete | rename ]
[FILE] ip6tables-nft-restore [ edit | delete | rename ]
[FILE] ip6tables-nft-save [ edit | delete | rename ]
[FILE] ip6tables-restore [ edit | delete | rename ]
[FILE] ip6tables-restore-translate [ edit | delete | rename ]
[FILE] ip6tables-save [ edit | delete | rename ]
[FILE] ip6tables-translate [ edit | delete | rename ]
[FILE] iptables [ edit | delete | rename ]
[FILE] iptables-apply [ edit | delete | rename ]
[FILE] iptables-legacy [ edit | delete | rename ]
[FILE] iptables-legacy-restore [ edit | delete | rename ]
[FILE] iptables-legacy-save [ edit | delete | rename ]
[FILE] iptables-nft [ edit | delete | rename ]
[FILE] iptables-nft-restore [ edit | delete | rename ]
[FILE] iptables-nft-save [ edit | delete | rename ]
[FILE] iptables-restore [ edit | delete | rename ]
[FILE] iptables-restore-translate [ edit | delete | rename ]
[FILE] iptables-save [ edit | delete | rename ]
[FILE] iptables-translate [ edit | delete | rename ]
[FILE] isosize [ edit | delete | rename ]
[FILE] killall5 [ edit | delete | rename ]
[FILE] ldattach [ edit | delete | rename ]
[FILE] ldconfig [ edit | delete | rename ]
[FILE] ldconfig.real [ edit | delete | rename ]
[FILE] logsave [ edit | delete | rename ]
[FILE] losetup [ edit | delete | rename ]
[FILE] lsmod [ edit | delete | rename ]
[FILE] luksformat [ edit | delete | rename ]
[FILE] mkdosfs [ edit | delete | rename ]
[FILE] mke2fs [ edit | delete | rename ]
[FILE] mkfs [ edit | delete | rename ]
[FILE] mkfs.bfs [ edit | delete | rename ]
[FILE] mkfs.cramfs [ edit | delete | rename ]
[FILE] mkfs.ext2 [ edit | delete | rename ]
[FILE] mkfs.ext3 [ edit | delete | rename ]
[FILE] mkfs.ext4 [ edit | delete | rename ]
[FILE] mkfs.fat [ edit | delete | rename ]
[FILE] mkfs.minix [ edit | delete | rename ]
[FILE] mkfs.msdos [ edit | delete | rename ]
[FILE] mkfs.vfat [ edit | delete | rename ]
[FILE] mkhomedir_helper [ edit | delete | rename ]
[FILE] mklost+found [ edit | delete | rename ]
[FILE] mkswap [ edit | delete | rename ]
[FILE] modinfo [ edit | delete | rename ]
[FILE] modprobe [ edit | delete | rename ]
[FILE] netplan [ edit | delete | rename ]
[FILE] newusers [ edit | delete | rename ]
[FILE] nfnl_osf [ edit | delete | rename ]
[FILE] nologin [ edit | delete | rename ]
[FILE] pam-auth-update [ edit | delete | rename ]
[FILE] pam_extrausers_chkpwd [ edit | delete | rename ]
[FILE] pam_extrausers_update [ edit | delete | rename ]
[FILE] pam_getenv [ edit | delete | rename ]
[FILE] pam_timestamp_check [ edit | delete | rename ]
[FILE] pivot_root [ edit | delete | rename ]
[FILE] plymouthd [ edit | delete | rename ]
[FILE] poweroff [ edit | delete | rename ]
[FILE] pwck [ edit | delete | rename ]
[FILE] pwconv [ edit | delete | rename ]
[FILE] pwunconv [ edit | delete | rename ]
[FILE] readprofile [ edit | delete | rename ]
[FILE] reboot [ edit | delete | rename ]
[FILE] remove-shell [ edit | delete | rename ]
[FILE] resize2fs [ edit | delete | rename ]
[FILE] rfkill [ edit | delete | rename ]
[FILE] rmmod [ edit | delete | rename ]
[FILE] rmt [ edit | delete | rename ]
[FILE] rmt-tar [ edit | delete | rename ]
[FILE] rtacct [ edit | delete | rename ]
[FILE] rtcwake [ edit | delete | rename ]
[FILE] rtmon [ edit | delete | rename ]
[FILE] runlevel [ edit | delete | rename ]
[FILE] runuser [ edit | delete | rename ]
[FILE] service [ edit | delete | rename ]
[FILE] setcap [ edit | delete | rename ]
[FILE] sfdisk [ edit | delete | rename ]
[FILE] shadowconfig [ edit | delete | rename ]
[FILE] shutdown [ edit | delete | rename ]
[FILE] sshd [ edit | delete | rename ]
[FILE] start-stop-daemon [ edit | delete | rename ]
[FILE] sudo_logsrvd [ edit | delete | rename ]
[FILE] sudo_sendlog [ edit | delete | rename ]
[FILE] sulogin [ edit | delete | rename ]
[FILE] swaplabel [ edit | delete | rename ]
[FILE] swapoff [ edit | delete | rename ]
[FILE] swapon [ edit | delete | rename ]
[FILE] switch_root [ edit | delete | rename ]
[FILE] sysctl [ edit | delete | rename ]
[FILE] tarcat [ edit | delete | rename ]
[FILE] tc [ edit | delete | rename ]
[FILE] telinit [ edit | delete | rename ]
[FILE] tipc [ edit | delete | rename ]
[FILE] tune2fs [ edit | delete | rename ]
[FILE] tzconfig [ edit | delete | rename ]
[FILE] unix_chkpwd [ edit | delete | rename ]
[FILE] unix_update [ edit | delete | rename ]
[FILE] update-ca-certificates [ edit | delete | rename ]
[FILE] update-passwd [ edit | delete | rename ]
[FILE] update-rc.d [ edit | delete | rename ]
[FILE] update-shells [ edit | delete | rename ]
[FILE] useradd [ edit | delete | rename ]
[FILE] userdel [ edit | delete | rename ]
[FILE] usermod [ edit | delete | rename ]
[FILE] vdpa [ edit | delete | rename ]
[FILE] veritysetup [ edit | delete | rename ]
[FILE] vigr [ edit | delete | rename ]
[FILE] vipw [ edit | delete | rename ]
[FILE] visudo [ edit | delete | rename ]
[FILE] wipefs [ edit | delete | rename ]
[FILE] wpa_action [ edit | delete | rename ]
[FILE] wpa_cli [ edit | delete | rename ]
[FILE] wpa_supplicant [ edit | delete | rename ]
[FILE] xtables-legacy-multi [ edit | delete | rename ]
[FILE] xtables-monitor [ edit | delete | rename ]
[FILE] xtables-nft-multi [ edit | delete | rename ]
[FILE] zic [ edit | delete | rename ]
[FILE] zramctl [ edit | delete | rename ]

Viewing: /snap/core22/2955/usr/sbin/update-rc.d

#! /usr/bin/perl
# vim: ft=perl
#
# update-rc.d	Update the links in /etc/rc[0-9S].d/
#

use strict;
use warnings;
# NB: All Perl modules used here must be in perl-base. Specifically, depending
# on modules in perl-modules is not okay! See bug #716923

my $initd = "/etc/init.d";
my $etcd  = "/etc/rc";

# Print usage message and die.

sub usage {
	print STDERR "update-rc.d: error: @_\n" if ($#_ >= 0);
	print STDERR <<EOF;
usage: update-rc.d [-f] <basename> remove
       update-rc.d [-f] <basename> defaults
       update-rc.d [-f] <basename> defaults-disabled
       update-rc.d <basename> disable|enable [S|2|3|4|5]
		-f: force

The disable|enable API is not stable and might change in the future.
EOF
	exit (1);
}

exit main(@ARGV);

sub info {
    print STDOUT "update-rc.d: @_\n";
}

sub warning {
    print STDERR "update-rc.d: warning: @_\n";
}

sub error {
    print STDERR "update-rc.d: error: @_\n";
    exit (1);
}

sub error_code {
    my $rc = shift;
    print STDERR "update-rc.d: error: @_\n";
    exit ($rc);
}

sub make_path {
    my ($path) = @_;
    my @dirs = ();
    my @path = split /\//, $path;
    map { push @dirs, $_; mkdir join('/', @dirs), 0755; } @path;
}

# Given a script name, return any runlevels except 0 or 6 in which the
# script is enabled.  If that gives nothing and the script is not
# explicitly disabled, return 6 if the script is disabled in runlevel
# 0 or 6.
sub script_runlevels {
    my ($scriptname) = @_;
    my @links=<"/etc/rc[S12345].d/S[0-9][0-9]$scriptname">;
    if (@links) {
        return map(substr($_, 7, 1), @links);
    } elsif (! <"/etc/rc[S12345].d/K[0-9][0-9]$scriptname">) {
        @links=<"/etc/rc[06].d/K[0-9][0-9]$scriptname">;
        return ("6") if (@links);
    } else {
	return ;
    }
}

# Map the sysvinit runlevel to that of openrc.
sub openrc_rlconv {
    my %rl_table = (
        "S" => "sysinit",
        "1" => "recovery",
        "2" => "default",
        "3" => "default",
        "4" => "default",
        "5" => "default",
        "6" => "off" );

    my %seen; # return unique runlevels
    return grep !$seen{$_}++, map($rl_table{$_}, @_);
}

sub systemd_reload {
    if (-d "/run/systemd/system") {
        system("systemctl", "daemon-reload");
    }
}

# Creates the necessary links to enable/disable a SysV init script (fallback if
# no insserv/rc-update exists)
sub make_sysv_links {
    my ($scriptname, $action) = @_;

    # for "remove" we cannot rely on the init script still being present, as
    # this gets called in postrm for purging. Just remove all symlinks.
    if ("remove" eq $action) { unlink($_) for
        glob("/etc/rc?.d/[SK][0-9][0-9]$scriptname"); return; }

    # if the service already has any links, do not touch them
    # numbers we don't care about, but enabled/disabled state we do
    return if glob("/etc/rc?.d/[SK][0-9][0-9]$scriptname");

    # for "defaults", parse Default-{Start,Stop} and create these links
    my ($lsb_start_ref, $lsb_stop_ref) = parse_def_start_stop("/etc/init.d/$scriptname");
    my $start = $action eq "defaults-disabled" ? "K" : "S";
    foreach my $lvl (@$lsb_start_ref) {
        make_path("/etc/rc$lvl.d");
        my $l = "/etc/rc$lvl.d/${start}01$scriptname";
        symlink("../init.d/$scriptname", $l);
    }

    foreach my $lvl (@$lsb_stop_ref) {
        make_path("/etc/rc$lvl.d");
        my $l = "/etc/rc$lvl.d/K01$scriptname";
        symlink("../init.d/$scriptname", $l);
    }
}

# Creates the necessary links to enable/disable the service (equivalent of an
# initscript) in systemd.
sub make_systemd_links {
    my ($scriptname, $action) = @_;

    # If called by systemctl (via systemd-sysv-install), do nothing to avoid
    # an endless loop.
    if (defined($ENV{_SKIP_SYSTEMD_NATIVE}) && $ENV{_SKIP_SYSTEMD_NATIVE} == 1) {
        return;
    }

    # If systemctl is available, let's use that to create the symlinks.
    if (-x "/bin/systemctl" || -x "/usr/bin/systemctl") {
        # Set this env var to avoid loop in systemd-sysv-install.
        local $ENV{SYSTEMCTL_SKIP_SYSV} = 1;
        # Use --quiet to mimic the old update-rc.d behaviour.
        system("systemctl", "--quiet", "$action", "$scriptname");
        return;
    }

    # In addition to the insserv call we also enable/disable the service
    # for systemd by creating the appropriate symlink in case there is a
    # native systemd service. In case systemd is not installed we do this
    # on our own instead of using systemctl.
    my $service_path;
    if (-f "/etc/systemd/system/$scriptname.service") {
        $service_path = "/etc/systemd/system/$scriptname.service";
    } elsif (-f "/lib/systemd/system/$scriptname.service") {
        $service_path = "/lib/systemd/system/$scriptname.service";
    } elsif (-f "/usr/lib/systemd/system/$scriptname.service") {
        $service_path = "/usr/lib/systemd/system/$scriptname.service";
    }
    if (defined($service_path)) {
        my $changed_sth;
        open my $fh, '<', $service_path or error("unable to read $service_path");
        while (<$fh>) {
            chomp;
            if (/^\s*WantedBy=(.+)$/i) {
                my $wants_dir = "/etc/systemd/system/$1.wants";
                my $service_link = "$wants_dir/$scriptname.service";
                if ("enable" eq $action) {
                    make_path($wants_dir);
                    symlink($service_path, $service_link);
                } else {
                    unlink($service_link) if -e $service_link;
                }
            }
        }
        close($fh);
    }
}

sub create_sequence {
    my $force = (@_);
    my $insserv = "/usr/lib/insserv/insserv";
    # Fallback for older insserv package versions [2014-04-16]
    $insserv = "/sbin/insserv" if ( -x "/sbin/insserv");
    # If insserv is not configured it is not fully installed
    my $insserv_installed = -x $insserv && -e "/etc/insserv.conf";
    my @opts;
    push(@opts, '-f') if $force;
    # Add force flag if initscripts is not installed
    # This enables inistcripts-less systems to not fail when a facility is missing
    unshift(@opts, '-f') unless is_initscripts_installed();

    my $openrc_installed = -x "/sbin/openrc";

    my $sysv_insserv ={};
    $sysv_insserv->{remove} = sub {
        my ($scriptname) = @_;
        if ( -f "/etc/init.d/$scriptname" ) {
            return system($insserv, @opts, "-r", $scriptname) >> 8;
        } else {
            # insserv removes all dangling symlinks, no need to tell it
            # what to look for.
            my $rc = system($insserv, @opts) >> 8;
            error_code($rc, "insserv rejected the script header") if $rc;
        }
    };
    $sysv_insserv->{defaults} = sub {
        my ($scriptname) = @_;
        if ( -f "/etc/init.d/$scriptname" ) {
            my $rc = system($insserv, @opts, $scriptname) >> 8;
            error_code($rc, "insserv rejected the script header") if $rc;
        } else {
            error("initscript does not exist: /etc/init.d/$scriptname");
        }
    };
    $sysv_insserv->{defaults_disabled} = sub {
        my ($scriptname) = @_;
        return if glob("/etc/rc?.d/[SK][0-9][0-9]$scriptname");
        if ( -f "/etc/init.d/$scriptname" ) {
            my $rc = system($insserv, @opts, $scriptname) >> 8;
            error_code($rc, "insserv rejected the script header") if $rc;
        } else {
            error("initscript does not exist: /etc/init.d/$scriptname");
        }
        sysv_toggle("disable", $scriptname);
    };
    $sysv_insserv->{toggle} = sub {
        my ($action, $scriptname) = (shift, shift);
        sysv_toggle($action, $scriptname, @_);

        # Call insserv to resequence modified links
        my $rc = system($insserv, @opts, $scriptname) >> 8;
        error_code($rc, "insserv rejected the script header") if $rc;
    };

    my $sysv_plain = {};
    $sysv_plain->{remove} = sub {
        my ($scriptname) = @_;
        make_sysv_links($scriptname, "remove");
    };
    $sysv_plain->{defaults} = sub {
        my ($scriptname) = @_;
        make_sysv_links($scriptname, "defaults");
    };
    $sysv_plain->{defaults_disabled} = sub {
        my ($scriptname) = @_;
        make_sysv_links($scriptname, "defaults-disabled");
    };
    $sysv_plain->{toggle} = sub {
        my ($action, $scriptname) = (shift, shift);
        sysv_toggle($action, $scriptname, @_);
    };

    my $systemd = {};
    $systemd->{remove} = sub {
        systemd_reload;
    };
    $systemd->{defaults} = sub {
        systemd_reload;
    };
    $systemd->{defaults_disabled} = sub {
        systemd_reload;
    };
    $systemd->{toggle} = sub {
        my ($action, $scriptname) = (shift, shift);
        make_systemd_links($scriptname, $action);
        systemd_reload;
    };

    # Should we check exit codeS?
    my $openrc = {};
    $openrc->{remove} = sub {
        my ($scriptname) = @_;
        system("rc-update", "-qqa", "delete", $scriptname);

    };
    $openrc->{defaults} = sub {
        my ($scriptname) = @_;
        # OpenRC does not distinguish halt and reboot.  They are handled
        # by /etc/init.d/transit instead.
        return if ("halt" eq $scriptname || "reboot" eq $scriptname);
        # no need to consider default disabled runlevels
        # because everything is disabled by openrc by default
        my @rls=script_runlevels($scriptname);
        if ( @rls ) {
            system("rc-update", "add", $scriptname, openrc_rlconv(@rls));
        }
    };
    $openrc->{defaults_disabled} = sub {
        # In openrc everything is disabled by default
    };
    $openrc->{toggle} = sub {
        my ($action, $scriptname) = (shift, shift);
        my (@toggle_lvls, $start_lvls, $stop_lvls, @symlinks);
        my $lsb_header = lsb_header_for_script($scriptname);

        # Extra arguments to disable|enable action are runlevels. If none
        # given parse LSB info for Default-Start value.
        if ($#_ >= 0) {
            @toggle_lvls = @_;
        } else {
            ($start_lvls, $stop_lvls) = parse_def_start_stop($lsb_header);
            @toggle_lvls = @$start_lvls;
            if ($#toggle_lvls < 0) {
                error("$scriptname Default-Start contains no runlevels, aborting.");
            }
        }
        my %openrc_act = ( "disable" => "del", "enable" => "add" );
        system("rc-update", $openrc_act{$action}, $scriptname,
               openrc_rlconv(@toggle_lvls))
    };

    my @sequence;
    if ($insserv_installed) {
        push @sequence, $sysv_insserv;
    }
    else {
        push @sequence, $sysv_plain;
    }
    # OpenRC has to be after sysv_{insserv,plain} because it depends on them to synchronize
    # states.
    if ($openrc_installed) {
        push @sequence, $openrc;
    }
    push @sequence, $systemd;

    return @sequence;
}

## Dependency based
sub main {
    my @args = @_;
    my $scriptname;
    my $action;
    my $force = 0;

    while($#args >= 0 && ($_ = $args[0]) =~ /^-/) {
        shift @args;
        if (/^-f$/) { $force = 1; next }
        if (/^-h|--help$/) { usage(); }
        usage("unknown option");
    }

    usage("not enough arguments") if ($#args < 1);

    my @sequence = create_sequence($force);

    $scriptname = shift @args;
    $action = shift @args;
    if ("remove" eq $action) {
        foreach my $init (@sequence) {
            $init->{remove}->($scriptname);
        }
    } elsif ("defaults" eq $action || "start" eq $action ||
             "stop" eq $action) {
        # All start/stop/defaults arguments are discarded so emit a
        # message if arguments have been given and are in conflict
        # with Default-Start/Default-Stop values of LSB comment.
        if ("start" eq $action || "stop" eq $action) {
            cmp_args_with_defaults($scriptname, $action, @args);
        }
        foreach my $init (@sequence) {
            $init->{defaults}->($scriptname);
        }
    } elsif ("defaults-disabled" eq $action) {
        foreach my $init (@sequence) {
            $init->{defaults_disabled}->($scriptname);
        }
    } elsif ("disable" eq $action || "enable" eq $action) {
        foreach my $init (@sequence) {
            $init->{toggle}->($action, $scriptname, @args);
        }
    } else {
        usage();
    }
}

sub parse_def_start_stop {
    my $script = shift;
    my (%lsb, @def_start_lvls, @def_stop_lvls);

    open my $fh, '<', $script or error("unable to read $script");
    while (<$fh>) {
        chomp;
        if (m/^### BEGIN INIT INFO\s*$/) {
            $lsb{'begin'}++;
        }
        elsif (m/^### END INIT INFO\s*$/) {
            $lsb{'end'}++;
            last;
        }
        elsif ($lsb{'begin'} and not $lsb{'end'}) {
            if (m/^# Default-Start:\s*(\S?.*)$/) {
                @def_start_lvls = split(' ', $1);
            }
            if (m/^# Default-Stop:\s*(\S?.*)$/) {
                @def_stop_lvls = split(' ', $1);
            }
        }
    }
    close($fh);

    return (\@def_start_lvls, \@def_stop_lvls);
}

sub lsb_header_for_script {
    my $name = shift;

    foreach my $file ("/etc/insserv/overrides/$name", "/etc/init.d/$name",
                      "/usr/share/insserv/overrides/$name") {
        return $file if -s $file;
    }

    error("cannot find a LSB script for $name");
}

sub cmp_args_with_defaults {
    my ($name, $act) = (shift, shift);
    my ($lsb_start_ref, $lsb_stop_ref, $arg_str, $lsb_str);
    my (@arg_start_lvls, @arg_stop_lvls, @lsb_start_lvls, @lsb_stop_lvls);

    ($lsb_start_ref, $lsb_stop_ref) = parse_def_start_stop("/etc/init.d/$name");
    @lsb_start_lvls = @$lsb_start_ref;
    @lsb_stop_lvls  = @$lsb_stop_ref;
    return if (!@lsb_start_lvls and !@lsb_stop_lvls);

    warning "start and stop actions are no longer supported; falling back to defaults";
    my $start = $act eq 'start' ? 1 : 0;
    my $stop = $act eq 'stop' ? 1 : 0;

    # The legacy part of this program passes arguments starting with
    # "start|stop NN x y z ." but the insserv part gives argument list
    # starting with sequence number (ie. strips off leading "start|stop")
    # Start processing arguments immediately after the first seq number.
    my $argi = $_[0] eq $act ? 2 : 1;

    while (defined $_[$argi]) {
        my $arg = $_[$argi];

        # Runlevels 0 and 6 are always stop runlevels
        if ($arg eq 0 or $arg eq 6) {
            $start = 0; $stop = 1;
        } elsif ($arg eq 'start') {
            $start = 1; $stop = 0; $argi++; next;
        } elsif ($arg eq 'stop') {
            $start = 0; $stop = 1; $argi++; next;
        } elsif ($arg eq '.') {
            next;
        }
        push(@arg_start_lvls, $arg) if $start;
        push(@arg_stop_lvls, $arg) if $stop;
    } continue {
        $argi++;
    }

    if ($#arg_start_lvls != $#lsb_start_lvls or
        join("\0", sort @arg_start_lvls) ne join("\0", sort @lsb_start_lvls)) {
        $arg_str = @arg_start_lvls ? "@arg_start_lvls" : "none";
        $lsb_str = @lsb_start_lvls ? "@lsb_start_lvls" : "none";
        warning "start runlevel arguments ($arg_str) do not match",
                "$name Default-Start values ($lsb_str)";
    }
    if ($#arg_stop_lvls != $#lsb_stop_lvls or
        join("\0", sort @arg_stop_lvls) ne join("\0", sort @lsb_stop_lvls)) {
        $arg_str = @arg_stop_lvls ? "@arg_stop_lvls" : "none";
        $lsb_str = @lsb_stop_lvls ? "@lsb_stop_lvls" : "none";
        warning "stop runlevel arguments ($arg_str) do not match",
                "$name Default-Stop values ($lsb_str)";
    }
}

sub sysv_toggle {
    my ($act, $name) = (shift, shift);
    my (@toggle_lvls, $start_lvls, $stop_lvls, @symlinks);
    my $lsb_header = lsb_header_for_script($name);

    # Extra arguments to disable|enable action are runlevels. If none
    # given parse LSB info for Default-Start value.
    if ($#_ >= 0) {
        @toggle_lvls = @_;
    } else {
        ($start_lvls, $stop_lvls) = parse_def_start_stop($lsb_header);
        @toggle_lvls = @$start_lvls;
        if ($#toggle_lvls < 0) {
            error("$name Default-Start contains no runlevels, aborting.");
        }
    }

    # Find symlinks in rc.d directories. Refuse to modify links in runlevels
    # not used for normal system start sequence.
    for my $lvl (@toggle_lvls) {
        if ($lvl !~ /^[S2345]$/) {
            warning("$act action will have no effect on runlevel $lvl");
            next;
        }
        push(@symlinks, $_) for glob("/etc/rc$lvl.d/[SK][0-9][0-9]$name");
    }

    if (!@symlinks) {
        error("no runlevel symlinks to modify, aborting!");
    }

    # Toggle S/K bit of script symlink.
    for my $cur_lnk (@symlinks) {
        my $sk;
        my @new_lnk = split(//, $cur_lnk);

        if ("disable" eq $act) {
            $sk = rindex($cur_lnk, '/S') + 1;
            next if $sk < 1;
            $new_lnk[$sk] = 'K';
        } else {
            $sk = rindex($cur_lnk, '/K') + 1;
            next if $sk < 1;
            $new_lnk[$sk] = 'S';
        }

        rename($cur_lnk, join('', @new_lnk)) or error($!);
    }
}

# Try to determine if initscripts is installed
sub is_initscripts_installed {
    # Check if mountkernfs is available. We cannot make inferences
    # using the running init system because we may be running in a
    # chroot
    return  glob('/etc/rcS.d/S??mountkernfs.sh');
}

Upload File: