diff options
Diffstat (limited to 'perl-install/any.pm')
| -rw-r--r-- | perl-install/any.pm | 260 |
1 files changed, 175 insertions, 85 deletions
diff --git a/perl-install/any.pm b/perl-install/any.pm index fa335a9af..9d6a24d1e 100644 --- a/perl-install/any.pm +++ b/perl-install/any.pm @@ -8,15 +8,15 @@ use strict; #-###################################################################################### use common; use detect_devices; -use partition_table qw(:types); -use fsedit; -use fs; +use partition_table; +use fs::type; use lang; use run_program; use keyboard; use devices; use modules; use log; +use fs; use c; sub drakx_version() { @@ -43,7 +43,7 @@ sub addKdmIcon { eval { cp_af(facesdir() . $icon . ".png", $dest) } if $icon; } -sub allocUsers { +sub alloc_user_faces { my ($users) = @_; my @m = my @l = facesnames(); foreach (grep { !$_->{icon} || $_->{icon} eq "automagic" } @$users) { @@ -53,34 +53,77 @@ sub allocUsers { } } -sub addUsers { - my ($users) = @_; +sub create_user { + my ($u, $isMD5) = @_; + + my @existing = stat("$::prefix/home/$u->{name}"); + + if (!getpwnam($u->{name})) { + my $uid = $u->{uid} || $existing[4]; + if ($uid && getpwuid($uid)) { + undef $uid; #- suggested uid already in use + } + my $gid = $u->{gid} || $existing[5] || int getgrnam($u->{name}); + if ($gid) { + if (getgrgid($gid)) { + undef $gid if getgrgid($gid) ne $u->{name}; + } else { + run_program::rooted($::prefix, 'groupadd', '-g', $gid, $u->{name}); + } + } + require authentication; + run_program::rooted($::prefix, + 'adduser', + '-p', authentication::user_crypted_passwd($u, $isMD5), + if_($uid, '-u', $uid), if_($gid, '-g', $gid), + if_($u->{shell}, '-s', $u->{shell}), + $u->{name}); + } + + my (undef, undef, $uid, $gid, undef, undef, undef, $home) = getpwnam($u->{name}); - allocUsers($users); - foreach my $u (@$users) { - run_program::rooted($::prefix, "usermod", "-G", join(",", @{$u->{groups}}), $u->{name}) if !is_empty_array_ref($u->{groups}); - addKdmIcon($u->{name}, delete $u->{auto_icon} || $u->{icon}); + if (@existing && $::isInstall && ($uid != $existing[4] || $gid != $existing[5])) { + log::l("chown'ing $home from $existing[4].$existing[5] to $uid.$gid"); + require commands; + eval { commands::chown_("-r", "$uid.$gid", "$::prefix$home") }; } } -sub crypt { - my ($password, $md5) = @_; - crypt($password, $md5 ? '$1$' . salt(8) : salt(2)); +sub add_users { + my ($users, $authentication) = @_; + + alloc_user_faces($users); + + foreach (@$users) { + create_user($_, $authentication->{md5}); + run_program::rooted($::prefix, "usermod", "-G", join(",", @{$_->{groups}}), $_->{name}) if !is_empty_array_ref($_->{groups}); + addKdmIcon($_->{name}, delete $_->{auto_icon} || $_->{icon}); + } } + sub enableShadow() { run_program::rooted($::prefix, "pwconv") or log::l("pwconv failed"); run_program::rooted($::prefix, "grpconv") or log::l("grpconv failed"); } sub hdInstallPath() { - my $tail = first(readlink("/tmp/image") =~ m|^/tmp/hdimage/?(.*)|); + my $tail = first(readlink("/tmp/image") =~ m|^(?:/tmp/)?hdimage/*(.*)|); my $head = first(readlink("/tmp/hdimage") =~ m|$::prefix(.*)|); + log::l("search HD install path, tail=$tail, head=$head, tail defined=" . to_bool(defined $tail)); defined $tail && ($head ? "$head/$tail" : "/mnt/hd/$tail"); } +sub install_acpi_pkgs { + my ($do_pkgs, $b) = @_; + + my $acpi = bootloader::get_append($b, 'acpi') or return; + if (!member($acpi, 'off', 'ht')) { + $do_pkgs->install('acpi', 'acpid') if !(-x "$::prefix/usr/bin/acpi" && -x "$::prefix/usr/sbin/acpid") + } +} + sub setupBootloader { my ($in, $b, $all_hds, $fstab, $security) = @_; - my $hds = $all_hds->{hds}; require bootloader; general: @@ -88,18 +131,53 @@ sub setupBootloader { local $::Wizard_no_previous = 1 if $::isStandalone; setupBootloader__general($in, $b, $all_hds, $fstab, $security) or return 0; } - setupBootloader__boot_bios_drive($in, $b, $hds) or goto general; + setupBootloader__boot_bios_drive($in, $b, $all_hds->{hds}) or goto general; { local $::Wizard_finished = 1 if $::isStandalone; setupBootloader__entries($in, $b, $all_hds, $fstab) or goto general; } +} + +sub installBootloader { + my ($in, $b, $all_hds) = @_; - #- somewhere should bootloader really installed ? - $::isStandalone and my $_w = $in->wait_message(N("Please wait"), N("Bootloader installation in progress")); + install_acpi_pkgs($in->do_pkgs, $b); - eval { run_program::rooted($::prefix, 'lilo', '-u') } if $::isInstall && !$::o->{isUpgrade} && -e "$::prefix/etc/lilo.conf" && glob("$::prefix/boot/boot.*"); + eval { run_program::rooted($::prefix, 'echo | lilo -u') } if $::isInstall && !$::o->{isUpgrade} && -e "$::prefix/etc/lilo.conf" && glob("$::prefix/boot/boot.*"); + + retry: + eval { + my $_w = $in->wait_message(N("Please wait"), N("Bootloader installation in progress")); + bootloader::install($b, $all_hds); + }; - bootloader::install($b, $hds); + if (my $err = $@) { + $err =~ /wizcancel/ and return; + $err =~ s/^\w+ failed// or die; + $err = formatError($err); + while ($err =~ s/^Warning:.*//m) {} + if (my ($dev) = $err =~ /^Reference:\s+disk\s+"(.*?)".*^Is the above disk an NT boot disk?/ms) { + if ($in->ask_yesorno('', +formatAlaTeX(N("LILO wants to assign a new Volume ID to drive %s. However, changing +the Volume ID of a Windows NT, 2000, or XP boot disk is a fatal Windows error. +This caution does not apply to Windows 95 or 98, or to NT data disks. + +Assign a new Volume ID?", $dev)))) { + $b->{force_lilo_answer} = 'n'; + } else { + $b->{'static-bios-codes'} = 1; + } + goto retry; + } else { + $in->ask_warn('', [ N("Installation of bootloader failed. The following error occurred:"), $err ]); + return; + } + } elsif (arch() =~ /ppc/) { + my $of_boot = cat_("$::prefix/tmp/of_boot_dev") || die "Can't open $::prefix/tmp/of_boot_dev"; + chop($of_boot); + $in->ask_warn('', N("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)); + } + 1; } @@ -158,7 +236,7 @@ sub setupBootloader__mbr_or_not { my @l = ( [ N("First sector of drive (MBR)") => '/dev/' . $hds->[0]{device} ], - [ N("First sector of the root partition") => '/dev/' . fsedit::get_root($fstab, 'boot')->{device} ], + [ N("First sector of the root partition") => '/dev/' . fs::get::root($fstab, 'boot')->{device} ], if_($floppy, [ N("On Floppy") => "/dev/$floppy" ], ), @@ -184,7 +262,6 @@ sub setupBootloader__general { my ($in, $b, $all_hds, $fstab, $security) = @_; my @method_choices = bootloader::method_choices($fstab); - my $profiles = bootloader::has_profiles($b); my $prev_force_acpi = my $force_acpi = bootloader::get_append($b, 'acpi') !~ /off|ht/; my $prev_force_noapic = my $force_noapic = bootloader::get_append($b, 'noapic'); my $prev_force_nolapic = my $force_nolapic = bootloader::get_append($b, 'nolapic'); @@ -209,7 +286,7 @@ sub setupBootloader__general { }, [ { label => N("Bootloader to use"), val => \$b->{method}, list => \@method_choices, format => \&bootloader::method2text }, if_(arch() !~ /ia64/, - { label => N("Boot device"), val => \$b->{boot}, list => [ map { "/dev/$_" } (map { $_->{device} } (@{$all_hds->{hds}}, grep { !isFat_or_NTFS($_) } @$fstab)), detect_devices::floppies_dev() ], not_edit => !$::expert }, + { label => N("Boot device"), val => \$b->{boot}, list => [ map { "/dev/$_->{device}" } bootloader::allowed_boot_parts($b, $all_hds) ], not_edit => !$::expert }, ), { label => N("Delay before booting default image"), val => \$b->{timeout} }, { text => N("Enable ACPI"), val => \$force_acpi, type => 'bool' }, @@ -225,7 +302,6 @@ sub setupBootloader__general { { text => N("Clean /tmp at each boot"), val => \$clean_tmp, type => 'bool', advanced => 1 }, { label => N("Precise RAM size if needed (found %d MB)", availableRamMB()), val => \$memsize, advanced => 1 }, if_(detect_devices::isLaptop(), - { text => N("Enable multiple profiles"), val => \$profiles, type => 'bool', advanced => 1 }, ), ]) or return 0; } else { @@ -247,11 +323,16 @@ sub setupBootloader__general { #- remove bios mapping if the user changed the boot device delete $b->{bios} if $b->{boot} ne $prev_boot; + if ($b->{boot} =~ m!/dev/md\d+$!) { + $b->{'raid-extra-boot'} = 'mbr'; + } else { + delete $b->{'raid-extra-boot'} if $b->{'raid-extra-boot'} eq 'mbr'; + } + if ($b->{method} eq 'grub') { - $in->do_pkgs->ensure_is_installed('grub', "/usr/sbin/grub", 1) or return 0; + $in->do_pkgs->ensure_binary_is_installed('grub', "grub", 1) or return 0; } - bootloader::set_profiles($b, $profiles); bootloader::set_append($b, "mem", $memsize || 0); if ($prev_force_acpi != $force_acpi) { bootloader::set_append($b, acpi => ($force_acpi ? '' : 'ht')); @@ -264,8 +345,8 @@ sub setupBootloader__general { } if ($prev_clean_tmp != $clean_tmp) { - if ($clean_tmp && !fsedit::has_mntpoint('/tmp', $all_hds)) { - push @{$all_hds->{special}}, { device => 'none', mntpoint => '/tmp', pt_type => 'tmpfs' }; + if ($clean_tmp && !fs::get::has_mntpoint('/tmp', $all_hds)) { + push @{$all_hds->{special}}, { device => 'none', mntpoint => '/tmp', fs_type => 'tmpfs' }; } else { @{$all_hds->{special}} = grep { $_->{mntpoint} ne '/tmp' } @{$all_hds->{special}}; } @@ -279,20 +360,23 @@ sub setupBootloader__entries { require Xconfig::resolution_and_depth; my $Modify = sub { + require network::netconnect; #- to list network profiles my ($e) = @_; my $default = my $old_default = $e->{label} eq $b->{default}; my $vga = Xconfig::resolution_and_depth::from_bios($e->{vga}); + my ($append, $netprofile) = bootloader::get_append_netprofile($e); my @l; if ($e->{type} eq "image") { @l = ( { label => N("Image"), val => \$e->{kernel_or_dev}, list => [ map { "/boot/$_" } bootloader::installed_vmlinuz() ], not_edit => 0 }, { label => N("Root"), val => \$e->{root}, list => [ map { "/dev/$_->{device}" } @$fstab ], not_edit => !$::expert }, -{ label => N("Append"), val => \$e->{append} }, +{ label => N("Append"), val => \$append }, if_(arch() !~ /ppc|ia64/, { label => N("Video mode"), val => \$vga, list => [ '', Xconfig::resolution_and_depth::bios_vga_modes() ], format => \&Xconfig::resolution_and_depth::to_string, advanced => 1 }, ), { label => N("Initrd"), val => \$e->{initrd}, list => [ map { if_(/^initrd/, "/boot/$_") } all("$::prefix/boot") ], not_edit => 0, advanced => 1 }, +{ label => N("Network profile"), val => \$netprofile, list => [ sort(uniq('', $netprofile, network::netconnect::get_profiles())) ], advanced => 1 }, ); } else { @l = ( @@ -331,6 +415,7 @@ sub setupBootloader__entries { $b->{default} = $old_default || $default ? $default && $e->{label} : $b->{default}; $e->{vga} = ref($vga) ? $vga->{bios} : $vga; + bootloader::set_append_netprofile($e, $append, $netprofile); bootloader::configure_entry($e); #- hack to make sure initrd file are built. 1; }; @@ -343,7 +428,7 @@ sub setupBootloader__entries { N_("Other OS (MacOS...)") : N_("Other OS (Windows...)") ] ) eq "Linux") { $e = { type => 'image', - root => '/dev/' . fsedit::get_root($fstab)->{device}, #- assume a good default. + root => '/dev/' . fs::get::root($fstab)->{device}, #- assume a good default. }; $prefix = "linux"; } else { @@ -384,17 +469,6 @@ You can create additional entries or change the existing ones."), [ { } } -my @etc_pass_fields = qw(name pw uid gid realname home shell); -sub unpack_passwd { - my ($l) = @_; - my %l; @l{@etc_pass_fields} = split ':', chomp_($l); - \%l; -} -sub pack_passwd { - my ($l) = @_; - join(':', @$l{@etc_pass_fields}) . "\n"; -} - sub get_autologin() { my %desktop = getVarsFromSh("$::prefix/etc/sysconfig/desktop"); my $desktop = $desktop{DESKTOP} || 'KDE'; @@ -411,33 +485,51 @@ sub get_autologin() { } sub set_autologin { - my ($user, $desktop) = @_; - my $autologin = bool2text($user); + my ($o_user, $o_wm) = @_; + log::l("set_autologin $o_user $o_wm"); + my $autologin = bool2text($o_user); #- Configure KDM / MDKKDM eval { update_gnomekderc("$::prefix/usr/share/config/kdm/kdmrc", 'X-:0-Core' => ( AutoLoginEnable => $autologin, - AutoLoginUser => $user, + AutoLoginUser => $o_user, )) }; #- Configure GDM eval { update_gnomekderc("$::prefix/etc/X11/gdm/gdm.conf", daemon => ( AutomaticLoginEnable => $autologin, - AutomaticLogin => $user, + AutomaticLogin => $o_user, )) }; - if ($user) { - my %l = getVarsFromSh("$::prefix/etc/sysconfig/desktop"); - $l{DESKTOP} = $desktop; - setVarsInSh("$::prefix/etc/sysconfig/desktop", \%l); - log::l("cat $::prefix/etc/sysconfig/desktop ($desktop):\n", cat_("$::prefix/etc/sysconfig/desktop")); - } my $xdm_autologin_cfg = "$::prefix/etc/sysconfig/autologin"; - if (member($desktop, 'KDE', 'GNOME')) { + if (member($o_wm, 'KDE', 'GNOME')) { unlink $xdm_autologin_cfg; } else { setVarsInShMode($xdm_autologin_cfg, 0644, - { USER => $user, AUTOLOGIN => bool2yesno($user), EXEC => '/usr/X11R6/bin/startx.autologin' }); + { USER => $o_user, AUTOLOGIN => bool2yesno($o_user), EXEC => '/usr/X11R6/bin/startx.autologin' }); + } + + if ($o_user) { + my $home = (getpwnam($o_user))[7]; + set_window_manager($home, $o_wm); + } +} +sub set_window_manager { + my ($home, $wm) = @_; + log::l("set_window_manager $home $wm"); + my $p_home = "$::prefix$home"; + + #- for KDM/GDM + my $wm_number = sessions_with_order()->{$wm} || ''; + update_gnomekderc("$p_home/.dmrc", 'Desktop', Session => "$wm_number$wm"); + my $user = find { $p_home eq $_->[7] } list_passwd(); + chown($user->[2], $user->[3], "$p_home/.dmrc"); + + #- for startx/autologin + { + my %l = getVarsFromSh("$p_home/.desktop"); + $l{DESKTOP} = $wm; + setVarsInSh("$p_home/.desktop", \%l); } } @@ -481,7 +573,7 @@ sub inspect { $dir = ''; } else { mkdir $dir, 0700; - eval { fs::mount($part->{device}, $dir, type2fs($part, 'skip'), !$b_rw) }; + eval { fs::mount($part->{device}, $dir, $part->{fs_type}, !$b_rw) }; $@ and return; } my $h = before_leaving { @@ -540,7 +632,7 @@ sub ask_user_one { ok_disabled => sub { $security >= 4 && !@$users || $options{needauser} && !$u->{name} }, } }, [ { label => N("Real name"), val => \$u->{realname} }, - { label => N("User name"), val => \$u->{name} }, + { label => N("Login name"), val => \$u->{name} }, { label => N("Password"),val => \$u->{password}, hidden => 1 }, { label => N("Password (again)"), val => \$u->{password2}, hidden => 1 }, { label => N("Shell"), val => \$u->{shell}, list => [ shells() ], not_edit => !$::expert, advanced => 1 }, @@ -574,6 +666,10 @@ sub ask_users { sub sessions() { split(' ', run_program::rooted_get_stdout($::prefix, '/usr/sbin/chksession', '-l')); } +sub sessions_with_order() { + my %h = map { /(.*)=(.*)/ } split(' ', run_program::rooted_get_stdout($::prefix, '/usr/sbin/chksession', '-L')); + \%h; +} sub autologin { my ($o, $in) = @_; @@ -605,7 +701,7 @@ sub selectLanguage { my ($in, $lang, $o_langs_) = @_; my $common = { messages => N("Please choose a language to use."), - title => 'language choice', + title => N("Language choice"), interactive_help_id => 'selectLanguage' }; if ($::isInstall) { @@ -646,7 +742,7 @@ when your installation is complete and you restart your system.")), $in->ask_from_($common, [ { val => \$lang, separator => '|', if_($using_images, image2f => sub { $name2l{$_[0]} =~ /^[a-z]/ ? ('', "langs/lang-$name2l{$_[0]}") : $_[0] }), - format => sub { $_[0] =~ /(.*\|)(.*)/ ? $1.lang::l2name($2) : lang::l2name($_[0]) }, + format => sub { $_[0] =~ /(.*\|)(.*)/ ? $1 . lang::l2name($2) : lang::l2name($_[0]) }, list => \@langs, sort => 0 }, if_($o_langs_ && !$::move, { val => \$in->{locale}{utf8}, type => 'bool', text => N("Use Unicode by default"), advanced => 1 }, @@ -693,38 +789,23 @@ sub selectCountry { messages => N("Please choose your country."), interactive_help_id => 'selectCountry', advanced_messages => N("Here is the full list of available countries"), - advanced_label => N("More"), + advanced_label => N("Other Countries"), advanced_state => $ext_country && scalar(@best), - callbacks => { changed => sub { $other = $_[0] == 1 } }, + callbacks => { changed => sub { $_[0] != 2 and $other = $_[0] == 1 } }, }, [ if_(@best, { val => \$country, type => 'list', format => \&lang::c2name, list => \@best, sort => 1 }), { val => \$ext_country, type => 'list', format => \&lang::c2name, - list => [ difference2(\@countries, \@best) ], advanced => scalar(@best) } + list => [ @countries ], advanced => scalar(@best) }, + { val => \$locale->{IM}, type => 'combo', label => N("Input method:"), sort => 0, + list => [ N_("None"), sort(lang::get_ims()) ], format => sub { uc(translate($_[0])) }, + advanced => !$locale->{IM} || $locale->{IM} eq 'None', + }, ]) or return; $locale->{country} = $other || !@best ? $ext_country : $country; } -sub write_passwd_user { - my ($u, $isMD5) = @_; - - $u->{pw} = $u->{password} ? &crypt($u->{password}, $isMD5) : $u->{pw} || ''; - $u->{shell} ||= '/bin/bash'; - - substInFile { - my $l = unpack_passwd($_); - if ($l->{name} eq $u->{name}) { - add2hash_($u, $l); - $_ = pack_passwd($u); - $u = {}; - } - if (eof && $u->{name}) { - $_ .= pack_passwd($u); - } - } "$::prefix/etc/passwd"; -} - sub set_login_serial_console { my ($port, $speed) = @_; @@ -790,6 +871,8 @@ UNREGISTER ^$devfs_if\$ CFUNCTION GLOBAL unlink $of UNREGISTER ^$devfs_if\$ CFUNCTION GLOBAL unlink $if ") if $devfs_if ne $if && $if !~ /^hd[a-z]/ && $if !~ /^sr/ && $if !~ /^sd[a-z]/; + output_p("$::prefix/etc/udev/rules.d/$of.rules", qq(KERNEL="$if", SYMLINK="$of"\n)); + #- when creating a symlink on the system, use devfs name if devfs is mounted symlinkf($devfs_if, "$::prefix/dev/$if") if $devfs_if ne $if && detect_devices::dev_is_devfs(); symlinkf($if, "$::prefix/dev/$of"); @@ -807,13 +890,18 @@ UNREGISTER ^$devfs_if\$ EXECUTE /etc/dynamic/scripts/rawdevice.script del /dev/$ "); } -sub fix_broken_alternatives() { +sub fix_broken_alternatives { + my ($force_default) = @_; #- fix bad update-alternatives that may occurs after upgrade (and sometimes for install too). -d "$::prefix/etc/alternatives" or return; foreach (all("$::prefix/etc/alternatives")) { - next if run_program::rooted($::prefix, 'test', '-e', "/etc/alternatives/$_"); - log::l("fixing broken alternative $_"); + if ($force_default) { + log::l("setting alternative $_"); + } else { + next if run_program::rooted($::prefix, 'test', '-e', "/etc/alternatives/$_"); + log::l("fixing broken alternative $_"); + } run_program::rooted($::prefix, 'update-alternatives', '--auto', $_); } } @@ -852,8 +940,10 @@ Allowing this will permit users to simply click on \"Share\" in konqueror and na %l = ($type => 1); } else { %l = map_each { $::a => services::starts_on_boot($::b->[1]) } %types; - $in->ask_from('', N("You can export using NFS or SMB. Please select which you would like to use."), - [ map { { text => $types{$_}[2], val => \$l{$_}, type => 'bool' } } keys %l ]) or return; + $in->ask_from_({ messages => N("You can export using NFS or SMB. Please select which you would like to use."), + callbacks => { ok_disabled => sub { !any { $_ } values %l } }, + }, + [ map { { text => $types{$_}[2], val => \$l{$_}, type => 'bool' } } keys %l ]) or return; } foreach (keys %types) { my ($pkg, $service, $_descr) = @{$types{$_}}; @@ -875,7 +965,7 @@ Allowing this will permit users to simply click on \"Share\" in konqueror and na run_program::rooted($::prefix, 'groupadd', '-r', 'fileshare'); if ($in->ask_from_no_check( { - -e '/usr/sbin/userdrake' ? (ok => N("Launch userdrake"), cancel => N("Cancel")) : (cancel => ''), + -e '/usr/sbin/userdrake' ? (ok => N("Launch userdrake"), cancel => N("Close")) : (cancel => ''), messages => N("The per-user sharing uses the group \"fileshare\". You can use userdrake to add a user to this group.") |
