CRUX-ARM : Home

Home :: Documentation :: Download :: Development :: Community :: Ports :: Packages :: Bugs :: Links :: About :: Donors
Fixed the permission lookup problem for hardlinks.
authorTilman Sauerbeck <tilman@crux.nu>
Fri, 24 Nov 2006 20:59:10 +0000 (21:59 +0100)
committerTilman Sauerbeck <tilman@crux.nu>
Fri, 24 Nov 2006 20:59:10 +0000 (21:59 +0100)
We now do two runs over the archive, where the first one remembers
permissions for hardlink targets, which are then looked up in the
second run.

pkgutil.cc

index 54c80b60c079d626450a931510a9da589618d69e..ce945017f360762dbb05ea86af085d59ddbdba69 100644 (file)
@@ -489,6 +489,42 @@ void pkgutil::pkg_footprint(string& filename) const
        struct archive* archive;
        struct archive_entry* entry;
 
+       map<string, mode_t> hardlink_target_modes;
+
+       // We first do a run over the archive and remember the modes
+       // of regular files.
+       // In the second run, we print the footprint - using the stored
+       // modes for hardlinks.
+       //
+       // FIXME the code duplication here is butt ugly
+       archive = archive_read_new();
+       archive_read_support_compression_all(archive);
+       archive_read_support_format_all(archive);
+
+       if (archive_read_open_filename(archive,
+           const_cast<char*>(filename.c_str()),
+           ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK)
+                throw runtime_error_with_errno("could not open " + filename, archive_errno(archive));
+
+       for (i = 0; archive_read_next_header(archive, &entry) ==
+            ARCHIVE_OK; ++i) {
+
+               mode_t mode = archive_entry_mode(entry);
+
+               if (!archive_entry_hardlink(entry)) {
+                       const char *s = archive_entry_pathname(entry);
+
+                       hardlink_target_modes[s] = mode;
+               }
+
+               if (S_ISREG(mode) && archive_read_data_skip(archive))
+                       throw runtime_error_with_errno("could not read " + filename, archive_errno(archive));
+       }
+
+       archive_read_finish(archive);
+
+       // Too bad, there doesn't seem to be a way to reuse our archive
+       // instance
        archive = archive_read_new();
        archive_read_support_compression_all(archive);
        archive_read_support_format_all(archive);
@@ -508,7 +544,12 @@ void pkgutil::pkg_footprint(string& filename) const
                        // To avoid getting different footprints we always use "lrwxrwxrwx".
                        cout << "lrwxrwxrwx";
                } else {
-                       cout << mtos(mode);
+                       const char *h = archive_entry_hardlink(entry);
+
+                       if (h)
+                               cout << mtos(hardlink_target_modes[h]);
+                       else
+                               cout << mtos(mode);
                }
 
                cout << '\t';