[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[SCM] Debian package checker branch, master, updated. 2.5.5-24-gca395a8



The following commit has been merged in the master branch:
commit ca395a8ef7dc24ba1602fa6fe4c3bf102b60c0aa
Author: Niels Thykier <niels@thykier.net>
Date:   Wed Sep 7 15:17:28 2011 +0200

    L::Collect::Package: Normalize hard links
    
    Signed-off-by: Niels Thykier <niels@thykier.net>

diff --git a/lib/Lintian/Collect/Package.pm b/lib/Lintian/Collect/Package.pm
index 06ad0d9..7c2b371 100644
--- a/lib/Lintian/Collect/Package.pm
+++ b/lib/Lintian/Collect/Package.pm
@@ -113,6 +113,7 @@ sub _fetch_index_data {
     my $base_dir = $self->base_dir();
     my (%idxh, %dir_counts);
     my $num_idx;
+    my %rhlinks;
     open my $idx, '<', "$base_dir/$index"
         or croak "cannot open index file $base_dir/$index: $!";
     if ($indexown) {
@@ -146,9 +147,12 @@ sub _fetch_index_data {
 
         $name =~ s,^\./,,;
         if ($name =~ s/ link to (.*)//) {
+            my $target = $1;
+            $target =~ s,^\./,,;
             $file{type} = 'h';
-            $file{link} = $1;
-            $file{link} =~ s,^\./,,;
+            $file{link} = $target;
+
+            push @{$rhlinks{$target}}, $name;
         } elsif ($file{type} eq 'l') {
             ($name, $file{link}) = split ' -> ', $name, 2;
         }
@@ -162,8 +166,48 @@ sub _fetch_index_data {
         $idxh{$name} = \%file;
     }
     foreach my $file (keys %idxh) {
-        if ($dir_counts{$idxh{$file}->{name}}) {
-            $idxh{$file}->{count} = $dir_counts{$idxh{$file}->{name}};
+        my $e = $idxh{$file};
+        if ($dir_counts{$e->{name}}) {
+            $e->{count} = $dir_counts{$e->{name}};
+        }
+        if ($rhlinks{$e->{name}}) {
+            # There is hard link pointing to this file (or hardlink).
+            my %candidates = ();
+            my @check = ($e->{name});
+            my @sorted;
+            my $target;
+            while ( my $current = pop @check) {
+                $candidates{$current} = 1;
+                foreach my $rdep (@{$rhlinks{$current}}) {
+                    # There should not be any cicles, but just in case
+                    push @check, $rdep unless $candidates{$rdep};
+                }
+                # Remove links we are fixing
+                delete $rhlinks{$current};
+            }
+            # keys %candidates will be a complete list of hardlinks
+            # that points (in)directly to $file.  Time to normalize
+            # the links.
+            #
+            # Sort in reverse order (allows pop instead of unshift)
+            @sorted = sort {$b cmp $a} keys %candidates;
+            # Our prefered target
+            $target = pop @sorted;
+
+            foreach my $link (@sorted) {
+                next unless exists $idxh{$target};
+                my $le = $idxh{$link};
+                # We may be "demoting" a "real file" to a "hardlink"
+                $le->{type} = 'h';
+                $le->{link} = $target;
+            }
+            if ($target ne $e->{name}) {
+                $idxh{$target}->{type} = '-';
+                # hardlinks does not have size, so copy that from the original
+                # entry.
+                $idxh{$target}->{size} = $e->{size};
+                delete $idxh{$target}->{link};
+            }
         }
     }
     $self->{$field} = \%idxh;
diff --git a/t/tests/files-hardlinks/debian/debian/rules b/t/tests/files-hardlinks/debian/debian/rules
new file mode 100755
index 0000000..50f62ad
--- /dev/null
+++ b/t/tests/files-hardlinks/debian/debian/rules
@@ -0,0 +1,14 @@
+#!/usr/bin/make -f
+PKG:=files-hardlinks
+DIR:=$(CURDIR)/debian/$(PKG)/usr/share/$(PKG)
+
+%:
+	dh $@
+
+override_dh_install:
+	dh_install
+	mkdir -p $(DIR)/1st $(DIR)/2nd $(DIR)/3rd $(DIR)/4th
+	echo "Hallo world" > $(DIR)/3rd/orig
+	ln $(DIR)/3rd/orig $(DIR)/4th/link1
+	ln $(DIR)/4th/link1 $(DIR)/1st/link2
+	ln $(DIR)/3rd/orig $(DIR)/2nd/link3
diff --git a/t/tests/files-hardlinks/desc b/t/tests/files-hardlinks/desc
new file mode 100644
index 0000000..ecaff44
--- /dev/null
+++ b/t/tests/files-hardlinks/desc
@@ -0,0 +1,5 @@
+Testname: files-hardlinks
+Sequence: 6000
+Version: 1.0
+Description: Test for (stable) handling of hardlinks
+Test-For: package-contains-hardlink
diff --git a/t/tests/files-hardlinks/tags b/t/tests/files-hardlinks/tags
new file mode 100644
index 0000000..eb402d1
--- /dev/null
+++ b/t/tests/files-hardlinks/tags
@@ -0,0 +1,3 @@
+W: files-hardlinks: package-contains-hardlink usr/share/files-hardlinks/1st/link2 -> usr/share/files-hardlinks/2nd/link3
+W: files-hardlinks: package-contains-hardlink usr/share/files-hardlinks/1st/link2 -> usr/share/files-hardlinks/3rd/orig
+W: files-hardlinks: package-contains-hardlink usr/share/files-hardlinks/1st/link2 -> usr/share/files-hardlinks/4th/link1

-- 
Debian package checker


Reply to: