mirror of
https://github.com/samba-team/samba.git
synced 2024-12-25 23:21:54 +03:00
r5221: replace the str_list_*() code with new code based on talloc(). This is
a precursor to adding the wins client code in the nbt server.
This commit is contained in:
parent
d89b493aaf
commit
e8e499755a
@ -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
|
||||
**/
|
||||
|
||||
#define S_LIST_ABS 16 /* List Allocation Block Size */
|
||||
|
||||
char **str_list_make(const char *string, const char *sep)
|
||||
/*
|
||||
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)
|
||||
{
|
||||
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"));
|
||||
int num_elements = 0;
|
||||
char **ret = NULL;
|
||||
|
||||
if (sep == NULL) {
|
||||
sep = LIST_SEP;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
num++;
|
||||
}
|
||||
|
||||
*dest = list;
|
||||
return True;
|
||||
size_t ret;
|
||||
for (ret=0;list && list[ret];ret++) /* noop */ ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/*
|
||||
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;
|
||||
}
|
||||
}
|
||||
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]))
|
||||
return False;
|
||||
}
|
||||
if (list2[num])
|
||||
return False; /* if list2 has more elements than list1 fail */
|
||||
|
||||
for (i=0;list1[i] && list2[i];i++) {
|
||||
if (strcmp(list1[i], list2[i]) != 0) {
|
||||
return False;
|
||||
}
|
||||
}
|
||||
if (list1[i] || list2[i]) {
|
||||
return False;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user