r5221: replace the str_list_*() code with new code based on talloc(). This is
authorAndrew Tridgell <tridge@samba.org>
Fri, 4 Feb 2005 04:58:48 +0000 (04:58 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:09:32 +0000 (13:09 -0500)
a precursor to adding the wins client code in the nbt server.

source/lib/util_strlist.c
source/libads/ldap.c
source/param/loadparm.c
source/rpc_server/remote/dcesrv_remote.c

index d945c78472cbbca0fd54ed1a99ffe4b1722a0296..c6ccad907bb4bf5f73172758fafbf56a61c79dfd 100644 (file)
@@ -1,9 +1,7 @@
 /* 
    Unix SMB/CIFS implementation.
    
-   Copyright (C) Andrew Tridgell 1992-2004
-   Copyright (C) Simo Sorce      2001-2002
-   Copyright (C) Martin Pool     2003
+   Copyright (C) Andrew Tridgell 2005
    
    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
 */
 
 #include "includes.h"
-#include "system/network.h"
 
-/**
- List of Strings manipulation functions
-**/
+/*
+  build a null terminated list of strings from a input string and a
+  separator list. The sepatator list must contain characters less than
+  or equal to 0x2f for this to work correctly on multi-byte strings
+*/
+char **str_list_make(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
+{
+       int num_elements = 0;
+       char **ret = NULL;
 
-#define S_LIST_ABS 16 /* List Allocation Block Size */
+       if (sep == NULL) {
+               sep = LIST_SEP;
+       }
 
-char **str_list_make(const char *string, const char *sep)
-{
-       char **list, **rlist;
-       const char *str;
-       char *s;
-       int num, lsize;
-       pstring tok;
-       
-       if (!string || !*string)
-               return NULL;
-       s = strdup(string);
-       if (!s) {
-               DEBUG(0,("str_list_make: Unable to allocate memory"));
+       ret = talloc_realloc(mem_ctx, NULL, char *, 1);
+       if (ret == NULL) {
                return NULL;
        }
-       if (!sep) sep = LIST_SEP;
-       
-       num = lsize = 0;
-       list = NULL;
-       
-       str = s;
-       while (next_token(&str, tok, sep, sizeof(tok))) {               
-               if (num == lsize) {
-                       lsize += S_LIST_ABS;
-                       rlist = realloc_p(list, char *, lsize + 1);
-                       if (!rlist) {
-                               DEBUG(0,("str_list_make: Unable to allocate memory"));
-                               str_list_free(&list);
-                               SAFE_FREE(s);
-                               return NULL;
-                       } else
-                               list = rlist;
-                       memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
-               }
+
+       while (string && *string) {
+               size_t len = strcspn(string, sep);
+               char **ret2;
                
-               list[num] = strdup(tok);
-               if (!list[num]) {
-                       DEBUG(0,("str_list_make: Unable to allocate memory"));
-                       str_list_free(&list);
-                       SAFE_FREE(s);
+               if (len == 0) {
+                       string += strspn(string, sep);
+                       continue;
+               }
+
+               ret2 = talloc_realloc(mem_ctx, ret, char *, num_elements+2);
+               if (ret2 == NULL) {
+                       talloc_free(ret);
                        return NULL;
                }
-       
-               num++;  
+               ret = ret2;
+
+               ret[num_elements] = talloc_strndup(ret, string, len);
+               if (ret[num_elements] == NULL) {
+                       talloc_free(ret);
+                       return NULL;
+               }
+
+               num_elements++;
+               string += len;
        }
-       
-       SAFE_FREE(s);
-       return list;
+
+       ret[num_elements] = NULL;
+
+       return ret;
 }
 
-BOOL str_list_copy(char ***dest, const char **src)
+/*
+  return the number of elements in a string list
+*/
+size_t str_list_length(const char **list)
 {
-       char **list, **rlist;
-       int num, lsize;
-       
-       *dest = NULL;
-       if (!src)
-               return False;
-       
-       num = lsize = 0;
-       list = NULL;
-               
-       while (src[num]) {
-               if (num == lsize) {
-                       lsize += S_LIST_ABS;
-                       rlist = realloc_p(list, char *, lsize + 1);
-                       if (!rlist) {
-                               DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
-                               str_list_free(&list);
-                               return False;
-                       } else
-                               list = rlist;
-                       memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
-               }
-               
-               list[num] = strdup(src[num]);
-               if (!list[num]) {
-                       DEBUG(0,("str_list_copy: Unable to allocate memory"));
-                       str_list_free(&list);
-                       return False;
-               }
+       size_t ret;
+       for (ret=0;list && list[ret];ret++) /* noop */ ;
+       return ret;
+}
+
 
-               num++;
+/*
+  copy a string list
+*/
+char **str_list_copy(TALLOC_CTX *mem_ctx, const char **list)
+{
+       int i;
+       char **ret = talloc_array(mem_ctx, char *, str_list_length(list)+1);
+       if (ret == NULL) return NULL;
+
+       for (i=0;list && list[i];i++) {
+               ret[i] = talloc_strdup(ret, list[i]);
+               if (ret[i] == NULL) {
+                       talloc_free(ret);
+                       return NULL;
+               }
        }
-       
-       *dest = list;
-       return True;    
+       ret[i] = NULL;
+       return ret;
 }
 
-/**
+/*
    Return true if all the elements of the list match exactly.
- **/
-BOOL str_list_compare(char **list1, char **list2)
+ */
+BOOL str_list_equal(const char **list1, const char **list2)
 {
-       int num;
+       int i;
        
-       if (!list1 || !list2)
+       if (list1 == NULL || list2 == NULL) {
                return (list1 == list2); 
+       }
        
-       for (num = 0; list1[num]; num++) {
-               if (!list2[num])
-                       return False;
-               if (!strcsequal(list1[num], list2[num]))
+       for (i=0;list1[i] && list2[i];i++) {
+               if (strcmp(list1[i], list2[i]) != 0) {
                        return False;
+               }
+       }
+       if (list1[i] || list2[i]) {
+               return False;
        }
-       if (list2[num])
-               return False; /* if list2 has more elements than list1 fail */
-       
        return True;
 }
-
-void str_list_free(char ***list)
-{
-       char **tlist;
-       
-       if (!list || !*list)
-               return;
-       tlist = *list;
-       for(; *tlist; tlist++)
-               SAFE_FREE(*tlist);
-       SAFE_FREE(*list);
-}
-
-
-
index d63d667777d8ee236a0c058608024644011a0088..f760843b59698769da51e76fd936423d63560a5e 100644 (file)
@@ -391,7 +391,8 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path,
        else {
                /* This would be the utf8-encoded version...*/
                /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */
-               if (!(str_list_copy(&search_attrs, attrs))) {
+               search_attrs = str_list_copy(ctx, attrs);
+               if (search_attrs == NULL) {
                        rc = LDAP_NO_MEMORY;
                        goto done;
                }
@@ -616,8 +617,8 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope,
        else {
                /* This would be the utf8-encoded version...*/
                /* if (!(search_attrs = ads_push_strvals(ctx, attrs)))  */
-               if (!(str_list_copy(&search_attrs, attrs)))
-               {
+               search_attrs = str_list_copy(ctx, attrs);
+               if (search_attrs == NULL) {
                        DEBUG(1,("ads_do_search: str_list_copy() failed!"));
                        rc = LDAP_NO_MEMORY;
                        goto done;
index 90f8c682fde7e7c6cc782928096ba3f54e8b4b8e..f83754599997d244fd0c117196ef9cc0f9871336 100644 (file)
@@ -1437,7 +1437,7 @@ char **lp_parm_string_list(int lookup_service, const char *type, const char *opt
        const char *value = get_parametrics(lookup_service, type, option);
        
        if (value)
-               return str_list_make(value, separator);
+               return str_list_make(NULL, value, separator);
 
        return NULL;
 }
@@ -1513,15 +1513,17 @@ static void free_service(service *pservice)
        for (i = 0; parm_table[i].label; i++) {
                if ((parm_table[i].type == P_STRING ||
                     parm_table[i].type == P_USTRING) &&
-                   parm_table[i].class == P_LOCAL)
+                   parm_table[i].class == P_LOCAL) {
                        string_free((char **)
                                    (((char *)pservice) +
                                     PTR_DIFF(parm_table[i].ptr, &sDefault)));
-               else if (parm_table[i].type == P_LIST &&
-                        parm_table[i].class == P_LOCAL)
-                            str_list_free((char ***)
-                                           (((char *)pservice) +
-                                            PTR_DIFF(parm_table[i].ptr, &sDefault)));
+               } else if (parm_table[i].type == P_LIST &&
+                          parm_table[i].class == P_LOCAL) {
+                       char ***listp = (char ***)(((char *)pservice) + 
+                                                  PTR_DIFF(parm_table[i].ptr, &sDefault));
+                       talloc_free(*listp);
+                       *listp = NULL;
+               }
        }
                                
        DEBUG(5,("Freeing parametrics:\n"));
@@ -1853,7 +1855,7 @@ static void copy_service(service * pserviceDest, service * pserviceSource, BOOL
                                        strupper(*(char **)dest_ptr);
                                        break;
                                case P_LIST:
-                                       str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
+                                       *(char ***)dest_ptr = str_list_copy(NULL, *(const char ***)src_ptr);
                                        break;
                                default:
                                        break;
@@ -2365,7 +2367,7 @@ BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
                        break;
 
                case P_LIST:
-                       *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
+                       *(char ***)parm_ptr = str_list_make(NULL, pszParmValue, NULL);
                        break;
 
                case P_STRING:
@@ -2588,7 +2590,8 @@ static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
                        return (*((char *)ptr1) == *((char *)ptr2));
                
                case P_LIST:
-                       return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
+                       return str_list_equal((const char **)(*(char ***)ptr1), 
+                                             (const char **)(*(char ***)ptr2));
 
                case P_STRING:
                case P_USTRING:
@@ -2664,8 +2667,8 @@ static BOOL is_default(int i)
                return False;
        switch (parm_table[i].type) {
                case P_LIST:
-                       return str_list_compare (parm_table[i].def.lvalue, 
-                                               *(char ***)parm_table[i].ptr);
+                       return str_list_equal((const char **)parm_table[i].def.lvalue, 
+                                             (const char **)(*(char ***)parm_table[i].ptr));
                case P_STRING:
                case P_USTRING:
                        return strequal(parm_table[i].def.svalue,
@@ -2922,8 +2925,8 @@ static void lp_save_defaults(void)
                        continue;
                switch (parm_table[i].type) {
                        case P_LIST:
-                               str_list_copy(&(parm_table[i].def.lvalue),
-                                           *(const char ***)parm_table[i].ptr);
+                               parm_table[i].def.lvalue = str_list_copy(NULL, 
+                                                                        *(const char ***)parm_table[i].ptr);
                                break;
                        case P_STRING:
                        case P_USTRING:
index b1e96591985c03698d544ca77ec950e6d192d240..fc8c8a670608ea8e5c4951c3289dcebbeed00512 100644 (file)
@@ -164,7 +164,7 @@ static NTSTATUS remote_register_one_iface(struct dcesrv_context *dce_ctx, const
 static NTSTATUS remote_op_init_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server)
 {
        int i;
-       char **ifaces = str_list_make(lp_parm_string(-1,"dcerpc_remote","interfaces"),NULL);
+       char **ifaces = str_list_make(dce_ctx, lp_parm_string(-1,"dcerpc_remote","interfaces"),NULL);
 
        if (!ifaces) {
                DEBUG(3,("remote_op_init_server: no interfaces configured\n"));
@@ -177,19 +177,19 @@ static NTSTATUS remote_op_init_server(struct dcesrv_context *dce_ctx, const stru
                
                if (!ep_server->interface_by_name(&iface, ifaces[i])) {
                        DEBUG(0,("remote_op_init_server: failed to find interface = '%s'\n", ifaces[i]));
-                       str_list_free(&ifaces);
+                       talloc_free(ifaces);
                        return NT_STATUS_UNSUCCESSFUL;
                }
 
                ret = remote_register_one_iface(dce_ctx, &iface);
                if (!NT_STATUS_IS_OK(ret)) {
                        DEBUG(0,("remote_op_init_server: failed to register interface = '%s'\n", ifaces[i]));
-                       str_list_free(&ifaces);
+                       talloc_free(ifaces);
                        return ret;
                }
        }
 
-       str_list_free(&ifaces);
+       talloc_free(ifaces);
        return NT_STATUS_OK;
 }