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

Last change on this file since 3229 was 3229, checked in by Bruno Cornec, 7 years ago
  • Improve mr_file_process_ldd interface (now similar to read_all_link). These functions are now ready to be used by mindi
File size: 5.0 KB
Line 
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;
15use Cwd;
16use File::Basename;
17use ProjectBuilder::Base;
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);
28our @EXPORT = qw(mr_file_read_all_link mr_file_process_ldd mr_file_normalize);
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
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(2,"mr_file_normalize file: **$f**\n");
65pb_log(2,"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
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
91The return value is a hash of all input files pointing to arrays of links
92
93=cut
94
95sub mr_file_read_all_link {
96
97# TODO: Can be parallelized
98my $files;
99
100foreach my $f (@_) {
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
105    my @fullpath = split(/\//,$f);
106    my $curdir = "";
107    while (@fullpath) {
108        my $dir = shift @fullpath;
109        pb_log(2,"curdir is now: $curdir** and dir: $dir**\n");
110        next if ($dir eq "");
111       
112        my $link = readlink("$curdir/$dir");
113        if (defined $link) {
114            $link = mr_file_normalize($link,"$curdir/$dir");
115            # It's a real symlink so handle it
116            push @{$files->{$f}},"$curdir/$dir";
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            }
124            if ((-e $curdir) && ((! -d $curdir) || (-l $curdir))) {
125                my $h = mr_file_read_all_link($curdir);
126                pb_log(2,"File: $curdir - Return:\n".Dumper($h)."\n");
127                foreach my $k (keys %$h) {
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                    }
133                }
134            }
135        } else {
136            $curdir .= "/$dir";
137        }
138    }
139    pb_log(2,"curdir is now: $curdir**\n");
140    push @{$files->{$f}},$curdir if (-e $curdir);
141}
142return($files);
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
156my $files;
157
158foreach my $f (@_) {
159    pb_log(2,"mr_file_process_ldd: **$f**\n");
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 =~ /^\//));
173        push @{$files->{$f}},$answer if (defined $answer);
174    }
175}
176close(CMD);
177
178return($files);
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.