summaryrefslogtreecommitdiffstats
path: root/perl-install/handle_configs.pm
blob: 97011f1f61bd1695a08e984ca0b570de8140aff0 (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
158
159
package handle_configs;


use diagnostics;
use strict;

use common;

sub searchstr {
    # Preceed all characters which are special characters in regexps with
    # a backslash, so that the returned string used in a regexp searches
    # a literal occurence of the original string. White space is replaced
    # by "\s+"
    # "quotemeta()" does not serve for this, as it also quotes some regular
    # characters, as the space
    my ($s) = @_;
    $s =~ s!([\\/\(\)\[\]\{\}\|\.\$\@\%\*\?#\+\-])!\\$1!g;
    return $s;
}

sub read_directives {
    # Read one or more occurences of a directive
    my ($lines_ptr, $directive) = @_;

    my $searchdirective = searchstr($directive);
    # do not use if_() below because it slow down printerdrake
    # to the point one can believe in process freeze:
    map { (/^\s*$searchdirective\s+(\S.*)$/ ? chomp_($1) : ()) } @$lines_ptr;
}

sub read_unique_directive {

    # Read a directive, if the directive appears more than once, use
    # the last occurence and remove all the others, if it does not
    # occur, return the default value

    my ($lines_ptr, $directive, $default) = @_;

    if ((my @d = read_directives($lines_ptr, $directive)) > 0) {
	my $value = $d[-1];
	set_directive($lines_ptr, "$directive $value");
	return $value;
    } else {
        return $default;
    }
}

sub insert_directive {

    # Insert a directive only if it is not already there

    my ($lines_ptr, $directive) = @_;

    my $searchdirective = searchstr($directive);
    (/^\s*$searchdirective$/ and return 0) foreach @$lines_ptr;
    push @$lines_ptr, "$directive\n";
    return 1;
}

sub remove_directive {

    # Remove a directive

    my ($lines_ptr, $directive) = @_;

    my $success = 0;
    my $searchdirective = searchstr($directive);
    (/^\s*$searchdirective/ and $_ = "" and $success = 1)
	foreach @$lines_ptr;
    return $success;
}

sub comment_directive {

    # Comment out a directive

    my ($lines_ptr, $directive, $exactmatch) = @_;

    my $success = 0;
    my $searchdirective = searchstr($directive);
    $searchdirective .= ".*" if !$exactmatch;
    (s/^\s*($searchdirective)$/#$1/ and $success = 1)
	foreach @$lines_ptr;
    return $success;
}

sub replace_directive {

    # Replace a directive, if it appears more than once, remove
    # the additional occurences.

    my ($lines_ptr, $olddirective, $newdirective) = @_;

    my $success = 0;
    $newdirective = "$newdirective\n";
    my $searcholddirective = searchstr($olddirective);
    (/^\s*$searcholddirective/ and $_ = $newdirective and 
     $success = 1 and $newdirective = "") foreach @$lines_ptr;
    return $success;
}


sub move_directive_to_version_commented_out {

    # If there is a version of the directive "commentedout" which is
    # commented out, the directive "directive" will be moved in its place.

    my ($lines_ptr, $commentedout, $directive, $exactmatch) = @_;

    my $success = 0;
    my $searchcommentedout = searchstr($commentedout);
    $searchcommentedout .= ".*" if !$exactmatch;
    (/^\s*#$searchcommentedout$/ and 
     $success = 1 and last) foreach @$lines_ptr;
    if ($success) {
	remove_directive($lines_ptr, $directive);
	(s/^\s*#($searchcommentedout)$/$directive/ and 
	 $success = 1 and last) foreach @$lines_ptr;
    }
    return $success;
}

sub set_directive {

    # Set a directive, replace the old definition or a commented definition

    my ($lines_ptr, $directive, $full_line) = @_;

    my $olddirective = $directive;
    if (!$full_line) {
	$olddirective =~ s/^\s*(\S+)\s+.*$/$1/s;
	$olddirective ||= $directive;
    }

    my $success = (replace_directive($lines_ptr, $olddirective,
				     $directive) ||
		   insert_directive($lines_ptr, $directive));
    if ($success) {
	move_directive_to_version_commented_out($lines_ptr, $directive, 
						$directive, 1);
    }
    return $success;
}

sub add_directive {

    # Add a directive, replace a commented definition

    my ($lines_ptr, $directive) = @_;

    my $success = insert_directive($lines_ptr, $directive);
    if ($success) {
	move_directive_to_version_commented_out($lines_ptr, $directive, 
						$directive, 1);
    }
    return $success;
}

1;
class="hl slc">#- misc imports #-###################################################################################### use common qw(:common :file :system :functional); use install_any qw(:all); use install_steps; use commands; use lang; use keyboard; use mouse; use fsedit; use devices; use partition_table qw(:types); use modules; use detect_devices; use run_program; use any; use log; use fs; #-$::corporate=1; #-###################################################################################### #- Steps table #-###################################################################################### my (%installSteps, @orderedInstallSteps); { my @installStepsFields = qw(text redoable onError hidden needs icon); #entered reachable toBeDone next done; my @installSteps = ( selectLanguage => [ __("Choose your language"), 1, 1, '', '', 'default' ], selectInstallClass => [ __("Select installation class"), 1, 1, '', '', 'default' ], setupSCSI => [ __("Hard drive detection"), 1, 0, '', '', 'harddrive' ], selectMouse => [ __("Configure mouse"), 1, 1, '', "selectInstallClass", 'mouse' ], selectKeyboard => [ __("Choose your keyboard"), 1, 1, '', "selectInstallClass", 'keyboard' ], miscellaneous => [ __("Security"), 1, 1, '!$::expert', '', 'security' ], doPartitionDisks => [ __("Setup filesystems"), 1, 0, '', "selectInstallClass", 'default' ], formatPartitions => [ __("Format partitions"), 1, -1, '$o->{isUpgrade}', "doPartitionDisks", 'default' ], choosePackages => [ __("Choose packages to install"), 1, -2, '!$::expert', "formatPartitions", 'default' ], installPackages => [ __("Install system"), 1, -1, '', ["formatPartitions", "selectInstallClass"], '' ], setRootPassword => [ __("Set root password"), 1, 1, '', "installPackages", 'rootpasswd' ], addUser => [ __("Add a user"), 1, 1, '', "installPackages", 'user' ], configureNetwork => [ __("Configure networking"), 1, 1, '', "formatPartitions", 'network' ], #- installCrypto => [ __("Cryptographic"), 1, 1, '!$::expert', "configureNetwork" ], summary => [ __("Summary"), 1, 0, '', "installPackages", 'default' ], configureServices => [ __("Configure services"), 1, 1, '!$::expert', "installPackages", 'services' ], if_((arch() !~ /alpha/) && (arch() !~ /ppc/), createBootdisk => [ __("Create a bootdisk"), 1, 0, '', "installPackages", 'bootdisk' ], ), setupBootloader => [ __("Install bootloader"), 1, 1, '', "installPackages", 'bootloader' ], configureX => [ __("Configure X"), 1, 1, '', ["formatPartitions", "setupBootloader"], 'X' ], exitInstall => [ __("Exit install"), 0, 0, '!$::expert && !$::live', '', 'default' ], ); for (my $i = 0; $i < @installSteps; $i += 2) { my %h; @h{@installStepsFields} = @{ $installSteps[$i + 1] }; $h{next} = $installSteps[$i + 2]; $h{entered} = 0; $h{onError} = $installSteps[$i + 2 * $h{onError}]; $h{reachable} = !$h{needs}; $installSteps{ $installSteps[$i] } = \%h; push @orderedInstallSteps, $installSteps[$i]; } $installSteps{first} = $installSteps[0]; } #-##################################################################################### #-INTERNAL CONSTANT #-##################################################################################### my @install_classes = qw(normal developer server); #-####################################################################################### #-$O #-the big struct which contain, well everything (globals + the interactive methods ...) #-if you want to do a kickstart file, you just have to add all the required fields (see for example #-the variable $default) #-####################################################################################### $o = $::o = { # bootloader => { linear => 0, lba32 => 1, message => 1, timeout => 5, restricted => 0 }, mkbootdisk => 1, #- no mkbootdisk if 0 or undef, find a floppy with 1, or fd1 #- packages => [ qw() ], partitioning => { clearall => 0, eraseBadPartitions => 0, auto_allocate => 0 }, #-, readonly => 0 }, security => 2, authentication => { md5 => 1, shadow => 1 }, lang => 'en_US', isUpgrade => 0, toRemove => [], toSave => [], #- simple_themes => 1, timezone => { #- timezone => "Europe/Paris", #- UTC => 1, }, #- superuser => { password => 'a', shell => '/bin/bash', realname => 'God' }, #- user => { name => 'foo', password => 'bar', home => '/home/foo', shell => '/bin/bash', realname => 'really, it is foo' }, #- keyboard => 'de', #- display => "192.168.1.19:1", steps => \%installSteps, orderedSteps => \@orderedInstallSteps, #- for the list of fields available for user and superuser, see @etc_pass_fields in install_steps.pm #- intf => { eth0 => { DEVICE => "eth0", IPADDR => '1.2.3.4', NETMASK => '255.255.255.128' } }, #-step : the current one #-prefix #-mouse #-keyboard #-netc #-methods #-packages compss #-printer haveone entry(cf printer.pm) }; #-###################################################################################### #- Steps Functions #- each step function are called with two arguments : clicked(because if you are a #- beginner you can force the the step) and the entered number #-###################################################################################### #------------------------------------------------------------------------------ sub selectLanguage { $o->selectLanguage($_[1] == 1); addToBeDone { lang::write_langs($o->{prefix}, $o->{langs}); } 'formatPartitions' unless $::g_auto_install; addToBeDone { lang::write($o->{prefix}, $o->{lang}); keyboard::write($o->{prefix}, $o->{keyboard}, lang::lang2charset($o->{lang})); } 'installPackages' unless $::g_auto_install; } #------------------------------------------------------------------------------ sub selectMouse { require pkgs; my ($first_time) = $_[1] == 1; add2hash($o->{mouse} ||= {}, mouse::read($o->{prefix})) if $o->{isUpgrade} && $first_time; $o->selectMouse(!$first_time); addToBeDone { mouse::write($o->{prefix}, $o->{mouse}) } 'installPackages'; } #------------------------------------------------------------------------------ sub setupSCSI { my ($clicked) = @_; $o->setupSCSI($clicked); } #------------------------------------------------------------------------------ sub selectKeyboard { my ($clicked, $first_time) = ($_[0], $_[1] == 1); if ($o->{isUpgrade} && $first_time && $o->{keyboard_unsafe}) { my $keyboard = keyboard::read($o->{prefix}); $keyboard and $o->{keyboard} = $keyboard; } return if !$::expert && !$clicked; $o->selectKeyboard($clicked); } #------------------------------------------------------------------------------ sub selectInstallClass { my ($clicked) = @_; $o->selectInstallClass($clicked); if ($o->{steps}{choosePackages}{entered} >= 1 && !$o->{steps}{installPackages}{done}) { $o->setPackages(\@install_classes); $o->selectPackagesToUpgrade if $o->{isUpgrade}; } if ($o->{isUpgrade}) { @{$o->{orderedSteps}} = map { /setupSCSI/ ? ($_, "doPartitionDisks") : $_ } grep { !/doPartitionDisks/ } @{$o->{orderedSteps}}; my $s; foreach (@{$o->{orderedSteps}}) { $s->{next} = $_ if $s; $s = $o->{steps}{$_}; } } } #------------------------------------------------------------------------------ sub doPartitionDisks { $o->{steps}{formatPartitions}{done} = 0; $o->doPartitionDisksBefore; $o->doPartitionDisks; $o->doPartitionDisksAfter; } sub formatPartitions { $o->{steps}{choosePackages}{done} = 0; $o->choosePartitionsToFormat($o->{fstab}) unless $o->{isUpgrade}; $o->formatMountPartitions($o->{fstab}) unless $::testing; mkdir "$o->{prefix}/$_", 0755 foreach qw(dev etc etc/profile.d etc/rpm etc/sysconfig etc/sysconfig/console etc/sysconfig/network-scripts etc/sysconfig/console/consolefonts etc/sysconfig/console/consoletrans home mnt tmp var var/tmp var/lib var/lib/rpm var/lib/urpmi); mkdir "$o->{prefix}/$_", 0700 foreach qw(root root/tmp); any::rotate_logs($o->{prefix}); require raid; raid::prepare_prefixed($o->{raid}, $o->{prefix}); my $d = "/initrd/loopfs/lnx4win"; if (-d $d) { #- install_any::useMedium(0); install_any::getAndSaveFile("lnx4win/$_", "$d/$_") foreach qw(ctl3d32.dll loadlin.exe linux.pif lnx4win.exe lnx4win.ico rm.exe uninstall.bat uninstall.pif); } #- chdir "$o->{prefix}"; was for core dumps #-noatime option for ext2 fs on laptops (do not wake up the hd) #- Do not update inode access times on this #- file system (e.g, for faster access on the #- news spool to speed up news servers). $o->{pcmcia} and $_->{options} = "noatime" foreach grep { isTrueFS($_) } @{$o->{fstab}}; } #------------------------------------------------------------------------------ sub choosePackages { require pkgs; #- always setPackages as it may have to copy hdlist files and depslist file. $o->setPackages; $o->selectPackagesToUpgrade if $o->{isUpgrade} && $_[1] == 1; $o->choosePackages($o->{packages}, $o->{compssUsers}, $_[1] == 1); log::l("compssUsersChoice's: ", join(" ", grep { $o->{compssUsersChoice}{$_} } keys %{$o->{compssUsersChoice}})); #- check pre-condition where base backage has to be selected. pkgs::packageFlagSelected(pkgs::packageByName($o->{packages}, 'basesystem')) or die "basesystem package not selected"; #- check if there are package that need installation. $o->{steps}{installPackages}{done} = 0 if $o->{steps}{installPackages}{done} && pkgs::packagesToInstall($o->{packages}) > 0; } #------------------------------------------------------------------------------ sub installPackages { $o->readBootloaderConfigBeforeInstall if $_[1] == 1; $o->beforeInstallPackages; $o->installPackages; $o->afterInstallPackages; } #------------------------------------------------------------------------------ sub miscellaneous { $o->miscellaneousBefore($_[0]); $o->miscellaneous($_[0]); addToBeDone { setVarsInSh("$o->{prefix}/etc/sysconfig/system", { CLEAN_TMP => $o->{miscellaneous}{CLEAN_TMP}, CLASS => $::expert && 'expert' || 'beginner', SECURITY => $o->{security}, META_CLASS => $o->{meta_class} || 'PowerPack', }); substInFile { s/KEYBOARD_AT_BOOT=.*/KEYBOARD_AT_BOOT=yes/ } "$o->{prefix}/etc/sysconfig/usb" if detect_devices::usbKeyboards(); } 'installPackages'; } #------------------------------------------------------------------------------ sub summary { $o->summary($_[1] == 1) } #------------------------------------------------------------------------------ sub configureNetwork { #- get current configuration of network device. require network; eval { network::read_all_conf($o->{prefix}, $o->{netc} ||= {}, $o->{intf} ||= {}) }; $o->configureNetwork($_[1] == 1); } #------------------------------------------------------------------------------ sub installCrypto { $o->installCrypto } #------------------------------------------------------------------------------ sub configureServices { $o->configureServices($_[0]) } #------------------------------------------------------------------------------ sub setRootPassword { return if $o->{isUpgrade}; $o->setRootPassword($_[0]); addToBeDone { install_any::setAuthentication($o) } 'installPackages'; } #------------------------------------------------------------------------------ sub addUser { return if $o->{isUpgrade} && !$_[0]; $o->addUser($_[0]); } #------------------------------------------------------------------------------ sub createBootdisk { modules::write_conf($o->{prefix}); $o->createBootdisk($_[1] == 1); } #------------------------------------------------------------------------------ sub setupBootloader { return if $::g_auto_install; modules::write_conf($o->{prefix}); $o->setupBootloaderBefore if $_[1] == 1; $o->setupBootloader($_[1] - 1); local $ENV{DRAKX_PASSWORD} = $o->{bootloader}{password}; local $ENV{DURING_INSTALL} = 1; run_program::rooted($o->{prefix}, "/usr/sbin/msec", $o->{security}); } #------------------------------------------------------------------------------ sub configureX { my ($clicked) = @_; #- done here and also at the end of install2.pm, just in case... install_any::write_fstab($o); modules::write_conf($o->{prefix}); require pkgs; $o->configureX($clicked) if pkgs::packageFlagInstalled(pkgs::packageByName($o->{packages}, 'XFree86')) && !$o->{X}{disabled} || $clicked || $::testing; } #------------------------------------------------------------------------------ sub exitInstall { $o->exitInstall(getNextStep() eq "exitInstall") } #-###################################################################################### #- MAIN #-###################################################################################### sub main { $SIG{__DIE__} = sub { chomp(my $err = $_[0]); log::l("warning: $err") }; $SIG{SEGV} = sub { my $msg = "segmentation fault: seems like memory is missing as the install crashes"; print "$msg\n"; log::l($msg); $o->ask_warn('', $msg); setVirtual(1); require install_steps_auto_install; install_steps_auto_install::errorInStep(); }; $ENV{PERL_BADLANG} = 1; umask 022; $::isInstall = 1; $::expert = $::g_auto_install = 0; #- c::unlimit_core() unless $::testing; my ($cfg, $patch, @auto); my %cmdline; map { my ($n, $v) = split '='; $cmdline{$n} = $v || 1; } split ' ', cat_("/proc/cmdline"); my $opt; foreach (@_) { if (/^--?(.*)/) { $cmdline{$opt} = 1 if $opt; $opt = $1; } else { $cmdline{$opt} = $_ if $opt; $opt = ''; } } $cmdline{$opt} = 1 if $opt; map_each { my ($n, $v) = @_; my $f = ${{ oem => sub { $::oem = $v }, lang => sub { $o->{lang} = $v }, flang => sub { $o->{lang} = $v ; push @auto, 'selectLanguage' }, method => sub { $o->{method} = $v }, pcmcia => sub { $o->{pcmcia} = $v }, vga16 => sub { $o->{vga16} = $v }, vga => sub { $o->{vga} = $v }, step => sub { $o->{steps}{first} = $v }, expert => sub { $::expert = $v }, fbeginner => sub { $::expert = 0; push @auto, 'selectInstallClass' }, fexpert => sub { $::expert = 1; push @auto, 'selectInstallClass' }, desktop => sub { $o->{meta_class} = 'desktop' }, firewall => sub { $o->{meta_class} = 'firewall'; push @auto, 'selectInstallClass'}, lnx4win => sub { $o->{lnx4win} = 1 }, readonly => sub { $o->{partitioning}{readonly} = $v ne "0" }, display => sub { $o->{display} = $v }, security => sub { $o->{security} = $v }, live => sub { $::live = 1 }, noauto => sub { $::noauto = 1 }, test => sub { $::testing = 1 }, nopci => sub { $::nopci = 1 }, patch => sub { $patch = 1 }, defcfg => sub { $cfg = $v }, newt => sub { $o->{interactive} = "newt" }, text => sub { $o->{interactive} = "newt" }, stdio => sub { $o->{interactive} = "stdio"}, corporate => sub { $::corporate = 1 }, kickstart => sub { $::auto_install = $v }, auto_install => sub { $::auto_install = $v }, simple_themes => sub { $o->{simple_themes} = 1 }, useless_thing_accepted => sub { $o->{useless_thing_accepted} = 1 }, alawindows => sub { $o->{security} = 0; $o->{partitioning}{clearall} = 1; $o->{bootloader}{crushMbr} = 1 }, fdisk => sub { $o->{partitioning}{fdisk} = 1 }, g_auto_install => sub { $::testing = $::g_auto_install = 1; $o->{partitioning}{auto_allocate} = 1 }, nomouseprobe => sub { $o->{nomouseprobe} = $v }, }}{lc $n}; &$f if $f; } %cmdline; if ($::testing) { $ENV{SHARE_PATH} ||= "/export/Mandrake/mdkinst/usr/share"; $ENV{SHARE_PATH} = "/usr/share" if !-e $ENV{SHARE_PATH}; } else { $ENV{SHARE_PATH} ||= "/usr/share"; } undef $::auto_install if $cfg; if ($::g_auto_install) { (my $root = `/bin/pwd`) =~ s|(/[^/]*){5}$||; symlinkf $root, "/tmp/image" or die "unable to create link /tmp/image"; $o->{method} ||= "cdrom"; $o->{mkbootdisk} = 0; } unless ($::testing || $::live) { symlink "rhimage", "/tmp/image"; #- for compatibility with old stage1 unlink $_ foreach "/modules/modules.mar", "/sbin/stage1"; } print STDERR "in second stage install\n"; log::openLog(($::testing || $o->{localInstall}) && 'debug.log'); log::l("second stage install running (", any::drakx_version(), ")"); $o->{prefix} = $::testing ? "/tmp/test-perl-install" : $::live ? "" : "/mnt"; $o->{root} = $::testing ? "/tmp/root-perl-install" : "/"; $o->{isUpgrade} = 1 if $::live; mkdir $o->{prefix}, 0755;