summaryrefslogtreecommitdiffstats
path: root/perl-install/install_any.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/install_any.pm')
-rw-r--r--perl-install/install_any.pm796
1 files changed, 683 insertions, 113 deletions
diff --git a/perl-install/install_any.pm b/perl-install/install_any.pm
index 514b940e7..bf337d8be 100644
--- a/perl-install/install_any.pm
+++ b/perl-install/install_any.pm
@@ -1,55 +1,216 @@
-package install_any;
+package install_any; # $Id$
use diagnostics;
use strict;
-use vars qw(@ISA %EXPORT_TAGS @EXPORT_OK);
+
+use vars qw(@ISA %EXPORT_TAGS @EXPORT_OK @needToCopy @needToCopyIfRequiresSatisfied $boot_medium);
@ISA = qw(Exporter);
%EXPORT_TAGS = (
- all => [ qw(versionString getNextStep doSuspend spawnSync spawnShell) ],
+ all => [ qw(getNextStep spawnShell addToBeDone) ],
);
@EXPORT_OK = map { @$_ } values %EXPORT_TAGS;
-use common qw(:system);
+#-######################################################################################
+#- misc imports
+#-######################################################################################
+use common qw(:common :system :functional :file);
+use run_program;
+use partition_table qw(:types);
+use partition_table_raw;
+use devices;
+use fsedit;
+use modules;
+use detect_devices;
+use lang;
+use any;
use log;
+use fs;
-1;
+#- package that have to be copied for proper installation (just to avoid changing cdrom)
+#- here XFree86 is copied entirey if not already installed, maybe better to copy only server.
+@needToCopy = qw(
+XFree86-8514 XFree86-AGX XFree86-Mach32 XFree86-Mach64 XFree86-Mach8 XFree86-Mono
+XFree86-P9000 XFree86-S3 XFree86-S3V XFree86-SVGA XFree86-W32 XFree86-I128
+XFree86-Sun XFree86-SunMono XFree86-Sun24 XFree86-3DLabs XFree86-FBDev XFree86-server
+XFree86 XFree86-glide-module Device3Dfx Glide_V3-DRI Glide_V5 Mesa
+dhcpcd pump dhcpxd dhcp-client isdn4net isdn4k-utils dev pptp-adsl-fr rp-pppoe ppp ypbind
+rhs-printfilters lpr cups cups-drivers samba ncpfs ghostscript-utils
+);
+#- package that have to be copied only if all their requires are satisfied.
+@needToCopyIfRequiresSatisfied = qw(
+xpp kups kisdn
+);
-sub versionString {
- my $kernel = $::o->{packages}->{kernel} or die "I couldn't find the kernel package!";
-
- c::headerGetEntry($kernel->{header}, 'version') . "-" .
- c::headerGetEntry($kernel->{header}, 'release');
+#- boot medium (the first medium to take into account).
+$boot_medium = 1;
+
+#-######################################################################################
+#- Media change variables&functions
+#-######################################################################################
+my $postinstall_rpms = '';
+my $current_medium = $boot_medium;
+my $asked_medium = $boot_medium;
+my $cdrom = undef;
+sub useMedium($) {
+ #- before ejecting the first CD, there are some files to copy!
+ #- does nothing if the function has already been called.
+ $_[0] > 1 and $::o->{method} eq 'cdrom' and setup_postinstall_rpms($::o->{prefix}, $::o->{packages});
+
+ $asked_medium eq $_[0] or log::l("selecting new medium '$_[0]'");
+ $asked_medium = $_[0];
+}
+sub changeMedium($$) {
+ my ($method, $medium) = @_;
+ log::l("change to medium $medium for method $method (refused by default)");
+ 0;
+}
+sub relGetFile($) {
+ local $_ = $_[0];
+ m|\.rpm$| ? "$::o->{packages}[2]{$asked_medium}{rpmsdir}/$_" : $_;
+}
+sub askChangeMedium($$) {
+ my ($method, $medium) = @_;
+ my $allow;
+ do {
+ eval { $allow = changeMedium($method, $medium) };
+ } while ($@); #- really it is not allowed to die in changeMedium!!! or install will cores with rpmlib!!!
+ $allow;
}
+sub errorOpeningFile($) {
+ my ($file) = @_;
+ $file eq 'XXX' and return; #- special case to force closing file after rpmlib transaction.
+ $current_medium eq $asked_medium and log::l("errorOpeningFile $file"), return; #- nothing to do in such case.
+ $::o->{packages}[2]{$asked_medium}{selected} or return; #- not selected means no need for worying about.
+ my $max = 32; #- always refuse after $max tries.
+ if ($::o->{method} eq "cdrom") {
+ cat_("/proc/mounts") =~ m|(/tmp/\S+)\s+/tmp/rhimage| and $cdrom = $1;
+ return unless $cdrom;
+ ejectCdrom($cdrom);
+ while ($max > 0 && askChangeMedium($::o->{method}, $asked_medium)) {
+ $current_medium = $asked_medium;
+ eval { fs::mount($cdrom, "/tmp/rhimage", "iso9660", 'readonly') };
+ my $getFile = getFile($file); $getFile and return $getFile;
+ $current_medium = 'unknown'; #- don't know what CD is inserted now.
+ ejectCdrom($cdrom);
+ --$max;
+ }
+ } else {
+ while ($max > 0 && askChangeMedium($::o->{method}, $asked_medium)) {
+ $current_medium = $asked_medium;
+ my $getFile = getFile($file); $getFile and return $getFile;
+ $current_medium = 'unknown'; #- don't know what CD image has been copied.
+ --$max;
+ }
+ }
-sub getNextStep {
- my ($lastStep) = @_;
+ #- keep in mind the asked medium has been refused on this way.
+ #- this means it is no more selected.
+ $::o->{packages}[2]{$asked_medium}{selected} = undef;
- $::o->{direction} = 1;
+ #- on cancel, we can expect the current medium to be undefined too,
+ #- this enable remounting if selecting a package back.
+ $current_medium = 'unknown';
- return $::o->{lastChoice} = $::o->{steps}->{$lastStep}->{next};
+ return;
+}
+sub getFile {
+ my ($f, $method) = @_;
+ my $rel = relGetFile($f);
+ log::l("getFile $f ($method) relGetFile $rel");
+ do {
+ if ($method =~ /crypto/i) {
+ require crypto;
+ log::l("crypto::getFile $f");
+ crypto::getFile($f);
+ } elsif ($::o->{method} eq "ftp") {
+ require ftp;
+ ftp::getFile($rel);
+ } elsif ($::o->{method} eq "http") {
+ require http;
+ log::l("http getFile $f");
+ http::getFile($rel);
+ } else {
+ #- try to open the file, but examine if it is present in the repository, this allow
+ #- handling changing a media when some of the file on the first CD has been copied
+ #- to other to avoid media change...
+ my $f2 = "$postinstall_rpms/$f";
+ $f2 = "/tmp/rhimage/$rel" unless $postinstall_rpms && -e $f2;
+ log::l("local getFile $f2");
+ open GETFILE, $f2 and *GETFILE;
+ }
+ } || errorOpeningFile($f);
+}
+sub getAndSaveFile {
+ my ($file, $local) = @_;
+ log::l("getAndSaveFile $file $local");
+ local *F; open F, ">$local" or return;
+ local $/ = \ (16 * 1024);
+ my $f = ref($file) ? $file : getFile($file) or return;
+ local $_;
+ while (<$f>) { syswrite F, $_ }
+ 1;
}
-sub doSuspend {
- exit 1 if $::o->{localInstall} || $::testing;
- if (my $pid = fork) {
- waitpid $pid, 0;
- } else {
- print "\n\nType <exit> to return to the install program.\n\n";
- exec {"/bin/sh"} "-/bin/sh";
- warn "error execing /bin/sh";
- sleep 5;
- exit 1;
+#-######################################################################################
+#- Post installation RPMS from cdrom only, functions
+#-######################################################################################
+sub setup_postinstall_rpms($$) {
+ my ($prefix, $packages) = @_;
+
+ $postinstall_rpms and return;
+ $postinstall_rpms = "$prefix/usr/postinstall-rpm";
+
+ require pkgs;
+ require commands;
+
+ log::l("postinstall rpms directory set to $postinstall_rpms");
+ clean_postinstall_rpms(); #- make sure in case of previous upgrade problem.
+ commands::mkdir_('-p', $postinstall_rpms);
+
+ #- compute closure of unselected package that may be copied,
+ #- don't complain if package does not exists as it may happen
+ #- for the various architecture taken into account (X servers).
+ my %toCopy;
+ foreach (@needToCopy) {
+ my $pkg = pkgs::packageByName($packages, $_);
+ pkgs::selectPackage($packages, $pkg, 0, \%toCopy) if $pkg;
}
+ @toCopy{@needToCopyIfRequiresSatisfied} = ();
+
+ my @toCopy = map { pkgs::packageByName($packages, $_) } keys %toCopy;
+
+ #- extract headers of package, this is necessary for getting
+ #- the complete filename of each package.
+ #- copy the package files in the postinstall RPMS directory.
+ #- last arg is default medium '' known as the CD#1.
+ pkgs::extractHeaders($prefix, \@toCopy, $packages->[2]{1});
+ commands::cp((map { "/tmp/rhimage/" . relGetFile(pkgs::packageFile($_)) } @toCopy), $postinstall_rpms);
+}
+sub clean_postinstall_rpms() {
+ require commands;
+ $postinstall_rpms and -d $postinstall_rpms and commands::rm('-rf', $postinstall_rpms);
}
-sub spawnSync {
- return if $::o->{localInstall} || $::testing;
+#-######################################################################################
+#- Functions
+#-######################################################################################
+sub kernelVersion {
+ my ($o) = @_;
+ local $_ = readlink("$::o->{prefix}/boot/vmlinuz") and return first(/vmlinuz-(.*)/);
- fork and return;
- while (1) { sleep(30); sync(); }
+ require pkgs;
+ my $p = pkgs::packageByName($o->{packages}, "kernel") or die "I couldn't find the kernel package!";
+ pkgs::packageVersion($p) . "-" . pkgs::packageRelease($p);
+}
+
+
+sub getNextStep {
+ my ($s) = $::o->{steps}{first};
+ $s = $::o->{steps}{$s}{next} while $::o->{steps}{$s}{done} || !$::o->{steps}{$s}{reachable};
+ $s;
}
sub spawnShell {
@@ -62,9 +223,9 @@ sub spawnShell {
local *F;
sysopen F, "/dev/tty2", 2 or die "cannot open /dev/tty2 -- no shell will be provided";
- open STDIN, "<&F" or die;
- open STDOUT, ">&F" or die;
- open STDERR, ">&F" or die;
+ open STDIN, "<&F" or die '';
+ open STDOUT, ">&F" or die '';
+ open STDERR, ">&F" or die '';
close F;
c::setsid();
@@ -74,88 +235,497 @@ sub spawnShell {
exec {"/bin/sh"} "-/bin/sh" or log::l("exec of /bin/sh failed: $!");
}
+sub fsck_option {
+ my ($o) = @_;
+ my $y = $o->{security} < 3 && $::beginner ? "-y " : "";
+ substInFile { s/^(\s*fsckoptions="?)(-y )?/$1$y/ } "$o->{prefix}/etc/rc.d/rc.sysinit";
+}
+
+sub getAvailableSpace {
+ my ($o) = @_;
+
+ #- make sure of this place to be available for installation, this could help a lot.
+ #- currently doing a very small install use 36Mb of postinstall-rpm, but installing
+ #- these packages may eat up to 90Mb (of course not all the server may be installed!).
+ #- 65mb may be a good choice to avoid almost all problem of insuficient space left...
+ my $minAvailableSize = 65 * sqr(1024);
+
+ my $n = !$::testing && getAvailableSpace_mounted($o->{prefix}) ||
+ getAvailableSpace_raw($o->{fstab}) * 512 / 1.07;
+ $n - max(0.1 * $n, $minAvailableSize);
+}
+
+sub getAvailableSpace_mounted {
+ my ($prefix) = @_;
+ my $dir = -d "$prefix/usr" ? "$prefix/usr" : "$prefix";
+ my (undef, $free) = common::df($dir) or return;
+ log::l("getAvailableSpace_mounted $free KB");
+ $free * 1024 || 1;
+}
+sub getAvailableSpace_raw {
+ my ($fstab) = @_;
+
+ do { $_->{mntpoint} eq '/usr' and return $_->{size} } foreach @$fstab;
+ do { $_->{mntpoint} eq '/' and return $_->{size} } foreach @$fstab;
+
+ if ($::testing) {
+ my $nb = 450;
+ log::l("taking ${nb}MB for testing");
+ return $nb << 11;
+ }
+ die "missing root partition";
+}
+
+sub setPackages($) {
+ my ($o) = @_;
+
+ require pkgs;
+ if (!$o->{packages} || is_empty_hash_ref($o->{packages}[0])) {
+ $o->{packages} = pkgs::psUsingHdlists($o->{prefix}, $o->{method});
+
+ push @{$o->{default_packages}}, "nfs-utils-clients" if $o->{method} eq "nfs";
+ push @{$o->{default_packages}}, "numlock" if $o->{miscellaneous}{numlock};
+ push @{$o->{default_packages}}, "kernel-secure" if $o->{security} > 3;
+ push @{$o->{default_packages}}, "kernel-smp" if $o->{security} <= 3 && detect_devices::hasSMP(); #- no need for kernel-smp if we have kernel-secure which is smp
+ push @{$o->{default_packages}}, "kernel-pcmcia-cs" if $o->{pcmcia};
+ push @{$o->{default_packages}}, "apmd" if $o->{pcmcia};
+ push @{$o->{default_packages}}, "raidtools" if $o->{raid} && !is_empty_array_ref($o->{raid}{raid});
+ push @{$o->{default_packages}}, "reiserfs-utils" if grep { isReiserfs($_) } @{$o->{fstab}};
+ push @{$o->{default_packages}}, "cdrecord" if detect_devices::burners();
+ push @{$o->{default_packages}}, "alsa", "alsa-utils" if modules::get_alias("snd-slot-0") =~ /^snd-card-/;
+
+ pkgs::getDeps($o->{prefix}, $o->{packages});
+ pkgs::selectPackage($o->{packages}, pkgs::packageByName($o->{packages}, 'basesystem') || die("missing basesystem package"), 1);
+
+ #- some program that may be crazy on some conditions (hack waiting for Aurora to work if no fb).
+ $o->{allowFB} && (!detect_devices::matching_desc('Rage LT') &&
+ !detect_devices::matching_desc('SiS') &&
+ !detect_devices::matching_desc('Rage Mobility'))
+ or push @pkgs::skip_list, 'Aurora';
+
+ #- must be done after selecting base packages (to save memory)
+ pkgs::getProvides($o->{packages});
+
+ $o->{compss} = pkgs::readCompss($o->{prefix}, $o->{packages});
+ #- must be done after getProvides
+ $o->{compssListLevels} = pkgs::readCompssList($o->{packages}, lang::get_langs());
+ ($o->{compssUsers}, $o->{compssUsersSorted}, $o->{compssUsersIcons}, $o->{compssUsersDescr}) =
+ pkgs::readCompssUsers($o->{packages}, $o->{compss}, $o->{meta_class});
+
+ my @l = ();
+ push @l, 'xawtv', 'kwintv' if grep { $_->{driver} eq 'bttv' } detect_devices::probeall();
+ push @l, "drakprofile", "draksync", "irda-utils" if $o->{pcmcia};
+ push @l, "Glide_V5" if detect_devices::matching_desc('Voodoo 5');
+ push @l, "Glide_V3-DRI" if detect_devices::matching_desc('Voodoo (3|Banshee)');
+ push @l, "Device3Dfx", "XFree86-glide-module" if detect_devices::matching_desc('Voodoo');
+ $_->{values} = [ map { $_ + 50 } @{$_->{values}} ] foreach grep {$_} map { pkgs::packageByName($o->{packages}, $_) } @l;
+
+ #- add OpenGL games that are only usefull if a 3D accelerated card is installed.
+ my @gl = ();
+ if (detect_devices::matching_desc('Matrox.* G[24]00') ||
+ detect_devices::matching_desc('Riva.*128') ||
+ detect_devices::matching_desc('Rage X[CL]') ||
+ detect_devices::matching_desc('Rage Mobility (?:P\/M|L) ') ||
+ detect_devices::matching_desc('3D Rage (?:LT|Pro)') ||
+ detect_devices::matching_desc('Voodoo [35]') ||
+ detect_devices::matching_desc('Voodoo Banshee') ||
+ detect_devices::matching_desc('8281[05].* CGC') ||
+ detect_devices::matching_desc('Rage 128')) {
+ push @gl, "xscreensaver-gl", "Mesa-demos", "xmms-mesa";
+ push @gl, "bzflag" if (!detect_devices::matching_desc('Riva.*128') &&
+ !detect_devices::matching_desc('Rage X[CL]') &&
+ !detect_devices::matching_desc('Rage Mobility (?:P\/M|L) ') &&
+ !detect_devices::matching_desc('3D Rage (?:LT|Pro)'));
+ push @gl, "csmash", "gltron" if (!detect_devices::matching_desc('Rage 128')); #- does not work well on transparancy.
+ push @gl, "spacecup", "chromium", "tuxracer";
+ }
+ $_->{values} = [ map { $_ + 60 } @{$_->{values}} ] foreach grep {$_} map { pkgs::packageByName($o->{packages}, $_) } @gl;
+ } else {
+ #- this has to be done to make sure necessary files for urpmi are
+ #- present.
+ pkgs::psUpdateHdlistsDeps($o->{prefix}, $o->{method});
+
+ #- remove upgrade flag with selection one. TOCHECK
+ #pkgs::unselectAllPackagesIncludingUpgradable($o->{packages});
+ }
+}
+
+sub addToBeDone(&$) {
+ my ($f, $step) = @_;
+
+ return &$f() if $::o->{steps}{$step}{done};
+
+ push @{$::o->{steps}{$step}{toBeDone}}, $f;
+}
+
+sub setAuthentication {
+ my ($o) = @_;
+ my ($shadow, $md5, $nis) = @{$o->{authentication} || {}}{qw(shadow md5 NIS)};
+ my $p = $o->{prefix};
+ any::enableMD5Shadow($p, $shadow, $md5);
+ any::enableShadow($p) if $shadow;
+ if ($nis) {
+ $o->pkg_install("ypbind");
+ my $domain = $o->{netc}{NISDOMAIN};
+ $domain || $nis ne "broadcast" or die _("Can't use broadcast with no NIS domain");
+ my $t = $domain ? "domain $domain" . ($nis ne "broadcast" && " server")
+ : "ypserver";
+ substInFile {
+ $_ = "#~$_" unless /^#/;
+ $_ .= "$t $nis\n" if eof;
+ } "$p/etc/yp.conf";
+ require network;
+ network::write_conf("$p/etc/sysconfig/network", $o->{netc});
+ }
+}
+
+sub killCardServices {
+ my $pid = chop_(cat_("/tmp/cardmgr.pid"));
+ $pid and kill(15, $pid); #- send SIGTERM
+}
+
+sub hdInstallPath() {
+ cat_("/proc/mounts") =~ m|/\w+/(\S+)\s+/tmp/hdimage| or return;
+ my ($part) = grep { $_->{device} eq $1 } @{$::o->{fstab}};
+ $part->{mntpoint} or grep { $_->{mntpoint} eq "/mnt/hd" } @{$::o->{fstab}} and return;
+ $part->{mntpoint} ||= "/mnt/hd";
+ $part->{mntpoint} . first(readlink("/tmp/rhimage") =~ m|^/tmp/hdimage/(.*)|);
+}
+
+sub unlockCdrom(;$) {
+ my ($cdrom) = @_;
+ $cdrom or cat_("/proc/mounts") =~ m|(/tmp/\S+)\s+/tmp/rhimage| and $cdrom = $1;
+ $cdrom or cat_("/proc/mounts") =~ m|(/dev/\S+)\s+/mnt/cdrom | and $cdrom = $1;
+ eval { $cdrom and ioctl detect_devices::tryOpen($1), c::CDROM_LOCKDOOR(), 0 };
+}
+sub ejectCdrom(;$) {
+ my ($cdrom) = @_;
+ $cdrom or cat_("/proc/mounts") =~ m|(/tmp/\S+)\s+/tmp/rhimage| and $cdrom = $1;
+ $cdrom or cat_("/proc/mounts") =~ m|(/dev/\S+)\s+/mnt/cdrom | and $cdrom = $1;
+ my $f = eval { $cdrom && detect_devices::tryOpen($cdrom) } or return;
+ getFile("XXX"); #- close still opened filehandle
+ eval { fs::umount("/tmp/rhimage") };
+ ioctl $f, c::CDROMEJECT(), 1;
+}
+
+sub setupFB {
+ my ($o, $vga) = @_;
+
+ $vga ||= 785; #- assume at least 640x480x16.
+
+ require bootloader;
+ #- update bootloader entries with vga, all kernel are now framebuffer.
+ foreach (qw(vmlinuz vmlinuz-secure vmlinuz-smp vmlinuz-hack)) {
+ if (my $e = bootloader::get("/boot/$_", $o->{bootloader})) {
+ $e->{vga} = $vga;
+ }
+ }
+ bootloader::install($o->{prefix}, $o->{bootloader}, $o->{fstab}, $o->{hds});
+ 1;
+}
+
+sub install_urpmi {
+ my ($prefix, $method, $mediums) = @_;
+
+ my @cfg = map_index {
+ my $name = $_->{fakemedium};
+
+ local *LIST;
+ open LIST, ">$prefix/var/lib/urpmi/list.$name" or log::l("failed to write list.$name"), return;
+
+ my $dir = ${{ nfs => "file://mnt/nfs",
+ hd => "file:/" . hdInstallPath(),
+ ftp => $ENV{URLPREFIX},
+ http => $ENV{URLPREFIX},
+ cdrom => "removable_cdrom_$::i://mnt/cdrom" }}{$method} . "/$_->{rpmsdir}";
+
+ local *FILES; open FILES, "packdrake -c /tmp/$_->{hdlist} | parsehdlist - |";
+ chop, print LIST "$dir/$_\n" foreach <FILES>;
+ close FILES or log::l("parsehdlist failed"), return;
+ close LIST;
+
+ $dir .= " with ../base/$_->{hdlist}" if $method =~ /ftp|http/;
+ "$name $dir\n";
+ } values %$mediums;
+ eval { output "$prefix/etc/urpmi/urpmi.cfg", @cfg };
+}
+
+
+#-###############################################################################
+#- kde stuff
+#-###############################################################################
+sub kderc_largedisplay {
+ my ($prefix) = @_;
+
+ update_userkderc($_, 'KDE',
+ Contrast => 7,
+ kfmIconStyle => "Large",
+ kpanelIconStyle => "Normal", #- to change to Large when icons looks better
+ KDEIconStyle => "Large") foreach list_skels($prefix, '.kderc');
+
+ substInFile {
+ s/^(GridWidth)=85/$1=100/;
+ s/^(GridHeight)=70/$1=75/;
+ } $_ foreach list_skels($prefix, '.kde/share/config/kfmrc');
+}
+
+sub kdeicons_postinstall {
+ my ($prefix) = @_;
+
+ #- parse etc/fstab file to search for dos/win, floppy, zip, cdroms icons.
+ #- handle both supermount and fsdev usage.
+ my %l = (
+ 'cdrom' => [ 'cdrom', 'Cd-Rom' ],
+ 'zip' => [ 'zip', 'Zip' ],
+ 'floppy-ls' => [ 'floppy', 'LS-120' ],
+ 'floppy' => [ 'floppy', 'Floppy' ],
+ );
+ foreach (fs::read_fstab("$prefix/etc/fstab")) {
+
+ my ($name_, $nb) = $_->{mntpoint} =~ m|.*/(\S+?)(\d*)$/|;
+ my ($name, $text) = @{$l{$name_} || []};
+
+ my $f = ${{
+ supermount => sub { $name .= '.fsdev' if $name },
+ vfat => sub { $name = 'Dos_'; $text = $name_ },
+ }}{$_->{type}};
+ &$f if $f;
+
+ template2userfile($prefix,
+ "$ENV{SHARE_PATH}/$name.kdelnk.in",
+ "Desktop/$text" . ($nb && " $nb"). ".kdelnk",
+ 1, %$_) if $name;
+ }
+
+ # rename the .kdelnk to the name found in the .kdelnk as kde doesn't use it
+ # for displaying
+ foreach my $dir (grep { -d $_ } list_skels($prefix, 'Desktop')) {
+ foreach (grep { /\.kdelnk$/ } all($dir)) {
+ cat_("$dir/$_") =~ /^Name\[\Q$ENV{LANG}\E\]=(.{2,14})$/m
+ and rename "$dir/$_", "$dir/$1.kdelnk";
+ }
+ }
+}
+
+sub kdemove_desktop_file {
+ my ($prefix) = @_;
+ my @toMove = qw(doc.kdelnk news.kdelnk updates.kdelnk home.kdelnk printer.kdelnk floppy.kdelnk cdrom.kdelnk FLOPPY.kdelnk CDROM.kdelnk);
+
+ #- remove any existing save in Trash of each user and
+ #- move appropriate file there after an upgrade.
+ foreach my $dir (grep { -d $_ } list_skels($prefix, 'Desktop')) {
+ unlink("$dir/Trash/$_") && rename("$dir/$_", "$dir/Trash/$_")
+ foreach grep { -e "$dir/$_" } @toMove, grep { /\.rpmorig$/ } all($dir)
+ }
+}
+
+
+#-###############################################################################
+#- auto_install stuff
+#-###############################################################################
+sub auto_inst_file() { ($::g_auto_install ? "/tmp" : "$::o->{prefix}/root") . "/auto_inst.cfg.pl" }
+
+sub g_auto_install(;$) {
+ my ($f) = @_; $f ||= auto_inst_file;
+ my $o = {};
+
+ require pkgs;
+ $o->{default_packages} = [ map { pkgs::packageName($_) } grep { pkgs::packageFlagSelected($_) && !pkgs::packageFlagBase($_) } values %{$::o->{packages}[0]} ];
+
+ my @fields = qw(mntpoint type size);
+ $o->{partitions} = [ map { my %l; @l{@fields} = @$_{@fields}; \%l } grep { $_->{mntpoint} } @{$::o->{fstab}} ];
+
+ exists $::o->{$_} and $o->{$_} = $::o->{$_} foreach qw(lang autoSCSI authentication printer mouse wacom netc timezone superuser intf keyboard mkbootdisk users installClass partitioning isUpgrade manualFstab nomouseprobe crypto security netcnx useSupermount autoExitInstall); #- TODO modules bootloader
+
+ if (my $card = $::o->{X}{card}) {
+ $o->{X}{$_} = $::o->{X}{$_} foreach qw(default_depth resolution_wanted);
+ if ($o->{X}{default_depth} and my $depth = $card->{depth}{$o->{X}{default_depth}}) {
+ $depth ||= [];
+ $o->{X}{resolution_wanted} ||= join "x", @{$depth->[0]} unless is_empty_array_ref($depth->[0]);
+ $o->{X}{monitor} = $::o->{X}{monitor} if $::o->{X}{monitor}{manual};
+ }
+ }
+
+ local $o->{partitioning}{auto_allocate} = 1;
+ local $o->{autoExitInstall} = 1;
+
+ $_ = { %{$_ || {}} }, delete @$_{qw(oldu oldg password password2)} foreach $o->{superuser}, @{$o->{users} || []};
+
+ output($f,
+ "# You should always check the syntax with 'perl -cw auto_inst.cfg.pl' before testing\n",
+ Data::Dumper->Dump([$o], ['$o']), "\0");
+}
+
+sub loadO {
+ my ($O, $f) = @_; $f ||= auto_inst_file;
+ my $o;
+ if ($f =~ /^(floppy|patch)$/) {
+ my $f = $f eq "floppy" ? 'auto_inst.cfg' : "patch";
+ unless ($::testing) {
+ fs::mount(devices::make(detect_devices::floppy()), "/mnt", (arch() =~ /sparc/ ? "romfs" : "vfat"), 'readonly');
+ $f = "/mnt/$f";
+ }
+ -e $f or $f .= '.pl';
+
+ my $b = before_leaving {
+ fs::umount("/mnt") unless $::testing;
+ modules::unload($_) foreach qw(vfat fat);
+ };
+ $o = loadO($O, $f);
+ } else {
+ -e "$f.pl" and $f .= ".pl" unless -e $f;
+
+ my $fh = -e $f ? do { local *F; open F, $f; *F } : getFile($f) or die _("Error reading file $f");
+ {
+ local $/ = "\0";
+ no strict;
+ eval <$fh>;
+ close $fh;
+ $@ and log::l("Bad kickstart file $f (failed $@)");
+ }
+ add2hash_($o ||= {}, $O);
+ }
+ bless $o, ref $O;
+}
+
+sub generate_ks_cfg {
+ my ($o) = @_;
+
+ return if $o->{method} =~ /hd|cdrom/;
+
+ my $ks;
+ if ($o->{method} =~ /ftp|http/) {
+ $ks .= "url --url $ENV{URLPREFIX}\n";
+ } elsif ($o->{method} =~ /nfs/) {
+ cat_("/proc/mounts") =~ m|(\S+):(\S+)\s+/tmp/rhimage nfs| or die;
+ $ks .= "nfs --server $1 --dir $2\n";
+ }
+ my ($intf) = values %{$o->{intf}};
+ if ($intf->{BOOTPROTO} =~ /^(dhcp|bootp)$/) {
+ $ks .= "network --bootproto $intf->{BOOTPROTO}\n";
+ } else {
+ require network;
+ my %l = (ip => $intf->{IPADDR}, netmask => $intf->{NETMASK}, gateway => $o->{netc}{GATEWAY});
+ $ks .= "network " . join(" ", map_each { $::b && "--$::a $::b" } %l);
+ $ks .= " --nameserver $_" foreach network::dnsServers($o->{netc});
+ $ks .= "\n";
+ }
+ $ks;
+}
+
+sub guess_mount_point {
+ my ($part, $prefix, $user) = @_;
+
+ my %l = (
+ '/' => 'etc/fstab',
+ '/boot' => 'vmlinuz',
+ '/tmp' => '.X11-unix',
+ '/usr' => 'X11R6',
+ '/var' => 'catman',
+ );
+
+ my $handle = any::inspect($part, $prefix) or return;
+ my $d = $handle->{dir};
+ my ($mnt) = grep { -e "$d/$l{$_}" } keys %l;
+ $mnt ||= (stat("$d/.bashrc"))[4] ? '/root' : '/home/user' . ++$$user if -e "$d/.bashrc";
+ $mnt ||= (grep { -d $_ && (stat($_))[4] >= 500 && -e "$_/.bashrc" } glob_("$d")) ? '/home' : '';
+ ($mnt, $handle);
+}
+
+sub suggest_mount_points {
+ my ($hds, $prefix, $uniq) = @_;
+ my @fstab = fsedit::get_fstab(@$hds);
+
+ my $user;
+ foreach my $part (grep { isTrueFS($_) } @fstab) {
+ $part->{mntpoint} && !$part->{unsafeMntpoint} and next; #- if already found via an fstab
+
+ my ($mnt, $handle) = guess_mount_point($part, $prefix, \$user) or next;
+
+ next if $uniq && fsedit::mntpoint2part($mnt, \@fstab);
+ $part->{mntpoint} = $mnt; delete $part->{unsafeMntpoint};
+
+ #- try to find other mount points via fstab
+ fs::get_mntpoints_from_fstab([ fsedit::get_fstab(@$hds) ], $handle->{dir}, $uniq) if $mnt eq '/';
+ }
+ $_->{mntpoint} and log::l("suggest_mount_points: $_->{device} -> $_->{mntpoint}") foreach @fstab;
+}
+
+#- mainly for finding the root partitions for upgrade
+sub find_root_parts {
+ my ($hds, $prefix) = @_;
+ log::l("find_root_parts");
+ my $user;
+ grep {
+ my ($mnt) = guess_mount_point($_, $prefix, \$user);
+ $mnt eq '/';
+ } fsedit::get_fstab(@$hds);
+}
+sub use_root_part {
+ my ($fstab, $part, $prefix) = @_;
+ {
+ my $handle = any::inspect($part, $prefix) or die;
+ fs::get_mntpoints_from_fstab($fstab, $handle->{dir}, 'uniq');
+ }
+ map { $_->{mntpoint} = 'swap' } grep { isSwap($_) } @$fstab; #- use all available swap.
+}
+
+sub getHds {
+ my ($o, $f_err) = @_;
+ my $ok = 1;
+ my $flags = $o->{partitioning};
+
+ my @drives = detect_devices::hds();
+# add2hash_($o->{partitioning}, { readonly => 1 }) if partition_table_raw::typeOfMBR($drives[0]{device}) eq 'system_commander';
+
+ getHds:
+ $o->{hds} = catch_cdie { fsedit::hds(\@drives, $flags) }
+ sub {
+ $ok = 0;
+ my $err = $@; $err =~ s/ at (.*?)$//;
+ log::l("error reading partition table: $err");
+ !$flags->{readonly} && $f_err and $f_err->($err);
+ };
+
+ if (is_empty_array_ref($o->{hds}) && $o->{autoSCSI}) {
+ $o->setupSCSI; #- ask for an unautodetected scsi card
+ goto getHds;
+ }
+
+ $ok = fsedit::verifyHds($o->{hds}, $flags->{readonly}, $ok)
+ unless $flags->{clearall} || $flags->{clear};
+ $o->{fstab} = [ fsedit::get_fstab(@{$o->{hds}}) ];
+ fs::check_mounted($o->{fstab});
+ fs::merge_fstabs($o->{fstab}, $o->{manualFstab});
-sub upgrFindInstall {
-# int rc;
-#
-# if (!$::o->{table}.parts) {
-# rc = findAllPartitions(NULL, &$::o->{table});
-# if (rc) return rc;
-# }
-#
-# umountFilesystems(&$::o->{fstab});
-#
-# # rootpath upgrade support
-# if (strcmp($::o->{rootPath} ,"/mnt"))
-# return INST_OKAY;
-#
-# # this also turns on swap for us
-# rc = readMountTable($::o->{table}, &$::o->{fstab});
-# if (rc) return rc;
-#
-# if (!testing) {
-# mountFilesystems(&$::o->{fstab});
-#
-# if ($::o->{method}->prepareMedia) {
-# rc = $::o->{method}->prepareMedia($::o->{method}, &$::o->{fstab});
-# if (rc) {
-# umountFilesystems(&$::o->{fstab});
-# return rc;
-# }
-# }
-# }
-#
-# return 0;
-}
-
-sub upgrChoosePackages {
-# static int firstTime = 1;
-# char * rpmconvertbin;
-# int rc;
-# char * path;
-# char * argv[] = { NULL, NULL };
-# char buf[128];
-#
-# if (testing)
-# path = "/";
-# else
-# path = $::o->{rootPath};
-#
-# if (firstTime) {
-# snprintf(buf, sizeof(buf), "%s%s", $::o->{rootPath},
-# "/var/lib/rpm/packages.rpm");
-# if (access(buf, R_OK)) {
-# snprintf(buf, sizeof(buf), "%s%s", $::o->{rootPath},
-# "/var/lib/rpm/packages");
-# if (access(buf, R_OK)) {
-# errorWindow("No RPM database exists!");
-# return INST_ERROR;
-# }
-#
-# if ($::o->{method}->getFile($::o->{method}, "rpmconvert",
-# &rpmconvertbin)) {
-# return INST_ERROR;
-# }
-#
-# symlink("/mnt/var", "/var");
-# winStatus(35, 3, _("Upgrade"), _("Converting RPM database..."));
-# chmod(rpmconvertbin, 0755);
-# argv[0] = rpmconvertbin;
-# rc = runProgram(RUN_LOG, rpmconvertbin, argv);
-# if ($::o->{method}->rmFiles)
-# unlink(rpmconvertbin);
-#
-# newtPopWindow();
-# if (rc) return INST_ERROR;
-# }
-# winStatus(35, 3, "Upgrade", _("Finding packages to upgrade..."));
-# rc = ugFindUpgradePackages(&$::o->{packages}, path);
-# newtPopWindow();
-# if (rc) return rc;
-# firstTime = 0;
-# psVerifyDependencies(&$::o->{packages}, 1);
-# }
-#
-# return psSelectPackages(&$::o->{packages}, &$::o->{comps}, NULL, 0, 1);
+ my @win = grep { isFat($_) && isFat({ type => fsedit::typeOfPart($_->{device}) }) } @{$o->{fstab}};
+ log::l("win parts: ", join ",", map { $_->{device} } @win) if @win;
+ if (@win == 1) {
+ $win[0]{mntpoint} = "/mnt/windows";
+ } else {
+ my %w; foreach (@win) {
+ my $v = $w{$_->{device_windobe}}++;
+ $_->{mntpoint} = $_->{unsafeMntpoint} = "/mnt/win_" . lc($_->{device_windobe}) . ($v ? $v+1 : ''); #- lc cuz of StartOffice(!) cf dadou
+ }
+ }
+
+ my @sunos = grep { isSunOS($_) && type2name($_->{type}) =~ /root/i } @{$o->{fstab}}; #- take only into account root partitions.
+ if (@sunos) {
+ my $v = '';
+ map { $_->{mntpoint} = $_->{unsafeMntpoint} = "/mnt/sunos" . ($v && ++$v) } @sunos;
+ }
+ #- a good job is to mount SunOS root partition, and to use mount point described here in /etc/vfstab.
+
+ $ok;
}
+
+sub log_sizes {
+ my ($o) = @_;
+ my @df = common::df($o->{prefix});
+ log::l(sprintf "Installed: %dMB(df), %dMB(rpm)",
+ ($df[0] - $df[1]) / 1024,
+ sum(`rpm --root $o->{prefix}/ -qa --queryformat "%{size}\n"`) / sqr(1024)) if -x "$o->{prefix}/bin/rpm";
+}
+
+1;