1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-12 09:18:10 +03:00

clitar.c: only list <include list> instead of whole share, handle wildcards

Signed-off-by: Aurélien Aptel <aurelien.aptel@gmail.com>
Reviewed-by: David Disseldorp <ddiss@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
This commit is contained in:
Aurélien Aptel 2013-07-17 16:25:34 +02:00 committed by Andreas Schneider
parent 679cd16270
commit 7c973de802

View File

@ -26,7 +26,7 @@
#include <archive_entry.h>
#define LEN(x) (sizeof(x)/sizeof((x)[0]))
#define DBG(a, b) (DEBUG(a, ("tar:%-3d ", __LINE__)), DEBUG(a, b))
#define DBG(a, b) (DEBUG(a, ("tar:%-4d ", __LINE__)), DEBUG(a, b))
/**
* Maximum value for the blocksize field
@ -147,6 +147,27 @@ static char *fix_unix_path (char *path, bool removeprefix)
return path;
}
static char *path_base_name (const char *path)
{
TALLOC_CTX *ctx = talloc_tos();
char *base = NULL;
int last = -1;
int i;
for (i = 0; path[i]; i++) {
if (path[i] == '\\' || path[i] == '/') {
last = i;
}
}
if (last >= 0) {
base = talloc_strdup(ctx, path);
base[last] = 0;
}
return base;
}
#define XSET(v) [v] = #v
#define XTABLE(v, t) DBG(2, ("DUMP:%-20.20s = %s\n", #v, t[v]))
#define XBOOL(v) DBG(2, ("DUMP:%-20.20s = %d\n", #v, v ? 1 : 0))
@ -374,16 +395,20 @@ static bool tar_create_skip_path(struct tar *t,
/* 3. is it in the selection list? */
/*
* tar_create_from_list() use the include list as a starting
* point, no need to check
*/
if (!exclude) {
return !skip;
}
/* we are now in exclude mode */
if (t->path_list_size > 0) {
in = tar_path_in_list(t, fullpath, isdir && !exclude);
}
/* inverse result if in exclude mode */
if (exclude) {
in = !in;
}
return in ? !skip : skip;
return in ? skip : !skip;
}
bool tar_to_process (struct tar *t)
@ -568,7 +593,7 @@ int cmd_setmode(void)
return 1;
}
DBG(2, ("\nperm set %d %d\n", attr[ATTR_SET], attr[ATTR_UNSET]));
DBG(2, ("perm set %d %d\n", attr[ATTR_SET], attr[ATTR_UNSET]));
set_remote_attr(fname, attr[ATTR_SET], ATTR_SET);
set_remote_attr(fname, attr[ATTR_UNSET], ATTR_UNSET);
return 0;
@ -856,13 +881,52 @@ static NTSTATUS get_file_callback(struct cli_state *cli,
return err;
}
static int tar_create_from_list(struct tar *t)
{
TALLOC_CTX *ctx = talloc_tos();
int err = 0;
NTSTATUS status;
const char *path, *mask, *base, *start_dir;
int i;
start_dir = talloc_strdup(ctx, client_get_cur_dir());
for (i = 0; i < t->path_list_size; i++) {
path = t->path_list[i];
base = path_base_name(path);
mask = talloc_asprintf(ctx, "%s\\%s", client_get_cur_dir(), path);
DBG(5, ("incl. path='%s', base='%s', mask='%s'\n",
path, base ? base : "NULL", mask));
if (base) {
base = talloc_asprintf(ctx, "%s%s\\",
client_get_cur_dir(), path_base_name(path));
DBG(5, ("cd '%s' before do_list\n", base));
client_set_cur_dir(base);
}
status = do_list(mask, TAR_DO_LIST_ATTR, get_file_callback, false, true);
if (base) {
client_set_cur_dir(start_dir);
}
if (!NT_STATUS_IS_OK(status)) {
DBG(0, ("do_list failed on %s (%s)\n", path, nt_errstr(status)));
err = 1;
goto out;
}
}
out:
return err;
}
static int tar_create(struct tar* t)
{
TALLOC_CTX *ctx = talloc_tos();
char *mask = talloc_asprintf(ctx, "%s\\*", client_get_cur_dir());
int r;
int err = 0;
NTSTATUS status;
const char *mask;
t->archive = archive_write_new();
@ -887,23 +951,36 @@ static int tar_create(struct tar* t)
}
}
DBG(5, ("tar_process do_list with mask: %s\n", mask));
status = do_list(mask, TAR_DO_LIST_ATTR, get_file_callback, false, true);
if (!NT_STATUS_IS_OK(status)) {
DBG(0, ("do_list fail %s\n", nt_errstr(status)));
err = 1;
goto out_close;
/*
* In inclusion mode, iterate on the inclusion list
*/
if (t->mode.selection == TAR_INCLUDE && t->path_list_size > 0) {
if (tar_create_from_list(t)) {
err = 1;
goto out_close;
}
} else {
mask = talloc_asprintf(ctx, "%s\\*", client_get_cur_dir());
DBG(5, ("tar_process do_list with mask: %s\n", mask));
status = do_list(mask, TAR_DO_LIST_ATTR, get_file_callback, false, true);
if (!NT_STATUS_IS_OK(status)) {
DBG(0, ("do_list fail %s\n", nt_errstr(status)));
err = 1;
goto out_close;
}
}
out_close:
DBG(0, ("Total bytes received: %" PRIu64 "\n", t->total_size));
r = archive_write_close(t->archive);
if (r != ARCHIVE_OK) {
DBG(0, ("Fatal: %s\n", archive_error_string(t->archive)));
err = 1;
goto out;
}
if (!t->mode.dry) {
r = archive_write_close(t->archive);
if (r != ARCHIVE_OK) {
DBG(0, ("Fatal: %s\n", archive_error_string(t->archive)));
err = 1;
goto out;
}
}
out:
archive_write_free(t->archive);
return err;