package any; # $Id$ use diagnostics; use strict; #-###################################################################################### #- misc imports #-###################################################################################### use common; use detect_devices; use partition_table; use fs::type; use lang; use run_program; use devices; use modules; use log; use fs; use c; sub facesdir() { "$::prefix/usr/share/mdk/faces/"; } sub face2png { my ($face) = @_; facesdir() . $face . ".png"; } sub facesnames() { my $dir = facesdir(); my @l = grep { /^[A-Z]/ } all($dir); map { if_(/(.*)\.png/, $1) } (@l ? @l : all($dir)); } sub addKdmIcon { my ($user, $icon) = @_; my $dest = "$::prefix/usr/share/faces/$user.png"; eval { cp_af(facesdir() . $icon . ".png", $dest) } if $icon; } sub alloc_user_faces { my ($users) = @_; my @m = my @l = facesnames(); 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 create_user { my ($u, $authentication) = @_; 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}); } } elsif ($u->{rename_from}) { run_program::rooted($::prefix, 'groupmod', '-n', $u->{name}, $u->{rename_from}); } require authentication; my $symlink_home_from = $u->{rename_from} && (getpwnam($u->{rename_from}))[7]; run_program::raw({ root => $::prefix, sensitive_arguments => 1 }, ($u->{rename_from} ? 'usermod' : 'adduser'), '-p', authentication::user_crypted_passwd($u, $authentication), if_($uid, '-u', $uid), if_($gid, '-g', $gid), if_($u->{realname}, '-c', $u->{realname}), if_($u->{home}, '-d', $u->{home}, if_($u->{rename_from}, '-m')), if_($u->{shell}, '-s', $u->{shell}), ($u->{rename_from} ? ('-l', $u->{name}, $u->{rename_from}) : $u->{name})); symlink($u->{home}, $symlink_home_from) if $symlink_home_from; } my (undef, undef, $uid, $gid, undef, undef, undef, $home) = getpwnam($u->{name}); if (@existing && $::isInstall && ($uid != $existing[4] || $gid != $existing[5])) { log::l("chown'ing $home from $existing[4].$existing[5] to $uid.$gid"); eval { common::chown_('recursive', $uid, $gid, "$::prefix$home") }; } } sub add_users { my ($users, $authentication) = @_; alloc_user_faces($users); foreach (@$users) { create_user($_, $authentication); run_program::rooted($::prefix, "usermod", "-G", join(",", @{$_->{groups}}), $_->{name}) if !is_empty_array_ref($_->{groups}); addKdmIcon($_->{name}, delete $_->{auto_icon} || $_->{icon}); } } sub install_bootloader_pkgs { my ($do_pkgs, $b) = @_; bootloader::ensure_pkg_is_installed($do_pkgs, $b); install_acpi_pkgs($do_pkgs, $b); } sub install_acpi_pkgs { my ($do_pkgs, $b) = @_; my $acpi = bootloader::get_append_with_key($b, 'acpi'); my $use_acpi = !member($acpi, 'off', 'ht'); if ($use_acpi) { $do_pkgs->ensure_is_installed('acpi', '/usr/bin/acpi', $::isInstall); $do_pkgs->ensure_is_installed('acpid', '/usr/sbin/acpid', $::isInstall); } require services; services::set_status($_, $use_acpi, $::isInstall) foreach qw(acpi acpid); } sub setupBootloaderBeforeStandalone { my ($do_pkgs, $b, $all_hds, $fstab) = @_; require keyboard; my $keyboard = keyboard::read_or_default(); my $allow_fb = listlength(cat_("/proc/fb")); my $cmdline = cat_('/proc/cmdline'); my $vga_fb = first($cmdline =~ /\bvga=(\S+)/); my $quiet = $cmdline =~ /\bsplash=silent\b/; setupBootloaderBefore($do_pkgs, $b, $all_hds, $fstab, $keyboard, $allow_fb, $vga_fb, $quiet); } sub setupBootloaderBefore { my ($do_pkgs, $bootloader, $all_hds, $fstab, $keyboard, $allow_fb, $vga_fb, $quiet) = @_; require bootloader; #- auto_install backward compatibility #- one should now use {message_text} if ($bootloader->{message} =~ m!^[^/]!) { $bootloader->{message_text} = delete $bootloader->{message}; } #- remove previous ide-scsi lines bootloader::modify_append($bootloader, sub { my ($_simple, $dict) = @_; @$dict = grep { $_->[1] ne 'ide-scsi' } @$dict; }); if (cat_("/proc/cmdline") =~ /mem=nopentium/) { bootloader::set_append_with_key($bootloader, mem => 'nopentium'); } if (cat_("/proc/cmdline") =~ /\b(pci)=(\S+)/) { bootloader::set_append_with_key($bootloader, $1, $2); } if (my ($acpi) = cat_("/proc/cmdline") =~ /\bacpi=(\w+)/) { if ($acpi eq 'ht') { #- the user is using the default, which may not be the best my $year = detect_devices::computer_info()->{BIOS_Year}; if ($year >= 2002) { log::l("forcing ACPI on recent bios ($year)"); $acpi = ''; } } bootloader::set_append_with_key($bootloader, acpi => $acpi); } if (cat_("/proc/cmdline") =~ /\bnoapic/) { bootloader::set_append_simple($bootloader, 'noapic'); } if (cat_("/proc/cmdline") =~ /\bnoresume/) { bootloader::set_append_simple($bootloader, 'noresume'); } elsif (bootloader::get_append_simple($bootloader, 'noresume')) { } else { my ($MemTotal) = cat_("/proc/meminfo") =~ /^MemTotal:\s*(\d+)/m; if (my ($biggest_swap) = sort { $b->{size} <=> $a->{size} } grep { isSwap($_) } @$fstab) { log::l("MemTotal: $MemTotal < ", $biggest_swap->{size} / 2); if ($MemTotal < $biggest_swap->{size} / 2) { bootloader::set_append_with_key($bootloader, resume => fs::wild_device::from_part('', $biggest_swap)); } } } #- check for valid fb mode to enable a default boot with frame buffer. my $vga = $allow_fb && (!detect_devices::matching_desc__regexp('3D Rage LT') && !detect_devices::matching_desc__regexp('Rage Mobility [PL]') && !detect_devices::matching_desc__regexp('i740') && !detect_devices::matching_desc__regexp('Matrox') && !detect_devices::matching_desc__regexp('Tseng.*ET6\d00') && !detect_devices::matching_desc__regexp('SiS.*SG86C2.5') && !detect_devices::matching_desc__regexp('SiS.*559[78]') && !detect_devices::matching_desc__regexp('SiS.*300') && !detect_devices::matching_desc__regexp('SiS.*540') && !detect_devices::matching_desc__regexp('SiS.*6C?326') && !detect_devices::matching_desc__regexp('SiS.*6C?236') && !detect_devices::matching_desc__regexp('Voodoo [35]|Voodoo Banshee') && #- 3d acceleration seems to bug in fb mode !detect_devices::matching_desc__regexp('828[14][05].* CGC') #- i810 & i845 now have FB support during install but we disable it afterwards ); my $force_vga = $allow_fb && (detect_devices::matching_desc__regexp('SiS.*630') || #- SiS 630 need frame buffer. detect_devices::matching_desc__regexp('GeForce.*Integrated') #- needed for fbdev driver (hack). ); #- propose the default fb mode for kernel fb, if bootsplash is installed. my $need_fb = $do_pkgs->are_installed('bootsplash'); bootloader::suggest($bootloader, $all_hds, vga_fb => ($force_vga || $vga && $need_fb) && $vga_fb, quiet => $quiet); $bootloader->{keytable} ||= keyboard::keyboard2kmap($keyboard); } sub setupBootloader { my ($in, $b, $all_hds, $fstab, $security) = @_; require bootloader; general: { local $::Wizard_no_previous = 1 if $::isStandalone; setupBootloader__general($in, $b, $all_hds, $fstab, $security) or return 0; } 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; } 1; } sub setupBootloaderUntilInstalled { my ($in, $b, $all_hds, $fstab, $security) = @_; do { my $before = fs::fstab_to_string($all_hds); setupBootloader($in, $b, $all_hds, $fstab, $security) or $in->exit; if ($before ne fs::fstab_to_string($all_hds)) { #- for /tmp using tmpfs when "clean /tmp" is chosen fs::write_fstab($all_hds); } } while !installBootloader($in, $b, $all_hds); } sub installBootloader { my ($in, $b, $all_hds) = @_; return if detect_devices::is_xbox(); install_bootloader_pkgs($in->do_pkgs, $b); 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); }; 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/) { if (detect_devices::get_mac_model() !~ /IBM/) { my $of_boot = bootloader::dev2yaboot($b->{boot}); $in->ask_warn('', N("You may need to change your Open Firmware boot-device to\n enable the bootloader. If you do not 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; } sub setupBootloader_simple { my ($in, $b, $all_hds, $fstab, $security) = @_; my $hds = $all_hds->{hds}; require bootloader; bootloader::ensafe_first_bios_drive($hds) || $b->{bootUnsafe} || arch() =~ /ppc/ or return 1; #- default is good enough if (arch() !~ /ia64/) { setupBootloader__mbr_or_not($in, $b, $hds, $fstab) or return 0; } else { general: setupBootloader__general($in, $b, $all_hds, $fstab, $security) or return 0; } setupBootloader__boot_bios_drive($in, $b, $hds) or goto general; 1; } sub setupBootloader__boot_bios_drive { my ($in, $b, $hds) = @_; if (arch() =~ /ppc/ || !is_empty_hash_ref($b->{bios})) { #- some bios mapping already there return 1; } elsif (bootloader::mixed_kind_of_disks($hds) && $b->{boot} =~ /\d$/) { #- on a partition # see below } else { return 1; } log::l("_ask_boot_bios_drive"); my $hd = $in->ask_from_listf('', N("You decided to install the bootloader on a partition. This implies you already have a bootloader on the hard drive you boot (eg: System Commander). On which drive are you booting?"), \&partition_table::description, $hds) or return 0; log::l("mixed_kind_of_disks chosen $hd->{device}"); $b->{first_hd_device} = "/dev/$hd->{device}"; 1; } sub setupBootloader__mbr_or_not { my ($in, $b, $hds, $fstab) = @_; log::l("setupBootloader__mbr_or_not"); if (arch() =~ /ppc/) { if (defined $partition_table::mac::bootstrap_part) { $b->{boot} = $partition_table::mac::bootstrap_part; log::l("set bootstrap to $b->{boot}"); } else { die "no bootstrap partition - yaboot.conf creation failed"; } } else { my $floppy = detect_devices::floppy(); my @l = ( bootloader::ensafe_first_bios_drive($hds) ? (map { [ N("First sector (MBR) of drive %s", partition_table::description($_)) => '/dev/' . $_->{device} ] } @$hds) : [ N("First sector of drive (MBR)") => '/dev/' . $hds->[0]{device} ], [ N("First sector of the root partition") => '/dev/' . fs::get::root($fstab, 'boot')->{device} ], if_($floppy, [ N("On Floppy") => "/dev/$floppy" ], ), [ N("Skip") => '' ], ); my $default = find { $_->[1] eq $b->{boot} } @l; $in->ask_from_({ title => N("Bootloader Installation"), interactive_help_id => 'setupBootloaderBeginner', }, [ { label => N("Where do you want to install the bootloader?"), title => 1 }, { val => \$default, list => \@l, format => sub { $_[0][0] }, type => 'list' }, ] ); my $new_boot = $default->[1]; #- remove bios mapping if the user changed the boot device delete $b->{bios} if $new_boot && $new_boot ne $b->{boot}; $b->{boot} = $new_boot or return; } 1; } sub setupBootloader__general { my ($in, $b, $all_hds, $fstab, $security) = @_; return if detect_devices::is_xbox(); my @method_choices = bootloader::method_choices($all_hds); my $prev_force_acpi = my $force_acpi = bootloader::get_append_with_key($b, 'acpi') !~ /off|ht/; my $prev_enable_apic = my $enable_apic = !bootloader::get_append_simple($b, 'noapic'); my $prev_enable_lapic = my $enable_lapic = !bootloader::get_append_simple($b, 'nolapic'); my $prev_enable_smp = my $enable_smp = !bootloader::get_append_simple($b, 'nosmp'); my $prev_clean_tmp = my $clean_tmp = any { $_->{mntpoint} eq '/tmp' } @{$all_hds->{special} ||= []}; my $prev_boot = $b->{boot}; my $prev_method = $b->{method}; $b->{password2} ||= $b->{password} ||= ''; $::Wizard_title = N("Boot Style Configuration"); if (arch() !~ /ppc/) { my (@boot_devices, %boot_devices); foreach (bootloader::allowed_boot_parts($b, $all_hds)) { my $dev = "/dev/$_->{device}"; push @boot_devices, $dev; $boot_devices{$dev} = $_->{info} ? "$dev ($_->{info})" : $dev; } $in->ask_from_({ #messages => N("Bootloader main options"), title => N("Bootloader main options"), interactive_help_id => 'setupBootloader', }, [ #title => N("Bootloader main options"), { label => N("Bootloader"), title => 1 }, { 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 => \@boot_devices, format => sub { $boot_devices{$_[0]} } }, ), { label => N("Main options"), title => 1 }, { label => N("Delay before booting default image"), val => \$b->{timeout} }, { text => N("Enable ACPI"), val => \$force_acpi, type => 'bool' }, { text => N("Enable SMP"), val => \$enable_smp, type => 'bool', advanced => 1 }, { text => N("Enable APIC"), val => \$enable_apic, type => 'bool', advanced => 1, disabled => sub { !$enable_lapic } }, { text => N("Enable Local APIC"), val => \$enable_lapic, type => 'bool', advanced => 1 }, if_($security >= 4 || $b->{password} || $b->{restricted}, { label => N("Password"), val => \$b->{password}, hidden => 1, validate => sub { my $ok = $b->{password} eq $b->{password2} or $in->ask_warn('', [ N("The passwords do not match"), N("Please try again") ]); my $ok2 = !($b->{password} && $b->{method} eq 'grub-graphic') or $in->ask_warn('', N("You can not use a password with %s", bootloader::method2text($b->{method}))); $ok && $ok2; } }, { label => N("Password (again)"), val => \$b->{password2}, hidden => 1 }, { text => N("Restrict command line options"), val => \$b->{restricted}, type => "bool", text => N("restrict"), validate => sub { my $ok = !$b->{restricted} || $b->{password} or $in->ask_warn('', N("Option ``Restrict command line options'' is of no use without a password")); $ok } }, ), { text => N("Clean /tmp at each boot"), val => \$clean_tmp, type => 'bool', advanced => 1 }, ]) or return 0; } else { $b->{boot} = $partition_table::mac::bootstrap_part; $in->ask_from_({ messages => N("Bootloader main options"), title => N("Bootloader main options"), interactive_help_id => 'setupYabootGeneral', }, [ { label => N("Bootloader to use"), val => \$b->{method}, list => \@method_choices, format => \&bootloader::method2text }, { label => N("Init Message"), val => \$b->{'init-message'} }, { label => N("Boot device"), val => \$b->{boot}, list => [ map { "/dev/$_" } (map { $_->{device} } (grep { isAppleBootstrap($_) } @$fstab)) ] }, { label => N("Open Firmware Delay"), val => \$b->{delay} }, { label => N("Kernel Boot Timeout"), val => \$b->{timeout} }, { label => N("Enable CD Boot?"), val => \$b->{enablecdboot}, type => "bool" }, { label => N("Enable OF Boot?"), val => \$b->{enableofboot}, type => "bool" }, { label => N("Default OS?"), val => \$b->{defaultos}, list => [ 'linux', 'macos', 'macosx', 'darwin' ] }, ]) or return 0; } #- 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'; } bootloader::ensure_pkg_is_installed($in->do_pkgs, $b) or goto &setupBootloader__general; bootloader::suggest_message_text($b) if ! -e "$::prefix/boot/message-text"; #- in case we switch from grub to lilo if ($prev_force_acpi != $force_acpi) { bootloader::set_append_with_key($b, acpi => ($force_acpi ? '' : 'ht')); } if ($prev_enable_smp != $enable_smp) { ($enable_smp ? \&bootloader::remove_append_simple : \&bootloader::set_append_simple)->($b, 'nosmp'); } if ($prev_enable_apic != $enable_apic) { ($enable_apic ? \&bootloader::remove_append_simple : \&bootloader::set_append_simple)->($b, 'noapic'); ($enable_apic ? \&bootloader::set_append_simple : \&bootloader::remove_append_simple)->($b, 'apic'); } if ($prev_enable_lapic != $enable_lapic) { ($enable_lapic ? \&bootloader::remove_append_simple : \&bootloader::set_append_simple)->($b, 'nolapic'); ($enable_lapic ? \&bootloader::set_append_simple : \&bootloader::remove_append_simple)->($b, 'lapic'); } if ($prev_clean_tmp != $clean_tmp) { 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}}; } } if (bootloader::main_method($prev_method) eq 'lilo' && bootloader::main_method($b->{method}) eq 'grub') { log::l("switching for lilo to grub, ensure we don't read lilo.conf anymore"); renamef("$::prefix/etc/lilo.conf", "$::prefix/etc/lilo.conf.unused"); } 1; } sub setupBootloader__entries { my ($in, $b, $all_hds, $fstab) = @_; require Xconfig::resolution_and_depth; my $Modify = sub { require network::network; #- 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 %hd_infos = map { $_->{device} => $_->{info} } fs::get::hds($all_hds); my %root_descr = map { my $info = delete $hd_infos{$_->{rootDevice}}; my $dev = "/dev/$_->{device}"; my $info_ = $info ? "$dev ($info)" : $dev; ($dev => $info_, fs::wild_device::from_part('', $_) => $info_); } @$fstab; 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 { fs::wild_device::from_part('', $_) } @$fstab ], format => sub { $root_descr{$_[0]} } }, { label => N("Append"), val => \$append }, if_($e->{xen}, { label => N("Xen append"), val => \$e->{xen_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::network::netprofile_list())) ], advanced => 1 }, ); } else { @l = ( { label => N("Root"), val => \$e->{kernel_or_dev}, list => [ map { "/dev/$_->{device}" } @$fstab, detect_devices::floppies() ] }, ); } if (arch() !~ /ppc/) { @l = ( { label => N("Label"), val => \$e->{label} }, @l, { text => N("Default"), val => \$default, type => 'bool' }, ); } e $o->{in}->do_pkgs->install($pkg); } if (! -e $file) { $o->{in}->ask_warn('', _("Mandatory package %s is missing", $pkg)); return; } 1; } sub what_provides { my ($o, $name) = @_; my ($what) = split '\n', `urpmq '$name' 2>/dev/null`; split '\|', $what; } sub is_installed { my ($o, @l) = @_; run_program::run('rpm', '>', '/dev/null', '-q', @l); } sub are_installed { my ($o, @l) = @_; my @l2; run_program::run('rpm', '>', \@l2, '-q', '--qf', "%{name}\n", @l); intersection(\@l, [ map { chomp_($_) } @l2 ]); } sub remove { my ($o, @l) = @_; $o->{in}->suspend; standalone::explanations("removed packages @l"); my $ret = system('rpm', '-e', @l) == 0; $o->{in}->resume; $ret; } sub remove_nodeps { my ($o, @l) = @_; $o->{in}->suspend; standalone::explanations("removed (with --nodeps) packages @l"); my $ret = system('rpm', '-e', '--nodeps', @l) == 0; $o->{in}->resume; $ret; } ################################################################################ package standalone; #- stuff will go to special /var/log/explanations file my $standalone_name; sub explanations { c::syslog(c::LOG_INFO()|c::LOG_LOCAL1(), "@_") } @common_functs = qw(renamef linkf symlinkf output substInFile mkdir_p rm_rf cp_af touch setVarsInSh setExportedVarsInSh setExportedVarsInCsh update_gnomekderc); @builtin_functs = qw(chmod chown unlink link symlink rename system); @drakx_modules = qw(Xconfig::card Xconfig::default Xconfig::main Xconfig::monitor Xconfig::parse Xconfig::proprietary Xconfig::resolution_and_depth Xconfig::screen Xconfig::test Xconfig::various Xconfig::xfree Xconfig::xfree3 Xconfig::xfree4 Xconfig::xfreeX any bootloader bootlook c class_discard commands crypto detect_devices devices diskdrake diskdrake::hd_gtk diskdrake::interactive diskdrake::removable diskdrake::removable_gtk diskdrake::smbnfs_gtk fs fsedit http keyboard lang log loopback lvm modparm modules mouse my_gtk network network::adsl network::ethernet network::isdn_consts network::isdn network::modem network::netconnect network::network network::nfs network::smb network::tools partition_table partition_table_bsd partition_table::dos partition_table::empty partition_table::gpt partition_table::mac partition_table::raw partition_table::sun printer printerdrake proxy raid run_program scanner services steps swap timezone tinyfirewall); sub import { ($standalone_name = $0) =~ s|.*/||; c::openlog("$standalone_name"."[$$]"); explanations('### Program is starting ###'); eval "*MDK::Common::$_ = *$_" foreach @common_functs; foreach my $f (@builtin_functs) { eval "*$_"."::$f = *$f" foreach @drakx_modules; eval "*".caller()."::$f = *$f"; } } sub renamef { explanations "moved file $_[0] to $_[1]"; goto &MDK::Common::File::renamef; } sub linkf { explanations "hard linked file $_[0] to $_[1]"; goto &MDK::Common::File::linkf; } sub symlinkf { explanations "symlinked file $_[0] to $_[1]"; goto &MDK::Common::File::symlinkf; } sub output { explanations "created file $_[0]"; goto &MDK::Common::File::output; } sub substInFile(&@) { explanations "modified file $_[1]"; goto &MDK::Common::File::substInFile; } sub mkdir_p { explanations "created directory $_[0] (and parents if necessary)"; goto &MDK::Common::File::mkdir_p; } sub rm_rf { explanations "removed files/directories (recursively) @_"; goto &MDK::Common::File::rm_rf; } sub cp_af { my $retval = MDK::Common::File::cp_af @_; my $dest = pop @_; explanations "copied recursively @_ to $dest"; return $retval; } sub touch { explanations "touched file @_"; goto &MDK::Common::File::touch; } sub setVarsInSh { explanations "modified file $_[0]"; goto &MDK::Common::System::setVarsInSh; } sub setExportedVarsInSh { explanations "modified file $_[0]"; goto &MDK::Common::System::setExportedVarsInSh; } sub setExportedVarsInCsh { explanations "modified file $_[0]"; goto &MDK::Common::System::setExportedVarsInCsh; } sub update_gnomekderc { explanations "modified file $_[0]"; goto &MDK::Common::System::update_gnomekderc; } sub chmod { my $retval = CORE::chmod @_; my $mode = shift @_; explanations sprintf("changed mode of %s to %o", $_, $mode) foreach @_; return $retval; } sub chown { my $retval = CORE::chown @_; my $uid = shift @_; my $gid = shift @_; explanations sprintf("changed owner of $_ to $uid.$gid") foreach @_; return $retval; } sub unlink { explanations "removed files/directories @_"; CORE::unlink @_; } sub link { explanations "hard linked file $_[0] to $_[1]"; CORE::link $_[0], $_[1]; } sub symlink { explanations "symlinked file $_[0] to $_[1]"; CORE::symlink $_[0], $_[1]; } sub rename { explanations "renamed file $_[0] to $_[1]"; CORE::rename $_[0], $_[1]; } sub system { explanations "launched command: @_"; CORE::system @_; } 1; ix/var/log/syslog"), header("Xorg.log"), cat_("/var/log/Xorg.0.log"), header("monitor_full_edid"), monitor_full_edid(), header("stage1.log"), cat_("/tmp/stage1.log") || cat_("$::prefix/root/drakx/stage1.log"), header("ddebug.log"), cat_("/tmp/ddebug.log") || cat_("$::prefix/root/drakx/ddebug.log"), header("install.log"), cat_("$::prefix/root/drakx/install.log"), header("fstab"), cat_("$::prefix/etc/fstab"), header("modprobe.conf"), cat_("$::prefix/etc/modprobe.conf"), header("lilo.conf"), cat_("$::prefix/etc/lilo.conf"), header("grub: menu.lst"), join('', map { s/^(\s*password)\s+(.*)/$1 xxx/; $_ } cat_("$::prefix/boot/grub/menu.lst")), header("grub: install.sh"), cat_("$::prefix/boot/grub/install.sh"), header("grub: device.map"), cat_("$::prefix/boot/grub/device.map"), header("xorg.conf"), cat_("$::prefix/etc/X11/xorg.conf"), header("urpmi.cfg"), cat_("$::prefix/etc/urpmi/urpmi.cfg"), header("modprobe.preload"), cat_("$::prefix/etc/modprobe.preload"), header("sysconfig/i18n"), cat_("$::prefix/etc/sysconfig/i18n"), header("/proc/iomem"), cat_("/proc/iomem"), header("/proc/ioport"), cat_("/proc/ioports"), map_index { even($::i) ? header($_) : $_ } @other; } 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")) { 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', $_); } } sub fileshare_config { my ($in, $type) = @_; #- $type is 'nfs', 'smb' or '' my $file = '/etc/security/fileshare.conf'; my %conf = getVarsFromSh($file); my @l = (N_("No sharing"), N_("Allow all users"), N_("Custom")); my $restrict = exists $conf{RESTRICT} ? text2bool($conf{RESTRICT}) : 1; my $r = $in->ask_from_list_('fileshare', N("Would you like to allow users to share some of their directories? Allowing this will permit users to simply click on \"Share\" in konqueror and nautilus. \"Custom\" permit a per-user granularity. "), \@l, $l[$restrict ? (getgrnam('fileshare') ? 2 : 0) : 1]) or return; $restrict = $r ne $l[1]; my $custom = $r eq $l[2]; if ($r ne $l[0]) { require services; my %types = ( nfs => [ 'nfs-utils', 'nfs-server', N("NFS: the traditional Unix file sharing system, with less support on Mac and Windows.") ], smb => [ 'samba-server', 'smb', N("SMB: a file sharing system used by Windows, Mac OS X and many modern Linux systems.") ], ); my %l; if ($type) { %l = ($type => 1); } else { %l = map_each { $::a => services::starts_on_boot($::b->[1]) } %types; $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{$_}}; my $file = "/etc/init.d/$service"; if ($l{$_}) { $in->do_pkgs->ensure_is_installed($pkg, $file) or return; services::start($service); services::start_service_on_boot($service); } elsif (-e $file) { services::stop($service); services::do_not_start_service_on_boot($service); } } if ($in->do_pkgs->is_installed('nautilus')) { $in->do_pkgs->ensure_is_installed('nautilus-filesharing') or return; } } $conf{RESTRICT} = bool2yesno($restrict); setVarsInSh($file, \%conf); if ($custom) { run_program::rooted($::prefix, 'groupadd', '-r', 'fileshare'); if ($in->ask_from_no_check( { -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.") }, [])) { run_program::run('userdrake'); } } } sub monitor_full_edid() { return if $::noauto; devices::make('zero'); my ($vbe, $edid); { # prevent warnings in install's logs: local $ENV{LC_ALL} = 'C'; run_program::raw({ timeout => 20 }, 'monitor-edid', '>', \$edid, '2>', \$vbe, '-v', '--perl', if_($::isStandalone, '--try-in-console')); } if ($::isInstall) { foreach (['edid', \$edid], ['vbe', \$vbe]) { my ($name, $val) = @$_; if (-e "/tmp/$name") { my $old = cat_("/tmp/$name"); if (length($$val) < length($old)) { log::l("new $name is worse, keeping the previous one"); $$val = $old; } elsif (length($$val) > length($old)) { log::l("new $name is better, dropping the previous one"); } } output("/tmp/$name", $$val); } } ($edid, $vbe); } sub running_window_manager() { my @window_managers = qw(ksmserver kwin gnome-session icewm wmaker afterstep fvwm fvwm2 fvwm95 mwm twm enlightenment xfce blackbox sawfish olvwm fluxbox compiz drakx-matchbox-window-manager); foreach (@window_managers) { my @pids = fuzzy_pidofs(qr/\b$_\b/) or next; return wantarray() ? ($_, @pids) : $_; } undef; } sub set_wm_hints_if_needed { my ($o_in) = @_; my $wm = any::running_window_manager(); $o_in->{no_Window_Manager} = !$wm if $o_in; $::set_dialog_hint = $wm eq 'drakx-matchbox-window-manager'; } sub ask_window_manager_to_logout { my ($wm) = @_; my %h = ( 'ksmserver' => '/usr/lib/qt4/bin/qdbus org.kde.ksmserver /KSMServer logout 1 0 0', 'kwin' => "dcop kdesktop default logout", 'gnome-session' => "gnome-session-save --kill", 'icewm' => "killall -QUIT icewm", ); my $cmd = $h{$wm} or return; if (member($wm, 'ksmserver', 'kwin', 'gnome-session') && $> == 0) { #- we can not use dcop when we are root if (my $user = $ENV{USERHELPER_UID} && getpwuid($ENV{USERHELPER_UID})) { $cmd = "su $user -c '$cmd'"; } else { log::l('missing or unknown $USERHELPER_UID'); } } system($cmd); 1; } sub ask_window_manager_to_logout_then_do { my ($wm, $pid, $action) = @_; if (fork()) { ask_window_manager_to_logout($wm); return; } open STDIN, "/dev/null"; open STDERR, ">&STDERR"; c::setsid(); exec 'perl', '-e', q( my ($wm, $pid, $action) = @ARGV; my $nb; for ($nb = 30; $nb && -e "/proc/$pid"; $nb--) { sleep 1 } system($action) if $nb; ), $wm, $pid, $action; } sub ask_for_X_restart { my ($in) = @_; $::isStandalone && $in->isa('interactive::gtk') or return; my ($wm, $pid) = running_window_manager(); if (!$wm) { # no window manager, ctrl-alt-del may not be supported, but we still have to restart X.. $in->ask_okcancel('', N("You need to logout and back in again for changes to take effect. Press OK to logout now."), 1) or return; system('killall X'); } else { $in->ask_okcancel('', N("You need to log out and back in again for changes to take effect"), 1) or return; ask_window_manager_to_logout_then_do($wm, $pid, 'killall X'); } } sub alloc_raw_device { my ($prefix, $device) = @_; my $used = 0; my $raw_dev; substInFile { $used = max($used, $1) if m|^\s*/dev/raw/raw(\d+)|; if (eof) { $raw_dev = "raw/raw" . ($used + 1); $_ .= "/dev/$raw_dev /dev/$device\n"; } } "$prefix/etc/sysconfig/rawdevices"; $raw_dev; } sub config_mtools { my ($prefix) = @_; my $file = "$prefix/etc/mtools.conf"; -e $file or return; my ($f1, $f2) = detect_devices::floppies_dev(); substInFile { s|drive a: file="(.*?)"|drive a: file="/dev/$f1"|; s|drive b: file="(.*?)"|drive b: file="/dev/$f2"| if $f2; } $file; } sub configure_timezone { my ($in, $timezone, $ask_gmt, $o_hide_ntp) = @_; require timezone; my $selected_timezone = $in->ask_from_treelist(N("Timezone"), N("Which is your timezone?"), '/', [ timezone::getTimeZones() ], $timezone->{timezone}) or return; $timezone->{timezone} = $selected_timezone; configure_time_more($in, $timezone, $o_hide_ntp) or goto &configure_timezone if $ask_gmt || to_bool($timezone->{ntp}); 1; } sub configure_time_more { my ($in, $timezone, $o_hide_ntp) = @_; my $ntp = to_bool($timezone->{ntp}); my $servers = timezone::ntp_servers(); $timezone->{ntp} ||= 'pool.ntp.org'; require POSIX; use POSIX qw(strftime); my $time_format = "%H:%M:%S"; my $tz_prefix = timezone::get_timezone_prefix(); local $ENV{TZ} = ':' . $tz_prefix . '/' . $timezone->{timezone}; $in->ask_from_({ interactive_help_id => 'misc-params#drakxid-configureTimezoneGMT', title => N("Date, Clock & Time Zone Settings"), }, [ { label => N("Date, Clock & Time Zone Settings"), title => 1 }, { label => N("What is the best time?") }, { val => \$timezone->{UTC}, type => 'list', list => [ 0, 1 ], format => sub { $_[0] ? N("%s (hardware clock set to UTC)", POSIX::strftime($time_format, localtime())) : N("%s (hardware clock set to local time)", POSIX::strftime($time_format, gmtime())); } }, { label => N("NTP Server"), title => 1, advanced => $o_hide_ntp }, { text => N("Automatic time synchronization (using NTP)"), val => \$ntp, type => 'bool', advanced => $o_hide_ntp }, { val => \$timezone->{ntp}, disabled => sub { !$ntp }, advanced => $o_hide_ntp, type => "list", separator => '|', list => [ keys %$servers ], format => sub { $servers->{$_[0]} } }, ]) or return; $timezone->{ntp} = '' if !$ntp; 1; } sub disable_x_screensaver() { run_program::run("xset", "s", "off"); run_program::run("xset", "-dpms"); } sub enable_x_screensaver() { run_program::run("xset", "+dpms"); run_program::run("xset", "s", "on"); run_program::run("xset", "s", "reset"); } 1;