diff options
-rw-r--r-- | source4/lib/util_strlist.c | 190 | ||||
-rw-r--r-- | source4/libads/ldap.c | 7 | ||||
-rw-r--r-- | source4/param/loadparm.c | 31 | ||||
-rw-r--r-- | source4/rpc_server/remote/dcesrv_remote.c | 8 |
4 files changed, 104 insertions, 132 deletions
diff --git a/source4/lib/util_strlist.c b/source4/lib/util_strlist.c index d945c78472..c6ccad907b 100644 --- a/source4/lib/util_strlist.c +++ b/source4/lib/util_strlist.c @@ -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 @@ -21,136 +19,106 @@ */ #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); -} - - - diff --git a/source4/libads/ldap.c b/source4/libads/ldap.c index d63d667777..f760843b59 100644 --- a/source4/libads/ldap.c +++ b/source4/libads/ldap.c @@ -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; diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c index 90f8c682fd..f837545999 100644 --- a/source4/param/loadparm.c +++ b/source4/param/loadparm.c @@ -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: diff --git a/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c index b1e9659198..fc8c8a6706 100644 --- a/source4/rpc_server/remote/dcesrv_remote.c +++ b/source4/rpc_server/remote/dcesrv_remote.c @@ -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; } |