[SCM] Samba Shared Repository - branch v3-5-test updated

Jeremy Allison jra at samba.org
Fri Nov 13 14:46:14 MST 2009


The branch, v3-5-test has been updated
       via  1ace5f9... s3: Convert libsmb/cli_message to the async API (cherry picked from commit 2b759339601ad853588cb74e986a7a88301aea17)
       via  8a5c8d5... util: str_list_unique() bugfix
       via  c2a511b... util: str_list_unique_2() test implementation
      from  d0ac2c8... add e2fsprogs-devel as build dependency this is needed for AD because it contains libcom/libcom_err files and headers

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-5-test


- Log -----------------------------------------------------------------
commit 1ace5f961629fc02c2ff79ed2bdd86e9e988cf28
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Nov 10 19:49:41 2009 +0100

    s3: Convert libsmb/cli_message to the async API
    (cherry picked from commit 2b759339601ad853588cb74e986a7a88301aea17)

commit 8a5c8d559e6b34544a3cc0811d269d46bcad5182
Author: Kamen Mazdrashki <kamen.mazdrashki at postpath.com>
Date:   Fri Nov 13 03:57:48 2009 +0200

    util: str_list_unique() bugfix
    
    j is actually the index of the last element in the list
    size of the list though is j+1 <- to make room for the
    terminating NULL element
    (cherry picked from commit 5b75201dbb9f2e6799fd5c3eee8da6230caee96c)

commit c2a511b8c95a92676fbf0895d3a6fd627662ecb8
Author: Kamen Mazdrashki <kamen.mazdrashki at postpath.com>
Date:   Fri Nov 13 03:56:07 2009 +0200

    util: str_list_unique_2() test implementation
    
    Difference with previous test for str_list_unique() is
    that this test allows number of elements and number
    of duplicates to be supplied on command line using
    --option="list_unique:count=47"
    --option="list_unique:dups=7"
    (cherry picked from commit b7839b73b10746c374ca2ed96eb152fa3a03e66a)

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

Summary of changes:
 lib/util/tests/strlist.c    |   33 ++++
 lib/util/util_strlist.c     |    2 +-
 source3/client/client.c     |   54 ++----
 source3/include/proto.h     |   15 +-
 source3/libsmb/climessage.c |  445 +++++++++++++++++++++++++++++++++----------
 5 files changed, 406 insertions(+), 143 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/util/tests/strlist.c b/lib/util/tests/strlist.c
index 877b671..a974f58 100644
--- a/lib/util/tests/strlist.c
+++ b/lib/util/tests/strlist.c
@@ -22,6 +22,7 @@
 
 #include "includes.h"
 #include "torture/torture.h"
+#include "param/param.h"
 
 struct test_list_element {
 	const char *list_as_string;
@@ -364,6 +365,37 @@ static bool test_list_unique(struct torture_context *tctx)
 	return true;
 }
 
+static bool test_list_unique_2(struct torture_context *tctx)
+{
+	int i;
+	int count, num_dups;
+	const char **result;
+	const char **list = (const char **)str_list_make_empty(tctx);
+	const char **list_dup = (const char **)str_list_make_empty(tctx);
+
+	count = lp_parm_int(tctx->lp_ctx, NULL, "list_unique", "count", 9);
+	num_dups = lp_parm_int(tctx->lp_ctx, NULL, "list_unique", "dups", 7);
+	torture_comment(tctx, "test_list_unique_2() with %d elements and %d dups\n", count, num_dups);
+
+	for (i = 0; i < count; i++) {
+		list = str_list_add_const(list, (const char *)talloc_asprintf(tctx, "element_%03d", i));
+	}
+
+	for (i = 0; i < num_dups; i++) {
+		list_dup = str_list_append(list_dup, list);
+	}
+
+	result = (const char **)str_list_copy(tctx, list_dup);
+	/* We must copy the list, as str_list_unique does a talloc_realloc() on it's parameter */
+	result = str_list_unique(result);
+	torture_assert(tctx, result, "str_list_unique() must not return NULL");
+
+	torture_assert(tctx, str_list_equal(list, result),
+		       "str_list_unique() failed");
+
+	return true;
+}
+
 static bool test_list_append(struct torture_context *tctx)
 {
 	char **result;
@@ -458,6 +490,7 @@ struct torture_suite *torture_local_util_strlist(TALLOC_CTX *mem_ctx)
 	torture_suite_add_simple_test(suite, "list_check", test_list_check);
 	torture_suite_add_simple_test(suite, "list_check_ci", test_list_check_ci);
 	torture_suite_add_simple_test(suite, "list_unique", test_list_unique);
+	torture_suite_add_simple_test(suite, "list_unique_2", test_list_unique_2);
 	torture_suite_add_simple_test(suite, "list_append", test_list_append);
 	torture_suite_add_simple_test(suite, "list_append_const", test_list_append_const);
 
diff --git a/lib/util/util_strlist.c b/lib/util/util_strlist.c
index 1331fee..8d69eef 100644
--- a/lib/util/util_strlist.c
+++ b/lib/util/util_strlist.c
@@ -401,7 +401,7 @@ _PUBLIC_ const char **str_list_unique(const char **list)
 		}
 	}
 	list[j] = NULL;
