summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/lib/util_strlist.c190
-rw-r--r--source4/libads/ldap.c7
-rw-r--r--source4/param/loadparm.c31
-rw-r--r--source4/rpc_server/remote/dcesrv_remote.c8
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;
}