[PATCH] parametric options

Stefan (metze) Metzmacher metze at metzemix.de
Tue Dec 31 15:45:01 GMT 2002


Hi *,

here are the parametric option changes of my big patch...

all lp_param_*() functions now take the default value as last parameter
this is usefull for all fn's and needed for the enum,bool,int and ulong 
functions :-)

lp_parm_string_list() now use talloc_str_list_make() and 
talloc_realloc_str_list_make and caches the the result for the called 
seperator, so if the function is called with the same separator it is not 
needed to call *_str_list_make()

if the function is called with an other separator the old list is free'ed

so we didn't get a memory leek if we call:

lp_parm_string_list(SNUM(conn), "test","name"," \n\r\t", NULL);
lp_parm_string_list(SNUM(conn), "test","name",";,.", NULL);
lp_parm_string_list(SNUM(conn), "test","name"," \n\r\t", NULL);
lp_parm_string_list(SNUM(conn), "test","name",";,.", NULL);
lp_parm_string_list(SNUM(conn), "test","name"," \n\r\t", NULL);


talloc_realloc_str_list_make()

a add talloc_free() witch free's the memory of one talloc'ed memory segment

a also add a view talloc_realloc_*() functions

talloc_realloc_strdup() ...

here''s the patch for HEAD



metze
-----------------------------------------------------------------------------
Stefan "metze" Metzmacher <metze at metzemix.de>
-------------- next part --------------
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=*.so --exclude=.#* --exclude=Makefile --exclude=stamp-h --exclude=configure --exclude=findsmb --exclude=*proto*.h --exclude=build_env.h --exclude=tdbsam2_parse_info.h --exclude=config.* --exclude=bin --exclude=*.configure HEAD/source/include/local.h HEAD-param/source/include/local.h
--- HEAD/source/include/local.h	Thu Oct 24 11:10:57 2002
+++ HEAD-param/source/include/local.h	Mon Dec 30 21:35:32 2002
@@ -75,6 +75,8 @@
 /* separators for lists */
 #define LIST_SEP " \t,;\n\r"
 
+#define S_LIST_ABS 16 /* List Allocation Block Size */
+
 /* wchar separators for lists */
 #define LIST_SEP_W wchar_list_sep
 
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=*.so --exclude=.#* --exclude=Makefile --exclude=stamp-h --exclude=configure --exclude=findsmb --exclude=*proto*.h --exclude=build_env.h --exclude=tdbsam2_parse_info.h --exclude=config.* --exclude=bin --exclude=*.configure HEAD/source/lib/talloc.c HEAD-param/source/lib/talloc.c
--- HEAD/source/lib/talloc.c	Tue Dec 24 01:14:22 2002
+++ HEAD-param/source/lib/talloc.c	Mon Dec 30 21:36:49 2002
@@ -216,6 +216,32 @@ void *talloc_realloc(TALLOC_CTX *t, void
 	return NULL;
 }
 
+/** free the memory allocated inside @p t, but not @p t
+ * itself. */
+void talloc_free(TALLOC_CTX *t, void *ptr)
+{
+	struct talloc_chunk *tc;
+	struct talloc_chunk *prev=NULL;
+
+	if (!t||!ptr)
+		return;
+
+	for (tc=t->list; tc; prev=tc,tc=tc->next) {
+		if (tc->ptr == ptr) {
+			if (prev) {
+				prev->next = tc->next;
+			} else {
+				t->list = tc->next;
+			}
+
+			t->total_alloc_size -= tc->size;
+			SAFE_FREE(tc->ptr);
+			SAFE_FREE(tc);
+			break;
+		}
+	}
+}
+
 /** Destroy all the memory allocated inside @p t, but not @p t
  * itself. */
 void talloc_destroy_pool(TALLOC_CTX *t)
@@ -288,6 +314,17 @@ void *talloc_memdup(TALLOC_CTX *t, const
 	return newp;
 }
 