-	list = talloc_realloc(NULL, list, const char *, j);
+	list = talloc_realloc(NULL, list, const char *, j + 1);
 	talloc_free(list2);
 	return list;
 }
diff --git a/source3/client/client.c b/source3/client/client.c
index 255c75b..f81762a 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -243,51 +243,29 @@ static size_t push_source(uint8_t *buf, size_t n, void *priv)
 
 static void send_message(const char *username)
 {
-	int total_len = 0;
-	int grp_id;
-
-	if (!cli_message_start(cli, desthost, username, &grp_id)) {
-		d_printf("message start: %s\n", cli_errstr(cli));
-		return;
-	}
-
-
-	d_printf("Connected. Type your message, ending it with a Control-D\n");
-
-	while (!feof(stdin) && total_len < 1600) {
-		int maxlen = MIN(1600 - total_len,127);
-		char msg[1024];
-		int l=0;
-		int c;
-
-		ZERO_ARRAY(msg);
+	char buf[1600];
+	NTSTATUS status;
+	int i;
 
-		for (l=0;l<maxlen && (c=fgetc(stdin))!=EOF;l++) {
-			if (c == '\n')
-				msg[l++] = '\r';
-			msg[l] = c;
-		}
+	d_printf("Type your message, ending it with a Control-D\n");
 
-		if ((total_len > 0) && (strlen(msg) == 0)) {
+	i = 0;
+	while (i<sizeof(buf)-2) {
+		int c = fgetc(stdin);
+		if (c == EOF) {
 			break;
 		}
-
-		if (!cli_message_text(cli, msg, l, grp_id)) {
-			d_printf("SMBsendtxt failed (%s)\n",cli_errstr(cli));
-			return;
+		if (c == '\n') {
+			buf[i++] = '\r';
 		}
-
-		total_len += l;
+		buf[i++] = c;
 	}
+	buf[i] = '\0';
 
-	if (total_len >= 1600)
-		d_printf("the message was truncated to 1600 bytes\n");
-	else
-		d_printf("sent %d bytes\n",total_len);
-
-	if (!cli_message_end(cli, grp_id)) {
-		d_printf("SMBsendend failed (%s)\n",cli_errstr(cli));
-		return;
+	status = cli_message(cli, desthost, username, buf);
+	if (!NT_STATUS_IS_OK(status)) {
+		d_fprintf(stderr, "cli_message returned %s\n",
+			  nt_errstr(status));
 	}
 }
 
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 01546f8..44e6ee0 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -2740,13 +2740,14 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
 
 /* The following definitions come from libsmb/climessage.c  */
 
-int cli_message_start_build(struct cli_state *cli, const char *host, const char *username);
-bool cli_message_start(struct cli_state *cli, const char *host, const char *username,
-			      int *grp);
-int cli_message_text_build(struct cli_state *cli, const char *msg, int len, int grp);
-bool cli_message_text(struct cli_state *cli, const char *msg, int len, int grp);
-int cli_message_end_build(struct cli_state *cli, int grp);
-bool cli_message_end(struct cli_state *cli, int grp);
+struct tevent_req *cli_message_send(TALLOC_CTX *mem_ctx,
+				    struct tevent_context *ev,
+				    struct cli_state *cli,
+				    const char *host, const char *username,
+				    const char *message);
+NTSTATUS cli_message_recv(struct tevent_req *req);
+NTSTATUS cli_message(struct cli_state *cli, const char *host,
+		     const char *username, const char *message);
 
 /* The following definitions come from libsmb/clioplock.c  */
 
diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c
index 6538902..2c8ef58 100644
--- a/source3/libsmb/climessage.c
+++ b/source3/libsmb/climessage.c
@@ -1,162 +1,413 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
    client message handling routines
    Copyright (C) Andrew Tridgell 1994-1998
-   
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 
-/****************************************************************************
- Start a message sequence.
-****************************************************************************/
+struct cli_message_start_state {
+	uint16_t grp;
+};
+
+static void cli_message_start_done(struct tevent_req *subreq);
 
-int cli_message_start_build(struct cli_state *cli, const char *host, const char *username)
+static struct tevent_req *cli_message_start_send(TALLOC_CTX *mem_ctx,
+						 struct tevent_context *ev,
+						 struct cli_state *cli,
+						 const char *host,
+						 const char *username)
 {
-	char *p;
+	struct tevent_req *req, *subreq;
+	struct cli_message_start_state *state;
+	char *htmp = NULL;
+	char *utmp = NULL;
+	size_t hlen, ulen;
+	uint8_t *bytes, *p;
+
+	req = tevent_req_create(mem_ctx, &state,
+				struct cli_message_start_state);
+	if (req == NULL) {
+		return NULL;
+	}
+
+	if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_DOS,
+				   username, strlen(username)+1,
+				   &utmp, &ulen, true)) {
+		goto fail;
+	}
+	if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_DOS,
+				   host, strlen(host)+1,
+				   &htmp, &hlen, true)) {
+		goto fail;
+	}
 
-	/* construct a SMBsendstrt command */
-	memset(cli->outbuf,'\0',smb_size);
-	cli_set_message(cli->outbuf,0,0,True);
-	SCVAL(cli->outbuf,smb_com,SMBsendstrt);
-	SSVAL(cli->outbuf,smb_tid,cli->cnum);
-	cli_setup_packet(cli);
+	bytes = talloc_array(state, uint8_t, ulen+hlen+2);
+	if (bytes == NULL) {
+		goto fail;
+	}
+	p = bytes;
 
-	p = smb_buf(cli->outbuf);
 	*p++ = 4;
-	p += clistr_push(cli, p, username,
-			cli->bufsize - PTR_DIFF(p,cli->outbuf), STR_ASCII|STR_TERMINATE);
+	memcpy(p, utmp, ulen);
 	*p++ = 4;
-	p += clistr_push(cli, p, host,
-			cli->bufsize - PTR_DIFF(p,cli->outbuf), STR_ASCII|STR_TERMINATE);
+	memcpy(p, htmp, hlen);
+	TALLOC_FREE(htmp);
+	TALLOC_FREE(utmp);
+
+	subreq = cli_smb_send(state, ev, cli, SMBsendstrt, 0, 0, NULL,
+			      talloc_get_size(bytes), bytes);
+	if (tevent_req_nomem(subreq, req)) {
+		return tevent_req_post(req, ev);
+	}
+	tevent_req_set_callback(subreq, cli_message_start_done, req);
+	return req;
+fail:
+	TALLOC_FREE(htmp);
+	TALLOC_FREE(utmp);
+	tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
+	return tevent_req_post(req, ev);
+}
 
