[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha7-1859-gd74e42e

Jeremy Allison jra at samba.org
Thu May 28 20:06:30 GMT 2009


The branch, master has been updated
       via  d74e42e0eca0bb15c12fa51f125d905a6cee5db5 (commit)
      from  de4c13ca682671d46d9d6512f84670c88b2e7837 (commit)

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


- Log -----------------------------------------------------------------
commit d74e42e0eca0bb15c12fa51f125d905a6cee5db5
Author: Jeremy Allison <jra at samba.org>
Date:   Thu May 28 13:05:50 2009 -0700

    Make getfacl async.
    Jeremy.

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

Summary of changes:
 source3/client/client.c  |    8 +--
 source3/include/proto.h  |   14 ++++-
 source3/libsmb/clifile.c |  170 +++++++++++++++++++++++++++++++++++-----------
 3 files changed, 145 insertions(+), 47 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/client/client.c b/source3/client/client.c
index 2edeb1a..0e874ec 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -3043,17 +3043,16 @@ static int cmd_getfacl(void)
 		return 1;
 	}
 
-	if (!cli_unix_getfacl(targetcli, targetname, &rb_size, &retbuf)) {
+	if (!NT_STATUS_IS_OK(cli_posix_getfacl(targetcli, targetname, ctx, &rb_size, &retbuf))) {
 		d_printf("%s getfacl file %s\n",
 			cli_errstr(targetcli), src);
 		return 1;
 	}
 
 	/* ToDo : Print out the ACL values. */
-	if (SVAL(retbuf,0) != SMB_POSIX_ACL_VERSION || rb_size < 6) {
+	if (rb_size < 6 || SVAL(retbuf,0) != SMB_POSIX_ACL_VERSION) {
 		d_printf("getfacl file %s, unknown POSIX acl version %u.\n",
 			src, (unsigned int)CVAL(retbuf,0) );
-		SAFE_FREE(retbuf);
 		return 1;
 	}
 
@@ -3064,8 +3063,6 @@ static int cmd_getfacl(void)
 			src,
 			(unsigned int)(SMB_POSIX_ACL_HEADER_SIZE + SMB_POSIX_ACL_ENTRY_SIZE*(num_file_acls+num_dir_acls)),
 			(unsigned int)rb_size);
-
-		SAFE_FREE(retbuf);
 		return 1;
 	}
 
@@ -3150,7 +3147,6 @@ static int cmd_getfacl(void)
 		d_printf("%s\n", perms_to_string(permstring, perms));
 	}
 
-	SAFE_FREE(retbuf);
 	return 0;
 }
 
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 2217b33..60810cc 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -2361,7 +2361,19 @@ NTSTATUS cli_posix_hardlink(struct cli_state *cli,
 			const char *newname);
 uint32_t unix_perms_to_wire(mode_t perms);
 mode_t wire_perms_to_unix(uint32_t perms);
-bool cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, char **retbuf);
+struct tevent_req *cli_posix_getfacl_send(TALLOC_CTX *mem_ctx,
+					struct event_context *ev,
+					struct cli_state *cli,
+					const char *fname);
+NTSTATUS cli_posix_getfacl_recv(struct tevent_req *req,
+				TALLOC_CTX *mem_ctx,
+				size_t *prb_size,
+				char **retbuf);
+NTSTATUS cli_posix_getfacl(struct cli_state *cli,
+			const char *fname,
+			TALLOC_CTX *mem_ctx,
+			size_t *prb_size,
+			char **retbuf);
 bool cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbuf);
 bool cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode);
 bool cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t gid);
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 187fcdf..be2e812 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -453,7 +453,6 @@ NTSTATUS cli_posix_readlink(struct cli_state *cli, const char *fname,
 	return status;
 }
 
-
 /****************************************************************************
  Hard link a file (UNIX extensions).
 ****************************************************************************/
@@ -624,58 +623,149 @@ static mode_t unix_filetype_from_wire(uint32_t wire_type)
  Do a POSIX getfacl (UNIX extensions).
 ****************************************************************************/
 
-bool cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, char **retbuf)
+struct getfacl_state {
+	uint16_t setup;
+	uint8_t *param;
+	uint32_t num_data;
+	uint8_t *data;
+};
+
+static void cli_posix_getfacl_done(struct tevent_req *subreq)
 {
-	unsigned int param_len = 0;
-	unsigned int data_len = 0;
-	uint16_t setup = TRANSACT2_QPATHINFO;
-	char *param;
-	size_t nlen = 2*(strlen(name)+1);
-	char *rparam=NULL, *rdata=NULL;
-	char *p;
+	struct tevent_req *req = tevent_req_callback_data(
+				subreq, struct tevent_req);
+	struct getfacl_state *state = tevent_req_data(req, struct getfacl_state);
+	NTSTATUS status;
 
-	param = SMB_MALLOC_ARRAY(char, 6+nlen+2);
-	if (!param) {
-		return false;
+	status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL,
+			&state->data, &state->num_data);
+	TALLOC_FREE(subreq);
+	if (!NT_STATUS_IS_OK(status)) {
+		tevent_req_nterror(req, status);
+		return;
 	}
+	tevent_req_done(req);
+}
 