+/** realloc_memdup with a talloc_realloc. */
+void *talloc_realloc_memdup(TALLOC_CTX *t, void *ptr, const void *p, size_t size)
+{
+	void *newp = talloc_realloc(t,ptr,size);
+
+	if (newp)
+		memcpy(newp, p, size);
+
+	return newp;
+}
+
 /** strdup with a talloc */
 char *talloc_strdup(TALLOC_CTX *t, const char *p)
 {
@@ -297,11 +334,95 @@ char *talloc_strdup(TALLOC_CTX *t, const
 		return NULL;
 }
 
+/** realloc_strdup with a talloc */
+char *talloc_realloc_strdup(TALLOC_CTX *t, void *ptr, const char *p)
+{
+	if (p)
+		return talloc_realloc_memdup(t, ptr, p, strlen(p) + 1);
+	else
+		return NULL;
+}
+
+void talloc_str_list_free(TALLOC_CTX *t, char ***list)
+{
+	char **tlist;
+	
+	if (!list || !*list)
+		return;
+	tlist = *list;
+	for(; *tlist; tlist++)
+		talloc_free(t,*tlist);
+	talloc_free(t,*list);
+}
+
+/** str_list_make with a talloc */
+char **talloc_str_list_make(TALLOC_CTX *t, const char *string, const char *sep)
+{
+	char **list=NULL, **rlist;
+	const char *str;
+	char *s;
+	int num=0, lsize=0;
+	pstring tok;
+	
+	if (!string || !*string)
+		return NULL;
+	s = strdup(string);
+	if (!s) {
+		DEBUG(0,("talloc_str_list_make: Unable to allocate memory"));
+		return NULL;
+	}
+	if (!sep) sep = LIST_SEP;
+	
+	str = s;
+	while (next_token(&str, tok, sep, sizeof(tok))) {		
+		if (num == lsize) {
+			lsize += S_LIST_ABS;
+			rlist = (char **)talloc_realloc(t, list, ((sizeof(char **)) * (lsize +1)));
+			if (!rlist) {
+				DEBUG(0,("talloc_str_list_make: Unable to allocate memory"));
+				SAFE_FREE(s);
+				return NULL;
+			} else
+				list = rlist;
+			memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
+		}
+		
+		list[num] = talloc_strdup(t,tok);
+		if (!list[num]) {
+			DEBUG(0,("talloc_str_list_make: Unable to allocate memory"));
+			SAFE_FREE(s);
+			return NULL;
+		}
+	
+		num++;	
+	}
+
+	SAFE_FREE(s);
+	return list;
+}
+
+/** realloc_str_list_make with a talloc */
+char **talloc_realloc_str_list_make(TALLOC_CTX *t, void *ptr, const char *string, const char *sep)
+{
+	talloc_str_list_free(t,ptr);
+
+	return talloc_str_list_make(t,string,sep);
+}
+
 /** strdup_w with a talloc */
 smb_ucs2_t *talloc_strdup_w(TALLOC_CTX *t, const smb_ucs2_t *p)
 {
 	if (p)
 		return talloc_memdup(t, p, (strlen_w(p) + 1) * sizeof(smb_ucs2_t));
+	else
+		return NULL;
+}
+
+/** realloc_strdup_w with a talloc */
+smb_ucs2_t *talloc_realloc_strdup_w(TALLOC_CTX *t, void *ptr, const smb_ucs2_t *p)
+{
+	if (p)
+		return talloc_realloc_memdup(t, ptr, p, (strlen_w(p) + 1) * sizeof(smb_ucs2_t));
 	else
 		return NULL;
 }
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=*.so --exclude=.#* --exclude=Makefile --exclude=stamp-h --exclude=configure --exclude=findsmb --exclude=*proto*.h --exclude=build_env.h --exclude=tdbsam2_parse_info.h --exclude=config.* --exclude=bin --exclude=*.configure HEAD/source/lib/util_str.c HEAD-param/source/lib/util_str.c
--- HEAD/source/lib/util_str.c	Thu Dec 12 20:24:26 2002
+++ HEAD-param/source/lib/util_str.c	Mon Dec 30 21:36:49 2002
@@ -1180,8 +1180,6 @@ int fstr_sprintf(fstring s, const char *
  List of Strings manipulation functions
 ***********************************************************/
 
-#define S_LIST_ABS 16 /* List Allocation Block Size */
-
 char **str_list_make(const char *string, const char *sep)
 {
 	char **list, **rlist;
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=*.so --exclude=.#* --exclude=Makefile --exclude=stamp-h --exclude=configure --exclude=findsmb --exclude=*proto*.h --exclude=build_env.h --exclude=tdbsam2_parse_info.h --exclude=config.* --exclude=bin --exclude=*.configure HEAD/source/modules/mysql.c HEAD-param/source/modules/mysql.c
--- HEAD/source/modules/mysql.c	Tue Dec 24 01:14:23 2002
+++ HEAD-param/source/modules/mysql.c	Mon Dec 30 21:41:04 2002
@@ -147,10 +147,7 @@ static NTSTATUS pdb_mysql_string_field(s
 
 static char * config_value(pdb_mysql_data * data, char *name, char *default_value)
 {
-	if (lp_parm_string(NULL, data->location, name))
-		return lp_parm_string(NULL, data->location, name);
-
-	return default_value;
+	return lp_parm_string(NULL, data->location, name, default_value);
 }
 
 static char * config_value_write(pdb_mysql_data * data, char *name, char *default_value) {
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=*.so --exclude=.#* --exclude=Makefile --exclude=stamp-h --exclude=configure --exclude=findsmb --exclude=*proto*.h --exclude=build_env.h --exclude=tdbsam2_parse_info.h --exclude=config.* --exclude=bin --exclude=*.configure HEAD/source/modules/vfs_recycle.c HEAD-param/source/modules/vfs_recycle.c
--- HEAD/source/modules/vfs_recycle.c	Mon Dec 23 08:37:01 2002
+++ HEAD-param/source/modules/vfs_recycle.c	Mon Dec 30 21:44:24 2002
@@ -183,35 +183,24 @@ static int recycle_connect(struct connec
 	}
 	recbin->mem_ctx = ctx;
 
-	/* Set defaults */
-	recbin->repository = talloc_strdup(recbin->mem_ctx, ".recycle");
-	ALLOC_CHECK(recbin->repository, error);
-	recbin->keep_dir_tree = False;
-	recbin->versions = False;
-	recbin->touch = False;
-	recbin->exclude = "";
-	recbin->exclude_dir = "";
-	recbin->noversions = "";
-	recbin->maxsize = 0;
-
 	/* parse configuration options */
-	if ((tmp_str = lp_parm_string(SNUM(conn), "vfs_recycle_bin", "repository")) != NULL) {
+	if ((tmp_str = lp_parm_string(SNUM(conn), "vfs_recycle_bin", "repository",".recycle")) != NULL) {
 		recbin->repository = talloc_sub_conn(recbin->mem_ctx, conn, tmp_str);
 		ALLOC_CHECK(recbin->repository, error);
 		trim_string(recbin->repository, "/", "/");
 		DEBUG(5, ("recycle.bin: repository = %s\n", recbin->repository));
 	}
 	
-	recbin->keep_dir_tree = lp_parm_bool(SNUM(conn), "vfs_recycle_bin", "keeptree");
+	recbin->keep_dir_tree = lp_parm_bool(SNUM(conn), "vfs_recycle_bin", "keeptree", False);
 	DEBUG(5, ("recycle.bin: keeptree = %d\n", recbin->keep_dir_tree));
 	
-	recbin->versions = lp_parm_bool(SNUM(conn), "vfs_recycle_bin", "versions");
+	recbin->versions = lp_parm_bool(SNUM(conn), "vfs_recycle_bin", "versions", False);
 	DEBUG(5, ("recycle.bin: versions = %d\n", recbin->versions));
 	
-	recbin->touch = lp_parm_bool(SNUM(conn), "vfs_recycle_bin", "touch");
+	recbin->touch = lp_parm_bool(SNUM(conn), "vfs_recycle_bin", "touch", False);
 	DEBUG(5, ("recycle.bin: touch = %d\n", recbin->touch));
 
-	recbin->maxsize = lp_parm_ulong(SNUM(conn), "vfs_recycle_bin", "maxsize");
+	recbin->maxsize = lp_parm_ulong(SNUM(conn), "vfs_recycle_bin", "maxsize",0);
 	if (recbin->maxsize == 0) {
 		recbin->maxsize = -1;
 		DEBUG(5, ("recycle.bin: maxsize = -infinite-\n"));
@@ -219,17 +208,17 @@ static int recycle_connect(struct connec
 		DEBUG(5, ("recycle.bin: maxsize = %ld\n", (long int)recbin->maxsize));
 	}
 
-	if ((tmp_str = lp_parm_string(SNUM(conn), "vfs_recycle_bin", "exclude")) != NULL) {
+	if ((tmp_str = lp_parm_string(SNUM(conn), "vfs_recycle_bin", "exclude", "")) != NULL) {
 		recbin->exclude = talloc_strdup(recbin->mem_ctx, tmp_str);
 		ALLOC_CHECK(recbin->exclude, error);
 		DEBUG(5, ("recycle.bin: exclude = %s\n", recbin->exclude));
 	}
-	if ((tmp_str = lp_parm_string(SNUM(conn), "vfs_recycle_bin", "exclude_dir")) != NULL) {
+	if ((tmp_str = lp_parm_string(SNUM(conn), "vfs_recycle_bin", "exclude_dir", "")) != NULL) {
 		recbin->exclude_dir = talloc_strdup(recbin->mem_ctx, tmp_str);
 		ALLOC_CHECK(recbin->exclude_dir, error);
 		DEBUG(5, ("recycle.bin: exclude_dir = %s\n", recbin->exclude_dir));
 	}
-	if ((tmp_str = lp_parm_string(SNUM(conn), "vfs_recycle_bin", "noversions")) != NULL) {
+	if ((tmp_str = lp_parm_string(SNUM(conn), "vfs_recycle_bin", "noversions", "")) != NULL) {
 		recbin->noversions = talloc_strdup(recbin->mem_ctx, tmp_str);
 		ALLOC_CHECK(recbin->noversions, error);
 		DEBUG(5, ("recycle.bin: noversions = %s\n", recbin->noversions));
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=*.so --exclude=.#* --exclude=Makefile --exclude=stamp-h --exclude=configure --exclude=findsmb --exclude=*proto*.h --exclude=build_env.h --exclude=tdbsam2_parse_info.h --exclude=config.* --exclude=bin --exclude=*.configure HEAD/source/param/loadparm.c HEAD-param/source/param/loadparm.c
--- HEAD/source/param/loadparm.c	Mon Dec 30 18:36:24 2002
+++ HEAD-param/source/param/loadparm.c	Tue Dec 31 01:14:05 2002
@@ -84,8 +84,11 @@ static BOOL defaults_saved = False;
 typedef struct _param_opt_struct param_opt_struct;
 struct _param_opt_struct {
 	param_opt_struct *prev, *next;
+	TALLOC_CTX *mem_ctx;
 	char *key;
 	char *value;
+	char **list;
+	char *list_sep;
 };
 
 /* 
@@ -1835,7 +1838,7 @@ static void init_copymap(service * pserv
 /* This is a helper function for parametrical options support. */
 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
 /* Actual parametrical functions are quite simple */
-static const char *get_parametrics(int lookup_service, const char *type, const char *option)
+static param_opt_struct *get_parametrics(int lookup_service, const char *type, const char *option)
 {
 	char* vfskey;
         param_opt_struct *data;
@@ -1849,26 +1852,25 @@ static const char *get_parametrics(int l
 	while (data) {
 		if (strcmp(data->key, vfskey) == 0) {
 			string_free(&vfskey);
-			return data->value;
+			return data;
 		}
 		data = data->next;
 	}
-
 	if (lookup_service >= 0) {
 		/* Try to fetch the same option but from globals */
 		/* but only if we are not already working with Globals */
 		data = Globals.param_opt;
 		while (data) {
-			if (strcmp(data->key, vfskey) == 0) {
-				string_free(&vfskey);
-				return data->value;
+		        if (strcmp(data->key, vfskey) == 0) {
+			        string_free(&vfskey);
+				return data;
 			}
 			data = data->next;
 		}
 	}
-
-	string_free(&vfskey);
 	
+	string_free(&vfskey);
+
 	return NULL;
 }
 
@@ -1930,7 +1932,7 @@ static int lp_enum(const char *s,const s
 
 	if (!s || !_enum) {
 		DEBUG(0,("lp_enum(%s,enum): is called with NULL!\n",s));
-		return False;
+		return (-1);
 	}
 	
 	for (i=0; _enum[i].name; i++) {
@@ -1944,87 +1946,105 @@ static int lp_enum(const char *s,const s
 
 /* Return parametric option from a given service. Type is a part of option before ':' */
 /* Parametric option has following syntax: 'Type: option = value' */
-/* Returned value is allocated in 'lp_talloc' context */
 
-char *lp_parm_string(int lookup_service, const char *type, const char *option)
+
+char *lp_parm_string(int lookup_service, const char *type, const char *option, char *def)
 {
-	const char *value = get_parametrics(lookup_service, type, option);
+	param_opt_struct *data = get_parametrics(lookup_service, type, option);
 	
-	if (value)
-		return lp_string(value);
-
-	return NULL;
+	if (data == NULL||data->value==NULL)
+		return def;
+		
+	return data->value;
 }
 
 /* Return parametric option from a given service. Type is a part of option before ':' */
 /* Parametric option has following syntax: 'Type: option = value' */
-/* Returned value is allocated in 'lp_talloc' context */
 
-char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
-			   const char *separator)
+const char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
+			   const char *separator,char **def)
 {
-	const char *value = get_parametrics(lookup_service, type, option);
-	
-	if (value)
-		return str_list_make(value, separator);
+	param_opt_struct *data = get_parametrics(lookup_service, type, option);
 
-	return NULL;
+	if (data == NULL||data->value==NULL)
+		return (const char **)def;
+		
+	if ((data->list_sep == separator)||
+		(data->list_sep && separator && 
+		 strstr(separator,data->list_sep))) {
+		if (data->list==NULL) {
+			data->list = talloc_str_list_make(data->mem_ctx, data->value, separator);
+			if (separator) {
+				data->list_sep = talloc_strdup(data->mem_ctx, separator);
+			} else {
+				data->list_sep = NULL;	
+			}
+		}
+	} else {
+		data->list = talloc_realloc_str_list_make(data->mem_ctx, data->list,data->value, separator);
+		if (separator) {
+			data->list_sep = talloc_realloc_strdup(data->mem_ctx, data->list_sep, separator);
+		} else {
+			data->list_sep = NULL;	
+		}	
+	}
+
+	return (const char **)data->list;
 }
 
 /* Return parametric option from a given service. Type is a part of option before ':' */
 /* Parametric option has following syntax: 'Type: option = value' */
 
-int lp_parm_int(int lookup_service, const char *type, const char *option)
+int lp_parm_int(int lookup_service, const char *type, const char *option, int def)
 {
-	const char *value = get_parametrics(lookup_service, type, option);
+	param_opt_struct *data = get_parametrics(lookup_service, type, option);
 	
-	if (value)
-		return lp_int(value);
+	if (data && data->value && *data->value)
+		return lp_int(data->value);
 
-	return (-1);
+	return def;
 }
 
 /* Return parametric option from a given service. Type is a part of option before ':' */
 /* Parametric option has following syntax: 'Type: option = value' */
 
-unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option)
+unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long def)
 {
-	const char *value = get_parametrics(lookup_service, type, option);
+	param_opt_struct *data = get_parametrics(lookup_service, type, option);
 	
-	if (value)
-		return lp_ulong(value);
+	if (data && data->value && *data->value)
+		return lp_ulong(data->value);
 
-	return (0);
+	return def;
 }
 
 /* Return parametric option from a given service. Type is a part of option before ':' */
 /* Parametric option has following syntax: 'Type: option = value' */
 
-BOOL lp_parm_bool(int lookup_service, const char *type, const char *option)
+BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL def)
 {
-	const char *value = get_parametrics(lookup_service, type, option);
+	param_opt_struct *data = get_parametrics(lookup_service, type, option);
 	
-	if (value)
-		return lp_bool(value);
+	if (data && data->value && *data->value)
+		return lp_bool(data->value);
 
-	return False;
+	return def;
 }
 
 /* Return parametric option from a given service. Type is a part of option before ':' */
 /* Parametric option has following syntax: 'Type: option = value' */
 
 int lp_parm_enum(int lookup_service, const char *type, const char *option,
-		 const struct enum_list *_enum)
+		 const struct enum_list *_enum, int def)
 {
-	const char *value = get_parametrics(lookup_service, type, option);
+	param_opt_struct *data = get_parametrics(lookup_service, type, option);
 	
-	if (value)
-		return lp_enum(value, _enum);
+	if (data && data->value && *data->value && _enum)
+		return lp_enum(data->value, _enum);
 
-	return (-1);
+	return def;
 }
 
-
 /***************************************************************************
  Initialise a service to the defaults.
 ***************************************************************************/
@@ -2066,15 +2086,14 @@ static void free_service(service *pservi
 			     		    (((char *)pservice) +
 					     PTR_DIFF(parm_table[i].ptr, &sDefault)));
 	}
-				
-	DEBUG(5,("Freeing parametrics:\n"));
+
 	data = pservice->param_opt;
+	if (data)
+		DEBUG(5,("Freeing parametrics:\n"));
 	while (data) {
-		DEBUG(5,("[%s = %s]\n", data->key, data->value));
-		string_free(&data->key);
-		string_free(&data->value);
+		DEBUGADD(5,("[%s = %s]\n", data->key, data->value));
 		pdata = data->next;
-		SAFE_FREE(data);
+		talloc_destroy(data->mem_ctx);
 		data = pdata;
 	}
 
@@ -2103,10 +2122,8 @@ static int add_a_service(const service *
 			/* They will be added during parsing again */
 			data = ServicePtrs[i]->param_opt;
 			while (data) {
-				string_free(&data->key);
-				string_free(&data->value);
 				pdata = data->next;
-				SAFE_FREE(data);
+				talloc_destroy(data->mem_ctx);
 				data = pdata;
 			}
 			ServicePtrs[i]->param_opt = NULL;
@@ -2355,7 +2372,6 @@ static void copy_service(service * pserv
 	int i;
 	BOOL bcopyall = (pcopymapDest == NULL);
 	param_opt_struct *data, *pdata, *paramo;
-	BOOL not_added;
 
 	for (i = 0; parm_table[i].label; i++)
 		if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
@@ -2412,24 +2428,33 @@ static void copy_service(service * pserv
 	
 	data = pserviceSource->param_opt;
 	while (data) {
-		not_added = True;
 		pdata = pserviceDest->param_opt;
 		/* Traverse destination */
 		while (pdata) {
-			/* If we already have same option, override it */
+			/* If we already have same option, remove it */
 			if (strcmp(pdata->key, data->key) == 0) {
-				string_free(&pdata->value);
-				pdata->value = strdup(data->value);
-				not_added = False;
+				DLIST_REMOVE(pserviceDest->param_opt,pdata);
+				talloc_destroy(pdata->mem_ctx);
 				break;
 			}
 			pdata = pdata->next;
 		}
-		if (not_added) {
-		    paramo = smb_xmalloc(sizeof(param_opt_struct));
-		    paramo->key = strdup(data->key);
-		    paramo->value = strdup(data->value);
-		    DLIST_ADD(pserviceDest->param_opt, paramo);
+		{
+			TALLOC_CTX *mem_ctx = NULL;
+			if ((mem_ctx = talloc_init("param options entry"))==NULL) {
+				DEBUG(0,("copy_service: talloc_init failed!\n"));
+				return;
+			}
+			if ((paramo=(param_opt_struct *)talloc(mem_ctx,sizeof(param_opt_struct)))==NULL) {
+				DEBUG(0,("copy_service: talloc failed!\n"));
+				return;
+			}
+			paramo->key = talloc_strdup(mem_ctx,data->key);
+			paramo->value = talloc_strdup(mem_ctx,data->value);
+			paramo->list = NULL;
+			paramo->list_sep = NULL;
+			paramo->mem_ctx = mem_ctx;
+			DLIST_ADD(pserviceDest->param_opt, paramo);
 		}
 		data = data->next;
 	}
@@ -3035,39 +3060,51 @@ BOOL lp_do_parameter(int snum, char *psz
 	pstring vfskey;
 	char *sep;
 	param_opt_struct *paramo, *data;
-	BOOL not_added;
 
 	parmnum = map_parameter(pszParmName);
 
 	if (parmnum < 0) {
 		if ((sep=strchr(pszParmName, ':')) != NULL) {
-			*sep = 0;
+			*sep = '\0';
 			ZERO_STRUCT(vfskey);
 			pstr_sprintf(vfskey, "%s:", pszParmName);
 			slen = strlen(vfskey);
 			safe_strcat(vfskey, sep+1, sizeof(pstring));
 			trim_string(vfskey+slen, " ", " ");
-			not_added = True;
 			data = (snum < 0) ? Globals.param_opt : 
 				ServicePtrs[snum]->param_opt;
 			/* Traverse destination */
 			while (data) {
 				/* If we already have same option, override it */
 				if (strcmp(data->key, vfskey) == 0) {
-					string_free(&data->value);
-					data->value = strdup(pszParmValue);
-					not_added = False;
+					if (snum < 0){
+						DLIST_REMOVE(Globals.param_opt,data);
+					} else {
+						DLIST_REMOVE(ServicePtrs[snum]->param_opt,data);	
+					}
+					talloc_destroy(data->mem_ctx);
 					break;
 				}
 				data = data->next;
 			}
-			if (not_added) {
-				paramo = smb_xmalloc(sizeof(param_opt_struct));
-				paramo->key = strdup(vfskey);
-				paramo->value = strdup(pszParmValue);
-				if (snum < 0) {
+			{
+				TALLOC_CTX *mem_ctx = NULL;
+				if ((mem_ctx = talloc_init("param options entry"))==NULL) {
+					DEBUG(0,("lp_do_parameter: talloc_init failed!\n"));
+					return False;
+				}
+				if ((paramo=(param_opt_struct *)talloc(mem_ctx,sizeof(param_opt_struct)))==NULL) {
+					DEBUG(0,("lp_do_parameter: talloc failed!\n"));
+					return False;
+				}
+				paramo->key = talloc_strdup(mem_ctx,vfskey);
+				paramo->value = talloc_strdup(mem_ctx,pszParmValue);
+				paramo->list = NULL;
+				paramo->list_sep = NULL;
+				paramo->mem_ctx = mem_ctx;
+				if (snum < 0 ) {
 					DLIST_ADD(Globals.param_opt, paramo);
-				} else {
+				} else { 
 					DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
 				}
 			}
@@ -3834,10 +3871,8 @@ BOOL lp_load(const char *pszFname, BOOL 
 	if (Globals.param_opt != NULL) {
 		data = Globals.param_opt;
 		while (data) {
-			string_free(&data->key);
-			string_free(&data->value);
 			pdata = data->next;
-			SAFE_FREE(data);
+			talloc_destroy(data->mem_ctx);
 			data = pdata;
 		}
 		Globals.param_opt = NULL;
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=*.so --exclude=.#* --exclude=Makefile --exclude=stamp-h --exclude=configure --exclude=findsmb --exclude=*proto*.h --exclude=build_env.h --exclude=tdbsam2_parse_info.h --exclude=config.* --exclude=bin --exclude=*.configure HEAD/source/sam/sam_ads.c HEAD-param/source/sam/sam_ads.c
--- HEAD/source/sam/sam_ads.c	Mon Dec 23 08:37:03 2002
+++ HEAD-param/source/sam/sam_ads.c	Mon Dec 30 21:55:39 2002
@@ -1328,10 +1328,10 @@ NTSTATUS sam_init_ads(SAM_METHODS *sam_m
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	sam_ads_state->ads_bind_dn = talloc_strdup(sam_ads_state->mem_ctx, lp_parm_string(NULL,"sam_ads","bind as"));
-	sam_ads_state->ads_bind_pw = talloc_strdup(sam_ads_state->mem_ctx, lp_parm_string(NULL,"sam_ads","bind pw"));
+	sam_ads_state->ads_bind_dn = talloc_strdup(sam_ads_state->mem_ctx, lp_parm_string(-2,"sam_ads","bind as",""));
+	sam_ads_state->ads_bind_pw = talloc_strdup(sam_ads_state->mem_ctx, lp_parm_string(-2,"sam_ads","bind pw",""));
 
-	sam_ads_state->bind_plaintext = strequal(lp_parm_string(NULL, "sam_ads", "plaintext bind"), "yes");
+	sam_ads_state->bind_plaintext = lp_parm_bool(-2, "sam_ads", "plaintext bind",True);
 
 	if (!sam_ads_state->ads_bind_dn || !sam_ads_state->ads_bind_pw) {
 		DEBUG(0, ("talloc_strdup() failed for bind dn or password\n"));


More information about the samba-technical mailing list