summaryrefslogtreecommitdiffstats
path: root/rebootin
blob: 1304b6eda42e2c6827c98b4f351ba01e628ae07e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/usr/bin/perl
#--------------------------------------------------------------------
# Copyright (C) 2000-2010 by Mandriva,
# Pixel <pixel@mandriva.com>,
# Chmouel Boudjnah <chmouel@mandriva.com>,
# Redistribution of this file is permitted under the terms of the GNU
# Public License (GPL)
#--------------------------------------------------------------------
# $Id: rebootin 109033 2007-01-15 09:40:20Z pixel $
#--------------------------------------------------------------------
## description:
#		Reboot once on a specified image for grub or lilo

use strict;
use MDK::Common;

my $lilo_conf = "/etc/lilo.conf";

my $grub_menu = "/boot/grub/menu.lst";
my $grub2_menu = "/boot/grub2/grub.cfg";
my $grub2_cfg = "/etc/default/grub";
my ($fastboot, $noreboot, $list, $menu);

while ($ARGV[0] =~ /^-/) {
    local $_ = shift;
    if (/^-f/) {
	$fastboot++;
    } elsif (/^-l/) {
	$list++;
    } elsif (/^-n/) {
	$noreboot++;
    } elsif (/^-m/) {
	$menu++;
    } else {
	die "Unknown switch $_\n";
    }
}

$menu || $list || @ARGV == 1 && $ARGV[0] or usage();
!$menu || @ARGV == 0 or usage();

my ($wanted_entry) = @ARGV;

my $bootloader  = `/usr/sbin/detectloader -q` or die "Can't detect your bootloader\n";chomp $bootloader;

my @entries;
if ($bootloader =~ /GRUB2/) {
    grub2_conf();
} elsif ($bootloader =~ /GRUB/) {
    grub_conf();
} elsif ($bootloader =~ /LILO/) {
    lilo_conf();
} elsif ($bootloader =~ /YABOOT/) {
    die "Sorry, can't do this with yaboot...\n";
} else {
    die "Can't detect your bootloader\n";
}
exec "reboot" unless $noreboot;


sub list_entries() { print "$_\n" foreach @entries; exit(0) }
sub select_entry() {
    my $i = 1;
    print $i++ . ") $_\n" foreach @entries;
    print "0) exit\n";
    my $userinput;
    do {
	print "> ";
        $userinput = <STDIN>;
	chomp $userinput;
    } while ($userinput > $i);
    exit(1) unless $userinput;
    $entries[$userinput-1];
}

sub lilo_conf() {
    open(my $F, $lilo_conf) or die "lilo is not installed ($lilo_conf is missing)\n";
    @entries = map { /="?([^"\n]+)/ } grep { /\s*label=\S*/ } <$F>;
    list_entries() if $list;
    $wanted_entry = select_entry() if $menu;
    @entries > 0 or die "Bad lilo.conf (no entry found)\n";
    grep { $_ eq $wanted_entry } @entries or usage();
    write_fast_boot() if $fastboot;
    system("lilo -R $wanted_entry"); die "error while wanting to reboot on $wanted_entry\n" if $?;
}

sub grub2_conf() {
    open(my $F, $grub2_menu) or die "grub2 is not installed ($grub2_menu is missing)\n";

    # Update menu if needed:
    if (cat_($grub2_cfg) !~ /^GRUB_DEFAULT="saved"/sm) {
	append_to_file($grub2_cfg, qq(GRUB_DEFAULT="saved"\n));
	system('updates-grub2');
    }

    foreach (<$F>) {
	if (/^[^#]*menuentry\s+'([^']*)/) {
	    push @entries, $1;
	}
    }
    list_entries() if $list;
    $wanted_entry = select_entry() if $menu;
    @entries > 0 or die "bad menu.lst (no entry found)\n";

    if (member($wanted_entry, @entries)) {
	system('grub2-reboot', $wanted_entry);
	write_fast_boot() if $fastboot;
	return;
    }

    print STDERR "$wanted_entry not found\n";
    usage(); # not found
}

sub grub_conf() {
    open(my $F, $grub_menu) or die "grub is not installed ($grub_menu is missing)\n";
    my @short_entries;
    foreach (<$F>) {
	if (/^title\s+(.*)/) {
	    push @entries, $1;
	} elsif (/BOOT_IMAGE=(\S+)/) {
	    $short_entries[$#entries] = $1;
	}
    }
    list_entries() if $list;
    $wanted_entry = select_entry() if $menu;
    @entries > 0 or die "bad menu.lst (no entry found)\n";

    for (my $i = 0; $i < @entries; $i++) {
	if ($wanted_entry eq $entries[$i] || $wanted_entry eq $short_entries[$i]) {
	    set_grub($i);
	    return;
	}
    }

    print STDERR "$wanted_entry not found\n";
    usage(); # not found
}

sub set_grub {
    open(my $F, "| grub --device-map=/boot/grub/device.map --batch");
    print $F "savedefault --default=$_[0] --once\nquit\n";
    write_fast_boot() if $fastboot;
}

sub usage() {
    my $entries = @entries ? "  where <label> is one of " . join(", ", @entries) . "\n" : '';
    die <<'EOF' . $entries;
usage: rebootin -l 
       rebootin [-n] [-f] -m
       rebootin [-n] [-f] <label>
EOF
}

sub write_fast_boot() {
    open(my $_F, ">/fastboot");
}