-	p = param;
-	memset(p, '\0', 6);
-	SSVAL(p, 0, SMB_QUERY_POSIX_ACL);
-	p += 6;
-	p += clistr_push(cli, p, name, nlen, STR_TERMINATE);
-	param_len = PTR_DIFF(p, param);
+struct tevent_req *cli_posix_getfacl_send(TALLOC_CTX *mem_ctx,
+					struct event_context *ev,
+					struct cli_state *cli,
+					const char *fname)
+{
+	struct tevent_req *req = NULL, *subreq = NULL;
+	struct link_state *state = NULL;
 
-	if (!cli_send_trans(cli, SMBtrans2,
-		NULL,                        /* name */
-		-1, 0,                       /* fid, flags */
-		&setup, 1, 0,                /* setup, length, max */
-		param, param_len, 2,         /* param, length, max */
-		NULL,  0, cli->max_xmit      /* data, length, max */
-		)) {
-		SAFE_FREE(param);
-		return false;
+	req = tevent_req_create(mem_ctx, &state, struct getfacl_state);
+	if (req == NULL) {
+		return NULL;
 	}
 
-	SAFE_FREE(param);
+	/* Setup setup word. */
+	SSVAL(&state->setup, 0, TRANSACT2_QPATHINFO);
 
-	if (!cli_receive_trans(cli, SMBtrans2,
-			&rparam, &param_len,
-			&rdata, &data_len)) {
-		return false;
+	/* Setup param array. */
+	state->param = talloc_array(state, uint8_t, 6);
+	if (tevent_req_nomem(state->param, req)) {
+		return tevent_req_post(req, ev);
 	}
+	memset(state->param, '\0', 6);
+	SSVAL(state->param, 0, SMB_QUERY_POSIX_ACL);
 
-	if (data_len < 6) {
-		SAFE_FREE(rdata);
-		SAFE_FREE(rparam);
-		return false;
+	state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), fname,
+				   strlen(fname)+1, NULL);
+
+	if (tevent_req_nomem(state->param, req)) {
+		return tevent_req_post(req, ev);
 	}
 
-	SAFE_FREE(rparam);
-	*retbuf = rdata;
-	*prb_size = (size_t)data_len;
+	subreq = cli_trans_send(state,			/* mem ctx. */
+				ev,			/* event ctx. */
+				cli,			/* cli_state. */
+				SMBtrans2,		/* cmd. */
+				NULL,			/* pipe name. */
+				-1,			/* fid. */
+				0,			/* function. */
+				0,			/* flags. */
+				&state->setup,		/* setup. */
+				1,			/* num setup uint16_t words. */
+				0,			/* max returned setup. */
+				state->param,		/* param. */
+				talloc_get_size(state->param),	/* num param. */
+				2,			/* max returned param. */
+				NULL,			/* data. */
+				0,			/* num data. */
+				cli->max_xmit);		/* max returned data. */
 
-	return true;
+	if (tevent_req_nomem(subreq, req)) {
+		return tevent_req_post(req, ev);
+	}
+	tevent_req_set_callback(subreq, cli_posix_getfacl_done, req);
+	return req;
+}
+
+NTSTATUS cli_posix_getfacl_recv(struct tevent_req *req,
+				TALLOC_CTX *mem_ctx,
+				size_t *prb_size,
+				char **retbuf)
+{
+	struct getfacl_state *state = tevent_req_data(req, struct getfacl_state);
+	NTSTATUS status;
+
+	if (tevent_req_is_nterror(req, &status)) {
+		return status;
+	}
+	*prb_size = (size_t)state->num_data;
+	*retbuf = (char *)talloc_move(mem_ctx, &state->data);
+	return NT_STATUS_OK;
+}
+
+NTSTATUS cli_posix_getfacl(struct cli_state *cli,
+			const char *fname,
+			TALLOC_CTX *mem_ctx,
+			size_t *prb_size,
+			char **retbuf)
+{
+	TALLOC_CTX *frame = talloc_stackframe();
+	struct event_context *ev = NULL;
+	struct tevent_req *req = NULL;
+	NTSTATUS status = NT_STATUS_OK;
+
+	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) {
+		status = NT_STATUS_NO_MEMORY;
+		goto fail;
+	}
+
+	req = cli_posix_getfacl_send(frame,
+				ev,
+				cli,
+				fname);
+	if (req == NULL) {
+		status = NT_STATUS_NO_MEMORY;
+		goto fail;
+	}
+
+	if (!tevent_req_poll(req, ev)) {
+		status = map_nt_error_from_unix(errno);
+		goto fail;
+	}
+
+	status = cli_posix_getfacl_recv(req, mem_ctx, prb_size, retbuf);
+
+ 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