summaryrefslogtreecommitdiffstats
path: root/source3/client
diff options
context:
space:
mode:
authorAurélien Aptel <aurelien.aptel@gmail.com>2013-07-09 18:01:47 +0200
committerAndreas Schneider <asn@samba.org>2014-02-19 18:22:27 +0100
commit29542d1cb5d94b5edf952210f800db1e7b0d210b (patch)
treebf295eaf47cb7d1bd0c238a37bb05bd88ade4c05 /source3/client
parented9d22097d2595fb096646f3a63ec434c4f20b60 (diff)
downloadsamba-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.c70
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); */