summaryrefslogtreecommitdiffstats
path: root/perl-install/standalone/service_harddrake
blob: b5e39b843cea9eca7843743fa9a5eaa550c952bd (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
#!/usr/bin/perl -w

use lib qw(/usr/lib/libDrakX);

use strict;
use standalone;     #- warning, standalone must be loaded very first, for 'explanations'
use MDK::Common;
use interactive;
use harddrake::data;
use Storable qw(store retrieve);

my $hw_sysconfdir = "/etc/sysconfig/harddrake2";
my $last_boot_config = $hw_sysconfdir."/previous_hw";

my $invert_do_it = $ARGV[0] eq 'X11' ? 1 : 0;
$last_boot_config .= '_X11' if $invert_do_it;

# first run ? if not read old hw config
my $previous_config = (-f $last_boot_config && -s $last_boot_config) ? retrieve($last_boot_config) : {};
my (%config, $in);

# For each hw, class, detect device, compare and offer to reconfigure if needed
foreach (@harddrake::data::tree) {
    my ($Ident, $item, undef, $configurator, $detector, $do_it) = @$_;
    next unless $do_it ^ $invert_do_it;
    # No detector ? (should never happen but who know ?)
    ref($detector) eq 'CODE' or next;

    my %ID = map {
	   my $i = $_;
	   my $id = defined $i->{device} ? $i->{device} : join(':', map { $i->{$_} } qw(vendor id subvendor subid));
	   $id => $i;
    } &$detector;
    $config{$Ident} = \%ID;
    next if is_empty_hash_ref $previous_config; # don't fsck on first run

    my $oldconfig = $previous_config->{$Ident};

    my $msg;
    my @was_removed = difference2([ keys %$oldconfig ], [ keys %ID ]);
    $msg .= _("Some devices in the \"%s\" hardware class were removed:\n", $item) if @was_removed;
    $msg .= "- ". harddrake::data::custom_id($oldconfig->{$_}, $item) ." was removed\n" foreach @was_removed;
    my @added = difference2([ keys %ID ], [ keys %$oldconfig ]);
    $msg .= _("\nSome devices in the %s class were added:\n", $item) if @added;
    $msg .= "- ". harddrake::data::custom_id($ID{$_}, $item) ." was added\n" foreach (@added);
    @added || @was_removed or next;
    next unless (-x $configurator);

    my $res;
    $SIG{ALRM} = sub { undef $in; undef $res; next }; #die "TIMED OUT\n" };
    undef $@;
    eval {
	alarm (5) unless $invert_do_it;
	$in = 'interactive'->vnew('su') unless defined $in;
	$res = $in->ask_okcancel("Hardware changes in $Ident class (5 seconds to answer)",
				 $msg . "\nDo you want to run the appropriate config tool ?", 1)
	    or $in->wait_message(_('Please wait'), _('Hardware probing in progress'));
	alarm (0) unless $invert_do_it;
    };
    next if ($@ || !$res);     # timed out || canceled
    if (my $pid = fork) {
		require POSIX;
		POSIX::wait();
    } else { exec("$configurator 2>/dev/null") or die "$configurator missing\n" }
}

# output new hw config
standalone::explanations "created file $last_boot_config";
store \%config, $last_boot_config;
$in->exit(0) if defined $in; exit 0;