0

I'm trying to rename the entries of an archive using the libarchive library. In particular I'm using the function archive_entry_set_pathname.

Files and empty directories are correctly renamed, but unfortunately this is not working if a directory is not empty: instead of being renamed, a new empty directory with the new name is created as sibling of the target directory, which has the old name.

Relevant code snippet:

...
while (archive_read_next_header(inputArchive, &entry) == ARCHIVE_OK) {
        if (file == QFile::decodeName(archive_entry_pathname(entry))) {
            // FIXME: not working with non-empty directories
            archive_entry_set_pathname(entry, QFile::encodeName(newPath));    
        }

        int header_response;
        if ((header_response = archive_write_header(outputArchive, entry)) == ARCHIVE_OK) {
            ... // write the (new) outputArchive on disk
        }
    }

What's wrong with non-empty directories?

eang
  • 1,615
  • 7
  • 21
  • 41

1 Answers1

1

In an archive, the files are stored with their full path names relative to the root of the archive. Your code only matches the directory entry, you also need to match all entries below that directory and rename them. I'm no Qt expert and I haven't tried this code, but you will get the idea.

QStringLiteral oldPath("foo/");
QStringLiteral newPath("bar/");
while (archive_read_next_header(inputArchive, &entry) == ARCHIVE_OK) {
    QString arEntryPath = QFile::decodeName(archive_entry_pathname(entry));
    if(arEntryPath.startsWith(oldPath) {
        arEntryPath.replace(0, oldPath.length(), newPath);
        archive_entry_set_pathname(entry, QFile::encodeName(arEntryPath));
    }

    int header_response;
    if ((header_response = archive_write_header(outputArchive, entry)) == ARCHIVE_OK) {
        ... // write the (new) outputArchive on disk
    }
}            
BitByteDog
  • 3,074
  • 2
  • 26
  • 39