summaryrefslogtreecommitdiffstats
path: root/source/lib
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2007-09-27 22:50:48 +0000
committerGerald Carter <jerry@samba.org>2007-09-27 22:50:48 +0000
commit1a6570fce8f96fca00f557ecb0d9b14528b1faf9 (patch)
treefced4d31f98c2f0c876fe3c5e9cf3976b063bea4 /source/lib
parent39c8e7b8485f7f0e14d79aced523711ea9f4e55e (diff)
downloadsamba-1a6570fce8f96fca00f557ecb0d9b14528b1faf9.tar.gz
samba-1a6570fce8f96fca00f557ecb0d9b14528b1faf9.tar.xz
samba-1a6570fce8f96fca00f557ecb0d9b14528b1faf9.zip
r25387: Sync with 3.2.0 svn tree
Diffstat (limited to 'source/lib')
-rw-r--r--source/lib/adt_tree.c52
-rw-r--r--source/lib/charcnv.c251
-rw-r--r--source/lib/ctdbd_conn.c2
-rw-r--r--source/lib/events.c5
-rw-r--r--source/lib/fault.c8
-rw-r--r--source/lib/module.c47
-rw-r--r--source/lib/ms_fnmatch.c43
-rw-r--r--source/lib/replace/dlfcn.m42
-rw-r--r--source/lib/replace/libreplace.m412
-rw-r--r--source/lib/replace/replace.h77
-rw-r--r--source/lib/replace/system/network.h8
-rw-r--r--source/lib/replace/test/testsuite.c2
-rw-r--r--source/lib/smbrun.c28
-rw-r--r--source/lib/system.c176
-rw-r--r--source/lib/talloc/configure.ac2
-rw-r--r--source/lib/talloc/talloc.c239
-rw-r--r--source/lib/talloc/talloc.h24
-rw-r--r--source/lib/talloc/talloc_guide.txt19
-rw-r--r--source/lib/talloc/testsuite.c48
-rw-r--r--source/lib/util.c16
-rw-r--r--source/lib/util_str.c241
-rw-r--r--source/lib/util_unistr.c4
22 files changed, 794 insertions, 512 deletions
diff --git a/source/lib/adt_tree.c b/source/lib/adt_tree.c
index f26f924d61f..cf305d7307e 100644
--- a/source/lib/adt_tree.c
+++ b/source/lib/adt_tree.c
@@ -278,31 +278,41 @@ done:
Recursive routine to print out all children of a TREE_NODE
*************************************************************************/
-static void pathtree_print_children( TREE_NODE *node, int debug, const char *path )
+static void pathtree_print_children(TALLOC_CTX *ctx,
+ TREE_NODE *node,
+ int debug,
+ const char *path )
{
int i;
int num_children;
- pstring path2;
-
+ char *path2 = NULL;
+
if ( !node )
return;
-
-
+
if ( node->key )
DEBUG(debug,("%s: [%s] (%s)\n", path ? path : "NULL", node->key,
node->data_p ? "data" : "NULL" ));
- *path2 = '\0';
- if ( path )
- pstrcpy( path2, path );
- pstrcat( path2, node->key ? node->key : "NULL" );
- pstrcat( path2, "/" );
-
- num_children = node->num_children;
- for ( i=0; i<num_children; i++ )
- pathtree_print_children( node->children[i], debug, path2 );
-
+ if ( path ) {
+ path2 = talloc_strdup(ctx, path);
+ if (!path2) {
+ return;
+ }
+ }
+
+ path2 = talloc_asprintf(ctx,
+ "%s%s/",
+ path ? path : "",
+ node->key ? node->key : "NULL");
+ if (!path2) {
+ return;
+ }
+ num_children = node->num_children;
+ for ( i=0; i<num_children; i++ ) {
+ pathtree_print_children(ctx, node->children[i], debug, path2 );
+ }
}
/**************************************************************************
@@ -313,21 +323,23 @@ static void pathtree_print_children( TREE_NODE *node, int debug, const char *pat
{
int i;
int num_children = tree->root->num_children;
-
+
if ( tree->root->key )
DEBUG(debug,("ROOT/: [%s] (%s)\n", tree->root->key,
tree->root->data_p ? "data" : "NULL" ));
-
+
for ( i=0; i<num_children; i++ ) {
- pathtree_print_children( tree->root->children[i], debug,
+ TALLOC_CTX *ctx = talloc_stackframe();
+ pathtree_print_children(ctx, tree->root->children[i], debug,
tree->root->key ? tree->root->key : "ROOT/" );
+ TALLOC_FREE(ctx);
}
-
+
}
/**************************************************************************
return the data_p for for the node in tree matching the key string
- The key string is the full path. We must break it apart and walk
+ The key string is the full path. We must break it apart and walk
the tree
*************************************************************************/
diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c
index 349fbff8506..b1e3d3bdcfb 100644
--- a/source/lib/charcnv.c
+++ b/source/lib/charcnv.c
@@ -745,7 +745,7 @@ size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
size = push_ucs2_allocate(&buffer, src);
if (size == (size_t)-1) {
- smb_panic("failed to create UCS2 buffer");
+ return (size_t)-1;
}
if (!strupper_w(buffer) && (dest == src)) {
free(buffer);
@@ -759,49 +759,131 @@ size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
/**
strdup() a unix string to upper case.
- Max size is pstring.
**/
char *strdup_upper(const char *s)
{
- pstring out_buffer;
+ char *out_buffer = SMB_STRDUP(s);
const unsigned char *p = (const unsigned char *)s;
unsigned char *q = (unsigned char *)out_buffer;
+ if (!q) {
+ return NULL;
+ }
+
/* this is quite a common operation, so we want it to be
fast. We optimise for the ascii case, knowing that all our
supported multi-byte character sets are ascii-compatible
(ie. they match for the first 128 chars) */
- while (1) {
+ while (*p) {
if (*p & 0x80)
break;
*q++ = toupper_ascii(*p);
- if (!*p)
- break;
p++;
- if (p - ( const unsigned char *)s >= sizeof(pstring))
- break;
}
if (*p) {
/* MB case. */
size_t size;
- wpstring buffer;
- size = convert_string(CH_UNIX, CH_UTF16LE, s, -1, buffer, sizeof(buffer), True);
+ smb_ucs2_t *buffer = NULL;
+
+ SAFE_FREE(out_buffer);
+ size = convert_string_allocate(NULL,
+ CH_UNIX,
+ CH_UTF16LE,
+ s,
+ strlen(s) + 1,
+ (void **)(void *)&buffer,
+ True);
if (size == (size_t)-1) {
return NULL;
}
strupper_w(buffer);
- size = convert_string(CH_UTF16LE, CH_UNIX, buffer, -1, out_buffer, sizeof(out_buffer), True);
+ size = convert_string_allocate(NULL,
+ CH_UTF16LE,
+ CH_UNIX,
+ buffer,
+ size,
+ (void **)(void *)&out_buffer,
+ True);
+
+ /* Don't need the intermediate buffer
+ * anymore.
+ */
+
+ TALLOC_FREE(buffer);
+ if (size == (size_t)-1) {
+ return NULL;
+ }
+ }
+
+ return out_buffer;
+}
+
+/**
+ talloc_strdup() a unix string to upper case.
+**/
+
+char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *s)
+{
+ char *out_buffer = talloc_strdup(ctx,s);
+ const unsigned char *p = (const unsigned char *)s;
+ unsigned char *q = (unsigned char *)out_buffer;
+
+ if (!q) {
+ return NULL;
+ }
+
+ /* this is quite a common operation, so we want it to be
+ fast. We optimise for the ascii case, knowing that all our
+ supported multi-byte character sets are ascii-compatible
+ (ie. they match for the first 128 chars) */
+
+ while (*p) {
+ if (*p & 0x80)
+ break;
+ *q++ = toupper_ascii(*p);
+ p++;
+ }
+
+ if (*p) {
+ /* MB case. */
+ size_t size;
+ smb_ucs2_t *ubuf = NULL;
+
+ /* We're not using the ascii buffer above. */
+ TALLOC_FREE(out_buffer);
+
+ size = convert_string_talloc(ctx, CH_UNIX, CH_UTF16LE,
+ s, strlen(s)+1,
+ (void *)&ubuf,
+ True);
+ if (size == (size_t)-1) {
+ return NULL;
+ }
+
+ strupper_w(ubuf);
+
+ size = convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX,
+ ubuf, size,
+ (void *)&out_buffer,
+ True);
+
+ /* Don't need the intermediate buffer
+ * anymore.
+ */
+
+ TALLOC_FREE(ubuf);
+
if (size == (size_t)-1) {
return NULL;
}
}
- return SMB_STRDUP(out_buffer);
+ return out_buffer;
}
size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
@@ -870,27 +952,40 @@ static size_t ucs2_align(const void *base_ptr, const void *p, int flags)
* </dl>
*
* @param dest_len the maximum length in bytes allowed in the
- * destination. If @p dest_len is -1 then no maximum is used.
+ * destination.
**/
size_t push_ascii(void *dest, const char *src, size_t dest_len, int flags)
{
size_t src_len = strlen(src);
- pstring tmpbuf;
+ char *tmpbuf = NULL;
+ size_t ret;
- /* treat a pstring as "unlimited" length */
- if (dest_len == (size_t)-1)
- dest_len = sizeof(pstring);
+ /* No longer allow a length of -1. */
+ if (dest_len == (size_t)-1) {
+ smb_panic("push_ascii - dest_len == -1");
+ }
if (flags & STR_UPPER) {
- pstrcpy(tmpbuf, src);
+ tmpbuf = SMB_STRDUP(src);
+ if (!tmpbuf) {
+ smb_panic("malloc fail");
+ }
strupper_m(tmpbuf);
src = tmpbuf;
}
- if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII))
+ if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII)) {
src_len++;
+ }
- return convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len, True);
+ ret = convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len, True);
+ if (ret == (size_t)-1 &&
+ (flags & (STR_TERMINATE | STR_TERMINATE_ASCII))
+ && dest_len > 0) {
+ ((char *)dest)[0] = '\0';
+ }
+ SAFE_FREE(tmpbuf);
+ return ret;
}
size_t push_ascii_fstring(void *dest, const char *src)
@@ -942,6 +1037,18 @@ size_t push_ascii_nstring(void *dest, const char *src)
return dest_len;
}
+/********************************************************************
+ Push and malloc an ascii string. src and dest null terminated.
+********************************************************************/
+
+size_t push_ascii_allocate(char **dest, const char *src)
+{
+ size_t src_len = strlen(src)+1;
+
+ *dest = NULL;
+ return convert_string_allocate(NULL, CH_UNIX, CH_DOS, src, src_len, (void **)dest, True);
+}
+
/**
* Copy a string from a dos codepage source to a unix char* destination.
*
@@ -961,8 +1068,10 @@ size_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t src_len,
{
size_t ret;
- if (dest_len == (size_t)-1)
- dest_len = sizeof(pstring);
+ if (dest_len == (size_t)-1) {
+ /* No longer allow dest_len of -1. */
+ smb_panic("pull_ascii - invalid dest_len of -1");
+ }
if (flags & STR_TERMINATE) {
if (src_len == (size_t)-1) {
@@ -1041,7 +1150,11 @@ static size_t pull_ascii_base_talloc(TALLOC_CTX *ctx,
}
/* Ensure we don't use an insane length from the client. */
if (src_len >= 1024*1024) {
- smb_panic("Bad src length in pull_ascii_base_talloc\n");
+ char *msg = talloc_asprintf(ctx,
+ "Bad src length (%u) in "
+ "pull_ascii_base_talloc",
+ (unsigned int)src_len);
+ smb_panic(msg);
}
}
@@ -1054,7 +1167,7 @@ static size_t pull_ascii_base_talloc(TALLOC_CTX *ctx,
True);
if (dest_len == (size_t)-1) {
- return 0;
+ dest_len = 0;
}
if (dest_len && dest) {
@@ -1102,7 +1215,7 @@ size_t pull_ascii_nstring(char *dest, size_t dest_len, const void *src)
* </dl>
*
* @param dest_len is the maximum length allowed in the
- * destination. If dest_len is -1 then no maxiumum is used.
+ * destination.
**/
size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags)
@@ -1111,9 +1224,10 @@ size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_
size_t src_len;
size_t ret;
- /* treat a pstring as "unlimited" length */
- if (dest_len == (size_t)-1)
- dest_len = sizeof(pstring);
+ if (dest_len == (size_t)-1) {
+ /* No longer allow dest_len of -1. */
+ smb_panic("push_ucs2 - invalid dest_len of -1");
+ }
if (flags & STR_TERMINATE)
src_len = (size_t)-1;
@@ -1133,7 +1247,12 @@ size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_
ret = convert_string(CH_UNIX, CH_UTF16LE, src, src_len, dest, dest_len, True);
if (ret == (size_t)-1) {
- return 0;
+ if ((flags & STR_TERMINATE) &&
+ dest &&
+ dest_len) {
+ *(char *)dest = 0;
+ }
+ return len;
}
len += ret;
@@ -1204,23 +1323,32 @@ size_t push_ucs2_allocate(smb_ucs2_t **dest, const char *src)
static size_t push_utf8(void *dest, const char *src, size_t dest_len, int flags)
{
- size_t src_len = strlen(src);
- pstring tmpbuf;
+ size_t src_len = 0;
+ size_t ret;
+ char *tmpbuf = NULL;
- /* treat a pstring as "unlimited" length */
- if (dest_len == (size_t)-1)
- dest_len = sizeof(pstring);
+ if (dest_len == (size_t)-1) {
+ /* No longer allow dest_len of -1. */
+ smb_panic("push_utf8 - invalid dest_len of -1");
+ }
if (flags & STR_UPPER) {
- pstrcpy(tmpbuf, src);
- strupper_m(tmpbuf);
+ tmpbuf = strdup_upper(src);
+ if (!tmpbuf) {
+ return (size_t)-1;
+ }
src = tmpbuf;
+ src_len = strlen(src);
}
- if (flags & STR_TERMINATE)
+ src_len = strlen(src);
+ if (flags & STR_TERMINATE) {
src_len++;
+ }
- return convert_string(CH_UNIX, CH_UTF8, src, src_len, dest, dest_len, True);
+ ret = convert_string(CH_UNIX, CH_UTF8, src, src_len, dest, dest_len, True);
+ SAFE_FREE(tmpbuf);
+ return ret;
}
size_t push_utf8_fstring(void *dest, const char *src)
@@ -1275,8 +1403,17 @@ size_t pull_ucs2(const void *base_ptr, char *dest, const void *src, size_t dest_
{
size_t ret;
- if (dest_len == (size_t)-1)
- dest_len = sizeof(pstring);
+ if (dest_len == (size_t)-1) {
+ /* No longer allow dest_len of -1. */
+ smb_panic("pull_ucs2 - invalid dest_len of -1");
+ }
+
+ if (!src_len) {
+ if (dest && dest_len > 0) {
+ dest[0] = '\0';
+ }
+ return 0;
+ }
if (ucs2_align(base_ptr, src, flags)) {
src = (const void *)((const char *)src + 1);
@@ -1301,7 +1438,8 @@ size_t pull_ucs2(const void *base_ptr, char *dest, const void *src, size_t dest_
ret = convert_string(CH_UTF16LE, CH_UNIX, src, src_len, dest, dest_len, True);
if (ret == (size_t)-1) {
- return 0;
+ ret = 0;
+ dest_len = 0;
}
if (src_len == (size_t)-1)
@@ -1352,6 +1490,10 @@ static size_t pull_ucs2_base_talloc(TALLOC_CTX *ctx,
}
#endif
+ if (!src_len) {
+ return 0;
+ }
+
if (ucs2_align(base_ptr, src, flags)) {
src = (const void *)((const char *)src + 1);
if (src_len != (size_t)-1)
@@ -1386,7 +1528,7 @@ static size_t pull_ucs2_base_talloc(TALLOC_CTX *ctx,
(void *)&dest,
True);
if (dest_len == (size_t)-1) {
- return 0;
+ dest_len = 0;
}
if (src_len == (size_t)-1)
@@ -1395,7 +1537,21 @@ static size_t pull_ucs2_base_talloc(TALLOC_CTX *ctx,
if (dest_len) {
/* Did we already process the terminating zero ? */
if (dest[dest_len-1] != 0) {
- dest[dest_len-1] = 0;
+ size_t size = talloc_get_size(dest);
+ /* Have we got space to append the '\0' ? */
+ if (size <= dest_len) {
+ /* No, realloc. */
+ dest = TALLOC_REALLOC_ARRAY(ctx, dest, char,
+ dest_len+1);
+ if (!dest) {
+ /* talloc fail. */
+ dest_len = (size_t)-1;
+ return 0;
+ }
+ }
+ /* Yay - space ! */
+ dest[dest_len] = '\0';
+ dest_len++;
}
} else if (dest) {
dest[0] = 0;
@@ -1517,11 +1673,9 @@ size_t push_string_fn(const char *function, unsigned int line,
* JRA.
*/
#if 0
- if (dest_len != (size_t)-1)
- clobber_region(function, line, dest, dest_len);
+ clobber_region(function, line, dest, dest_len);
#else
- if (dest_len != (size_t)-1)
- memset(dest, '\0', dest_len);
+ memset(dest, '\0', dest_len);
#endif
#endif
@@ -1554,8 +1708,7 @@ size_t pull_string_fn(const char *function, unsigned int line,
int flags)
{
#ifdef DEVELOPER
- if (dest_len != (size_t)-1)
- clobber_region(function, line, dest, dest_len);
+ clobber_region(function, line, dest, dest_len);
#endif
if ((base_ptr == NULL) && ((flags & (STR_ASCII|STR_UNICODE)) == 0)) {
diff --git a/source/lib/ctdbd_conn.c b/source/lib/ctdbd_conn.c
index f56520b4a36..08ab256accf 100644
--- a/source/lib/ctdbd_conn.c
+++ b/source/lib/ctdbd_conn.c
@@ -95,7 +95,7 @@ static NTSTATUS get_cluster_vnn(struct ctdbd_connection *conn, uint32 *vnn)
int32_t cstatus=-1;
NTSTATUS status;
status = ctdbd_control(conn,
- CTDB_CURRENT_NODE, CTDB_CONTROL_GET_VNN, 0,
+ CTDB_CURRENT_NODE, CTDB_CONTROL_GET_PNN, 0,
tdb_null, NULL, NULL, &cstatus);
if (!NT_STATUS_IS_OK(status)) {
cluster_fatal("ctdbd_control failed\n");
diff --git a/source/lib/events.c b/source/lib/events.c
index e915777217b..befab3f5c00 100644
--- a/source/lib/events.c
+++ b/source/lib/events.c
@@ -409,10 +409,11 @@ void dump_event_list(struct event_context *event_ctx)
evt = timeval_until(&now, &te->when);
- DEBUGADD(10,("Timed Event \"%s\" %lx handled in %d seconds\n",
+ DEBUGADD(10,("Timed Event \"%s\" %lx handled in %d seconds (at %s)\n",
te->event_name,
(unsigned long)te,
- (int)evt.tv_sec));
+ (int)evt.tv_sec,
+ http_timestring(te->when.tv_sec)));
}
for (fe = event_ctx->fd_events; fe; fe = fe->next) {
diff --git a/source/lib/fault.c b/source/lib/fault.c
index 3ddb88edc75..6ab1a079006 100644
--- a/source/lib/fault.c
+++ b/source/lib/fault.c
@@ -150,6 +150,14 @@ void dump_core_setup(const char *progname)
void dump_core(void)
{
+ static bool called;
+
+ if (called) {
+ DEBUG(0, ("dump_core() called recursive\n"));
+ exit(1);
+ }
+ called = true;
+
/* Note that even if core dumping has been disabled, we still set up
* the core path. This is to handle the case where core dumping is
* turned on in smb.conf and the relevant daemon is not restarted.
diff --git a/source/lib/module.c b/source/lib/module.c
index 1bf305ea3f7..57b4c38edc9 100644
--- a/source/lib/module.c
+++ b/source/lib/module.c
@@ -76,7 +76,7 @@ NTSTATUS smb_load_module(const char *module_name)
return do_smb_load_module(module_name, False);
}
-/* Load all modules in list and return number of
+/* Load all modules in list and return number of
* modules that has been successfully loaded */
int smb_load_modules(const char **modules)
{
@@ -96,28 +96,41 @@ int smb_load_modules(const char **modules)
NTSTATUS smb_probe_module(const char *subsystem, const char *module)
{
- pstring full_path;
-
+ char *full_path = NULL;
+ TALLOC_CTX *ctx = talloc_stackframe();
+ NTSTATUS status;
+
/* Check for absolute path */
- /* if we make any 'samba multibyte string'
- calls here, we break
+ /* if we make any 'samba multibyte string'
+ calls here, we break
for loading string modules */
DEBUG(5, ("Probing module '%s'\n", module));
- if (module[0] == '/')
- return do_smb_load_module(module, True);
-
- pstrcpy(full_path, lib_path(subsystem));
- pstrcat(full_path, "/");
- pstrcat(full_path, module);
- pstrcat(full_path, ".");
- pstrcat(full_path, shlib_ext());
-
- DEBUG(5, ("Probing module '%s': Trying to load from %s\n", module, full_path));
-
- return do_smb_load_module(full_path, True);
+ if (module[0] == '/') {
+ status = do_smb_load_module(module, True);
+ TALLOC_FREE(ctx);
+ return status;
+ }
+
+ full_path = talloc_asprintf(ctx,
+ "%s/%s.%s",
+ lib_path(subsystem),
+ module,
+ shlib_ext());
+ if (!full_path) {
+ TALLOC_FREE(ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ DEBUG(5, ("Probing module '%s': Trying to load from %s\n",
+ module, full_path));
+
+ status = do_smb_load_module(full_path, True);
+
+ TALLOC_FREE(ctx);
+ return status;
}
#else /* HAVE_DLOPEN */
diff --git a/source/lib/ms_fnmatch.c b/source/lib/ms_fnmatch.c
index bdfaca143cf..9dc942c5f2e 100644
--- a/source/lib/ms_fnmatch.c
+++ b/source/lib/ms_fnmatch.c
@@ -1,4 +1,4 @@
-/*
+/*
Unix SMB/CIFS implementation.
filename matching routine
Copyright (C) Andrew Tridgell 1992-2004
@@ -7,21 +7,21 @@
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
This module was originally based on fnmatch.c copyright by the Free
Software Foundation. It bears little (if any) resemblence to that
code now
-*/
+*/
#include "includes.h"
@@ -53,7 +53,7 @@ struct max_n {
an optimisation only. The ldot pointer is NULL if the string does
not contain a '.', otherwise it points at the last dot in 'n'.
*/
-static int ms_fnmatch_core(const smb_ucs2_t *p, const smb_ucs2_t *n,
+static int ms_fnmatch_core(const smb_ucs2_t *p, const smb_ucs2_t *n,
struct max_n *max_n, const smb_ucs2_t *ldot,
BOOL is_case_sensitive)
{
@@ -137,22 +137,23 @@ static int ms_fnmatch_core(const smb_ucs2_t *p, const smb_ucs2_t *n,
break;
}
}
-
+
if (! *n) {
return 0;
}
-
+
return -1;
}
int ms_fnmatch(const char *pattern, const char *string, BOOL translate_pattern,
BOOL is_case_sensitive)
{
- wpstring p, s;
+ smb_ucs2_t *p = NULL;
+ smb_ucs2_t *s = NULL;
int ret, count, i;
struct max_n *max_n = NULL;
- if (strcmp(string, "..") == 0) {
+ if (ISDOTDOT(string)) {
string = ".";
}
@@ -166,15 +167,12 @@ int ms_fnmatch(const char *pattern, const char *string, BOOL translate_pattern,
}
}
- if (push_ucs2(NULL, p, pattern, sizeof(p), STR_TERMINATE) == (size_t)-1) {
- /* Not quite the right answer, but finding the right one
- under this failure case is expensive, and it's pretty close */
+ if (push_ucs2_allocate(&p, pattern) == (size_t)-1) {
return -1;
}
- if (push_ucs2(NULL, s, string, sizeof(s), STR_TERMINATE) == (size_t)-1) {
- /* Not quite the right answer, but finding the right one
- under this failure case is expensive, and it's pretty close */
+ if (push_ucs2_allocate(&s, string) == (size_t)-1) {
+ SAFE_FREE(p);
return -1;
}
@@ -187,8 +185,8 @@ int ms_fnmatch(const char *pattern, const char *string, BOOL translate_pattern,
for (i=0;p[i];i++) {
if (p[i] == UCS2_CHAR('?')) {
p[i] = UCS2_CHAR('>');
- } else if (p[i] == UCS2_CHAR('.') &&
- (p[i+1] == UCS2_CHAR('?') ||
+ } else if (p[i] == UCS2_CHAR('.') &&
+ (p[i+1] == UCS2_CHAR('?') ||
p[i+1] == UCS2_CHAR('*') ||
p[i+1] == 0)) {
p[i] = UCS2_CHAR('"');
@@ -205,16 +203,17 @@ int ms_fnmatch(const char *pattern, const char *string, BOOL translate_pattern,
if (count != 0) {
max_n = SMB_CALLOC_ARRAY(struct max_n, count);
if (!max_n) {
+ SAFE_FREE(p);
+ SAFE_FREE(s);
return -1;
}
}
ret = ms_fnmatch_core(p, s, max_n, strrchr_w(s, UCS2_CHAR('.')), is_case_sensitive);
- if (max_n) {
- free(max_n);
- }
-
+ SAFE_FREE(max_n);
+ SAFE_FREE(p);
+ SAFE_FREE(s);
return ret;
}
diff --git a/source/lib/replace/dlfcn.m4 b/source/lib/replace/dlfcn.m4
index a1b57d10ec4..c5b7597d7a3 100644
--- a/source/lib/replace/dlfcn.m4
+++ b/source/lib/replace/dlfcn.m4
@@ -12,7 +12,7 @@ AC_VERIFY_C_PROTOTYPE([void *dlopen(const char* filename, unsigned int flags)],
[
return 0;
],[
- AC_DEFINE(DLOPEN_TAKES_UNSIGNED_FLAGS, 1, [Whether dlopen takes unsinged int flags])
+ AC_DEFINE(DLOPEN_TAKES_UNSIGNED_FLAGS, 1, [Whether dlopen takes unsigned int flags])
],[],[
#include <dlfcn.h>
])
diff --git a/source/lib/replace/libreplace.m4 b/source/lib/replace/libreplace.m4
index f06d7f83dc3..a6b1c4f5e68 100644
--- a/source/lib/replace/libreplace.m4
+++ b/source/lib/replace/libreplace.m4
@@ -152,6 +152,7 @@ AC_CHECK_FUNCS(seteuid setresuid setegid setresgid chroot bzero strerror)
AC_CHECK_FUNCS(vsyslog setlinebuf mktime ftruncate chsize rename)
AC_CHECK_FUNCS(waitpid strlcpy strlcat initgroups memmove strdup)
AC_CHECK_FUNCS(pread pwrite strndup strcasestr strtok_r mkdtemp socketpair)
+AC_CHECK_FUNCS(isatty)
AC_HAVE_DECL(setresuid, [#include <unistd.h>])
AC_HAVE_DECL(setresgid, [#include <unistd.h>])
AC_HAVE_DECL(errno, [#include <errno.h>])
@@ -306,17 +307,6 @@ if test x"$samba_cv_HAVE_OPEN_O_DIRECT" = x"yes"; then
fi
-AC_CACHE_CHECK([that the C compiler can precompile header files],samba_cv_precompiled_headers, [
- dnl Check whether the compiler can generate precompiled headers
- touch conftest.h
- if ${CC-cc} conftest.h 2> /dev/null && test -f conftest.h.gch; then
- precompiled_headers=yes
- else
- precompiled_headers=no
- fi])
-AC_SUBST(precompiled_headers)
-
-
dnl Check if the C compiler understands volatile (it should, being ANSI).
AC_CACHE_CHECK([that the C compiler understands volatile],samba_cv_volatile, [
AC_TRY_COMPILE([#include <sys/types.h>],[volatile int i = 0],
diff --git a/source/lib/replace/replace.h b/source/lib/replace/replace.h
index 06173bd84b9..af05516e8ce 100644
--- a/source/lib/replace/replace.h
+++ b/source/lib/replace/replace.h
@@ -44,13 +44,6 @@
#include "win32_replace.h"
#endif
-#ifdef __COMPAR_FN_T
-#define QSORT_CAST (__compar_fn_t)
-#endif
-
-#ifndef QSORT_CAST
-#define QSORT_CAST (int (*)(const void *, const void *))
-#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
@@ -78,28 +71,6 @@
#include <stddef.h>
#endif
-/**
- this is a warning hack. The idea is to use this everywhere that we
- get the "discarding const" warning from gcc. That doesn't actually
- fix the problem of course, but it means that when we do get to
- cleaning them up we can do it by searching the code for
- discard_const.
-
- It also means that other error types aren't as swamped by the noise
- of hundreds of const warnings, so we are more likely to notice when
- we get new errors.
-
- Please only add more uses of this macro when you find it
- _really_ hard to fix const warnings. Our aim is to eventually use
- this function in only a very few places.
-
- Also, please call this via the discard_const_p() macro interface, as that
- makes the return type safe.
-*/
-#define discard_const(ptr) ((void *)((intptr_t)(ptr)))
-
-/** Type-safe version of discard_const */
-#define discard_const_p(type, ptr) ((type *)discard_const(ptr))
#ifndef HAVE_STRERROR
extern char *sys_errlist[];
@@ -363,6 +334,10 @@ ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset)
#include <limits.h>
#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
/* The extra casts work around common compiler bugs. */
#define _TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
/* The outer cast is needed to work around a bug in Cray C 5.0.3.0.
@@ -375,6 +350,14 @@ ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset)
#define HOST_NAME_MAX 64
#endif
+/*
+ * Some older systems seem not to have MAXHOSTNAMELEN
+ * defined.
+ */
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN HOST_NAME_MAX
+#endif
+
#ifndef UINT16_MAX
#define UINT16_MAX 65535
#endif
@@ -450,9 +433,6 @@ typedef int bool;
#endif
#endif
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
@@ -462,11 +442,34 @@ typedef int bool;
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
+/**
+ this is a warning hack. The idea is to use this everywhere that we
+ get the "discarding const" warning from gcc. That doesn't actually
+ fix the problem of course, but it means that when we do get to
+ cleaning them up we can do it by searching the code for
+ discard_const.
+
+ It also means that other error types aren't as swamped by the noise
+ of hundreds of const warnings, so we are more likely to notice when
+ we get new errors.
+
+ Please only add more uses of this macro when you find it
+ _really_ hard to fix const warnings. Our aim is to eventually use
+ this function in only a very few places.
+
+ Also, please call this via the discard_const_p() macro interface, as that
+ makes the return type safe.
+*/
+#define discard_const(ptr) ((void *)((intptr_t)(ptr)))
+
+/** Type-safe version of discard_const */
+#define discard_const_p(type, ptr) ((type *)discard_const(ptr))
+
#ifndef __STRING
#define __STRING(x) #x
#endif
-#ifndef _STRINGSTRING
+#ifndef __STRINGSTRING
#define __STRINGSTRING(x) __STRING(x)
#endif
@@ -511,4 +514,12 @@ typedef int bool;
#undef HAVE_MMAP
#endif
+#ifdef __COMPAR_FN_T
+#define QSORT_CAST (__compar_fn_t)
+#endif
+
+#ifndef QSORT_CAST
+#define QSORT_CAST (int (*)(const void *, const void *))
+#endif
+
#endif /* _LIBREPLACE_REPLACE_H */
diff --git a/source/lib/replace/system/network.h b/source/lib/replace/system/network.h
index 13d95a8ba7b..7469040b283 100644
--- a/source/lib/replace/system/network.h
+++ b/source/lib/replace/system/network.h
@@ -98,14 +98,6 @@ char *rep_inet_ntoa(struct in_addr ip);
#define MSG_WAITALL 0
#endif
-/*
- * Some older systems seem not to have MAXHOSTNAMELEN
- * defined.
- */
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 254
-#endif
-
#ifndef INADDR_LOOPBACK
#define INADDR_LOOPBACK 0x7f000001
#endif
diff --git a/source/lib/replace/test/testsuite.c b/source/lib/replace/test/testsuite.c
index 8584bcaa667..269a2ff5d62 100644
--- a/source/lib/replace/test/testsuite.c
+++ b/source/lib/replace/test/testsuite.c
@@ -743,7 +743,7 @@ static int test_strtoull(void)
TEST_STRTOULL("-02000000000000000000000",8, 18446744073709551615LLU, 24, ERANGE);
TEST_STRTOULL("-2000000000000000000000",8, 18446744073709551615LLU, 23, ERANGE);
- printf("success: strtuoll\n");
+ printf("success: strtoull\n");
return true;
}
diff --git a/source/lib/smbrun.c b/source/lib/smbrun.c
index b656822321d..26330ab992b 100644
--- a/source/lib/smbrun.c
+++ b/source/lib/smbrun.c
@@ -1,18 +1,18 @@
-/*
+/*
Unix SMB/CIFS implementation.
run a command as a specified user
Copyright (C) Andrew Tridgell 1992-1998
-
+
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
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -27,11 +27,19 @@ This is a utility function of smbrun().
****************************************************************************/
static int setup_out_fd(void)
-{
+{
int fd;
- pstring path;
-
- slprintf(path, sizeof(path)-1, "%s/smb.XXXXXX", tmpdir());
+ TALLOC_CTX *ctx = talloc_stackframe();
+ char *path = NULL;
+
+ path = talloc_asprintf(ctx,
+ "%s/smb.XXXXXX",
+ tmpdir());
+ if (!path) {
+ TALLOC_FREE(ctx);
+ errno = ENOMEM;
+ return -1;
+ }
/* now create the file */
fd = smb_mkstemp(path);
@@ -39,6 +47,7 @@ static int setup_out_fd(void)
if (fd == -1) {
DEBUG(0,("setup_out_fd: Failed to create file %s. (%s)\n",
path, strerror(errno) ));
+ TALLOC_FREE(ctx);
return -1;
}
@@ -46,6 +55,7 @@ static int setup_out_fd(void)
/* Ensure file only kept around by open fd. */
unlink(path);
+ TALLOC_FREE(ctx);
return fd;
}
@@ -59,7 +69,7 @@ static int smbrun_internal(const char *cmd, int *outfd, BOOL sanitize)
pid_t pid;
uid_t uid = current_user.ut.uid;
gid_t gid = current_user.ut.gid;
-
+
/*
* Lose any elevated privileges.
*/
diff --git a/source/lib/system.c b/source/lib/system.c
index 9cef818fab2..ab5c06d5f67 100644
--- a/source/lib/system.c
+++ b/source/lib/system.c
@@ -573,7 +573,11 @@ char *sys_getwd(char *s)
{
char *wd;
#ifdef HAVE_GETCWD
+#ifdef PATH_MAX
+ wd = (char *)getcwd(s, PATH_MAX);
+#else
wd = (char *)getcwd(s, sizeof (pstring));
+#endif
#else
wd = (char *)getwd(s);
#endif
@@ -1193,178 +1197,6 @@ struct group *sys_getgrgid(gid_t gid)
return getgrgid(gid);
}
-#if 0 /* NOT CURRENTLY USED - JRA */
-/**************************************************************************
- The following are the UNICODE versions of *all* system interface functions
- called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
- which currently are left as ascii as they are not used other than in name
- resolution.
-****************************************************************************/
-
-/**************************************************************************
- Wide stat. Just narrow and call sys_xxx.
-****************************************************************************/
-
-int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
-{
- pstring fname;
- return sys_stat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
-}
-
-/**************************************************************************
- Wide lstat. Just narrow and call sys_xxx.
-****************************************************************************/
-
-int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
-{
- pstring fname;
- return sys_lstat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
-}
-
-/**************************************************************************
- Wide creat. Just narrow and call sys_xxx.
-****************************************************************************/
-
-int wsys_creat(const smb_ucs2_t *wfname, mode_t mode)
-{
- pstring fname;
- return sys_creat(unicode_to_unix(fname,wfname,sizeof(fname)), mode);
-}
-
-/**************************************************************************
- Wide open. Just narrow and call sys_xxx.
-****************************************************************************/
-
-int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode)
-{
- pstring fname;
- return sys_open(unicode_to_unix(fname,wfname,sizeof(fname)), oflag, mode);
-}
-
-/**************************************************************************
- Wide fopen. Just narrow and call sys_xxx.
-****************************************************************************/
-
-FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type)
-{
- pstring fname;
- return sys_fopen(unicode_to_unix(fname,wfname,sizeof(fname)), type);
-}
-
-/**************************************************************************
- Wide opendir. Just narrow and call sys_xxx.
-****************************************************************************/
-
-SMB_STRUCT_DIR *wsys_opendir(const smb_ucs2_t *wfname)
-{
- pstring fname;
- return opendir(unicode_to_unix(fname,wfname,sizeof(fname)));
-}
-
-/**************************************************************************
- Wide readdir. Return a structure pointer containing a wide filename.
-****************************************************************************/
-
-SMB_STRUCT_WDIRENT *wsys_readdir(SMB_STRUCT_DIR *dirp)
-{
- static SMB_STRUCT_WDIRENT retval;
- SMB_STRUCT_DIRENT *dirval = sys_readdir(dirp);
-
- if(!dirval)
- return NULL;
-
- /*
- * The only POSIX defined member of this struct is d_name.
- */
-
- unix_to_unicode(retval.d_name,dirval->d_name,sizeof(retval.d_name));
-
- return &retval;
-}
-
-/**************************************************************************
- Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring.
-****************************************************************************/
-
-smb_ucs2_t *wsys_getwd(smb_ucs2_t *s)
-{
- pstring fname;
- char *p = sys_getwd(fname);
-
- if(!p)
- return NULL;
-
- return unix_to_unicode(s, p, sizeof(wpstring));
-}
-
-/**************************************************************************
- Wide chown. Just narrow and call sys_xxx.
-****************************************************************************/
-
-int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid)
-{
- pstring fname;
- return chown(unicode_to_unix(fname,wfname,sizeof(fname)), uid, gid);
-}
-
-/**************************************************************************
- Wide chroot. Just narrow and call sys_xxx.
-****************************************************************************/
-
-int wsys_chroot(const smb_ucs2_t *wfname)
-{
- pstring fname;
- return chroot(unicode_to_unix(fname,wfname,sizeof(fname)));
-}
-
-/**************************************************************************
- Wide getpwnam. Return a structure pointer containing wide names.
-****************************************************************************/
-
-SMB_STRUCT_WPASSWD *wsys_getpwnam(const smb_ucs2_t *wname)
-{
- static SMB_STRUCT_WPASSWD retval;
- fstring name;
- struct passwd *pwret = sys_getpwnam(unicode_to_unix(name,wname,sizeof(name)));
-
- if(!pwret)
- return NULL;
-
- unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
- retval.pw_passwd = pwret->pw_passwd;
- retval.pw_uid = pwret->pw_uid;
- retval.pw_gid = pwret->pw_gid;
- unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
- unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
- unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
-
- return &retval;
-}
-
-/**************************************************************************
- Wide getpwuid. Return a structure pointer containing wide names.
-****************************************************************************/
-
-SMB_STRUCT_WPASSWD *wsys_getpwuid(uid_t uid)
-{
- static SMB_STRUCT_WPASSWD retval;
- struct passwd *pwret = sys_getpwuid(uid);
-
- if(!pwret)
- return NULL;
-
- unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
- retval.pw_passwd = pwret->pw_passwd;
- retval.pw_uid = pwret->pw_uid;
- retval.pw_gid = pwret->pw_gid;
- unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
- unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
- unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
-
- return &retval;
-}
-#endif /* NOT CURRENTLY USED - JRA */
-
/**************************************************************************
Extract a command into an arg list.
****************************************************************************/
diff --git a/source/lib/talloc/configure.ac b/source/lib/talloc/configure.ac
index 5f465fe93ab..afc2a944f01 100644
--- a/source/lib/talloc/configure.ac
+++ b/source/lib/talloc/configure.ac
@@ -1,5 +1,5 @@
AC_PREREQ(2.50)
-AC_INIT(talloc, 1.0)
+AC_INIT(talloc, 1.1.0)
AC_CONFIG_SRCDIR([talloc.c])
AC_SUBST(datarootdir)
AC_CONFIG_HEADER(config.h)
diff --git a/source/lib/talloc/talloc.c b/source/lib/talloc/talloc.c
index c073a8c7743..4d72c0e871a 100644
--- a/source/lib/talloc/talloc.c
+++ b/source/lib/talloc/talloc.c
@@ -1109,64 +1109,132 @@ void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name
return newp;
}
+static inline char *__talloc_strlendup(const void *t, const char *p, size_t len)
+{
+ char *ret;
+
+ ret = (char *)__talloc(t, len + 1);
+ if (unlikely(!ret)) return NULL;
+
+ memcpy(ret, p, len);
+ ret[len] = 0;
+
+ _talloc_set_name_const(ret, ret);
+ return ret;
+}
+
/*
- strdup with a talloc
+ strdup with a talloc
*/
char *talloc_strdup(const void *t, const char *p)
{
+ if (unlikely(!p)) return NULL;
+ return __talloc_strlendup(t, p, strlen(p));
+}
+
+/*
+ strndup with a talloc
+*/
+char *talloc_strndup(const void *t, const char *p, size_t n)
+{
+ if (unlikely(!p)) return NULL;
+ return __talloc_strlendup(t, p, strnlen(p, n));
+}
+
+static inline char *__talloc_strlendup_append(char *s, size_t slen,
+ const char *a, size_t alen)
+{
char *ret;
- if (!p) {
- return NULL;
+
+ ret = talloc_realloc(NULL, s, char, slen + alen + 1);
+ if (unlikely(!ret)) return NULL;
+
+ /* append the string and the trailing \0 */
+ memcpy(&ret[slen], a, alen);
+ ret[slen+alen] = 0;
+
+ _talloc_set_name_const(ret, ret);
+ return ret;
+}
+
+/*
+ * Appends at the end of the string.
+ */
+char *talloc_strdup_append(char *s, const char *a)
+{
+ if (unlikely(!s)) {
+ return talloc_strdup(NULL, a);
}
- ret = (char *)talloc_memdup(t, p, strlen(p) + 1);
- if (likely(ret)) {
- _talloc_set_name_const(ret, ret);
+
+ if (unlikely(!a)) {
+ return s;
}
- return ret;
+
+ return __talloc_strlendup_append(s, strlen(s), a, strlen(a));
}
/*
- append to a talloced string
-*/
-char *talloc_append_string(const void *t, char *orig, const char *append)
+ * Appends at the end of the talloc'ed buffer,
+ * not the end of the string.
+ */
+char *talloc_strdup_append_buffer(char *s, const char *a)
{
- char *ret;
- size_t olen = strlen(orig);
- size_t alenz;
+ size_t slen;
- if (!append)
- return orig;
+ if (unlikely(!s)) {
+ return talloc_strdup(NULL, a);
+ }
- alenz = strlen(append) + 1;
+ if (unlikely(!a)) {
+ return s;
+ }
- ret = talloc_realloc(t, orig, char, olen + alenz);
- if (!ret)
- return NULL;
+ slen = talloc_get_size(s);
+ if (likely(slen > 0)) {
+ slen--;
+ }
- /* append the string with the trailing \0 */
- memcpy(&ret[olen], append, alenz);
+ return __talloc_strlendup_append(s, slen, a, strlen(a));
+}
- _talloc_set_name_const(ret, ret);
+/*
+ * Appends at the end of the string.
+ */
+char *talloc_strndup_append(char *s, const char *a, size_t n)
+{
+ if (unlikely(!s)) {
+ return talloc_strdup(NULL, a);
+ }
- return ret;
+ if (unlikely(!a)) {
+ return s;
+ }
+
+ return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n));
}
/*
- strndup with a talloc
-*/
-char *talloc_strndup(const void *t, const char *p, size_t n)
+ * Appends at the end of the talloc'ed buffer,
+ * not the end of the string.
+ */
+char *talloc_strndup_append_buffer(char *s, const char *a, size_t n)
{
- size_t len;
- char *ret;
+ size_t slen;
- for (len=0; len<n && p[len]; len++) ;
+ if (unlikely(!s)) {
+ return talloc_strdup(NULL, a);
+ }
- ret = (char *)__talloc(t, len + 1);
- if (!ret) { return NULL; }
- memcpy(ret, p, len);
- ret[len] = 0;
- _talloc_set_name_const(ret, ret);
- return ret;
+ if (unlikely(!a)) {
+ return s;
+ }
+
+ slen = talloc_get_size(s);
+ if (likely(slen > 0)) {
+ slen--;
+ }
+
+ return __talloc_strlendup_append(s, slen, a, strnlen(a, n));
}
#ifndef HAVE_VA_COPY
@@ -1188,18 +1256,18 @@ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
va_copy(ap2, ap);
len = vsnprintf(&c, 1, fmt, ap2);
va_end(ap2);
- if (len < 0) {
+ if (unlikely(len < 0)) {
return NULL;
}
ret = (char *)__talloc(t, len+1);
- if (ret) {
- va_copy(ap2, ap);
- vsnprintf(ret, len+1, fmt, ap2);
- va_end(ap2);
- _talloc_set_name_const(ret, ret);
- }
+ if (unlikely(!ret)) return NULL;
+
+ va_copy(ap2, ap);
+ vsnprintf(ret, len+1, fmt, ap2);
+ va_end(ap2);
+ _talloc_set_name_const(ret, ret);
return ret;
}
@@ -1219,52 +1287,78 @@ char *talloc_asprintf(const void *t, const char *fmt, ...)
return ret;
}
+static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
+ const char *fmt, va_list ap)
+ PRINTF_ATTRIBUTE(3,0);
-/**
- * Realloc @p s to append the formatted result of @p fmt and @p ap,
- * and return @p s, which may have moved. Good for gradually
- * accumulating output into a string buffer.
- **/
-char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
-{
- struct talloc_chunk *tc;
- int len, s_len;
+static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
+ const char *fmt, va_list ap)
+{
+ ssize_t alen;
va_list ap2;
char c;
- if (s == NULL) {
- return talloc_vasprintf(NULL, fmt, ap);
- }
-
- tc = talloc_chunk_from_ptr(s);
-
- s_len = tc->size - 1;
-
va_copy(ap2, ap);
- len = vsnprintf(&c, 1, fmt, ap2);
+ alen = vsnprintf(&c, 1, fmt, ap2);
va_end(ap2);
- if (len <= 0) {
+ if (alen <= 0) {
/* Either the vsnprintf failed or the format resulted in
* no characters being formatted. In the former case, we
* ought to return NULL, in the latter we ought to return
- * the original string. Most current callers of this
+ * the original string. Most current callers of this
* function expect it to never return NULL.
*/
return s;
}
- s = talloc_realloc(NULL, s, char, s_len + len+1);
+ s = talloc_realloc(NULL, s, char, slen + alen + 1);
if (!s) return NULL;
va_copy(ap2, ap);
- vsnprintf(s+s_len, len+1, fmt, ap2);
+ vsnprintf(s + slen, alen + 1, fmt, ap2);
va_end(ap2);
- _talloc_set_name_const(s, s);
+ _talloc_set_name_const(s, s);
return s;
}
+/**
+ * Realloc @p s to append the formatted result of @p fmt and @p ap,
+ * and return @p s, which may have moved. Good for gradually
+ * accumulating output into a string buffer. Appends at the end
+ * of the string.
+ **/
+char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
+{
+ if (unlikely(!s)) {
+ return talloc_vasprintf(NULL, fmt, ap);
+ }
+
+ return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap);
+}
+
+/**
+ * Realloc @p s to append the formatted result of @p fmt and @p ap,
+ * and return @p s, which may have moved. Always appends at the
+ * end of the talloc'ed buffer, not the end of the string.
+ **/
+char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap)
+{
+ size_t slen;
+
+ if (unlikely(!s)) {
+ return talloc_vasprintf(NULL, fmt, ap);
+ }
+
+ slen = talloc_get_size(s);
+ if (likely(slen > 0)) {
+ slen--;
+ }
+
+ return __talloc_vaslenprintf_append(s, slen, fmt, ap);
+}
+
/*
Realloc @p s to append the formatted result of @p fmt and return @p
s, which may have moved. Good for gradually accumulating output
@@ -1281,6 +1375,21 @@ char *talloc_asprintf_append(char *s, const char *fmt, ...)
}
/*
+ Realloc @p s to append the formatted result of @p fmt and return @p
+ s, which may have moved. Good for gradually accumulating output
+ into a buffer.
+ */
+char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ s = talloc_vasprintf_append_buffer(s, fmt, ap);
+ va_end(ap);
+ return s;
+}
+
+/*
alloc an array, checking for integer overflow in the array size
*/
void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
diff --git a/source/lib/talloc/talloc.h b/source/lib/talloc/talloc.h
index 15130d0d982..e1033916817 100644
--- a/source/lib/talloc/talloc.h
+++ b/source/lib/talloc/talloc.h
@@ -111,6 +111,7 @@ typedef void TALLOC_CTX;
#define talloc_array_p(ctx, type, count) talloc_array(ctx, type, count)
#define talloc_realloc_p(ctx, p, type, count) talloc_realloc(ctx, p, type, count)
#define talloc_destroy(ctx) talloc_free(ctx)
+#define talloc_append_string(c, s, a) (s?talloc_strdup_append(s,a):talloc_strdup(c, a))
#endif
/* The following definitions come from talloc.c */
@@ -152,13 +153,6 @@ void talloc_enable_leak_report(void);
void talloc_enable_leak_report_full(void);
void *_talloc_zero(const void *ctx, size_t size, const char *name);
void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name);
-char *talloc_strdup(const void *t, const char *p);
-char *talloc_strndup(const void *t, const char *p, size_t n);
-char *talloc_append_string(const void *t, char *orig, const char *append);
-char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
-char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
-char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
-char *talloc_asprintf_append(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name);
void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name);
void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name);
@@ -169,4 +163,20 @@ void *talloc_find_parent_byname(const void *ctx, const char *name);
void talloc_show_parents(const void *context, FILE *file);
int talloc_is_parent(const void *context, const void *ptr);
+char *talloc_strdup(const void *t, const char *p);
+char *talloc_strdup_append(char *s, const char *a);
+char *talloc_strdup_append_buffer(char *s, const char *a);
+
+char *talloc_strndup(const void *t, const char *p, size_t n);
+char *talloc_strndup_append(char *s, const char *a, size_t n);
+char *talloc_strndup_append_buffer(char *s, const char *a, size_t n);
+
+char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
+char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
+char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
+
+char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
+char *talloc_asprintf_append(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
+char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
+
#endif
diff --git a/source/lib/talloc/talloc_guide.txt b/source/lib/talloc/talloc_guide.txt
index c4634ae19a9..18663b370d9 100644
--- a/source/lib/talloc/talloc_guide.txt
+++ b/source/lib/talloc/talloc_guide.txt
@@ -568,8 +568,23 @@ string. This is equivalent to:
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
char *talloc_asprintf_append(char *s, const char *fmt, ...);
+The talloc_asprintf_append() function appends the given formatted
+string to the given string.
+Use this varient when the string in the current talloc buffer may
+have been truncated in length.
+
+This functions sets the name of the new pointer to the new
+string. This is equivalent to:
+ talloc_set_name_const(ptr, ptr)
+
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...);
+
The talloc_asprintf_append() function appends the given formatted
-string to the given string.
+string to the end of the currently allocated talloc buffer.
+Use this varient when the string in the current talloc buffer has
+not been changed.
This functions sets the name of the new pointer to the new
string. This is equivalent to:
@@ -577,7 +592,7 @@ string. This is equivalent to:
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-(type *)talloc_array(const void *ctx, type, uint_t count);
+((type *)talloc_array(const void *ctx, type, uint_t count);
The talloc_array() macro is equivalent to:
diff --git a/source/lib/talloc/testsuite.c b/source/lib/talloc/testsuite.c
index 2e3ae65082f..e16c91f8b9c 100644
--- a/source/lib/talloc/testsuite.c
+++ b/source/lib/talloc/testsuite.c
@@ -106,7 +106,7 @@ static bool test_ref1(void)
{
void *root, *p1, *p2, *ref, *r1;
- printf("test: ref1 [\nSINGLE REFERENCE FREE\n]\n");
+ printf("test: ref1\n# SINGLE REFERENCE FREE\n");
root = talloc_named_const(NULL, 0, "root");
p1 = talloc_named_const(root, 1, "p1");
@@ -162,7 +162,7 @@ static bool test_ref2(void)
{
void *root, *p1, *p2, *ref, *r1;
- printf("test: ref2 [\nDOUBLE REFERENCE FREE\n]\n");
+ printf("test: ref2\n# DOUBLE REFERENCE FREE\n");
root = talloc_named_const(NULL, 0, "root");
p1 = talloc_named_const(root, 1, "p1");
talloc_named_const(p1, 1, "x1");
@@ -217,7 +217,7 @@ static bool test_ref3(void)
{
void *root, *p1, *p2, *ref, *r1;
- printf("test: ref3 [\nPARENT REFERENCE FREE\n]\n");
+ printf("test: ref3\n# PARENT REFERENCE FREE\n");
root = talloc_named_const(NULL, 0, "root");
p1 = talloc_named_const(root, 1, "p1");
@@ -256,7 +256,7 @@ static bool test_ref4(void)
{
void *root, *p1, *p2, *ref, *r1;
- printf("test: ref4 [\nREFERRER REFERENCE FREE\n]\n");
+ printf("test: ref4\n# REFERRER REFERENCE FREE\n");
root = talloc_named_const(NULL, 0, "root");
p1 = talloc_named_const(root, 1, "p1");
@@ -306,7 +306,7 @@ static bool test_unlink1(void)
{
void *root, *p1, *p2, *ref, *r1;
- printf("test: unlink [\nUNLINK\n]\n");
+ printf("test: unlink\n# UNLINK\n");
root = talloc_named_const(NULL, 0, "root");
p1 = talloc_named_const(root, 1, "p1");
@@ -358,7 +358,7 @@ static bool test_misc(void)
double *d;
const char *name;
- printf("test: misc [\nMISCELLANEOUS\n]\n");
+ printf("test: misc\n# MISCELLANEOUS\n");
root = talloc_new(NULL);
@@ -419,15 +419,15 @@ static bool test_misc(void)
p2 = talloc_strndup(p1, "foo", 2);
torture_assert("misc", strcmp("fo", p2) == 0,
"strndup doesn't work\n");
- p2 = talloc_asprintf_append(p2, "o%c", 'd');
+ p2 = talloc_asprintf_append_buffer(p2, "o%c", 'd');
torture_assert("misc", strcmp("food", p2) == 0,
- "talloc_asprintf_append doesn't work\n");
+ "talloc_asprintf_append_buffer doesn't work\n");
CHECK_BLOCKS("misc", p2, 1);
CHECK_BLOCKS("misc", p1, 3);
- p2 = talloc_asprintf_append(NULL, "hello %s", "world");
+ p2 = talloc_asprintf_append_buffer(NULL, "hello %s", "world");
torture_assert("misc", strcmp("hello world", p2) == 0,
- "talloc_asprintf_append doesn't work\n");
+ "talloc_asprintf_append_buffer doesn't work\n");
CHECK_BLOCKS("misc", p2, 1);
CHECK_BLOCKS("misc", p1, 3);
talloc_free(p2);
@@ -509,7 +509,7 @@ static bool test_realloc(void)
{
void *root, *p1, *p2;
- printf("test: realloc [\nREALLOC\n]\n");
+ printf("test: realloc\n# REALLOC\n");
root = talloc_new(NULL);
@@ -553,7 +553,7 @@ static bool test_realloc(void)
talloc_free(root);
- printf("success: REALLOC\n");
+ printf("success: realloc\n");
return true;
}
@@ -617,7 +617,7 @@ static bool test_type(void)
};
struct el1 *el1;
- printf("test: type [\ntalloc type checking\n]\n");
+ printf("test: type\n# talloc type checking\n");
root = talloc_new(NULL);
@@ -646,7 +646,7 @@ static bool test_steal(void)
{
void *root, *p1, *p2;
- printf("test: steal [\nSTEAL\n]\n");
+ printf("test: steal\n# STEAL\n");
root = talloc_new(NULL);
@@ -702,7 +702,7 @@ static bool test_move(void)
int *x;
} *t1, *t2;
- printf("test: move [\nMOVE\n]\n");
+ printf("test: move\n# MOVE\n");
root = talloc_new(NULL);
@@ -732,7 +732,7 @@ static bool test_realloc_fn(void)
{
void *root, *p1;
- printf("test: realloc_fn [\ntalloc_realloc_fn\n]\n");
+ printf("test: realloc_fn\n# talloc_realloc_fn\n");
root = talloc_new(NULL);
@@ -757,7 +757,7 @@ static bool test_unref_reparent(void)
{
void *root, *p1, *p2, *c1;
- printf("test: unref_reparent [\nUNREFERENCE AFTER PARENT FREED\n]\n");
+ printf("test: unref_reparent\n# UNREFERENCE AFTER PARENT FREED\n");
root = talloc_named_const(NULL, 0, "root");
p1 = talloc_named_const(root, 1, "orig parent");
@@ -794,7 +794,7 @@ static bool test_speed(void)
int i;
struct timeval tv;
- printf("test: speed [\nTALLOC VS MALLOC SPEED\n]\n");
+ printf("test: speed\n# TALLOC VS MALLOC SPEED\n");
tv = timeval_current();
count = 0;
@@ -840,7 +840,7 @@ static bool test_lifeless(void)
char *parent, *child;
void *child_owner = talloc_new(NULL);
- printf("test: lifeless [\nTALLOC_UNLINK LOOP\n]\n");
+ printf("test: lifeless\n# TALLOC_UNLINK LOOP\n");
parent = talloc_strdup(top, "parent");
child = talloc_strdup(parent, "child");
@@ -874,7 +874,7 @@ static bool test_loop(void)
char *req2, *req3;
} *req1;
- printf("test: loop [\nTALLOC LOOP DESTRUCTION\n]\n");
+ printf("test: loop\n# TALLOC LOOP DESTRUCTION\n");
parent = talloc_strdup(top, "parent");
req1 = talloc(parent, struct req1);
@@ -908,7 +908,7 @@ static bool test_free_parent_deny_child(void)
char *level2;
char *level3;
- printf("test: free_parent_deny_child [\nTALLOC FREE PARENT DENY CHILD\n]\n");
+ printf("test: free_parent_deny_child\n# TALLOC FREE PARENT DENY CHILD\n");
level1 = talloc_strdup(top, "level1");
level2 = talloc_strdup(level1, "level2");
@@ -938,7 +938,7 @@ static bool test_talloc_ptrtype(void)
const char *location3;
const char *location4;
- printf("test: ptrtype [\nTALLOC PTRTYPE\n]\n");
+ printf("test: ptrtype\n# TALLOC PTRTYPE\n");
s1 = talloc_ptrtype(top, s1);location1 = __location__;
@@ -1024,7 +1024,7 @@ static bool test_talloc_free_in_destructor(void)
void *level4;
void **level5;
- printf("test: free_in_destructor [\nTALLOC FREE IN DESTRUCTOR\n]\n");
+ printf("test: free_in_destructor\n# TALLOC FREE IN DESTRUCTOR\n");
level0 = talloc_new(NULL);
level1 = talloc_new(level0);
@@ -1053,7 +1053,7 @@ static bool test_autofree(void)
#if _SAMBA_BUILD_ < 4
/* autofree test would kill smbtorture */
void *p;
- printf("test: autofree [\nTALLOC AUTOFREE CONTEXT\n]\n");
+ printf("test: autofree\n# TALLOC AUTOFREE CONTEXT\n");
p = talloc_autofree_context();
talloc_free(p);
diff --git a/source/lib/util.c b/source/lib/util.c
index cf39c0980d0..516598b357e 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -1557,20 +1557,22 @@ BOOL process_exists_by_pid(pid_t pid)
const char *uidtoname(uid_t uid)
{
- fstring name;
- struct passwd *pass;
+ TALLOC_CTX *ctx = talloc_tos();
+ char *name = NULL;
+ struct passwd *pass = NULL;
- pass = getpwuid_alloc(talloc_tos(), uid);
+ pass = getpwuid_alloc(ctx,uid);
if (pass) {
- fstrcpy(name, pass->pw_name);
+ name = talloc_strdup(ctx,pass->pw_name);
TALLOC_FREE(pass);
} else {
- slprintf(name, sizeof(name) - 1, "%ld",(long int)uid);
+ name = talloc_asprintf(ctx,
+ "%ld",
+ (long int)uid);
}
- return talloc_strdup(talloc_tos(), name);
+ return name;
}
-
/*******************************************************************
Convert a gid into a group name.
********************************************************************/
diff --git a/source/lib/util_str.c b/source/lib/util_str.c
index bac94740cd7..fbd9c1ca6da 100644
--- a/source/lib/util_str.c
+++ b/source/lib/util_str.c
@@ -6,6 +6,7 @@
Copyright (C) Simo Sorce 2001-2002
Copyright (C) Martin Pool 2003
Copyright (C) James Peach 2006
+ Copyright (C) Jeremy Allison 1992-2007
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
@@ -264,12 +265,63 @@ int StrCaseCmp(const char *s, const char *t)
/**
Case insensitive string compararison, length limited.
**/
-int StrnCaseCmp(const char *s, const char *t, size_t n)
+int StrnCaseCmp(const char *s, const char *t, size_t len)
{
- pstring buf1, buf2;
- unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
- unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
- return strncmp(buf1,buf2,n);
+ size_t n = 0;
+ const char *ps, *pt;
+ size_t size;
+ smb_ucs2_t *buffer_s, *buffer_t;
+ int ret;
+
+ for (ps = s, pt = t; n < len ; ps++, pt++, n++) {
+ char us, ut;
+
+ if (!*ps && !*pt)
+ return 0; /* both ended */
+ else if (!*ps)
+ return -1; /* s is a prefix */
+ else if (!*pt)
+ return +1; /* t is a prefix */
+ else if ((*ps & 0x80) || (*pt & 0x80))
+ /* not ascii anymore, do it the
+ * hard way from here on in */
+ break;
+
+ us = toupper_ascii(*ps);
+ ut = toupper_ascii(*pt);
+ if (us == ut)
+ continue;
+ else if (us < ut)
+ return -1;
+ else if (us > ut)
+ return +1;
+ }
+
+ if (n == len) {
+ return 0;
+ }
+
+ size = push_ucs2_allocate(&buffer_s, ps);
+ if (size == (size_t)-1) {
+ return strncmp(ps, pt, len-n);
+ /* Not quite the right answer, but finding the right one
+ under this failure case is expensive,
+ and it's pretty close */
+ }
+
+ size = push_ucs2_allocate(&buffer_t, pt);
+ if (size == (size_t)-1) {
+ SAFE_FREE(buffer_s);
+ return strncmp(ps, pt, len-n);
+ /* Not quite the right answer, but finding the right one
+ under this failure case is expensive,
+ and it's pretty close */
+ }
+
+ ret = strncasecmp_w(buffer_s, buffer_t, len-n);
+ SAFE_FREE(buffer_s);
+ SAFE_FREE(buffer_t);
+ return ret;
}
/**
@@ -283,7 +335,7 @@ BOOL strequal(const char *s1, const char *s2)
return(True);
if (!s1 || !s2)
return(False);
-
+
return(StrCaseCmp(s1,s2)==0);
}
@@ -298,7 +350,7 @@ BOOL strnequal(const char *s1,const char *s2,size_t n)
return(True);
if (!s1 || !s2 || !n)
return(False);
-
+
return(StrnCaseCmp(s1,s2,n)==0);
}
@@ -353,11 +405,16 @@ int strwicmp(const char *psz1, const char *psz2)
char *strupper_static(const char *s)
{
- static pstring str;
+ static char *str = NULL;
- pstrcpy(str, s);
+ if (str) {
+ SAFE_FREE(str);
+ }
+ str = SMB_STRDUP(s);
+ if (!str) {
+ return CONST_DISCARD(char *,s);
+ }
strupper_m(str);
-
return str;
}
@@ -381,7 +438,7 @@ BOOL strisnormal(const char *s, int case_default)
{
if (case_default == CASE_UPPER)
return(!strhaslower(s));
-
+
return(!strhasupper(s));
}
@@ -390,12 +447,9 @@ BOOL strisnormal(const char *s, int case_default)
String replace.
NOTE: oldc and newc must be 7 bit characters
**/
-
-void string_replace( pstring s, char oldc, char newc )
+void string_replace( char *s, char oldc, char newc )
{
char *p;
- smb_ucs2_t *tmp;
- size_t len;
/* this is quite a common operation, so we want it to be
fast. We optimise for the ascii case, knowing that all our
@@ -405,8 +459,9 @@ void string_replace( pstring s, char oldc, char newc )
for (p = s; *p; p++) {
if (*p & 0x80) /* mb string - slow path. */
break;
- if (*p == oldc)
+ if (*p == oldc) {
*p = newc;
+ }
}
if (!*p)
@@ -417,13 +472,18 @@ void string_replace( pstring s, char oldc, char newc )
/* With compose characters we must restart from the beginning. JRA. */
p = s;
#endif
- len = push_ucs2_allocate(&tmp, p);
- if (len == -1) {
- return;
+
+ while (*p) {
+ size_t c_size;
+ next_codepoint(p, &c_size);
+
+ if (c_size == 1) {
+ if (*p == oldc) {
+ *p = newc;
+ }
+ }
+ p += c_size;
}
- string_replace_w(tmp, UCS2_CHAR(oldc), UCS2_CHAR(newc));
- pull_ucs2(NULL, p, tmp, len/2, -1, STR_TERMINATE);
- SAFE_FREE(tmp);
}
/**
@@ -470,9 +530,14 @@ char *skip_string(const char *base, size_t len, char *buf)
size_t str_charnum(const char *s)
{
- uint16 tmpbuf2[sizeof(pstring)];
- push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
- return strlen_w(tmpbuf2);
+ size_t ret;
+ smb_ucs2_t *tmpbuf2 = NULL;
+ if (push_ucs2_allocate(&tmpbuf2, s) == (size_t)-1) {
+ return 0;
+ }
+ ret = strlen_w(tmpbuf2);
+ SAFE_FREE(tmpbuf2);
+ return ret;
}
/**
@@ -483,9 +548,14 @@ size_t str_charnum(const char *s)
size_t str_ascii_charnum(const char *s)
{
- pstring tmpbuf2;
- push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
- return strlen(tmpbuf2);
+ size_t ret;
+ char *tmpbuf2 = NULL;
+ if (push_ascii_allocate(&tmpbuf2, s) == (size_t)-1) {
+ return 0;
+ }
+ ret = strlen(tmpbuf2);
+ SAFE_FREE(tmpbuf2);
+ return ret;
}
BOOL trim_char(char *s,char cfront,char cback)
@@ -913,22 +983,38 @@ char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
BOOL in_list(const char *s, const char *list, BOOL casesensitive)
{
- pstring tok;
+ char *tok;
const char *p=list;
+ size_t bufsize = strlen(list);
+ BOOL ret = False;
if (!list)
return(False);
- while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
+ /* We know a token can't be larger
+ * than the entire list. */
+
+ tok = SMB_MALLOC_ARRAY(char, bufsize+1);
+ if (!tok) {
+ return False;
+ }
+
+ while (next_token(&p,tok,LIST_SEP,bufsize+1)) {
if (casesensitive) {
- if (strcmp(tok,s) == 0)
- return(True);
+ if (strcmp(tok,s) == 0) {
+ ret = True;
+ break;
+ }
} else {
- if (StrCaseCmp(tok,s) == 0)
- return(True);
+ if (StrCaseCmp(tok,s) == 0) {
+ ret = True;
+ break;
+ }
}
}
- return(False);
+
+ SAFE_FREE(tok);
+ return ret;
}
/* this is used to prevent lots of mallocs of size 1 */
@@ -1376,10 +1462,11 @@ char *string_truncate(char *s, unsigned int length)
char *strchr_m(const char *src, char c)
{
- wpstring ws;
- pstring s2;
+ smb_ucs2_t *ws = NULL;
+ char *s2 = NULL;
smb_ucs2_t *p;
const char *s;
+ char *ret;
/* characters below 0x3F are guaranteed to not appear in
non-initial position in multi-byte charsets */
@@ -1405,13 +1492,25 @@ char *strchr_m(const char *src, char c)
s = src;
#endif
- push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
+ if (push_ucs2_allocate(&ws, s)==(size_t)-1) {
+ /* Wrong answer, but what can we do... */
+ return strchr(src, c);
+ }
p = strchr_w(ws, UCS2_CHAR(c));
- if (!p)
+ if (!p) {
+ SAFE_FREE(ws);
return NULL;
+ }
*p = 0;
- pull_ucs2_pstring(s2, ws);
- return (char *)(s+strlen(s2));
+ if (pull_ucs2_allocate(&s2, ws)==(size_t)-1) {
+ SAFE_FREE(ws);
+ /* Wrong answer, but what can we do... */
+ return strchr(src, c);
+ }
+ ret = (char *)(s+strlen(s2));
+ SAFE_FREE(ws);
+ SAFE_FREE(s2);
+ return ret;
}
char *strrchr_m(const char *s, char c)
@@ -1457,17 +1556,30 @@ char *strrchr_m(const char *s, char c)
/* String contained a non-ascii char. Slow path. */
{
- wpstring ws;
- pstring s2;
+ smb_ucs2_t *ws = NULL;
+ char *s2 = NULL;
smb_ucs2_t *p;
+ char *ret;
- push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
+ if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
+ /* Wrong answer, but what can we do. */
+ return strrchr(s, c);
+ }
p = strrchr_w(ws, UCS2_CHAR(c));
- if (!p)
+ if (!p) {
+ SAFE_FREE(ws);
return NULL;
+ }
*p = 0;
- pull_ucs2_pstring(s2, ws);
- return (char *)(s+strlen(s2));
+ if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
+ SAFE_FREE(ws);
+ /* Wrong answer, but what can we do. */
+ return strrchr(s, c);
+ }
+ ret = (char *)(s+strlen(s2));
+ SAFE_FREE(ws);
+ SAFE_FREE(s2);
+ return ret;
}
}
@@ -1478,17 +1590,30 @@ char *strrchr_m(const char *s, char c)
char *strnrchr_m(const char *s, char c, unsigned int n)
{
- wpstring ws;
- pstring s2;
+ smb_ucs2_t *ws = NULL;
+ char *s2 = NULL;
smb_ucs2_t *p;
+ char *ret;
- push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
+ if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
+ /* Too hard to try and get right. */
+ return NULL;
+ }
p = strnrchr_w(ws, UCS2_CHAR(c), n);
- if (!p)
+ if (!p) {
+ SAFE_FREE(ws);
return NULL;
+ }
*p = 0;
- pull_ucs2_pstring(s2, ws);
- return (char *)(s+strlen(s2));
+ if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
+ SAFE_FREE(ws);
+ /* Too hard to try and get right. */
+ return NULL;
+ }
+ ret = (char *)(s+strlen(s2));
+ SAFE_FREE(ws);
+ SAFE_FREE(s2);
+ return ret;
}
/***********************************************************************
@@ -1794,7 +1919,7 @@ static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, co
char *s;
int num, lsize;
pstring tok;
-
+
if (!string || !*string)
return NULL;
if (mem_ctx) {
@@ -1807,12 +1932,12 @@ static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, co
return NULL;
}
if (!sep) sep = LIST_SEP;
-
+
num = lsize = 0;
list = NULL;
-
+
str = s;
- while (next_token(&str, tok, sep, sizeof(tok))) {
+ while (next_token(&str, tok, sep, sizeof(tok))) {
if (num == lsize) {
lsize += S_LIST_ABS;
if (mem_ctx) {
@@ -1842,7 +1967,7 @@ static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, co
} else {
list[num] = SMB_STRDUP(tok);
}
-
+
if (!list[num]) {
DEBUG(0,("str_list_make: Unable to allocate memory"));
str_list_free(&list);
diff --git a/source/lib/util_unistr.c b/source/lib/util_unistr.c
index a4952d137ee..64cfd521202 100644
--- a/source/lib/util_unistr.c
+++ b/source/lib/util_unistr.c
@@ -361,7 +361,7 @@ int rpcstr_push(void* dest, const char *src, size_t dest_len, int flags)
void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
{
- if (str == NULL) {
+ if ((str == NULL) || (str->uni_str_len == 0)) {
*dest='\0';
return;
}
@@ -374,7 +374,7 @@ void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
void unistr3_to_ascii(char *dest, const UNISTR3 *str, size_t maxlen)
{
- if (str == NULL) {
+ if ((str == NULL) || (str->uni_str_len == 0)) {
*dest='\0';
return;
}