Reputation: 4872
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.
Upvotes: 15
Views: 11342
Reputation: 4872
From the libarchive discussion boards:
"It depends, of course, on the archive being extracted.
Typically, you would chdir() to the directory where you want the output to go, then use code similar to that in the Wiki Examples page:
or in the untar.c sample program:
Of course, if the tar file you're extracting has interesting filenames (such as "c:\someotherdirectory"), then you'll need to play with the filenames as you extract.
Note that the examples all use archive_read_next_header() to get an entry object from the input archive describing the next entry; you are then free to edit that entry description in any way you wish -- in particular, you can change the name, owner, or permissions -- before calling archive_write_header() to recreate the entry on disk.
The Examples page in the Wiki above is probably the best place to start."
Upvotes: 8
Reputation: 2994
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);
}
Upvotes: 0
Reputation: 834
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.
Upvotes: 30