[SCM] Samba Shared Repository - branch master updated

Volker Lendecke vlendec at samba.org
Tue Nov 30 04:24:01 MST 2010


The branch, master has been updated
       via  e0e4dc1 s3: Add shadow copy info to smbclient allinfo
       via  3f6705e s3: Add cli_shadow_copy_data
      from  10d1cd7 s4:torture - partially revert "s4:torture - prefer the termination "return"s at the end of two unittests"

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit e0e4dc1c2282253cfaac5bae39b75361d13c843e
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Nov 29 18:09:49 2010 +0100

    s3: Add shadow copy info to smbclient allinfo
    
    Autobuild-User: Volker Lendecke <vlendec at samba.org>
    Autobuild-Date: Tue Nov 30 12:23:50 CET 2010 on sn-devel-104

commit 3f6705e8e3055133cc155797e66233d8a5919795
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Nov 29 17:39:43 2010 +0100

    s3: Add cli_shadow_copy_data

-----------------------------------------------------------------------

Summary of changes:
 source3/client/client.c  |   46 ++++++++++++++
 source3/include/proto.h  |   11 ++++
 source3/libsmb/clifile.c |  149 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 206 insertions(+), 0 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/client/client.c b/source3/client/client.c
index 062809d..b3bbcf5 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -1633,8 +1633,11 @@ static int do_allinfo(const char *name)
 	uint16_t mode;
 	SMB_INO_T ino;
 	NTTIME tmp;
+	uint16_t fnum;
 	unsigned int num_streams;
 	struct stream_struct *streams;
+	int num_snapshots;
+	char **snapshots;
 	unsigned int i;
 	NTSTATUS status;
 
@@ -1681,6 +1684,49 @@ static int do_allinfo(const char *name)
 			 (unsigned long long)streams[i].size);
 	}
 
+	status = cli_open(cli, name, O_RDONLY, DENY_NONE, &fnum);
+	if (!NT_STATUS_IS_OK(status)) {
+		/*
+		 * Ignore failure, it does not hurt if we can't list
+		 * snapshots
+		 */
+		return 0;
+	}
+	status = cli_shadow_copy_data(talloc_tos(), cli, fnum,
+				      true, &snapshots, &num_snapshots);
+	if (!NT_STATUS_IS_OK(status)) {
+		cli_close(cli, fnum);
+		return 0;
+	}
+
+	for (i=0; i<num_snapshots; i++) {
+		char *snap_name;
+
+		d_printf("%s\n", snapshots[i]);
+		snap_name = talloc_asprintf(talloc_tos(), "%s%s",
+					    snapshots[i], name);
+		status = cli_qpathinfo2(cli, snap_name, &b_time, &a_time,
+					&m_time, &c_time, &size,
+					NULL, NULL);
+		if (!NT_STATUS_IS_OK(status)) {
+			d_fprintf(stderr, "pathinfo(%s) failed: %s\n",
+				  snap_name, nt_errstr(status));
+			TALLOC_FREE(snap_name);
+			continue;
+		}
+		unix_timespec_to_nt_time(&tmp, b_time);
+		d_printf("create_time:    %s\n", nt_time_string(talloc_tos(), tmp));
+		unix_timespec_to_nt_time(&tmp, a_time);
+		d_printf("access_time:    %s\n", nt_time_string(talloc_tos(), tmp));
+		unix_timespec_to_nt_time(&tmp, m_time);
+		d_printf("write_time:     %s\n", nt_time_string(talloc_tos(), tmp));
+		unix_timespec_to_nt_time(&tmp, c_time);
+		d_printf("change_time:    %s\n", nt_time_string(talloc_tos(), tmp));
+		d_printf("size: %d\n", (int)size);
+	}
+
+	TALLOC_FREE(snapshots);
+
 	return 0;
 }
 
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 9f00e6d..85a7294 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -2381,6 +2381,17 @@ struct tevent_req *cli_flush_send(TALLOC_CTX *mem_ctx,
 NTSTATUS cli_flush_recv(struct tevent_req *req);
 NTSTATUS cli_flush(TALLOC_CTX *mem_ctx, struct cli_state *cli, uint16_t fnum);
 
+struct tevent_req *cli_shadow_copy_data_send(TALLOC_CTX *mem_ctx,
+					     struct tevent_context *ev,
+					     struct cli_state *cli,
+					     uint16_t fnum,
+					     bool get_names);
+NTSTATUS cli_shadow_copy_data_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
+				   char ***pnames, int *pnum_names);
+NTSTATUS cli_shadow_copy_data(TALLOC_CTX *mem_ctx, struct cli_state *cli,
+			      uint16_t fnum, bool get_names,
+			      char ***pnames, int *pnum_names);
+
 /* The following definitions come from libsmb/clirap2.c  */
 struct rap_group_info_1;
 struct rap_user_info_1;
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index b40f7d1..331777b 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -5338,3 +5338,152 @@ NTSTATUS cli_flush(TALLOC_CTX *mem_ctx, struct cli_state *cli, uint16_t fnum)
 	}
 	return status;
 }
