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:
parent
679cd16270
commit
7c973de802
@ -26,7 +26,7 @@
|
|||||||
#include <archive_entry.h>
|
#include <archive_entry.h>
|
||||||
|
|
||||||
#define LEN(x) (sizeof(x)/sizeof((x)[0]))
|
#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
|
* Maximum value for the blocksize field
|
||||||
@ -147,6 +147,27 @@ static char *fix_unix_path (char *path, bool removeprefix)
|
|||||||
return path;
|
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 XSET(v) [v] = #v
|
||||||
#define XTABLE(v, t) DBG(2, ("DUMP:%-20.20s = %s\n", #v, t[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))
|
#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? */
|
/* 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) {
|
if (t->path_list_size > 0) {
|
||||||
in = tar_path_in_list(t, fullpath, isdir && !exclude);
|
in = tar_path_in_list(t, fullpath, isdir && !exclude);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* inverse result if in exclude mode */
|
return in ? skip : !skip;
|
||||||
if (exclude) {
|
|
||||||
in = !in;
|
|
||||||
}
|
|
||||||
|
|
||||||
return in ? !skip : skip;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tar_to_process (struct tar *t)
|
bool tar_to_process (struct tar *t)
|
||||||
@ -568,7 +593,7 @@ int cmd_setmode(void)
|
|||||||
return 1;
|
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_SET], ATTR_SET);
|
||||||
set_remote_attr(fname, attr[ATTR_UNSET], ATTR_UNSET);
|
set_remote_attr(fname, attr[ATTR_UNSET], ATTR_UNSET);
|
||||||
return 0;
|
return 0;
|
||||||
@ -856,13 +881,52 @@ static NTSTATUS get_file_callback(struct cli_state *cli,
|
|||||||
return err;
|
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)
|
static int tar_create(struct tar* t)
|
||||||
{
|
{
|
||||||
TALLOC_CTX *ctx = talloc_tos();
|
TALLOC_CTX *ctx = talloc_tos();
|
||||||
char *mask = talloc_asprintf(ctx, "%s\\*", client_get_cur_dir());
|
|
||||||
int r;
|
int r;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
const char *mask;
|
||||||
|
|
||||||
t->archive = archive_write_new();
|
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);
|
* In inclusion mode, iterate on the inclusion list
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
*/
|
||||||
DBG(0, ("do_list fail %s\n", nt_errstr(status)));
|
if (t->mode.selection == TAR_INCLUDE && t->path_list_size > 0) {
|
||||||
err = 1;
|
if (tar_create_from_list(t)) {
|
||||||
goto out_close;
|
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:
|
out_close:
|
||||||
DBG(0, ("Total bytes received: %" PRIu64 "\n", t->total_size));
|
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:
|
out:
|
||||||
archive_write_free(t->archive);
|
archive_write_free(t->archive);
|
||||||
return err;
|
return err;
|
||||||
|
Loading…
Reference in New Issue
Block a user