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 <[EMAIL PROTECTED]>
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"));


Reply via email to