+
+struct cli_shadow_copy_data_state {
+	uint16_t setup[4];
+	uint8_t *data;
+	uint32_t num_data;
+	bool get_names;
+};
+
+static void cli_shadow_copy_data_done(struct tevent_req *subreq);
+
+struct tevent_req *cli_shadow_copy_data_send(TALLOC_CTX *mem_ctx,
+					     struct tevent_context *ev,
+					     struct cli_state *cli,
+					     uint16_t fnum,
+					     bool get_names)
+{
+	struct tevent_req *req, *subreq;
+	struct cli_shadow_copy_data_state *state;
+	uint32_t ret_size;
+
+	req = tevent_req_create(mem_ctx, &state,
+				struct cli_shadow_copy_data_state);
+	if (req == NULL) {
+		return NULL;
+	}
+	state->get_names = get_names;
+	ret_size = get_names ? cli->max_xmit : 16;
+
+	SIVAL(state->setup + 0, 0, FSCTL_GET_SHADOW_COPY_DATA);
+	SSVAL(state->setup + 2, 0, fnum);
+	SCVAL(state->setup + 3, 0, 0); /* isFsctl */
+	SCVAL(state->setup + 3, 1, 0); /* compfilter, isFlags (WSSP) */
+
+	subreq = cli_trans_send(
+		state, ev, cli, SMBnttrans, NULL, 0, NT_TRANSACT_IOCTL, 0,
+		state->setup, ARRAY_SIZE(state->setup), 0,
+		NULL, 0, 0,
+		NULL, 0, ret_size);
+	if (tevent_req_nomem(subreq, req)) {
+		return tevent_req_post(req, ev);
+	}
+	tevent_req_set_callback(subreq, cli_shadow_copy_data_done, req);
+	return req;
+}
+
+static void cli_shadow_copy_data_done(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct cli_shadow_copy_data_state *state = tevent_req_data(
+		req, struct cli_shadow_copy_data_state);
+	NTSTATUS status;
+
+	status = cli_trans_recv(subreq, state, NULL,
+				NULL, 0, NULL, /* setup */
+				NULL, 0, NULL, /* param */
+				&state->data, 12, &state->num_data);
+	TALLOC_FREE(subreq);
+	if (!NT_STATUS_IS_OK(status)) {
+		tevent_req_nterror(req, status);
+		return;
+	}
+	tevent_req_done(req);
+}
+
+NTSTATUS cli_shadow_copy_data_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
+				   char ***pnames, int *pnum_names)
+{
+	struct cli_shadow_copy_data_state *state = tevent_req_data(
+		req, struct cli_shadow_copy_data_state);
+	char **names;
+	int i, num_names;
+	uint32_t dlength;
+	NTSTATUS status;
+
+	if (tevent_req_is_nterror(req, &status)) {
+		return status;
+	}
+	num_names = IVAL(state->data, 4);
+	dlength = IVAL(state->data, 8);
+
+	if (!state->get_names) {
+		*pnum_names = num_names;
+		return NT_STATUS_OK;
+	}
+
+	if (dlength+12 > state->num_data) {
+		return NT_STATUS_INVALID_NETWORK_RESPONSE;
+	}
+	names = talloc_array(mem_ctx, char *, num_names);
+	if (names == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	for (i=0; i<num_names; i++) {
+		bool ret;
+		uint8_t *src;
+		size_t converted_size;
+
+		src = state->data + 12 + i * 2 * sizeof(SHADOW_COPY_LABEL);
+		ret = convert_string_talloc(
+			names, CH_UTF16LE, CH_UNIX,
+			src, 2 * sizeof(SHADOW_COPY_LABEL),
+			&names[i], &converted_size, True);
+		if (!ret) {
+			TALLOC_FREE(names);
+			return NT_STATUS_INVALID_NETWORK_RESPONSE;
+		}
+	}
+	*pnum_names = num_names;
+	*pnames = names;
+	return NT_STATUS_OK;
+}
+
+NTSTATUS cli_shadow_copy_data(TALLOC_CTX *mem_ctx, struct cli_state *cli,
+			      uint16_t fnum, bool get_names,
+			      char ***pnames, int *pnum_names)
+{
+	TALLOC_CTX *frame = talloc_stackframe();
+	struct event_context *ev;
+	struct tevent_req *req;
+	NTSTATUS status = NT_STATUS_NO_MEMORY;
+
+	if (cli_has_async_calls(cli)) {
+		/*
+		 * Can't use sync call while an async call is in flight
+		 */
+		status = NT_STATUS_INVALID_PARAMETER;
+		goto fail;
+	}
+	ev = event_context_init(frame);
+	if (ev == NULL) {
+		goto fail;
+	}
+	req = cli_shadow_copy_data_send(frame, ev, cli, fnum, get_names);
+	if (req == NULL) {
+		goto fail;
+	}
+	if (!tevent_req_poll_ntstatus(req, ev, &status)) {
+		goto fail;
+	}
+	status = cli_shadow_copy_data_recv(req, mem_ctx, pnames, pnum_names);
+ fail:
+	TALLOC_FREE(frame);
+	if (!NT_STATUS_IS_OK(status)) {
+		cli_set_error(cli, status);
+	}
+	return status;
+}


-- 
Samba Shared Repository


More information about the samba-cvs mailing list