From 00036effd132b046d46bf5c2339ba7cbec9f5477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= Date: Wed, 3 Jan 2018 03:42:40 +0100 Subject: [PATCH 1/2] smbclient/tar: add verbose mode A verbose mode got lost with the introduction of libarchive support. The verbose mode is optional, default is quiet mode. The output format is close to the verbose output format of POSIX tar implementations and should be good parsable. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11642 Signed-off-by: Bjoern Jacke --- source3/client/clitar.c | 86 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 24 deletions(-) diff --git a/source3/client/clitar.c b/source3/client/clitar.c index b8009c9..755c333 100644 --- a/source3/client/clitar.c +++ b/source3/client/clitar.c @@ -213,6 +213,10 @@ static NTSTATUS is_subpath(const char *sub, const char *full, bool *_subpath_match); /** + * counters + */ +static int tar_numdir, tar_numfile; +/** * tar_get_ctx - retrieve global tar context handle */ struct tar *tar_get_ctx() @@ -342,7 +346,7 @@ int cmd_tar(void) ok = next_token_talloc(ctx, &cmd_ptr, &buf, NULL); if (!ok) { - DBG(0, ("tar [IXFbganN] [options] [path list]\n")); + DBG(0, ("tar [IXFbgvanN] [options] [path list]\n")); err = 1; goto out; } @@ -364,6 +368,7 @@ int cmd_tar(void) err = 1; goto out; } + tar_numdir = tar_numfile = 0; rc = tar_process(&tar_ctx); if (rc != 0) { @@ -517,7 +522,7 @@ int tar_parse_args(struct tar* t, break; /* verbose */ - case 'q': + case 'v': t->mode.verbose = true; break; @@ -642,11 +647,14 @@ static int tar_create(struct tar* t) int err = 0; NTSTATUS status; const char *mask; + struct timespec tp_start, tp_end; TALLOC_CTX *ctx = talloc_new(NULL); if (ctx == NULL) { return 1; } + clock_gettime_mono(&tp_start); + t->archive = archive_write_new(); if (!t->mode.dry) { @@ -713,8 +721,14 @@ static int tar_create(struct tar* t) } } + clock_gettime_mono(&tp_end); + DEBUG(0, ("tar: dumped %d files and %d directories\n", + tar_numfile, tar_numdir)); + DEBUG(0, ("Total bytes written: %"PRIu64" (%.1f MiB/s)\n", + t->total_size, + t->total_size/timespec_elapsed2(&tp_start, &tp_end)/1024/1024)); + out_close: - DBG(0, ("Total bytes received: %" PRIu64 "\n", t->total_size)); if (!t->mode.dry) { r = archive_write_close(t->archive); @@ -823,8 +837,11 @@ static NTSTATUS get_file_callback(struct cli_state *cli, { NTSTATUS status = NT_STATUS_OK; char *remote_name; + char *old_dir; + char *new_dir; const char *initial_dir = client_get_cur_dir(); bool skip = false; + bool isdir; int rc; TALLOC_CTX *ctx = talloc_new(NULL); if (ctx == NULL) { @@ -846,7 +863,19 @@ static NTSTATUS get_file_callback(struct cli_state *cli, goto out; } - status = tar_create_skip_path(&tar_ctx, remote_name, finfo, &skip); + isdir = finfo->mode & FILE_ATTRIBUTE_DIRECTORY; + if (isdir) { + old_dir = talloc_strdup(ctx, initial_dir); + new_dir = talloc_asprintf(ctx, "%s\\", remote_name); + if ((old_dir == NULL) || (new_dir == NULL)) { + status = NT_STATUS_NO_MEMORY; + goto out; + } + } + + status = tar_create_skip_path(&tar_ctx, + isdir ? new_dir : remote_name, + finfo, &skip); if (!NT_STATUS_IS_OK(status)) { goto out; } @@ -857,18 +886,8 @@ static NTSTATUS get_file_callback(struct cli_state *cli, goto out; } - if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) { - char *old_dir; - char *new_dir; + if (isdir) { char *mask; - - old_dir = talloc_strdup(ctx, initial_dir); - new_dir = talloc_asprintf(ctx, "%s%s\\", - initial_dir, finfo->name); - if ((old_dir == NULL) || (new_dir == NULL)) { - status = NT_STATUS_NO_MEMORY; - goto out; - } mask = talloc_asprintf(ctx, "%s*", new_dir); if (mask == NULL) { status = NT_STATUS_NO_MEMORY; @@ -889,6 +908,7 @@ static NTSTATUS get_file_callback(struct cli_state *cli, client_set_cur_dir(new_dir); do_list(mask, TAR_DO_LIST_ATTR, get_file_callback, false, true); client_set_cur_dir(old_dir); + ++tar_numdir; } else { rc = tar_get_file(&tar_ctx, remote_name, finfo); if (rc != 0) { @@ -922,6 +942,7 @@ static int tar_get_file(struct tar *t, int err = 0, r; const bool isdir = finfo->mode & FILE_ATTRIBUTE_DIRECTORY; TALLOC_CTX *ctx = talloc_new(NULL); + if (ctx == NULL) { return 1; } @@ -969,25 +990,39 @@ static int tar_get_file(struct tar *t, archive_entry_set_size(entry, (int64_t)finfo->size); - r = archive_write_header(t->archive, entry); - if (r != ARCHIVE_OK) { - DBG(0, ("Fatal: %s\n", archive_error_string(t->archive))); - err = 1; - goto out_entry; - } - if (isdir) { + /* It's a directory just write a header */ + r = archive_write_header(t->archive, entry); + if (r != ARCHIVE_OK) { + DBG(0, ("Fatal: %s\n", archive_error_string(t->archive))); + err = 1; + } + if (t->mode.verbose) { + DEBUG(0,("a %s\\\n", full_dos_path)); + } DBG(5, ("get_file skip dir %s\n", full_dos_path)); goto out_entry; } status = cli_open(cli, full_dos_path, O_RDONLY, DENY_NONE, &remote_fd); if (!NT_STATUS_IS_OK(status)) { - DBG(0,("%s opening remote file %s\n", + DEBUG(0,("%s opening remote file %s\n", nt_errstr(status), full_dos_path)); goto out_entry; } + /* don't make tar file entry until after the file is open */ + r = archive_write_header(t->archive, entry); + if (r != ARCHIVE_OK) { + DBG(0, ("Fatal: %s\n", archive_error_string(t->archive))); + err = 1; + goto out_entry; + } + + if (t->mode.verbose) { + DEBUG(0, ("a %s\n", full_dos_path)); + } + do { status = cli_read(cli, remote_fd, buf, off, sizeof(buf), &len); if (!NT_STATUS_IS_OK(status)) { @@ -1007,6 +1042,7 @@ static int tar_get_file(struct tar *t, } } while (off < finfo->size); + ++tar_numfile; out_close: cli_close(cli, remote_fd); @@ -1075,7 +1111,9 @@ static int tar_extract(struct tar *t) continue; } - DBG(5, ("+++ %s\n", archive_entry_pathname(entry))); + if (t->mode.verbose) { + DEBUG(0, ("x %s\n", archive_entry_pathname(entry))); + } rc = tar_send_file(t, entry); if (rc != 0) { -- 2.7.4 From 149b953423c696e2cf734dc9f997a619b7cb674f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= Date: Wed, 3 Jan 2018 22:01:35 +0100 Subject: [PATCH 2/2] docs-xml: document verbose mode of smbclient tar Signed-off-by: Bjoern Jacke --- docs-xml/manpages/smbclient.1.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs-xml/manpages/smbclient.1.xml b/docs-xml/manpages/smbclient.1.xml index a5d4808..f67762f 100644 --- a/docs-xml/manpages/smbclient.1.xml +++ b/docs-xml/manpages/smbclient.1.xml @@ -406,8 +406,9 @@ files that have the archive bit set. Useful only with the c flag. - q - Quiet. Keeps tar from printing - diagnostics as it works. This is the same as tarmode quiet. + v - Verbose. Makes tar + print out the files being processed. By default tar is not verbose. + This is the same as tarmode verbose. r - Use wildcard @@ -1095,7 +1096,7 @@ - tarmode <full|inc|reset|noreset|system|nosystem|hidden|nohidden> + tarmode <full|inc|reset|noreset|system|nosystem|hidden|nohidden|quiet|verbose> Changes tar's behavior with regard to DOS attributes. There are 4 modes which can be turned on or off. -- 2.7.4