diff options
author | Aurélien Aptel <aurelien.aptel@gmail.com> | 2013-07-09 18:01:47 +0200 |
---|---|---|
committer | Andreas Schneider <asn@samba.org> | 2014-02-19 18:22:27 +0100 |
commit | 29542d1cb5d94b5edf952210f800db1e7b0d210b (patch) | |
tree | bf295eaf47cb7d1bd0c238a37bb05bd88ade4c05 /source3/client | |
parent | ed9d22097d2595fb096646f3a63ec434c4f20b60 (diff) | |
download | samba-29542d1cb5d94b5edf952210f800db1e7b0d210b.tar.gz samba-29542d1cb5d94b5edf952210f800db1e7b0d210b.tar.xz samba-29542d1cb5d94b5edf952210f800db1e7b0d210b.zip |
clitar.c: start processing tar files in extraction mode
- move default block size to a define
- add doc comments
- basic processing in tar_extract
Signed-off-by: Aurélien Aptel <aurelien.aptel@gmail.com>
Reviewed-by: David Disseldorp <ddiss@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Diffstat (limited to 'source3/client')
-rw-r--r-- | source3/client/clitar.c | 70 |
1 files changed, 67 insertions, 3 deletions
diff --git a/source3/client/clitar.c b/source3/client/clitar.c index 5f15f867406..46c51b50bf5 100644 --- a/source3/client/clitar.c +++ b/source3/client/clitar.c @@ -23,9 +23,22 @@ #include "client/clitar_proto.h" #include "libsmb/libsmb.h" #include <archive.h> +#include <archive_entry.h> #define LEN(x) (sizeof(x)/sizeof((x)[0])) -#define TAR_MAX_BLOCK_SIZE 65535 + +/** + * Maximum value for the blocksize field + */ +#define TAR_MAX_BLOCK_SIZE 0xffff + +/** + * A more adequate size will be used for better performance unless + * we're dealing with a tape device with fixed block size. + * + * The actual choice is made by libarchive. + */ +#define TAR_DEFAULT_BLOCK_SIZE 20 enum tar_operation { TAR_NO_OPERATION, @@ -46,6 +59,7 @@ enum { }; struct tar { + /* in state that needs/can be processed? */ bool to_process; /* flags */ @@ -77,7 +91,7 @@ struct tar { struct tar tar_ctx = { .mode.selection = TAR_INCLUDE, - .mode.blocksize = 20, + .mode.blocksize = TAR_DEFAULT_BLOCK_SIZE, .mode.hidden = true, .mode.system = true, .mode.incremental = false, @@ -415,13 +429,63 @@ int cmd_tar(void) return 0; } +static int tar_extract(struct tar *t) +{ + int err = 0; + int r; + struct archive_entry *entry; + + t->archive = archive_read_new(); + archive_read_support_format_all(t->archive); + archive_read_support_filter_all(t->archive); + + if (strequal(t->tar_path, "-")) { + r = archive_read_open_fd(t->archive, STDIN_FILENO, t->mode.blocksize); + } else { + r = archive_read_open_filename(t->archive, t->tar_path, + t->mode.blocksize); + } + + if (r != ARCHIVE_OK) { + DEBUG(0, ("Can't open %s : %s\n", t->tar_path, + archive_error_string(t->archive))); + return 1; + } + + for (;;) { + r = archive_read_next_header(t->archive, &entry); + if (r == ARCHIVE_EOF) { + break; + } + if (r == ARCHIVE_WARN) { + DEBUG(0, ("Warning: %s", archive_error_string(t->archive))); + } + if (r == ARCHIVE_FATAL) { + DEBUG(0, ("Fatal: %s", archive_error_string(t->archive))); + err = 1; + goto out; + } + + DEBUG(0, ("Processing %s...\n", archive_entry_pathname(entry))); + } + + out: + r = archive_read_free(t->archive); + if (r != ARCHIVE_OK) { + DEBUG(0, ("Can't close %s : %s\n", t->tar_path, + archive_error_string(t->archive))); + err = 1; + } + return err; +} + int tar_process(struct tar *t) { int rc = 0; switch(t->mode.operation) { case TAR_EXTRACT: - /* tar_extract(t); */ + rc = tar_extract(t); break; case TAR_CREATE: /* tar_create(t); */ |