-	cli_setup_bcc(cli, p);
+static void cli_message_start_done(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct cli_message_start_state *state = tevent_req_data(
+		req, struct cli_message_start_state);
+	NTSTATUS status;
+	uint8_t wct;
+	uint16_t *vwv;
+
+	status = cli_smb_recv(subreq, 0, &wct, &vwv, NULL, NULL);
+	if (!NT_STATUS_IS_OK(status)) {
+		TALLOC_FREE(subreq);
+		tevent_req_nterror(req, status);
+		return;
+	}
+	if (wct >= 1) {
+		state->grp = SVAL(vwv+0, 0);
+	} else {
+		state->grp = 0;
+	}
+	TALLOC_FREE(subreq);
+	tevent_req_done(req);
+}
 
-	return(PTR_DIFF(p, cli->outbuf));
+static NTSTATUS cli_message_start_recv(struct tevent_req *req,
+				       uint16_t *pgrp)
+{
+	struct cli_message_start_state *state = tevent_req_data(
+		req, struct cli_message_start_state);
+	NTSTATUS status;
+
+	if (tevent_req_is_nterror(req, &status)) {
+		return status;
+	}
+	*pgrp = state->grp;
+	return NT_STATUS_OK;
 }
 
-bool cli_message_start(struct cli_state *cli, const char *host, const char *username,
-			      int *grp)
+struct cli_message_text_state {
+	uint16_t vwv;
+};
+
+static void cli_message_text_done(struct tevent_req *subreq);
+
+static struct tevent_req *cli_message_text_send(TALLOC_CTX *mem_ctx,
+						struct tevent_context *ev,
+						struct cli_state *cli,
+						uint16_t grp,
+						const char *msg,
+						int msglen)
 {
-	cli_message_start_build(cli, host, username);
-	cli_send_smb(cli);
+	struct tevent_req *req, *subreq;
+	struct cli_message_text_state *state;
+	char *tmp;
+	size_t tmplen;
+	uint8_t *bytes;
+
+	req = tevent_req_create(mem_ctx, &state,
+				struct cli_message_text_state);
+	if (req == NULL) {
+		return NULL;
+	}
 
-	if (!cli_receive_smb(cli)) {
-		return False;
+	SSVAL(&state->vwv, 0, grp);
+
+	if (convert_string_talloc(talloc_tos(), CH_UNIX, CH_DOS, msg, msglen,
+				  &tmp, &tmplen, true)) {
+		msg = tmp;
+		msglen = tmplen;
+	} else {
+		DEBUG(3, ("Conversion failed, sending message in UNIX "
+			  "charset\n"));
+		tmp = NULL;
 	}
 
-	if (cli_is_error(cli)) return False;
+	bytes = talloc_array(state, uint8_t, msglen+3);
+	if (tevent_req_nomem(bytes, req)) {
+		TALLOC_FREE(tmp);
+		return tevent_req_post(req, ev);
+	}
+	SCVAL(bytes, 0, 0);	/* pad */
+	SSVAL(bytes, 1, msglen);
+	memcpy(bytes+3, msg, msglen);
+	TALLOC_FREE(tmp);
+
+	subreq = cli_smb_send(state, ev, cli, SMBsendtxt, 0, 1, &state->vwv,
+			      talloc_get_size(bytes), bytes);
+	if (tevent_req_nomem(subreq, req)) {
+		return tevent_req_post(req, ev);
+	}
+	tevent_req_set_callback(subreq, cli_message_text_done, req);
+	return req;
+}
 
-	*grp = SVAL(cli->inbuf,smb_vwv0);
+static void cli_message_text_done(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	NTSTATUS status;
+
+	status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);
+	TALLOC_FREE(subreq);
+	if (!NT_STATUS_IS_OK(status)) {
+		tevent_req_nterror(req, status);
+		return;
+	}
+	tevent_req_done(req);
+}
 
