package install_steps_interactive; # $Id: install_steps_interactive.pm,v 1.2 2003/10/14 13:49:29 rider Exp $ @ISA = qw(install_steps); #_Such licenses will in general prevent the transfer, duplication use common; use partition_table qw(:types); use partition_table_raw; use install_steps; use install_interactive; use install_any; use detect_devices; use run_program; use devices; use fsedit; use loopback; use mouse; use modules; use lang; use keyboard; use any; use fs; use log; sub errorInStep($$) { my ($o, $err) = @_; $o->ask_warn(_("Error"), [ _("An error occurred"), common::formatError($err) ]); } sub kill_action { my ($o) = @_; $o->kill; } sub charsetChanged {} sub selectLanguage { my ($o) = @_; $o->{lang} = any::selectLanguage($o, $o->{lang}, $o->{langs} ||= {}); install_steps::selectLanguage($o); $o->charsetChanged; $o->ask_warn('', formatAlaTeX( "If you see this message it is because you choose a language for which DrakX does not include a translation yet; however the fact that it is listed means there is some support for it anyway. That is, once GNU/Linux will be installed, you will be able to at least read and write in that language; and possibly more (various fonts, spell checkers, various programs translated etc. that varies from language to language).")) if $o->{lang} !~ /^en/ && !lang::load_mo(); unless ($o->{useless_thing_accepted}) { $o->set_help('license'); $o->{useless_thing_accepted} = $o->ask_from_list_("License Agreement", formatAlaTeX( " License Agreement Please read carefully this document. This document is a license agreement between you and ALT Linux, Moscow which applies to the Software Products included in ALT Linux . By installing, duplicating or using the Software Products in any manner, you explicitly accept and fully agree to conform to the terms and conditions of this License. If you disagree with any portion of the License, you are not allowed to install, duplicate or use the Software Products. Any attempt to install, duplicate or use the Software Products in a manner which does not comply with the terms and conditions of this License is void and will terminate your rights under this License. Upon termination of the License, you must immediately destroy all copies of the Software Products. 1. Limited Warranty 1.1. The Software Products and attached documentation are provided \"as is\", with no warranty. 1.2. ALT Linux will change CDs and manual with production defects. 1.3. ALT Linux hopes that the Software will be useful for you, but in no circumstances will be liable for any special, incidental, direct or indirect damages whatsoever (including without limitation damages for loss of business, interruption of business, financial loss, legal fees and penalties resulting from a court judgment, or any other consequential loss) arising out of the use or inability to use the Software 1.4. Users are responsible for abidance by national Laws while using the Software 1.5. ALT Linux takes no obligations on users support, unless it is not the subject of a special agreement 2. The GNU General Public License and Related Licenses 2.1. The Software Products consist of components created by different persons or entities. All these components except those listed in the Application below, are governed under the terms and conditions of the GNU General Public License, hereafter called \"GPL\",or of similar licenses. These licenses allow you to use on any number of computers, duplicate, adapt or redistribute the components which they cover. 2.2. All Software developed by ALT Linux and included in ALT Linux are governed under the terms and conditions of GNU GPL. 2.3. All documentation written by ALT Linux governed under the terms and conditions of GNU Free Documentation License. 2.4. ALT Linux contains some programs (sometimes these are demo versions) with Licenses, which may restrict usage, redistribution, or adaption. They all are listed in the Application below. These components are not basic or significantly necessary part of the system. Please read carefully the terms and conditions of the license agreements for these components before using them. 3. Intellectual Property Rights 3.1. All rights to the components of the Software Products belong to their respective authors and are protected by intellectual property and copyright laws applicable to software programs. 3.2.\"Mandrake\", \"Linux-Mandrake\" and associated logos are trademarks of MandrakeSoft S.A. 3.3. \"ALT Linux\", \"ALT Linux Team\" and associated logos are trademarks of ALT Linux, Moscow, Russia. 5. Governing Laws The terms and conditions of this License are governed by the Laws of Russia. "), [ "Agree", "Don't agree" ], "Don't agree") eq "Agree" or $o->exit; } } sub selectKeyboard { my ($o, $clicked) = @_; my $l = keyboard::lang2keyboards($o->{lang}); return install_steps::selectKeyboard($o) if !$::expert && !$clicked && $l->[0][1] >= 90; my @best = map { $_->[0] } @$l; push @best, 'us_intl' if !member('us_intl', @best); my $format = sub { translate(keyboard::keyboard2text($_[0])) }; my $other; my $ext_keyboard = $o->{keyboard}; $o->ask_from_( { title => _("Keyboard"), messages => _("Please, choose your keyboard layout."), advanced_messages => _("Here is the full list of keyboards available"), advanced_label => _("More"), callbacks => { changed => sub { $other = $_[0]==1 } }, }, [ if_(@best > 1, { val => \$o->{keyboard}, type => 'list', format => $format, list => [ @best ] }), { val => \$ext_keyboard, type => 'list', format => $format, list => [ keyboard::keyboards ], advanced => @best > 1 } ]); delete $o->{keyboard_unsafe}; $o->{keyboard} = $ext_keyboard if $other; install_steps::selectKeyboard($o); } sub selectInstallClass1 { my ($o, $verif, $l, $def, $l2, $def2) = @_; $verif->($o->ask_from_list(_("Install Class"), _("Which installation class do you want?"), $l, $def) || die 'already displayed'); $::live ? 'Update' : $o->ask_from_list_(_("Install/Update"), _("Is this an install or an update?"), $l2, $def2); } sub selectInstallClass { my ($o, $clicked) = @_; my %c = my @c = ( if_(!$::corporate, _("Recommended") => "beginner", ), if_($o->{meta_class} ne 'desktop', _("Expert") => "expert", ), ); %c = @c = (_("Expert") => "expert") if $::expert && !$clicked; $o->set_help('selectInstallClassCorpo') if $::corporate; my $verifInstallClass = sub { $::expert = $c{$_[0]} eq "expert" }; $o->{isUpgrade} = $o->selectInstallClass1($verifInstallClass, first(list2kv(@c)), ${{reverse %c}}{$::expert ? "expert" : "beginner"}, [ __("Install"), __("Update") ], $o->{isUpgrade} ? "Update" : "Install") eq "Update"; if ($o->{isUpgrade}){ $o->ask_warn('WARNING', _("You must use APT to upgrade your existing system.\n Read carefully documentation before upgrade\n")); $o->{isUpgrade}=undef; exit(0); } install_steps::selectInstallClass($o); } sub selectMouse { my ($o, $force) = @_; $force ||= $o->{mouse}{unsafe} || $::expert; my $prev = $o->{mouse}{type} . '|' . $o->{mouse}{name}; $o->{mouse} = mouse::fullname2mouse( $o->ask_from_treelist_('', _("Please, choose the type of your mouse."), '|', [ mouse::fullnames ], $prev) || return) if $force; if ($force && $o->{mouse}{type} eq 'serial') { $o->set_help('selectSerialPort'); $o->{mouse}{device} = $o->ask_from_listf(_("Mouse Port"), _("Please choose on which serial port your mouse is connected to."), \&mouse::serial_port2text, [ mouse::serial_ports ]) or return; } if (arch() =~ /ppc/ && $o->{mouse}{nbuttons} == 1) { $o->{mouse}{button2_key} = 87; $o->{mouse}{button3_key} = 88; $o->ask_from('', _("Buttons emulation"), [ { label => _("Button 2 Emulation"), val => \$o->{mouse}{button2_key}, list => [ mouse::ppc_one_button_keys() ], format => \&mouse::ppc_one_button_key2text }, { label => _("Button 3 Emulation"), val => \$o->{mouse}{button3_key}, list => [ mouse::ppc_one_button_keys() ], format => \&mouse::ppc_one_button_key2text }, ]) or return; } any::setup_thiskind($o, 'usb', !$::expert, 0, $o->{pcmcia}) if $o->{mouse}{device} eq "usbmouse"; eval { devices::make("usbmouse"); modules::load($_) foreach qw(hid mousedev usbmouse); } if $o->{mouse}{device} eq "usbmouse"; $o->SUPER::selectMouse; 1; } sub setupSCSI { my ($o, $clicked) = @_; if (!$::noauto && arch() =~ /i.86/) { if ($o->{pcmcia} ||= !$::testing && c::pcmcia_probe()) { my $w = $o->wait_message(_("PCMCIA"), _("Configuring PCMCIA cards...")); modules::configure_pcmcia($o->{pcmcia}); } } { my $w = $o->wait_message(_("IDE"), _("Configuring IDE")); modules::load_ide(); } any::setup_thiskind($o, 'scsi|disk', !$::expert && !$clicked, $clicked, $o->{pcmcia}); install_interactive::tellAboutProprietaryModules($o) if !$clicked; } sub ask_mntpoint_s { my ($o, $fstab) = @_; $o->set_help('ask_mntpoint_s'); my @fstab = grep { isTrueFS($_) } @$fstab; @fstab = grep { isSwap($_) } @$fstab if @fstab == 0; @fstab = @$fstab if @fstab == 0; die _("no available partitions") if @fstab == 0; { my $w = $o->wait_message('', _("Scanning partitions to find mount points")); install_any::suggest_mount_points($fstab, $o->{prefix}, 'uniq'); log::l("default mntpoint $_->{mntpoint} $_->{device}") foreach @fstab; } if (@fstab == 1) { $fstab[0]{mntpoint} = '/'; } else { $o->ask_from('', _("Choose the mount points"), [ map { { label => partition_table::description($_), val => \$_->{mntpoint}, not_edit => 0, list => [ '', fsedit::suggestions_mntpoint(fsedit::empty_all_hds()) ] } } grep { !$_->{real_mntpoint} || common::usingRamdisk() } @fstab ]) or return; } $o->SUPER::ask_mntpoint_s($fstab); } sub doPartitionDisks { my ($o) = @_; my $warned; install_any::getHds($o, sub { my ($err) = @_; $warned = 1; if ($o->ask_yesorno(_("Error"), _("I can't read your partition table, it's too corrupted for me :( I can try to go on blanking bad partitions (ALL DATA will be lost!). The other solution is to disallow DrakX to modify the partition table. (the error is %s) Do you agree to loose all the partitions? ", $err))) { 0; } else { $o->{partitioning}{readonly} = 1; 1; } }) or $warned or $o->ask_warn('', _("DiskDrake failed to read correctly the partition table. Continue at your own risk!")); if (detect_devices::getATARAID) { $o->ask_warn('', _("Hardware IDE RAID Controller found in your system. Please read section Hardware Troubles in Install Documentation.")); } if ($::expert && $o->isa('interactive_gtk')) { install_interactive::partition_with_diskdrake($o, $o->{all_hds}); } else { install_interactive::partitionWizard($o); } } sub rebootNeeded { my ($o) = @_; $o->ask_warn('', _("You need to reboot for the partition table modifications to take place")); install_steps::rebootNeeded($o); } sub choosePartitionsToFormat { my ($o, $fstab) = @_; $o->SUPER::choosePartitionsToFormat($fstab); my @l = grep { !$_->{isMounted} && $_->{mntpoint} && (!isSwap($_) || $::expert) && (!isFat($_) || $_->{notFormatted} || $::expert) && (!isOtherAvailableFS($_) || $::expert || $_->{toFormat}) } @$fstab; $_->{toFormat} = 1 foreach grep { isSwap($_) && !$::expert } @$fstab; return if @l == 0 || !$::expert && 0 == grep { ! $_->{toFormat} } @l; $_->{toFormatTmp} = $_->{toFormat} || $_->{toFormatUnsure} foreach @l; $o->ask_from_( { messages => _("Choose the partitions you want to format"), advanced_messages => _("Check bad blocks?"), }, [ map { my $e = $_; ({ text => partition_table::description($e), type => 'bool', val => \$e->{toFormatTmp} }, if_(!isLoopback($_) && !isThisFs("reiserfs35", $_) && !isThisFs("reiserfs36", $_) && !isThisFs("xfs", $_) && !isThisFs("jfs", $_), { text => partition_table::description($e), type => 'bool', advanced => 1, disabled => sub { !$e->{toFormatTmp} }, val => \$e->{toFormatCheck} })) } @l ] ) or die 'already displayed'; foreach (@l) { $_->{toFormat} = delete $_->{toFormatTmp}; $_->{isFormatted} = 0; } } sub formatMountPartitions { my ($o, $fstab) = @_; my $w; fs::formatMount_all($o->{all_hds}{raids}, $o->{fstab}, $o->{prefix}, sub { my ($part) = @_; $w ||= $o->wait_message('', _("Formatting partitions")); $w->set(isLoopback($part) ? _("Creating and formatting file %s", $part->{loopback_file}) : _("Formatting partition %s", $part->{device})); }); die _("Not enough swap to fulfill installation, please add some") if availableMemory < 40 * 1024; } sub setPackages { my ($o) = @_; my $w = $o->wait_message('', _("Looking for available packages")); $o->SUPER::setPackages; } sub selectPackagesToUpgrade { my ($o) = @_; my $w = $o->wait_message('', _("Finding packages to upgrade")); $o->SUPER::selectPackagesToUpgrade(); } sub choosePackages { my ($o, $packages, $compssUsers, $first_time) = @_; $o->chooseCD($packages) if $o->{method} eq 'cdrom' && !$::oem; my $availableC = install_steps::choosePackages(@_); my $individual = $::expert; require pkgs; my $min_size = pkgs::selectedSize($packages); $min_size < $availableC or die _("Your system has not enough space left for installation or upgrade (%d > %d)", $min_size, $availableC); my $min_mark = $::expert ? 3 : 4; my $def_mark = 4; my $b = pkgs::saveSelected($packages); pkgs::setSelectedFromCompssList($packages, $o->{compssUsersChoice}, $def_mark, 0); my $def_size = pkgs::selectedSize($packages) + 1; my $level = pkgs::setSelectedFromCompssList($packages, { map { $_ => 1 } map { @{$compssUsers->{$_}{flags}} } @{$o->{compssUsersSorted}} }, $min_mark, 0); my $max_size = pkgs::selectedSize($packages) + 1; pkgs::restoreSelected($b); $o->chooseGroups($packages, $compssUsers, $min_mark, \$individual, $max_size) if !$::corporate; my $size2install = min($availableC, do { my $max = round_up(min($max_size, $availableC) / sqr(1024), 100); if (1) { my (@l); my @text = (__("Minimum (%dMB)"), __("Recommended (%dMB)"), __("Complete (%dMB)")); if ($o->{meta_class} eq 'desktop') { @l = (300, 500, 800, 0); $max > $l[2] or splice(@l, 2, 1); $max > $l[1] or splice(@l, 1, 1); $max > $l[0] or @l = $max; $text[$#l] = __("Custom"); } else { @l = (300, 700, $max); $l[2] > $l[1] + 200 or splice(@l, 1, 1); $l[1] > $l[0] + 100 or splice(@l, 0, 1); } $o->set_help('empty'); $max * sqr(1024); } else { $o->chooseSizeToInstall($packages, $min_size, $def_size, $max_size, $availableC, $individual) || goto &choosePackages; } }); if (!$size2install) { $o->chooseGroups($packages, $compssUsers, $min_mark) or goto &choosePackages; $size2install = $availableC; } ($o->{packages_}{ind}) = pkgs::setSelectedFromCompssList($packages, $o->{compssUsersChoice}, $min_mark, $size2install); $o->choosePackagesTree($packages) if $individual; install_any::warnAboutNaughtyServers($o); } sub chooseSizeToInstall { my ($o, $packages, $min, $def, $max, $availableC) = @_; min($def, $availableC * 0.7); } sub choosePackagesTree { my ($o, $packages) = @_; $o->ask_many_from_list('', _("Choose the packages you want to install"), { list => [ map { pkgs::packageByName($packages, $_) } keys %{$packages->{names}} ], value => \&pkgs::packageFlagSelected, label => \&pkgs::packageName, sort => 1, }); } sub loadSavePackagesOnFloppy { my ($o, $packages) = @_; my $choice = $o->ask_from_listf('', _("Please choose load or save package selection on floppy. The format is the same as auto_install generated floppies."), sub { translate($_[0]{text}) }, [ { text => _("Load from floppy"), code => sub { while (1) { my $w = $o->wait_message(_("Package selection"), _("Loading from floppy")); log::l("load package selection from floppy"); my $O = eval { install_any::loadO({}, 'floppy') }; if ($@) { $w = undef; $o->ask_okcancel('', _("Insert a floppy containing package selection")) or return; } else { install_any::unselectMostPackages($o); foreach (@{$O->{default_packages} || []}) { my $pkg = pkgs::packageByName($packages, $_); pkgs::selectPackage($packages, $pkg) if $pkg; } return 1; } } } }, { text => _("Save on floppy"), code => sub { log::l("save package selection to floppy"); install_any::g_default_packages($o, 'quiet'); } }, ]); $choice->{code} and $choice->{code}(); } sub chooseGroups { my ($o, $packages, $compssUsers, $min_level, $individual, $max_size) = @_; my $b = pkgs::saveSelected($packages); install_any::unselectMostPackages($o); pkgs::setSelectedFromCompssList($packages, {}, $min_level, $max_size); my $system_size = pkgs::selectedSize($packages); my ($sizes, $pkgs) = pkgs::computeGroupSize($packages, $min_level); pkgs::restoreSelected($b); log::l("system_size: $system_size"); my @groups = @{$o->{compssUsersSorted}}; my %stable_flags = grep_each { $::b } %{$o->{compssUsersChoice}}; delete $stable_flags{$_} foreach map { @{$compssUsers->{$_}{flags}} } @groups; my $compute_size = sub { my %pkgs; my %flags = %stable_flags; @flags{@_} = (); my $total_size; A: while (my ($k, $size) = each %$sizes) { Or: foreach (split "\t", $k) { foreach (split "&&") { exists $flags{$_} or next Or; } $total_size += $size; $pkgs{$_} = 1 foreach @{$pkgs->{$k}}; next A; } } log::l("computed size $total_size"); log::l("chooseGroups: ", join(" ", sort keys %pkgs)); int $total_size; }; my %val = map { $_ => ! grep { ! $o->{compssUsersChoice}{$_} } @{$compssUsers->{$_}{flags}} } @groups; my ($all, $size); my $available_size = install_any::getAvailableSpace($o) / sqr(1024); my $size_to_display = sub { my $lsize = $system_size + $compute_size->(map { @{$compssUsers->{$_}{flags}} } grep { $val{$_} } @groups); $size > $lsize and install_any::unselectMostPackages($o); $size = $lsize; _("Total size: %d / %d MB", pkgs::correctSize($size / sqr(1024)), $available_size); }; while (1) { $o->reallyChooseGroups($size_to_display, $individual, \%val) or return; last if pkgs::correctSize($size / sqr(1024)) < $available_size || $individual; $o->ask_warn('', _("Selected size is larger than available space")); } $o->{compssUsersChoice}{$_} = 0 foreach map { @{$compssUsers->{$_}{flags}} } grep { !$val{$_} } keys %val; $o->{compssUsersChoice}{$_} = 1 foreach map { @{$compssUsers->{$_}{flags}} } grep { $val{$_} } keys %val; 1; } sub reallyChooseGroups { my ($o, $size_to_display, $individual, $val) = @_; my $size_text = &$size_to_display; my ($path, $all); $o->ask_from('', _("Package Group Selection"), [ { val => \$size_text, type => 'label' }, {}, (map {; my $old = $path; $path = $o->{compssUsers}{$_}{path}; if_($old ne $path, { val => translate($path) }), { val => \$val->{$_}, type => 'bool', disabled => sub { $all }, text => translate($o->{compssUsers}{$_}{label}), help => translate($o->{compssUsers}{$_}{descr}), } } @{$o->{compssUsersSorted}}), if_($o->{meta_class} eq 'desktop', { text => _("All"), val => \$all, type => 'bool' }), if_($individual, { text => _("Individual package selection"), val => $individual, advanced => 1, type => 'bool' }), ], changed => sub { $size_text = &$size_to_display }) or return; if ($all) { $val->{$_} = 1 foreach keys %$val; } 1; } sub chooseCD { my ($o, $packages) = @_; my @mediums = grep { $_ != $install_any::boot_medium } pkgs::allMediums($packages); my @mediumsDescr = (); my %mediumsDescr = (); if (!common::usingRamdisk()) { foreach (@mediums) { pkgs::mediumDescr($packages, $install_any::boot_medium) eq pkgs::mediumDescr($packages, $_) and next; undef $packages->{mediums}{$_}{selected}; } log::l("low memory install, using single CD installation (as it is not ejectable)"); return; } $mediumsDescr{pkgs::mediumDescr($packages, $install_any::boot_medium)} = 1; foreach (@mediums) { my $descr = pkgs::mediumDescr($packages, $_); exists $mediumsDescr{$descr} or push @mediumsDescr, $descr; $mediumsDescr{$descr} ||= $packages->{mediums}{$_}{selected}; } return if @mediumsDescr == () || !$::expert; $o->set_help('chooseCD'); $o->ask_many_from_list('', _("If you have all the CDs in the list below, click Ok. If you have none of those CDs, click Cancel. If only some CDs are missing, unselect them, then click Ok."), { list => \@mediumsDescr, label => sub { _("Cd-Rom labeled \"%s\"", $_[0]) }, val => sub { \$mediumsDescr{$_[0]} }, }) or do { $mediumsDescr{$_} = 0 foreach @mediumsDescr; }; $o->set_help('choosePackages'); foreach (@mediums) { my $descr = pkgs::mediumDescr($packages, $_); $packages->{mediums}{$_}{selected} = $mediumsDescr{$descr}; log::l("select status of medium $_ is $packages->{mediums}{$_}{selected}"); } } sub installPackages { my ($o, $packages) = @_; my ($current, $total) = 0; my $w = $o->wait_message(_("Installing"), _("Preparing installation")); my $old = \&pkgs::installCallback; local *pkgs::installCallback = sub { my $m = shift; if ($m =~ /^Starting installation/) { $total = $_[1]; } elsif ($m =~ /^Starting installing package/) { my $name = $_[0]; $w->set(_("Installing package %s\n%d%%", $name, $total && 100 * $current / $total)); $current += pkgs::packageSize(pkgs::packageByName($o->{packages}, $name)); } else { unshift @_, $m; goto $old } }; undef *install_any::changeMedium; *install_any::changeMedium = sub { my ($method, $medium) = @_; $method eq 'cdrom' && !$::oem and do { my $name = pkgs::mediumDescr($o->{packages}, $medium); local $| = 1; print "\a"; my $r = $o->ask_okcancel('', _("Change your Cd-Rom! Please insert the Cd-Rom labelled \"%s\" in your drive and press Ok when done. If you don't have it, press Cancel to avoid installation from this Cd-Rom.", $name), 1); return $r; }; }; my $install_result; catch_cdie { $install_result = $o->install_steps::installPackages($packages); } sub { if ($@ =~ /^error ordering package list: (.*)/) { $o->ask_yesorno('', [ _("There was an error ordering packages:"), $1, _("Go on anyway?") ], 1) and return 1; ${$_[0]} = "already displayed"; } elsif ($@ =~ /^error installing package list: (.*)/) { $o->ask_yesorno('', [ _("There was an error installing packages:"), $1, _("Go on anyway?") ], 1) and return 1; ${$_[0]} = "already displayed"; } 0; }; if ($pkgs::cancel_install) { $pkgs::cancel_install = 0; die "setstep choosePackages\n"; } $install_result; } sub afterInstallPackages($) { my ($o) = @_; my $w = $o->wait_message('', _("Post-install configuration")); $o->SUPER::afterInstallPackages($o); } sub copyKernelFromFloppy { my ($o) = @_; $o->ask_okcancel('', _("Please insert the Boot floppy used in %s drive ", $o->{blank}), 1) or return; $o->SUPER::copyKernelFromFloppy(); } sub updateModulesFromFloppy { my ($o) = @_; $o->ask_okcancel('', _("Please insert the Update Modules floppy in %s drive ", $o->{updatemodules}), 1) or return; $o->SUPER::updateModulesFromFloppy(); } sub configureNetwork { my ($o, $first_time, $noauto) = @_; require network::netconnect; network::netconnect::main($o->{prefix}, $o->{netcnx} ||= {}, $o->{netc}, $o->{mouse}, $o, $o->{intf}, $first_time, $o->{lang} eq "fr_FR" && $o->{keyboard} eq "fr", $noauto); } sub configureTimezone { my ($o, $clicked) = @_; require timezone; $o->{timezone}{timezone} = $o->ask_from_treelist('', _("Which is your timezone?"), '/', [ timezone::getTimeZones($::g_auto_install ? '' : $o->{prefix}) ], $o->{timezone}{timezone}); $o->set_help('configureTimezoneGMT'); my $ntp = to_bool($o->{timezone}{ntp}); $o->ask_from('', '', [ { text => _("Hardware clock set to GMT"), val => \$o->{timezone}{UTC}, type => 'bool' }, { text => _("Automatic time synchronization (using NTP)"), val => \$ntp, type => 'bool' }, ]) or goto &configureTimezone if $::expert || $clicked; if ($ntp) { my @servers = split("\n", $timezone::ntp_servers); $o->ask_from('', '', [ { label => _("NTP Server"), val => \$o->{timezone}{ntp}, list => \@servers, not_edit => 0 } ] ) or goto &configureTimezone; $o->{timezone}{ntp} =~ s/.*\((.+)\)/$1/; } else { $o->{timezone}{ntp} = ''; } install_steps::configureTimezone($o); } sub configureServices { my ($o, $clicked) = @_; require services; $o->{services} = services::ask($o, $o->{prefix}) if $::expert || $clicked; install_steps::configureServices($o); } sub summary { my ($o, $first_time) = @_; require pkgs; if ($first_time) { $o->configurePrinter(0) if !$::expert; install_any::preConfigureTimezone($o); } my $mouse_name; my $format_mouse = sub { $mouse_name = translate($o->{mouse}{type}) . ' ' . translate($o->{mouse}{name}) }; &$format_mouse; my $format_printers = sub { my $printer = $o->{printer}; if (is_empty_hash_ref($printer->{configured})) { pkgs::packageFlagInstalled(pkgs::packageByName($o->{packages}, 'cups')) and return _("Remote CUPS server"); return _("No printer"); } my $entry; foreach ($printer->{currentqueue}, map { $_->{queuedata} } ($printer->{configured}{$printer->{DEFAULT}}, values %{$printer->{configured}})) { $_ && ($_->{make} || $_->{model}) and return "$_->{make} $_->{model}"; } return _("Remote CUPS server"); }; $o->ask_from_({ messages => _("Summary"), cancel => '', }, [ { label => _("Mouse"), val => \$mouse_name, clicked => sub { $o->selectMouse(1); mouse::write($o->{prefix}, $o->{mouse}); &$format_mouse } }, { label => _("Keyboard"), val => \$o->{keyboard}, clicked => sub { $o->selectKeyboard(1) }, format => sub { translate(keyboard::keyboard2text($_[0])) } }, { label => _("Timezone"), val => \$o->{timezone}{timezone}, clicked => sub { $o->configureTimezone(1) } }, { label => _("Printer"), val => \$o->{printer}, clicked => sub { $o->configurePrinter(1) }, format => $format_printers }, # (map { #{ label => _("ISDN card"), val => $_->{description}, clicked => sub { $o->configureNetwork } } # } grep { $_->{driver} eq 'hisax' } detect_devices::probeall()), # (map { #{ label => _("Sound card"), val => $_->{description} } # } arch() !~ /ppc/ ? modules::get_that_type('sound') : modules::load_thiskind('sound')), # (map { #{ label => _("TV card"), val => $_->{description} } # } grep { $_->{driver} eq 'bttv' } detect_devices::probeall()), ]); install_steps::configureTimezone($o); } sub configurePrinter { my ($o, $clicked) = @_; $::corporate && !$clicked and return; require printer; require printerdrake; my $ask_multiple_printer = ($::expert || $clicked) && 2 || scalar(printerdrake::auto_detect($o)); $ask_multiple_printer-- or return; $::testing or $o->do_pkgs->install('foomatic'); my $printer = $o->{printer} ||= {}; eval { add2hash($printer, printer::getinfo($o->{prefix})) }; $printer->{PAPERSIZE} = $o->{lang} eq 'en' ? 'letter' : 'a4'; printerdrake::main($printer, $o, $ask_multiple_printer, sub { install_interactive::upNetwork($o, 'pppAvoided') }); } sub setRootPassword { my ($o, $clicked) = @_; my $sup = $o->{superuser} ||= {}; my $auth = ($o->{authentication}{LDAP} && __("LDAP") || $o->{authentication}{NIS} && __("NIS") || __("Local files")); $sup->{password2} ||= $sup->{password} ||= ""; return if $o->{security} < 1 && !$clicked; $::isInstall and $o->set_help("setRootPassword", if_($::expert, "setRootPasswordAuth")); $o->ask_from_( { title => _("Set root password"), messages => _("Set root password"), cancel => ($o->{security} <= 2 && !$::corporate ? _("No password") : ''), callbacks => { complete => sub { $sup->{password} eq $sup->{password2} or $o->ask_warn('', [ _("The passwords do not match"), _("Please try again") ]), return (1,1); length $sup->{password} < 2 * $o->{security} and $o->ask_warn('', _("This password is too simple (must be at least %d characters long)", 2 * $o->{security})), return (1,0); return 0 } } }, [ { label => _("Password"), val => \$sup->{password}, hidden => 1 }, { label => _("Password (again)"), val => \$sup->{password2}, hidden => 1 }, if_($::expert, ), # ]) or return; ]) or ( $o->ask_warn('', _("You will can't login into system!")) and return ); install_steps::setRootPassword($o); } sub addUser { my ($o, $clicked) = @_; $o->{users} ||= []; any::ask_users($o->{prefix}, $o, $o->{users}, $o->{security}); any::get_autologin($o->{prefix}, $o); any::autologin($o->{prefix}, $o, $o); install_steps::addUser($o); } sub createBootdisk { my ($o, $first_time, $noauto) = @_; if (arch() =~ /sparc/) { $o->ask_okcancel('', _("A custom bootdisk provides a way of booting into your Linux system without depending on the normal bootloader. This is useful if you don't want to install SILO on your system, or another operating system removes SILO, or SILO doesn't work with your hardware configuration. A custom bootdisk can also be used with the ALT Linux rescue image, making it much easier to recover from severe system failures. If you want to create a bootdisk for your system, insert a floppy in the first drive and press \"Ok\"."), $o->{mkbootdisk}) or return $o->{mkbootdisk} = ''; my @l = detect_devices::floppies_dev(); $o->{mkbootdisk} = $l[0] if !$o->{mkbootdisk} || $o->{mkbootdisk} eq "1"; $o->{mkbootdisk} or return; } else { my @l = detect_devices::floppies_dev(); my %l = ( 'fd0' => _("First floppy drive"), 'fd1' => _("Second floppy drive"), 'Skip' => _("Skip"), ); if ($first_time || @l == 1) { $o->ask_yesorno('', formatAlaTeX( _("A custom bootdisk provides a way of booting into your Linux system without depending on the normal bootloader. This is useful if you don't want to install LILO (or grub) on your system, or another operating system removes LILO, or LILO doesn't work with your hardware configuration. A custom bootdisk can also be used with the ALT Linux rescue image, making it much easier to recover from severe system failures. Would you like to create a bootdisk for your system?")), $o->{mkbootdisk}) or return $o->{mkbootdisk} = ''; $o->{mkbootdisk} = $l[0] if !$o->{mkbootdisk} || $o->{mkbootdisk} eq "1"; } else { @l or die _("Sorry, no floppy drive available"); $o->ask_from_( { messages => _("Choose the floppy drive you want to use to make the bootdisk"), }, [ { val => \$o->{mkbootdisk}, list => \@l, format => sub { $l{$_[0]} || $_[0] } } ] ) or return; } $o->ask_warn('', _("Insert a floppy in drive %s", $l{$o->{mkbootdisk}} || $o->{mkbootdisk})); } my $w = $o->wait_message('', _("Creating bootdisk")); install_steps::createBootdisk($o); } sub setupBootloaderBefore { my ($o) = @_; my $w = $o->wait_message('', _("Preparing bootloader")); $o->set_help('empty'); $o->SUPER::setupBootloaderBefore($o); } sub setupBootloader { my ($o, $more) = @_; if (arch() =~ /ppc/) { my $machtype = detect_devices::get_mac_generation(); if ($machtype !~ /NewWorld/) { $o->ask_warn('', _("You appear to have an OldWorld or Unknown\n machine, the yaboot bootloader will not work for you.\nThe install will continue, but you'll\n need to use BootX to boot your machine")); log::l("OldWorld or Unknown Machine - no yaboot setup"); return; } } if (arch() =~ /^alpha/) { $o->ask_yesorno('', _("Do you want to use aboot?"), 1) or return; catch_cdie { $o->SUPER::setupBootloader } sub { $o->ask_yesorno('', _("Error installing aboot, try to force installation even if that destroys the first partition?")); }; } else { any::setupBootloader($o, $o->{bootloader}, $o->{all_hds}, $o->{fstab}, $o->{security}, $o->{prefix}, $more) or return; { my $w = $o->wait_message('', _("Installing bootloader")); eval { $o->SUPER::setupBootloader }; } if (my $err = $@) { $err =~ /failed$/ or die; $o->ask_warn('', [ _("Installation of bootloader failed. The following error occured:"), grep { !/^Warning:/ } cat_("$o->{prefix}/tmp/.error") ]); unlink "$o->{prefix}/tmp/.error"; die "already displayed"; } elsif (arch() =~ /ppc/) { my $of_boot = cat_("$o->{prefix}/tmp/of_boot_dev") || die "Can't open $o->{prefix}/tmp/of_boot_dev"; chop($of_boot); unlink "$o->{prefix}/tmp/.error"; $o->ask_warn('', _("You may need to change your Open Firmware boot-device to\n enable the bootloader. If you don't see the bootloader prompt at\n reboot, hold down Command-Option-O-F at reboot and enter:\n setenv boot-device %s,\\\\:tbxi\n Then type: shut-down\nAt your next boot you should see the bootloader prompt.", $of_boot)); } } } sub miscellaneous { my ($o, $clicked) = @_; my %l = ( 2 => _("Low"), 3 => _("Medium"), 4 => _("High"), ); $ENV{SECURE_LEVEL} = $o->{security} = 2; install_steps::miscellaneous($o); } sub configureX { my ($o, $clicked) = @_; $o->configureXBefore; my $xfs_started if 0; run_program::rooted($o->{prefix}, "/etc/rc.d/init.d/xfs", "start") unless $::live || $xfs_started; $xfs_started = 1; require Xconfigurator; { local $::testing = 0; local $::auto = !$::expert && !$clicked; symlink "$o->{prefix}/etc/gtk", "/etc/gtk"; Xconfigurator::main($o->{prefix}, $o->{X}, $o, $o->do_pkgs, { allowFB => $o->{allowFB}, allowNVIDIA_rpms => install_any::allowNVIDIA_rpms($o->{packages},$o), }); } $o->configureXAfter; } sub generateAutoInstFloppy { my ($o, $replay) = @_; my $floppy = detect_devices::floppy(); $o->ask_okcancel('', _("Insert a blank floppy in drive %s", $floppy), 1) or return; my $dev = devices::make($floppy); { my $w = $o->wait_message('', _("Creating auto install floppy")); install_any::getAndSaveAutoInstallFloppy($o, $replay, $dev) or return; } common::sync(); } sub exitInstall { my ($o, $alldone) = @_; return $o->{step} = '' unless $alldone || $o->ask_yesorno('', _("Some steps are not completed. Do you really want to quit now?"), 0); install_steps::exitInstall($o); $o->exit unless $alldone; $o->ask_from_no_check( { messages => _("Congratulations, installation is complete. Remove the boot media and press return to reboot. For information on fixes which are available for this release of ALT Linux consult the Errata available from http://www.altlinux.ru/. Information on configuring your system is available in the post install chapter of the Official User's Guide."), cancel => '', }, [ if_($::expert, { val => \ (my $t1 = _("Generate auto install floppy")), clicked => sub { my $t = $o->ask_from_list_('', _("The auto install can be fully automated if wanted, in that case it will take over the hard drive!! (this is meant for installing on another box). You may prefer to replay the installation. "), [ __("Replay"), __("Automated") ]); $t and $o->generateAutoInstFloppy($t eq 'Replay'); }, advanced => 1 }, { val => \ (my $t2 = _("Save packages selection")), clicked => sub { install_any::g_default_packages($o) }, advanced => 1 }, ), ] ) if $alldone && !$::g_auto_install; } 1;