package any; # $Id$ use diagnostics; use strict; #-###################################################################################### #- misc imports #-###################################################################################### use common qw(:common :system :file :functional); use commands; use detect_devices; use partition_table qw(:types); use fsedit; use fs; use run_program; use modules; use log; sub drakx_version { sprintf "DrakX v%s built %s", $::testing ? ('TEST', scalar gmtime()) : (split('/', cat_("/usr/share/VERSION")))[2,3]; } sub facesdir { my ($prefix) = @_; "$prefix/usr/share/faces/"; } sub face2xpm { my ($face, $prefix) = @_; facesdir($prefix) . $face . ".xpm"; } sub facesnames { my ($prefix) = @_; my $dir = facesdir($prefix); grep { -e "$dir/$_.png" } map { /(.*)\.xpm/ } all($dir); } sub addKdmIcon { my ($prefix, $user, $icon) = @_; my $dest = "$prefix/usr/share/faces/$user.png"; eval { commands::cp("-f", facesdir($prefix) . $icon . ".png", $dest) } if $icon; } sub allocUsers { my ($prefix, $users) = @_; my @m = my @l = facesnames($prefix); foreach (grep { !$_->{icon} || $_->{icon} eq "automagic" } @$users) { $_->{auto_icon} = splice(@m, rand(@m), 1); #- known biased (see cookbook for better) log::l("auto_icon is $_->{auto_icon}"); @m = @l unless @m; } } sub addUsers { my ($prefix, $users) = @_; my $msec = "$prefix/etc/security/msec"; allocUsers($prefix, $users); foreach my $u (@$users) { substInFile { s/^$u->{name}\n//; $_ .= "$u->{name}\n" if eof } "$msec/user.conf" if -d $msec; addKdmIcon($prefix, $u->{name}, delete $u->{auto_icon} || $u->{icon}); } run_program::rooted($prefix, "/usr/share/msec/grpuser.sh --refresh >/dev/null"); } sub crypt { my ($password, $md5) = @_; $md5 ? c::crypt_md5($password, salt(8)) : crypt ($password, salt(2)); } sub enableShadow { my ($prefix) = @_; run_program::rooted($prefix, "pwconv") or log::l("pwconv failed"); run_program::rooted($prefix, "grpconv") or log::l("grpconv failed"); } sub enableMD5Shadow { my ($prefix, $shadow, $md5) = @_; substInFile { if (/^password.*pam_pwdb.so/) { s/\s*shadow//; s/\s*md5//; s/$/ shadow/ if $shadow; s/$/ md5/ if $md5; } } grep { -r $_ } map { "$prefix/etc/pam.d/$_" } qw(login rlogin passwd); } sub setupBootloader { my ($in, $b, $hds, $fstab, $security, $prefix, $more) = @_; $more++ if $b->{bootUnsafe}; if ($::beginner && $more >= 1) { my @l = (__("First sector of drive (MBR)"), __("First sector of boot partition")); $in->set_help('setupBootloaderBeginner') unless $::isStandalone; if (arch() =~ /sparc/) { $b->{use_partition} = $in->ask_from_list_(_("SILO Installation"), _("Where do you want to install the bootloader?"), \@l, $l[$b->{use_partition}]); } else { my $boot = $hds->[0]{device}; my $onmbr = "/dev/$boot" eq $b->{boot}; $b->{boot} = "/dev/" . ($in->ask_from_list_(_("LILO/grub Installation"), _("Where do you want to install the bootloader?"), \@l, $l[!$onmbr]) eq $l[0] ? $boot : fsedit::get_root($fstab, 'boot')->{device}); } } elsif ($more || !$::beginner) { $in->set_help(arch() =~ /sparc/ ? "setupSILOGeneral" : "setupBootloaderGeneral") unless $::isStandalone; #- TO MERGE ? if ($::expert) { my $default = arch() =~ /sparc/ ? 'silo' : 'grub'; my $m = $in->ask_from_list_('', _("Which bootloader(s) do you want to use?"), [ keys(%{$b->{methods}}), __("None") ], $default) or return; $b->{methods}{$_} = 0 foreach keys %{$b->{methods}}; $b->{methods}{$m} = 1 if $m ne "None"; } #- at least one method grep_each { $::b } %{$b->{methods}} or return; #- put lilo if grub is chosen, so that /etc/lilo.conf is generated exists $b->{methods}{lilo} and $b->{methods}{lilo} = 1 if $b->{methods}{grub}; my @silo_install_lang = (_("First sector of drive (MBR)"), _("First sector of boot partition")); my $silo_install_lang = $silo_install_lang[$b->{use_partition}]; my @l = ( arch() =~ /sparc/ ? ( { label => _("Bootloader installation"), val => \$silo_install_lang, list => \@silo_install_lang }, ) : ( { label => _("Boot device"), val => \$b->{boot}, list => [ map { "/dev/$_" } (map { $_->{device} } (@$hds, grep { !isFat($_) } @$fstab)), detect_devices::floppies() ], not_edit => !$::expert }, { label => _("LBA (doesn't work on old BIOSes)"), val => \$b->{lba32}, type => "bool", text => "lba" }, { label => _("Compact"), val => \$b->{compact}, type => "bool", text => _("compact") }, { label => _("Video mode"), val => \$b->{vga}, list => [ keys %bootloader::vga_modes ], not_edit => $::beginner }, ), { label => _("Delay before booting default image"), val => \$b->{timeout} }, $security < 4 ? () : ( { label => _("Password"), val => \$b->{password}, hidden => 1 }, { label => _("Password (again)"), val => \$b->{password2}, hidden => 1 }, { label => _("Restrict command line options"), val => \$b->{restricted}, type => "bool", text => _("restrict") }, ) ); @l = @l[0..1] unless $::expert; #- take "bootloader installation" and "delay before ..." on SPARC. $b->{vga} ||= 'Normal'; $in->ask_from_entries_refH('', _("Bootloader main options"), \@l, complete => sub { #- $security > 4 && length($b->{password}) < 6 and $in->ask_warn('', _("At this level of security, a password (and a good one) in lilo is requested")), return 1; $b->{restricted} && !$b->{password} and $in->ask_warn('', _("Option ``Restrict command line options'' is of no use without a password")), return 1; $b->{password} eq $b->{password2} or !$b->{restricted} or $in->ask_warn('', [ _("The passwords do not match"), _("Please try again") ]), return 1; 0; } ) or return 0; $b->{use_partition} = $silo_install_lang eq _("First sector of drive (MBR)") ? 0 : 1; $b->{vga} = $bootloader::vga_modes{$b->{vga}} || $b->{vga}; } until ($::beginner && $more <= 1) { $in->set_help(arch() =~ /sparc/ ? 'setupSILOAddEntry' : 'setupBootloaderAddEntry') unless $::isStandalone; my $c = $in->ask_from_listf([''], _("Here are the different entries. You can add some more or change the existing ones."), sub { my ($e) = @_; ref $e ? "$e->{label} ($e->{kernel_or_dev})" . ($b->{default} eq $e->{label} && " *") : translate($e); }, [ @{$b->{entries}}, __("Add"), __("Done") ]); $c eq "Done" and last; my ($e); if ($c eq "Add") { my @labels = map { $_->{label} } @{$b->{entries}}; my $prefix; if ($in->ask_from_list_('', _("Which type of entry do you want to add?"), [ __("Linux"), arch() =~ /sparc/ ? __("Other OS (SunOS...)") : __("Other OS (windows...)") ] ) eq "Linux") { $e = { type => 'image', root => '/dev/' . fsedit::get_root($fstab)->{device}, #- assume a good default. }; $prefix = "linux"; } else { $e = { type => 'other' }; $prefix = arch() =~ /sparc/ ? "sunos" : "windows"; } $e->{label} = $prefix; for (my $nb = 0; member($e->{label}, @labels); $nb++) { $e->{label} = "$prefix-$nb" } } else { $e = $c; } my %old_e = %$e; my $default = my $old_default = $e->{label} eq $b->{default}; my @l; if ($e->{type} eq "image") { @l = ( { label => _("Image"), val => \$e->{kernel_or_dev}, list => [ map { s/$prefix//; $_ } glob_("$prefix/boot/vmlinuz*") ], not_edit => 0 }, { label => _("Root"), val => \$e->{root}, list => [ map { "/dev/$_->{device}" } @$fstab ], not_edit => !$::expert }, { label => _("Append"), val => \$e->{append} }, { label => _("Video mode"), val => \$e->{vga}, list => [ keys %bootloader::vga_modes ], not_edit => !$::expert }, { label => _("Initrd"), val => \$e->{initrd}, list => [ map { s/$prefix//; $_ } glob_("$prefix/boot/initrd*") ] }, { label => _("Read-write"), val => \$e->{'read-write'}, type => 'bool' } ); @l = @l[0..2] unless $::expert; } else { @l = ( { label => _("Root"), val => \$e->{kernel_or_dev}, list => [ map { "/dev/$_->{device}" } @$fstab ], not_edit => !$::expert }, arch() !~ /sparc/ ? ( { label => _("Table"), val => \$e->{table}, list => [ '', map { "/dev/$_->{device}" } @$hds ], not_edit => !$::expert }, { label => _("Unsafe"), val => \$e->{unsafe}, type => 'bool' } ) : (), ); @l = $l[0] unless $::expert; } @l = ( { label => _("Label"), val => \$e->{label} }, @l, { label => _("Default"), val => \$default, type => 'bool' }, ); if ($in->ask_from_entries_refH_powered( { if_($c ne "Add", cancel => _("Remove entry")), callbacks => { complete => sub { $e->{label} or $in->ask_warn('', _("Empty label not allowed")), return 1; member($e->{label}, map { $_->{label} } grep { $_ != $e } @{$b->{entries}}) and $in->ask_warn('', _("This label is already used")), return 1; 0; } } }, \@l)) { $b->{default} = $old_default || $default ? $default && $e->{label} : $b->{default}; $e->{vga} = $bootloader::vga_modes{$e->{vga}} || $e->{vga}; require bootloader; bootloader::configure_entry($prefix, $e); #- hack to make sure initrd file are built. push @{$b->{entries}}, $e if $c eq "Add"; } else { @{$b->{entries}} = grep { $_ != $e } @{$b->{entries}}; } } 1; } my @etc_pass_fields = qw(name pw uid gid realname home shell); sub unpack_passwd { my ($l) = @_; chomp $l; my %l; @l{@etc_pass_fields} = split ':', $l; \%l; } sub pack_passwd { my ($l) = @_; join(':', @$l{@etc_pass_fields}) . "\n"; } sub setAutologin { my ($prefix, $user, $desktop) = @_; output "$prefix/etc/sysconfig/desktop", uc($desktop), "\n" if $user; setVarsInSh("$prefix/etc/sysconfig/autologin", { USER => $user, AUTOLOGIN => bool2yesno($user), EXEC => "/usr/X11R6/bin/startx" }); } sub rotate_log { my ($f) = @_; if (-e $f) { my $i = 1; for (; -e "$f$i" || -e "$f$i.gz"; $i++) {} rename $f, "$f$i"; } } sub rotate_logs { my ($prefix) = @_; rotate_log("$prefix/root/$_") foreach qw(ddebug.log install.log); } sub writeandclean_ldsoconf { my ($prefix) = @_; my $file = "$prefix/etc/ld.so.conf"; output $file, grep { !m|^(/usr)?/lib$| } #- no ne