2
0
mirror of https://github.com/vasi/pixz synced 2024-11-18 15:26:46 +00:00

Check tar contents on output. TODO: No wanted files? Check index against files?

This commit is contained in:
Dave Vasilevsky 2010-10-13 17:26:55 -04:00
parent b1ffeb1490
commit 009d616db5

112
pread.c
View File

@ -1,5 +1,8 @@
#include "pixz.h" #include "pixz.h"
#include <archive.h>
#include <archive_entry.h>
#include <getopt.h> #include <getopt.h>
/* TODO /* TODO
@ -55,6 +58,64 @@ static void set_block_sizes(void);
#pragma mark MAIN #pragma mark MAIN
static int tar_ok(struct archive *ar, void *ref) {
return ARCHIVE_OK;
}
static pipeline_item_t *gArItem = NULL, *gArLastItem = NULL;
static size_t gArLastOffset, gArLastSize;
static wanted_t *gArWanted = NULL;
static bool gArNextItem = false;
static bool tar_next_block(void) {
if (gArItem && !gArNextItem && gArWanted) {
io_block_t *ib = (io_block_t*)(gArItem->data);
if (gArWanted->start < ib->uoffset + ib->outsize)
return true; // No need
}
if (gArLastItem)
queue_push(gPipelineStartQ, PIPELINE_ITEM, gArLastItem);
gArLastItem = gArItem;
gArItem = pipeline_merged();
gArNextItem = false;
return gArItem;
}
static ssize_t tar_read(struct archive *ar, void *ref, const void **bufp) {
// If we got here, the last bit of archive is ok to write
if (gArItem) {
io_block_t *ib = (io_block_t*)(gArItem->data);
fwrite(ib->output + gArLastOffset, gArLastSize, 1, gOutFile);
}
// TODO: don't assume we have wanted files!!!
// Write the first wanted file
if (!tar_next_block())
return 0;
io_block_t *ib = (io_block_t*)(gArItem->data);
fprintf(stderr, "tar wanted: %s\n", gArWanted->name);
ssize_t off = gArWanted->start - ib->uoffset, size = gArWanted->size;
if (off < 0) {
size += off;
off = 0;
}
if (off + size > ib->outsize) {
size = ib->outsize - off;
gArNextItem = true; // force the end of this block
} else {
gArWanted = gArWanted->next;
}
fprintf(stderr, "tar read off = %zd, size = %zd\n", off, size);
gArLastOffset = off;
gArLastSize = size;
*bufp = ib->output + off;
return size;
}
int main(int argc, char **argv) { int main(int argc, char **argv) {
gInFile = stdin; gInFile = stdin;
gOutFile = stdout; gOutFile = stdout;
@ -82,39 +143,34 @@ int main(int argc, char **argv) {
#endif #endif
set_block_sizes(); set_block_sizes();
wanted_t *w = gWantedFiles; gArWanted = gWantedFiles;
pipeline_create(block_create, block_free, read_thread, decode_thread); pipeline_create(block_create, block_free, read_thread, decode_thread);
pipeline_item_t *pi; if (gFileIndexOffset) {
while ((pi = pipeline_merged())) { struct archive *ar = archive_read_new();
io_block_t *ib = (io_block_t*)(pi->data); archive_read_support_compression_none(ar);
archive_read_support_format_tar(ar);
if (gWantedFiles) { archive_read_open(ar, NULL, tar_ok, tar_read, tar_ok);
size_t uend = ib->uoffset + ib->outsize; struct archive_entry *entry;
while (w && w->start < uend) { while (true) {
ssize_t off = w->start - ib->uoffset, size = w->size; int aerr = archive_read_next_header(ar, &entry);
if (off < 0) { if (aerr == ARCHIVE_EOF) {
size += off; break;
off = 0; } else if (aerr != ARCHIVE_OK && aerr != ARCHIVE_WARN) {
} fprintf(stderr, "%s\n", archive_error_string(ar));
if (off + size > ib->outsize) die("Error reading archive entry");
size = ib->outsize - off;
fwrite(ib->output + off, size, 1, gOutFile);
if (w->end >= uend) {
break; // Next block wants this too
} else {
w = w->next;
}
} }
} else { // want everything fprintf(stderr, "%s\n", archive_entry_pathname(entry));
fwrite(ib->output, ib->outsize, 1, gOutFile); }
} else {
pipeline_item_t *pi;
while ((pi = pipeline_merged())) {
io_block_t *ib = (io_block_t*)(pi->data);
fwrite(ib->output, ib->outsize, 1, gOutFile);
queue_push(gPipelineStartQ, PIPELINE_ITEM, pi);
} }
queue_push(gPipelineStartQ, PIPELINE_ITEM, pi);
} }
pipeline_destroy();
pipeline_destroy();
wanted_free(gWantedFiles); wanted_free(gWantedFiles);
return 0; return 0;
} }