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

Last change on this file since 3262 was 3262, checked in by Bruno Cornec, 6 years ago
  • Change interface of mr_file_read_all_link to returning a hash of hash.
  • When recursing with a hash used, declare it with our so it's available correctly at all levels.
  • mr_file_read_all_link now really returns all the links neeed
File size: 5.2 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 hash of links
92
93=cut
94
95sub mr_file_read_all_link {
96
97# TODO: Can be parallelized
98our $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            $files->{$f}->{"$curdir/$dir"} = 1;
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,"After Return h:\n".Dumper($h)."\n");
127                foreach my $k (keys %$h) {
128                    foreach my $l (keys %$k) {
129                        # Use $f as key as we affects all the files
130                        # found in recursion to the current managed file
131                        $files->{$f}->{$l} = 1;
132                    }
133                }
134                pb_log(2,"After Return files:\n".Dumper($files)."\n");
135            }
136        } else {
137            $curdir .= "/$dir";
138        }
139    }
140    pb_log(2,"curdir is now: $curdir**\n");
141    $files->{$f}->{$curdir} = 1 if (-e $curdir);
142}
143pb_log(1,"mr_file_read_all_link returns:\n".Dumper($files)."\n");
144return($files);
145}
146
147=over 4
148
149=item B<mr_file_process_ldd>
150
151This 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
152It takes a list of parameters which are the path of the binaries to analyze and for which we want its dependencies to be included
153
154=cut
155
156sub mr_file_process_ldd {
157
158my $files;
159
160foreach my $f (@_) {
161    pb_log(2,"mr_file_process_ldd: **$f**\n");
162    open(CMD,"ldd $f 2> /dev/null |") || die "You need ldd for mindi support";
163    # Format is something like this:
164    #  linux-vdso.so.1 (0x00007fff7c0ee000)
165    #  libtermcap.so.2 => /lib64/libtermcap.so.2 (0x00007ff1f0b1b000)
166    #  libdl.so.2 => /lib64/libdl.so.2 (0x00007ff1f0917000)
167    #  libc.so.6 => /lib64/libc.so.6 (0x00007ff1f0564000)
168    #  /lib64/ld-linux-x86-64.so.2 (0x00007ff1f0d1f000)
169    my $answer = undef;
170    while (<CMD>) {
171        my ($empty,$orig,$symb,$dest,$hexa) = split(/\s+/);
172        # print "**$orig**$symb**$dest**$hexa\n";
173        $answer = $orig if ($orig =~ /^\//);
174        $answer = $dest if ((defined $dest) && ($dest =~ /^\//));
175        push @{$files->{$f}},$answer if (defined $answer);
176    }
177}
178close(CMD);
179
180return($files);
181}
182
183=back
184
185=head1 WEB SITES
186
187The 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/>.
188
189=head1 USER MAILING LIST
190
191For community exchanges around MondoRescue please use the list L<http://sourceforge.net/mailarchive/forum.php?forum_name=mondo-devel>
192
193=head1 AUTHORS
194
195The MondoRescue team lead by Bruno Cornec L<mailto:bruno@mondorescue.org>.
196
197=head1 COPYRIGHT
198
199MondoRescue is distributed under the GPL v2.0 license or later,
200described in the file C<COPYING> included with the distribution.
201
202=cut
203
204
Note: See TracBrowser for help on using the repository browser.