diff options
Diffstat (limited to 'tools/install-xml-file-list')
| -rwxr-xr-x | tools/install-xml-file-list | 113 | 
1 files changed, 78 insertions, 35 deletions
| diff --git a/tools/install-xml-file-list b/tools/install-xml-file-list index dbe5169a9..64c70b9c6 100755 --- a/tools/install-xml-file-list +++ b/tools/install-xml-file-list @@ -1,8 +1,10 @@  #!/usr/bin/perl +use FileHandle;  use MDK::Common;  use XML::Parser;  use Data::Dumper; +use File::Glob;  use Config;  use Cwd 'cwd'; @@ -17,14 +19,17 @@ if ($>) {      $ENV{PATH} = "/sbin:/usr/sbin:$ENV{PATH}";  } +my $verbose;  #$verbose = 1;  my $initial_dir = cwd();  my $ARCH = arch() =~ /i.86/ ? 'i386' : arch(); +$ARCH =~ s/^(arm).*/$1/;  my $LIB = arch() =~ /x86_64/ ? "lib64" : "lib";  my $base_cpio_options = '-pumd --quiet'; +my $problem;  my $tree = XML::Parser->new(Style => 'Tree')->parsefile($xml_file_list);  my $main_node = decompose($tree); @@ -33,13 +38,21 @@ $main_node->{tag} eq 'list' or die "bad file $xml_file_list (main tag should be  handle_nodes({}, $main_node); +$problem and exit 1; +  install_needed_libraries();  final_cleanup(); +sub error { +    my ($err) = @_; +    warn "FATAL: $err\n"; +    $problem = 1; +} +  sub final_cleanup() {      #- cpio creates directory 700, that's not nice -    system("find $DEST -type d | xargs $sudo chmod 755"); +    system("find $DEST -type d -print0 | xargs -0 $sudo chmod 755");  }  sub handle_nodes { @@ -80,7 +93,7 @@ sub valid_cond {  sub add_to_env {      my ($env, $tag, $attr) = @_; -    my %env = map_each { $::a => +{%$::b} } %$env; +    my %env = map_each { $::a => +{ %$::b } } %$env;      foreach (keys %$attr) {  	!$env{$tag}{$_} or die qq(overriding attribute <$tag $_="$env{$tag}{$_}"> with $_="$attr->{$_}"\n);   	$env{$tag}{$_} = $attr->{$_}; @@ -128,28 +141,35 @@ sub collect_needed_libraries {  	my $to_check = join(' ', @to_check);  	my @l = `ldd $to_check 2>/dev/null` =~ m! => (/\S+)!g;  	foreach (@l) { -	    s!^(/lib(64)?/).*?/!$1! if $main_node->{attr}{'no-arch-libraries'}; #- replace /lib/tls or /lib/i686 with /lib +	    if ($main_node->{attr}{'no-arch-libraries'}) { +		#- replace /lib/tls or /lib/i686 with /lib +		s!^(/lib(64)?/).*?/!$1! if arch() !~ /x86_64/; +	    }  	}  	@to_check = grep { !$needed_libraries{$_}++ } @l;	  	@to_check = ();      }  } -sub install_needed_libraries { +sub install_needed_libraries() {      copy_files('', $DEST, [ keys %needed_libraries ], '', '--dereference');  }  sub collect_needed_perl_files { -    my ($local_rep, $dest, @scripts) = @_; +    my ($local_rep, @scripts) = @_;      my (%local, %global);      foreach my $script (@scripts) {  	foreach (`strace -efile perl -cw -I$local_rep $script 2>&1`) { -	    my ($f) = /^open\("(.*?)",.*\)\s*=\s*\d+$/ or next; +	    my ($f) = /^open(?:at\([^,]*, |)"(.*?)",.*\)\s*=\s*\d+$/ or next;  	    if ($f =~ m!^\Q$local_rep\E/(.*)!) {  		$local{$1} = 1;  	    } elsif (begins_with($f, '/dev/')) {  		# skip  	    } elsif (begins_with($f, '/')) { +		if ($main_node->{attr}{'no-arch-libraries'}) { +		    #- replace /lib/tls or /lib/i686 with /lib +		    $f =~ s!^(/lib(64)?/).*?/!$1! if arch() !~ /x86_64/; +		}  		$global{$f} = 1;  	    }  	} @@ -169,7 +189,7 @@ sub copy_files {  	}      } else {  	my $options = join(' ', $base_cpio_options, @options); -	warn "cpio $options to_dir $to_dir from $working_dir: @$files\n" if $verbose; +	warn "cpio $options to_dir=$to_dir from=$working_dir: @$files\n" if $verbose;  	open(my $F, "| cd $working_dir ; $sudo cpio $options $to_dir");  	print $F "$_\n" foreach @$files;  	close($F) or die "cpio $to_dir failed\n"; @@ -196,30 +216,38 @@ sub install {  	my @l = $f;  	chdir $working_dir;  	if ($f =~ /\*/ || $b_full_glob) { -	    @l = glob($f) or die "no match for $f\n";  - -	    @l == 1 || $b_full_glob or die "multiple match for $f\n";	     -	} else { -	    -e $f or die "missing file $f ($rel) in $working_dir\n"; +	    @l = File::Glob::bsd_glob($f); #- using bsd_glob because CORE::glob() splits on whitespace and we don't want this +	    if (@l == 0) {  +		error("no match for $f"); +	    } elsif (@l == 1 || $b_full_glob) { +	    } else {  +		error("multiple match for $f"); +		@l = (); +	    } +	} elsif (! -e $f) { +	    error("missing file $f ($rel) in $working_dir"); +	    @l = ();  	}  	if (@l == 1 && -d $l[0] && $b_recursive_dirs) {  	    @l = all_files_rec_($l[0]);  	} -	@l = grep { !m!/CVS($|/)! } @l; -	if (my $re = $env->{from}{matching}) { +	@l = grep { !m!/(\.svn|CVS)($|/)! } @l; +	if (my $re = expand_macros($env->{from}{matching})) {  	    @l = grep { eval $re } @l;  	} -	collect_needed_libraries(grep { -x $_ } @l); +	collect_needed_libraries(grep { -f $_ && -x $_ } @l);  	chdir $initial_dir;  	@l;      }; +    my @text_l = $env->{from}{spaces_in_filename} ? $text =~ /^\s*(.*?)\s*$/ : split(' ', $text);      my @files;      if ($expand eq 'tar') { -	foreach (split(' ', $text)) { -	    system('tar', 'xfj', $from_file->($_), '-C', $to_dir); +	foreach (@text_l) { +	    my ($tarball) = $from_file->($_) or next; +	    system('tar', 'xfj', $tarball, '-C', $to_dir);  	}  	# not filling @files, things are already done @@ -228,14 +256,16 @@ sub install {      } elsif ($expand eq 'glob') {  	#- glob done in $from_file -	@files = split(' ', $text); +	@files = @text_l;      } elsif ($expand eq 'binary') {  	$disallow_from_dir->(); -	my @PATH = qw(/sbin /bin /usr/bin /usr/sbin /usr/X11R6/bin); -	foreach my $name (map { expand_macros($_) } split(' ', $text)) { +	my @PATH = qw(/usr/sbin /usr/bin /usr/X11R6/bin); +	unshift(@PATH, "/bin") unless -l "/bin"; +	unshift(@PATH, "/sbin") unless -l "/sbin"; +	foreach my $name (map { expand_macros($_) } @text_l) {  	    my @l = grep { -x $_ } map { "$_/$name" } @PATH; -	    @l or die "can't find binary $name\n"; +	    @l or error("can't find binary $name"), next;  	    if (@l > 1) {  		my @m = grep { ! -l $_ } @l;  		if (@m == 1) { @@ -250,6 +280,7 @@ sub install {  	    my $f = $l[0];  	    while (1) {  		push @files, $f; +		$copy_mode ne 'dereference' or last;  		my $l = readlink($f) or last;  		if ($l =~ m!/! && $l !~ m!^\.\..*/s?bin/[^/]+$!) {  		    warn "keeping symlink $f -> $l as is\n"; @@ -257,39 +288,48 @@ sub install {  		}  		$f = dirname($f) . '/' . $l;  	    } -	} -	$copy_mode = 'keep-links'; +	}	 +	$copy_mode ||= 'keep-links';  	$env->{filter}{command} ||= 'strip';      } elsif ($expand eq 'rpm') {  	$disallow_from_dir->(); -	foreach my $rpm (split(' ', $text)) { -	    my @l = chomp_(`rpm -ql $rpm`) or die "rpm $rpm must be installed\n"; +	foreach my $rpm (@text_l) { +	    my @l = chomp_(`rpm -ql $rpm`) or error("rpm $rpm must be installed");  	    push @files, @l;  	} +    } elsif ($expand eq 'perl-bin') { +	$disallow_from_dir->(); +	$from_dir = '/usr/LIB/perl5/vendor_perl/'; +	@files = @text_l;      } elsif ($expand eq 'perl') {  	$disallow_from_dir->(); -	$from_dir = '/usr/lib/perl5/vendor_perl/*'; -	@files = split(' ', $text); +	$from_dir = '/usr/share/perl5/vendor_perl/'; +	@files = @text_l;      } elsif ($expand eq 'main-perl') {  	$disallow_from_dir->();  	$from_dir = $Config{privlib}; -	@files = split(' ', $text); +	@files = @text_l; +    } elsif ($expand eq 'main-perl-bin') { +	$disallow_from_dir->(); +	$from_dir = $Config{archlib}; +	@files = @text_l;      } elsif ($expand =~ /collect-perl-files/) {  	my (undef, $local, $to) = split(' ', $expand); -	@files = split(' ', $text); +	@files = @text_l;  	warn "collect-perl-files $local $to @files ($env->{filter}{command})\n"; -	my ($local_perl_files, $global_perl_files) = collect_needed_perl_files($local, $to, @files); +	my ($local_perl_files, $global_perl_files) = collect_needed_perl_files($local, @files);  	warn "collect-perl-files gave: ", join(' ', @$local_perl_files), "\n"; -	copy_and_filter("$working_dir/$local", "$DEST$to", $local_perl_files, $env->{filter}, '', '--dereference'); +#	warn "                    and: ", join(' ', @$global_perl_files), "\n"; +	copy_and_filter($local =~ m!/! ? $local : "$working_dir/$local", "$DEST$to", $local_perl_files, $env->{filter}, '', '--dereference');  	copy_and_filter('', $DEST, $global_perl_files, $env->{filter}, '', '--dereference');      } elsif ($expand) {  	die "unknown expand method $expand\n";      } else { -	@files = split(' ', $text); +	@files = @text_l;  	$env->{filter}{command} ||= 'strip' if $to_dir =~ m!/bin$!;      } @@ -304,7 +344,9 @@ sub install {      my @options = (  	if_($copy_mode ne 'keep-links', '--dereference'),      ); -    copy_and_filter($working_dir, $to_dir, \@all_files, $env->{filter}, $env->{to}{flatten}, @options); +    if (@all_files) { +	copy_and_filter($working_dir, $to_dir, \@all_files, $env->{filter}, $env->{to}{flatten}, @options); +    }  }  sub copy_and_filter { @@ -320,15 +362,16 @@ sub apply_filter {      chdir $to_dir;      foreach (group_by_n(20, $all_files)) {  	my @l = $b_flatten ? (map { basename($_) } @$_) : (map { "./$_" } @$_); -	@l = grep { ! -d $_ } @l; +	@l = grep { ! -d $_ } @l or next;  	if (my $subst = $filter->{subst}) { +	    warn "running substition $subst \n" if $verbose;  	    system('perl', '-pi', '-e', $subst, @l);  	}  	if (my $command = $filter->{command}) {  	    $command = $initial_dir . "/$command" if $command =~ m!^..?/!;  	    if ($command =~ /simplify-drakx-modules/) { -		@l = grep { !/\.so($|\.)/ } @l; +		@l = grep { !/\.so($|\.)/ } @l or next;  	    }  	    my @options = (  		if_($command eq 'gzip', '-9f'), | 
