1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-11 16:58:40 +03:00

clitar.c: implement basic full extraction

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-10 13:16:08 +02:00 committed by Andreas Schneider
parent c9e23fd1a6
commit b7f6fd26b6

View File

@ -429,7 +429,119 @@ int cmd_setmode(void)
return 0;
}
/* static int send_file(struct archive_entry *entry, */
static int make_remote_path(const char *full_path)
{
/*
a. strrchr() to get last occ of \\ => NULL to get path without
filename
b. strtok to split on \\
c. accumulate each token to concat the whole path little by little
d. use cli_chkpath + cli_mkdir
*/
extern struct cli_state *cli;
TALLOC_CTX *ctx = talloc_tos();
char *path;
char *subpath;
char *state;
char *last_backslash;
char *p;
int len;
NTSTATUS status;
subpath = talloc_strdup(ctx, full_path);
path = talloc_strdup(ctx, full_path);
len = talloc_get_size(path) - 1;
last_backslash = strrchr_m(path, '\\');
if (!last_backslash) {
return 0;
}
*last_backslash = 0;
subpath[0] = 0;
p = strtok_r(path, "\\", &state);
while (p) {
strlcat(subpath, p, len);
status = cli_chkpath(cli, subpath);
if (!NT_STATUS_IS_OK(status)) {
status = cli_mkdir(cli, subpath);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("Can't mkdir %s: %s\n", subpath, nt_errstr(status)) );
return 1;
}
DEBUG(3, ("mkdir %s\n", subpath));
}
strlcat(subpath, "\\", len);
p = strtok_r(NULL, "/\\", &state);
}
return 0;
}
static int tar_send_file(struct tar *t, struct archive_entry *entry)
{
extern struct cli_state *cli;
TALLOC_CTX *ctx = talloc_tos();
char *dos_path;
char *full_path;
const void *buf;
size_t len;
off_t off;
int r;
NTSTATUS status;
uint16_t remote_fd = (uint16_t) -1;
int err = 0;
dos_path = talloc_strdup(ctx, archive_entry_pathname(entry));
fix_unix_path(dos_path, true);
full_path = talloc_strdup(ctx, client_get_cur_dir());
full_path = talloc_strdup_append(full_path, dos_path);
make_remote_path(full_path);
status = cli_open(cli, full_path, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &remote_fd);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("abandoning restore\n"));
return False;
}
for (;;) {
r = archive_read_data_block(t->archive, &buf, &len, &off);
if (r == ARCHIVE_EOF) {
break;
}
if (r == ARCHIVE_WARN) {
DEBUG(0, ("Warning: %s\n", archive_error_string(t->archive)));
}
if (r == ARCHIVE_FATAL) {
DEBUG(0, ("Fatal: %s\n", archive_error_string(t->archive)));
err = 1;
goto out;
}
status = cli_writeall(cli, remote_fd, 0, buf, off, len, NULL);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("Error writing remote file %s: %s\n",
full_path, nt_errstr(status)));
}
}
out:
status = cli_close(cli, remote_fd);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("Error losing remote file %s: %s\n",
full_path, nt_errstr(status)));
err = 1;
}
return err;
}
/**
* cmd_tar - interactive command to start a tar backup/restoration
@ -461,7 +573,8 @@ static int tar_extract(struct tar *t)
if (r != ARCHIVE_OK) {
DEBUG(0, ("Can't open %s : %s\n", t->tar_path,
archive_error_string(t->archive)));
return 1;
err = 1;
goto out;
}
for (;;) {
@ -479,6 +592,10 @@ static int tar_extract(struct tar *t)
}
DEBUG(0, ("Processing %s...\n", archive_entry_pathname(entry)));
if (tar_send_file(t, entry)) {
err = 1;
goto out;
}
}
out: