https://github.com/vadimkantorov/libarchivedd
libarchive primer of printing byte offsets/sizes for uncompressed entries in formats: TAR, ISO, ZIP
https://github.com/vadimkantorov/libarchivedd
dd file-systems iso libarchive tar zip
Last synced: 3 months ago
JSON representation
libarchive primer of printing byte offsets/sizes for uncompressed entries in formats: TAR, ISO, ZIP
- Host: GitHub
- URL: https://github.com/vadimkantorov/libarchivedd
- Owner: vadimkantorov
- Created: 2024-08-29T10:17:59.000Z (9 months ago)
- Default Branch: master
- Last Pushed: 2024-08-29T17:10:22.000Z (9 months ago)
- Last Synced: 2025-01-12T19:21:02.970Z (4 months ago)
- Topics: dd, file-systems, iso, libarchive, tar, zip
- Language: C
- Homepage:
- Size: 14.6 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# [libarchive](https://github.com/libarchive/libarchive) primer of printing byte offsets/sizes for uncompressed entries in formats: TAR, ZIP, ISO
On 29 august 2024 [libarchive](https://github.com/libarchive/libarchive) does not support built-in calculation of byte offsets of uncompressed entries. So a hack is needed. This feature might hopefully be added natively to libarchive in the future (so the hack in this primer would become not needed), see [issues](https://github.com/libarchive/libarchive/issues/2295) referenced below. Hack was developed with help of `libarchive` maintainer in discussion in https://github.com/libarchive/libarchive/issues/2283
[`libarhivedd.c`](./libarchivedd.c) is modeled after https://github.com/libarchive/libarchive/blob/master/examples/untar.c and https://github.com/libarchive/libarchive/wiki/Examples#A_Complete_Extractor, another useful example is https://github.com/libarchive/libarchive/blob/master/contrib/untar.c
```shell
# configures and build libarchive static lib and ./libarchivedd executable
make# prepare test archives
# sudo apt install -y zip mkisofs
make libarchivedd.tar libarchivedd.zip libarchivedd.iso./libarchivedd libarchivedd.tar
#dd if="libarchivedd.tar" of="libarchivedd.c" bs=1 skip=512 count=3756
#dd if="libarchivedd.tar" of="Makefile" bs=1 skip=5120 count=616./libarchivedd libarchivedd.zip
#dd if="libarchivedd.zip" of="libarchivedd.c" bs=1 skip=72 count=3756
#dd if="libarchivedd.zip" of="Makefile" bs=1 skip=3894 count=616./libarchivedd libarchivedd.iso
#false #. AE_IFDIR : 16384
#dd if="libarchivedd.iso" of="libarchivedd.c" bs=1 skip=63488 count=3756
#dd if="libarchivedd.iso" of="Makefile" bs=1 skip=67584 count=616
```# References
- https://github.com/libarchive/libarchive/issues/2295
- https://github.com/libarchive/libarchive/issues/2283## Bonus: helpers of extracting an entry to fd, `FILE*` and mem buffer
```cpp
size_t extract_to_fd(struct archive* a, const void* firstblock_buff, size_t firstblock_size, int64_t firstblock_offset, int fd)
{
(void)firstblock_offset;
size_t size = write(fd, firstblock_buff, firstblock_size);
for(;;)
{
int r = archive_read_data_block(a, &firstblock_buff, &firstblock_size, &firstblock_offset);
if (r == ARCHIVE_EOF || r != ARCHIVE_OK)
break;
assert(r == ARCHIVE_OK);
size += write(fd, firstblock_buff, firstblock_size);
}
return size;
}size_t extract_to_file(struct archive* a, const void* firstblock_buff, size_t firstblock_size, int64_t firstblock_offset, FILE* stream)
{
(void)firstblock_offset;
size_t size = fwrite(firstblock_buff, 1, firstblock_size, stream);
for(;;)
{
int r = archive_read_data_block(a, &firstblock_buff, &firstblock_size, &firstblock_offset);
if (r == ARCHIVE_EOF || r != ARCHIVE_OK)
break;
assert(r == ARCHIVE_OK);
size += fwrite(firstblock_buff, 1, firstblock_size, stream);
}
return size;
}size_t extract_to_mem(struct archive* a, const void* firstblock_buff, size_t firstblock_size, int64_t firstblock_offset, void* buf, size_t cnt)
{
(void)firstblock_offset;
size_t size = firstblock_size <= cnt ? firstblock_size : cnt;
memcpy(buf, firstblock_buff, size);
cnt -= size;
for(;;)
{
int r = archive_read_data_block(a, &firstblock_buff, &firstblock_size, &firstblock_offset);
if (r == ARCHIVE_EOF || r != ARCHIVE_OK)
break;
assert(r == ARCHIVE_OK);
size_t w = firstblock_size <= cnt ? firstblock_size : cnt;
memcpy((char*)buf + size, firstblock_buff, w);
cnt -= w;
}
return size;
}// ...
//extract_to_fd(a, firstblock_buff, firstblock_len, firstblock_offset, 2);
//extract_to_file(a, firstblock_buff, firstblock_len, firstblock_offset, stderr);
//char tmp[1024]; size_t size = extract_to_mem(a, firstblock_buff, firstblock_len, firstblock_offset, tmp, 1024); tmp[size <= 1023 ? size : 1023] = '\0'; fprintf(stderr, "%s", tmp);
```