source: MondoRescue/branches/3.2/MondoRescue/lib/MondoRescue/File.pm@ 3228

Last change on this file since 3228 was 3228, checked in by Bruno Cornec, 10 years ago
  • Add a test file for MondoRescue::File for the mr_read_all_link function which is a critical one
  • Function now work as expected including normalization
File size: 5.0 KB
RevLine 
[3222]1#!/usr/bin/perl -w
2#
3# File subroutines brought by the MondoRescue project
4#
5# $Id$
6#
7# Copyright B. Cornec 2008-2014
8# Provided under the GPL v2
9
10package MondoRescue::File;
11
12use strict 'vars';
13use Data::Dumper;
14use English;
[3228]15use Cwd;
16use File::Basename;
17use ProjectBuilder::Base;
[3222]18use lib qw (lib);
19
20# Inherit from the "Exporter" module which handles exporting functions.
21
22use Exporter;
23
24# Export, by default, all the functions into the namespace of
25# any code which uses this module.
26
27our @ISA = qw(Exporter);
[3228]28our @EXPORT = qw(mr_file_read_all_link mr_file_process_ldd mr_file_normalize);
[3222]29
30=pod
31
32=head1 NAME
33
34MondoRescue::File, part of the mondorescue.org
35
36=head1 DESCRIPTION
37
38This modules provides low level and generic functions for the Mondorescue project
39
40=head1 USAGE
41
42=over 4
43
[3228]44=item B<mr_file_normalize>
45
46This function normalize a path by removing .., . or // in paths given as parameters
47
48=cut
49
50$pbdebug = 2;
51
52sub mr_file_normalize {
53
54my $f = shift;
55my $dir = shift || undef;
56
57# We modify based on the current dir,
58# except when we're asked to use another one (case of a target link)
59my $newpath = cwd;
60$newpath = $dir if (defined $dir);
61
62return($f) if (not defined $f);
63
64pb_log(0,"mr_file_normalize file: **$f**\n");
65pb_log(0,"mr_file_normalize dir : **$dir**\n") if (defined $dir);
66
67# Handle case of . at the start in path
68if ($f =~ /^\.\//) {
69 $f =~ s/^\.\//$newpath\//;
70}
71# Handle case of .. at the start in path
72if ($f =~ /^\.\.\//) {
73 my $dn = dirname(dirname($newpath));
74 $f =~ s/^\.\.\//$dn\//;
75}
76# Now handles .. and . in the middle
77$f =~ s|([^/]*)/([^/]+)/\.\./([^/]+)|$1/$3|g;
78$f =~ s|([^/]*)/([^/]+)/\./([^/]+)|$1/$2/$3|g;
79# Handle double /
80$f =~ s|//|/|g;
81
82return($f);
83}
84
85=over 4
86
[3222]87=item B<mr_file_read_all_link>
88
89This function returns all the links found for a given file passed as parameter
90Example: mr_file_read_all_link(/lib64) returns (/lib64,/usr/lib64) on a system having a link from /lib64 to /usr/lib64
[3228]91The return value is a hash of all input files pointing to arrays of links
[3222]92
93=cut
94
95sub mr_file_read_all_link {
96
[3224]97# TODO: Can be parallelized
[3228]98my $files;
[3222]99
[3224]100foreach my $f (@_) {
[3228]101 pb_log(2,"mr_file_read_all_link: **$f**\n");
102 # Normalize the path if with .. or . or // in it
103 $f = mr_file_normalize($f);
104
[3224]105 my @fullpath = split(/\//,$f);
106 my $curdir = "";
107 while (@fullpath) {
108 my $dir = shift @fullpath;
[3228]109 pb_log(2,"curdir is now: $curdir** and dir: $dir**\n");
110 next if ($dir eq "");
111
[3224]112 my $link = readlink("$curdir/$dir");
[3222]113 if (defined $link) {
[3228]114 $link = mr_file_normalize($link,"$curdir/$dir");
[3224]115 # It's a real symlink so handle it
[3228]116 push @{$files->{$f}},"$curdir/$dir";
[3224]117 if (substr($link,0,1) eq "/") {
118 $curdir = $link;
119 } else {
120 my $dn = "";
121 $dn = $curdir if ($curdir ne "");
122 $curdir = "$dn/$link";
123 }
[3228]124 if ((-e $curdir) && ((! -d $curdir) || (-l $curdir))) {
[3224]125 my $h = mr_file_read_all_link($curdir);
[3228]126 pb_log(2,"File: $curdir - Return:\n".Dumper($h)."\n");
[3224]127 foreach my $k (keys %$h) {
[3228]128 # At that point there is only one key
129 # as there was one param passed to the function.
130 foreach my $l (keys %$k) {
131 push @{$files->{$f}},$k->{$l};
132 }
[3224]133 }
134 }
[3222]135 } else {
[3224]136 $curdir .= "/$dir";
[3222]137 }
138 }
[3228]139 pb_log(2,"curdir is now: $curdir**\n");
140 push @{$files->{$f}},$curdir if (-e $curdir);
[3222]141}
[3228]142return($files);
[3224]143}
144
145=over 4
146
147=item B<mr_file_process_ldd>
148
149This function keeps track of the dependencies of a binary with its dynamic libraries by analyzing the return of ldd on that binary and recursing on all the dependencies to provide the complete list of files needed to have this binary run in a mindi or chroot context
150It takes a list of parameters which are the path of the binaries to analyze and for which we want its dependencies to be included
151
152=cut
153
154sub mr_file_process_ldd {
155
[3228]156my $files;
[3224]157
158foreach my $f (@_) {
[3228]159 pb_log(2,"mr_file_process_ldd: **$f**\n");
[3224]160 open(CMD,"ldd $f 2> /dev/null |") || die "You need ldd for mindi support";
161 # Format is something like this:
162 # linux-vdso.so.1 (0x00007fff7c0ee000)
163 # libtermcap.so.2 => /lib64/libtermcap.so.2 (0x00007ff1f0b1b000)
164 # libdl.so.2 => /lib64/libdl.so.2 (0x00007ff1f0917000)
165 # libc.so.6 => /lib64/libc.so.6 (0x00007ff1f0564000)
166 # /lib64/ld-linux-x86-64.so.2 (0x00007ff1f0d1f000)
167 my $answer = undef;
168 while (<CMD>) {
169 my ($empty,$orig,$symb,$dest,$hexa) = split(/\s+/);
170 # print "**$orig**$symb**$dest**$hexa\n";
171 $answer = $orig if ($orig =~ /^\//);
172 $answer = $dest if ((defined $dest) && ($dest =~ /^\//));
[3228]173 $files->{$answer} = $answer if (defined $answer);
[3224]174 }
175}
176close(CMD);
177
[3228]178return($files);
[3224]179}
180
181=back
182
183=head1 WEB SITES
184
185The main Web site of the project is available at L<http://www.mondorescue.org>. Bug reports should be filled using the trac instance of the project at L<http://trac.mondorescue.org/>.
186
187=head1 USER MAILING LIST
188
189For community exchanges around MondoRescue please use the list L<http://sourceforge.net/mailarchive/forum.php?forum_name=mondo-devel>
190
191=head1 AUTHORS
192
193The MondoRescue team lead by Bruno Cornec L<mailto:bruno@mondorescue.org>.
194
195=head1 COPYRIGHT
196
197MondoRescue is distributed under the GPL v2.0 license or later,
198described in the file C<COPYING> included with the distribution.
199
200=cut
201
202
Note: See TracBrowser for help on using the repository browser.