'libarchive - Extract to specified directory

I have a tar file I want to extract with libarchive to a specific directory. How can I make libarchive extract into to any directory I want? At the moment it always extracts into my program's working directory. I looked at this answer but all this does is change the location of an archive entry within the archive, i.e. it still extracts into my program's working directory just at a different sub-directory.



Solution 1:[1]

I resolved this issue next way: (insert this code before calling 'archive_write_header' function)

    const char* currentFile = archive_entry_pathname(archiveEntry);
    const std::string fullOutputPath = destination + currentFile;
    archive_entry_set_pathname(archiveEntry, fullOutputPath.c_str());

where destination is output path. And it works.

Solution 2:[2]

A longer C version of Alex's answer. To extract files to a temp_dir, use archive_entry_pathname() and archive_entry_set_pathname() to re-write each entry::

char* dest_file;

for (;;) {
    r = archive_read_next_header(a, &entry);
    if (r == ARCHIVE_EOF)
      break;
    if (r < ARCHIVE_OK)
      fprintf(stderr, "%s\n", archive_error_string(a));
    if (r < ARCHIVE_WARN)
      return NULL;

    asprintf(&dest_file, "%s/%s", temp_dir, archive_entry_pathname(entry));
    archive_entry_set_pathname(entry, dest_file);
    // printf(" writing %s\n", dest_file);

    r = archive_write_header(ext, entry);
    if (r < ARCHIVE_OK)
      fprintf(stderr, "%s\n", archive_error_string(ext));
    else if (archive_entry_size(entry) > 0) {
      r = copy_data(a, ext);
      if (r < ARCHIVE_OK)
        fprintf(stderr, "%s\n", archive_error_string(ext));
      if (r < ARCHIVE_WARN)
        exit(1);
    }
    r = archive_write_finish_entry(ext);
    if (r < ARCHIVE_OK)
      fprintf(stderr, "%s\n", archive_error_string(ext));
    if (r < ARCHIVE_WARN)
      return NULL;

    free(dest_file);
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Alexandr Derkach
Solution 2 shuckc