--- ufed-0.40.1/Portage.pm 2009-10-26 20:56:53.000000000 +0100 +++ ufed-0.40.1/Portage.pm 2012-10-04 18:57:24.578344401 +0200 @@ -4,10 +4,14 @@ # Distributed under the terms of the GNU General Public License v2 # $Header: /var/cvsroot/gentoo-src/ufed/Portage.pm,v 1.3 2005/11/13 00:28:17 truedfx Exp $ +use strict; +use warnings; + my %environment; $environment{$_}={} for qw(USE); # INCREMENTALS, except we only need USE our %packages; +our @portagedirs; our @profiles; our %use_masked_flags; our %use_defaults_flags; @@ -16,8 +20,10 @@ our %make_conf_flags; our %archs; our %all_flags; +our $make_conf_path; sub have_package($); +sub follow_link($); sub merge(\%%); sub merge_env(\%); sub noncomments($); @@ -42,6 +48,7 @@ read_archs; my $lastorder; + for(reverse split /:/, $environment{USE_ORDER} || "env:pkg:conf:auto:defaults") { if($_ eq 'defaults') { merge %default_flags, %make_defaults_flags; @@ -60,11 +67,19 @@ die "Sorry, USE_ORDER without make.conf overriding global USE flags are not currently supported by ufed.\n"; } +sub follow_link($) { + my ($xPath) = @_; + $xPath = (map {my $x=$_;$x=~ s,/[^/]*$,/,;$x} ($xPath))[0].readlink($xPath) + while ( defined($xPath) && (-l $xPath)); + return (defined($xPath) ? norm_path('', $xPath) : $xPath); +} + sub have_package($) { my ($cp) = @_; return $packages{$cp}; } + sub merge(\%%) { my ($env, %env) = @_; %{$env} = () if(exists $env{'*'}); @@ -136,9 +151,36 @@ } sub read_make_conf() { - my %env = read_sh "/etc/make.conf"; - merge %make_conf_flags, %{$env{USE}} if exists $env{USE}; - @portagedirs = $environment{PORTDIR}; + my $mcFile = "/etc/make.conf"; + my $mcPath = follow_link $mcFile; + my %env = (); + + # 1. There is no known valid path, yet + $make_conf_path = ""; + + # 2. Read the old path if it is not a symlink to the new path + if ( defined($mcPath) && ( -e $mcPath ) && ("/etc/portage/make.conf" ne $mcPath) ) { + %env = read_sh $mcPath; + merge %make_conf_flags, %{$env{USE}} if exists $env{USE}; + %env = (); + ## Store this path as being valid for now + $make_conf_path = $mcPath; + } + + # 3. Now switch to the new location - it must not be a symlink to the old either + $mcFile = "/etc/portage/make.conf"; + $mcPath = follow_link $mcFile; + if ( defined($mcPath) && (-e $mcPath ) && ("/etc/make.conf" ne $mcPath) ) { + %env = read_sh $mcPath; + merge %make_conf_flags, %{$env{USE}} if exists $env{USE}; + + # Overwrite the old path, as the new location is the overriding one. + $make_conf_path = $mcPath; + } + + die ("Path to make.conf could not be determined!") unless (length($make_conf_path)); + + @portagedirs = $environment{PORTDIR} || ( "/usr/portage" ); ## PORTDIR is not necassarily set by make.conf push @portagedirs, split ' ', $environment{PORTDIR_OVERLAY} if defined $environment{PORTDIR_OVERLAY}; } @@ -204,9 +246,12 @@ } sub read_profiles() { - $_ = readlink '/etc/make.profile'; - die "/etc/make.profile is not a symlink\n" if not defined $_; - @profiles = norm_path '/etc', $_; + my $mpFileOld = follow_link(-l "/etc/make.profile" ? "/etc/make.profile" : undef); + my $mpFileNew = follow_link(-l "/etc/portage/make.profile" ? "/etc/portage/make.profile" : undef); + + die "make.profile can not be found!\n" unless (defined($mpFileOld) || defined($mpFileNew)); + + @profiles = defined($mpFileNew) ? $mpFileNew : $mpFileOld; for (my $i = -1; $i >= -@profiles; $i--) { for(noncomments "$profiles[$i]/parent") { splice @profiles, $i, 0, norm_path $profiles[$i], $_; @@ -224,13 +269,17 @@ my $DQVAL = qr{"((?:[^\\"]|\\.)*)"}s; # doublequoted value my ($fname) = @_; + + # If the file is empty, return quietly + return unless (-s $fname); + my %env; if(open my $file, '<', $fname) { { local $/; $_ = <$file> } eval { for(;;) { /\G$BLANK/gc; - last if pos == length; + last if (pos || -1) == length; /\G$IDENT/gc or die; my $name = $1; /\G$BLANK/gc;