-	return True;
+static NTSTATUS cli_message_text_recv(struct tevent_req *req)
+{
+	return tevent_req_simple_recv_ntstatus(req);
 }
 
-/****************************************************************************
- Send a message
-****************************************************************************/
+struct cli_message_end_state {
+	uint16_t vwv;
+};
 
-int cli_message_text_build(struct cli_state *cli, const char *msg, int len, int grp)
+static void cli_message_end_done(struct tevent_req *subreq);
+
+static struct tevent_req *cli_message_end_send(TALLOC_CTX *mem_ctx,
+						struct tevent_context *ev,
+						struct cli_state *cli,
+						uint16_t grp)
 {
-	char *msgdos;
-	size_t lendos;
-	char *p;
-
-	memset(cli->outbuf,'\0',smb_size);
-	cli_set_message(cli->outbuf,1,0,True);
-	SCVAL(cli->outbuf,smb_com,SMBsendtxt);
-	SSVAL(cli->outbuf,smb_tid,cli->cnum);
-	cli_setup_packet(cli);
-
-	SSVAL(cli->outbuf,smb_vwv0,grp);
-
-	p = smb_buf(cli->outbuf);
-	*p++ = 1;
-
-	if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_DOS, msg, len,
-		(void **)(void *)&msgdos, &lendos, True) || !msgdos) {
-		DEBUG(3,("Conversion failed, sending message in UNIX charset\n"));
-		SSVAL(p, 0, len); p += 2;
-		if (len > cli->bufsize - PTR_DIFF(p,cli->outbuf)) {
-			return -1;
-		}
-		memcpy(p, msg, len);
-		p += len;
-	} else {
-		SSVAL(p, 0, lendos); p += 2;
-		if (lendos > cli->bufsize - PTR_DIFF(p,cli->outbuf)) {
-			return -1;
-		}
-		memcpy(p, msgdos, lendos);
-		p += lendos;
-		TALLOC_FREE(msgdos);
+	struct tevent_req *req, *subreq;
+	struct cli_message_end_state *state;
+
+	req = tevent_req_create(mem_ctx, &state,
+				struct cli_message_end_state);
+	if (req == NULL) {
+		return NULL;
 	}
 
-	cli_setup_bcc(cli, p);
+	SSVAL(&state->vwv, 0, grp);
+
+	subreq = cli_smb_send(state, ev, cli, SMBsendend, 0, 1, &state->vwv,
+			      0, NULL);
+	if (tevent_req_nomem(subreq, req)) {
+		return tevent_req_post(req, ev);
+	}
+	tevent_req_set_callback(subreq, cli_message_end_done, req);
+	return req;
+}
 
-	return(PTR_DIFF(p, cli->outbuf));
+static void cli_message_end_done(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	NTSTATUS status;
+
+	status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);
+	TALLOC_FREE(subreq);
+	if (!NT_STATUS_IS_OK(status)) {
+		tevent_req_nterror(req, status);
+		return;
+	}
+	tevent_req_done(req);
 }
 
-bool cli_message_text(struct cli_state *cli, const char *msg, int len, int grp)
+static NTSTATUS cli_message_end_recv(struct tevent_req *req)
 {
-	cli_message_text_build(cli, msg, len, grp);
+	return tevent_req_simple_recv_ntstatus(req);
+}
 
-	cli_send_smb(cli);
+struct cli_message_state {
+	struct tevent_context *ev;
+	struct cli_state *cli;
+	size_t sent;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list