2
0
mirror of https://github.com/vasi/pixz synced 2024-11-09 01:10:23 +00:00
pixz/tar.c

98 lines
2.8 KiB
C
Raw Normal View History

#include "pixz.h"
#include <archive.h>
#include <archive_entry.h>
#include <sys/errno.h>
2010-01-10 06:49:21 +00:00
#define CHUNKSIZE 4096
#define INDEXFILE "index.xz"
typedef struct {
FILE *file;
uint8_t buf[CHUNKSIZE];
2010-01-09 23:10:42 +00:00
} pixz_tar;
2010-01-09 23:10:42 +00:00
static int pixz_tar_open(struct archive *a, void *refp);
static int pixz_tar_close(struct archive *a, void *refp);
static ssize_t pixz_tar_read(struct archive *a, void *refp, const void **buf);
2010-01-10 06:49:21 +00:00
#include <string.h>
int main(void) {
2010-01-09 23:10:42 +00:00
pixz_index *index = pixz_index_new();
struct archive *a = archive_read_new();
archive_read_support_compression_none(a);
archive_read_support_format_tar(a);
2010-01-09 23:10:42 +00:00
FILE *infile = stdin;
pixz_tar input = { .file = infile };
if (archive_read_open(a, &input, pixz_tar_open, pixz_tar_read,
pixz_tar_close) != ARCHIVE_OK)
pixz_die("Can't open archive\n");
while (1) {
struct archive_entry *entry;
int aerr = archive_read_next_header(a, &entry);
2010-01-09 23:10:42 +00:00
if (aerr == ARCHIVE_EOF) {
pixz_index_finish(index, ftello(stdin));
break;
2010-01-10 06:49:21 +00:00
} else if (aerr != ARCHIVE_OK && aerr != ARCHIVE_WARN) {
// libarchive warns for silly things like failure to convert
// names into multibyte strings
pixz_die("Error reading header: %s\n", archive_error_string(a));
}
2010-01-09 23:10:42 +00:00
const char *name = archive_entry_pathname(entry);
size_t offset = archive_read_header_position(a);
pixz_index_add(index, offset, name);
if (archive_read_data_skip(a) != ARCHIVE_OK)
2010-01-09 23:10:42 +00:00
pixz_die("Error skipping data\n");
}
if (archive_read_finish(a) != ARCHIVE_OK)
pixz_die("Error finishing read\n");
2010-01-10 02:56:01 +00:00
FILE *ifile = fopen(INDEXFILE, "w+");
if (!ifile)
pixz_die("Can't open index file\n");
pixz_encode_options *opts = pixz_encode_options_new();
pixz_encode_options_default(opts);
pixz_index_write(index, ifile, opts);
2010-01-09 23:10:42 +00:00
pixz_index_free(index);
2010-01-10 06:49:21 +00:00
lzma_check check = opts->check;
2010-01-10 02:56:01 +00:00
pixz_encode_options_free(opts);
fseek(ifile, 0, SEEK_SET);
pixz_index *i2;
2010-01-10 06:49:21 +00:00
pixz_index_read_in_place(&i2, ifile, check);
2010-01-10 02:56:01 +00:00
fclose(ifile);
pixz_index_dump(i2, stdout);
pixz_index_free(i2);
return 0;
}
2010-01-09 23:10:42 +00:00
static int pixz_tar_open(struct archive *a, void *refp) {
return ARCHIVE_OK;
}
2010-01-09 23:10:42 +00:00
static int pixz_tar_close(struct archive *a, void *refp) {
fclose(((pixz_tar*)refp)->file);
return ARCHIVE_OK;
}
2010-01-09 23:10:42 +00:00
static ssize_t pixz_tar_read(struct archive *a, void *refp, const void **buf) {
pixz_tar *input = (pixz_tar*)refp;
size_t rd = fread(input->buf, 1, CHUNKSIZE, input->file);
if (ferror(input->file)) {
archive_set_error(a, errno, "Read error");
return -1;
}
*buf = input->buf;
return rd;
}