From c0441b17e6580de65d87d28bfd9ae72d09a3508f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 23 Apr 2011 11:01:34 +0200 Subject: lib/util: add RBVAL, RBVALS, RSBVAL and RSRBVALS macros They pull and push [u]int64_t values in big endian. metze --- lib/util/byteorder.h | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'lib/util') diff --git a/lib/util/byteorder.h b/lib/util/byteorder.h index 59ad8371e4..6bcf71e83b 100644 --- a/lib/util/byteorder.h +++ b/lib/util/byteorder.h @@ -201,18 +201,29 @@ static __inline__ void st_le32(uint32_t *addr, const uint32_t val) #endif /* not CAREFUL_ALIGNMENT */ +/* 64 bit macros */ +#define BVAL(p, ofs) (IVAL(p,ofs) | (((uint64_t)IVAL(p,(ofs)+4)) << 32)) +#define BVALS(p, ofs) ((int64_t)BVAL(p,ofs)) +#define SBVAL(p, ofs, v) (SIVAL(p,ofs,(v)&0xFFFFFFFF), SIVAL(p,(ofs)+4,((uint64_t)(v))>>32)) +#define SBVALS(p, ofs, v) (SBVAL(p,ofs,(uint64_t)v)) + /* now the reverse routines - these are used in nmb packets (mostly) */ #define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF)) #define IREV(x) ((SREV(x)<<16) | (SREV((x)>>16))) +#define BREV(x) ((IREV(x)<<32) | (IREV((x)>>32))) #define RSVAL(buf,pos) SREV(SVAL(buf,pos)) #define RSVALS(buf,pos) SREV(SVALS(buf,pos)) #define RIVAL(buf,pos) IREV(IVAL(buf,pos)) #define RIVALS(buf,pos) IREV(IVALS(buf,pos)) +#define RBVAL(buf,pos) BREV(BVAL(buf,pos)) +#define RBVALS(buf,pos) BREV(BVALS(buf,pos)) #define RSSVAL(buf,pos,val) SSVAL(buf,pos,SREV(val)) #define RSSVALS(buf,pos,val) SSVALS(buf,pos,SREV(val)) #define RSIVAL(buf,pos,val) SIVAL(buf,pos,IREV(val)) #define RSIVALS(buf,pos,val) SIVALS(buf,pos,IREV(val)) +#define RSBVAL(buf,pos,val) SBVAL(buf,pos,BREV(val)) +#define RSBVALS(buf,pos,val) SBVALS(buf,pos,BREV(val)) /* Alignment macros. */ #define ALIGN4(p,base) ((p) + ((4 - (PTR_DIFF((p), (base)) & 3)) & 3)) @@ -222,10 +233,4 @@ static __inline__ void st_le32(uint32_t *addr, const uint32_t val) /* macros for accessing SMB protocol elements */ #define VWV(vwv) ((vwv)*2) -/* 64 bit macros */ -#define BVAL(p, ofs) (IVAL(p,ofs) | (((uint64_t)IVAL(p,(ofs)+4)) << 32)) -#define BVALS(p, ofs) ((int64_t)BVAL(p,ofs)) -#define SBVAL(p, ofs, v) (SIVAL(p,ofs,(v)&0xFFFFFFFF), SIVAL(p,(ofs)+4,((uint64_t)(v))>>32)) -#define SBVALS(p, ofs, v) (SBVAL(p,ofs,(uint64_t)v)) - #endif /* _BYTEORDER_H */ -- cgit From 26a0ba7ee9ee0700746759c046a7e12edb8ecdd9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 21 Apr 2011 17:19:29 +1000 Subject: lib/util Define samba-util-common only for s3-waf It causes too much trouble in the top level build. Andrew Bartlett --- lib/util/wscript_build | 35 +++++++++++------------------------ 1 file changed, 11 insertions(+), 24 deletions(-) (limited to 'lib/util') diff --git a/lib/util/wscript_build b/lib/util/wscript_build index aad386ef2a..f1bb9e7493 100755 --- a/lib/util/wscript_build +++ b/lib/util/wscript_build @@ -15,7 +15,7 @@ s4_util_public_deps = 'talloc CHARSET execinfo uid_wrapper' s4_util_public_headers = 'attr.h byteorder.h data_blob.h memory.h safe_string.h time.h talloc_stack.h xfile.h dlinklist.h util.h' s4_util_header_path = [ ('dlinklist.h util.h', '.'), ('*', 'util') ] -if bld.env.enable_s3build or bld.env._SAMBA_BUILD_ == 3: +if bld.env._SAMBA_BUILD_ == 3: # as we move files into common between samba-util and samba-util3, move them here. # Both samba-util and samba-util3 depend on this private library bld.SAMBA_LIBRARY('samba-util-common', @@ -30,30 +30,17 @@ if bld.env.enable_s3build or bld.env._SAMBA_BUILD_ == 3: private_library=True ) - if bld.env._SAMBA_BUILD_ == 4: - bld.SAMBA_LIBRARY('samba-util', - source=s4_util_sources, - deps=s4_util_deps + ' samba-util-common', - public_deps=s4_util_public_deps, - public_headers=s4_util_public_headers, - header_path= s4_util_header_path, - local_include=False, - vnum='0.0.1', - pc_files='samba-util.pc' - ) - else: - if bld.env._SAMBA_BUILD_ == 4: - bld.SAMBA_LIBRARY('samba-util', - source=s4_util_sources + " " + common_util_sources, - deps=s4_util_deps, - public_deps=s4_util_public_deps + ' ' + common_util_public_deps, - public_headers=s4_util_public_headers + ' ' + common_util_headers, - header_path= s4_util_header_path, - local_include=False, - vnum='0.0.1', - pc_files='samba-util.pc' - ) + bld.SAMBA_LIBRARY('samba-util', + source=s4_util_sources + " " + common_util_sources, + deps=s4_util_deps, + public_deps=s4_util_public_deps + ' ' + common_util_public_deps, + public_headers=s4_util_public_headers + ' ' + common_util_headers, + header_path= s4_util_header_path, + local_include=False, + vnum='0.0.1', + pc_files='samba-util.pc' + ) # dummy subsystem for avoid wider deps changes. bld.SAMBA_SUBSYSTEM('samba-util-common', -- cgit From 3e85b960fae391af7a0592d5d38c18ae5a157209 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 27 Apr 2011 16:39:42 +1000 Subject: dynconfig: Have only one dynconfig.o in the common code. --- lib/util/charset/codepoints.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/util') diff --git a/lib/util/charset/codepoints.c b/lib/util/charset/codepoints.c index cd54420e8e..5e8ac64ed4 100644 --- a/lib/util/charset/codepoints.c +++ b/lib/util/charset/codepoints.c @@ -23,7 +23,7 @@ #include "includes.h" #include "lib/util/charset/charset.h" #include "system/locale.h" -#include "dynconfig.h" +#include "dynconfig/dynconfig.h" #ifdef strcasecmp #undef strcasecmp -- cgit From 75d5ba4109801957eef590b601cce61a6e67064f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 14 Apr 2011 17:23:25 +1000 Subject: lib/util/charset Fix string termination conditions for UTF16 strings This punts partial UTF16 strings to iconv() to deal with, as it's not a fast path any longer if it's got an odd length. Andrew Bartlett Signed-off-by: Andrew Tridgell --- lib/util/charset/convert_string.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/util') diff --git a/lib/util/charset/convert_string.c b/lib/util/charset/convert_string.c index e51add2aaf..f1772f448c 100644 --- a/lib/util/charset/convert_string.c +++ b/lib/util/charset/convert_string.c @@ -179,8 +179,8 @@ bool convert_string_error_handle(struct smb_iconv_handle *ic, unsigned char lastp = '\0'; /* If all characters are ascii, fast path here. */ - while (((slen == (size_t)-1) || (slen >= 2)) && dlen) { - if (((lastp = *p) <= 0x7f) && (p[1] == 0)) { + while (((slen == (size_t)-1) || (slen >= 1)) && dlen) { + if (slen >= 2 && ((lastp = *p) <= 0x7f) && (p[1] == 0)) { *q++ = *p; if (slen != (size_t)-1) { slen -= 2; @@ -221,8 +221,8 @@ bool convert_string_error_handle(struct smb_iconv_handle *ic, unsigned char lastp = '\0'; /* If all characters are ascii, fast path here. */ - while (slen && (dlen >= 2)) { - if ((lastp = *p) <= 0x7F) { + while (slen && (dlen >= 1)) { + if (dlen >=2 && (lastp = *p) <= 0x7F) { *q++ = *p++; *q++ = '\0'; if (slen != (size_t)-1) { -- cgit From 4081ea5b49c6b882174d633a1eb03436341c4e63 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 12 Apr 2011 14:49:41 +1000 Subject: lib/util/charset use convert_string.c in common This brings another layer of the charcnv library in common. Andrew Bartlett Signed-off-by: Andrew Tridgell --- lib/util/charset/charcnv.c | 135 -------------------------------------- lib/util/charset/convert_string.c | 5 +- lib/util/charset/util_unistr.c | 65 ------------------ lib/util/charset/wscript_build | 4 +- 4 files changed, 5 insertions(+), 204 deletions(-) (limited to 'lib/util') diff --git a/lib/util/charset/charcnv.c b/lib/util/charset/charcnv.c index 998bb08fd7..076795a0b2 100644 --- a/lib/util/charset/charcnv.c +++ b/lib/util/charset/charcnv.c @@ -113,138 +113,3 @@ convert: return destlen; } - -/** - * Convert string from one encoding to another, making error checking etc - * - * @param src pointer to source string (multibyte or singlebyte) - * @param srclen length of the source string in bytes - * @param dest pointer to destination string (multibyte or singlebyte) - * @param destlen maximal length allowed for string - * @returns the number of bytes occupied in the destination - * on error, returns -1, and sets errno - **/ -_PUBLIC_ bool convert_string_error_handle(struct smb_iconv_handle *ic, - charset_t from, charset_t to, - void const *src, size_t srclen, - void *dest, size_t destlen, - size_t *converted_size) -{ - size_t i_len, o_len; - ssize_t retval; - const char* inbuf = (const char*)src; - char* outbuf = (char*)dest; - smb_iconv_t descriptor; - - if (srclen == (size_t)-1) - srclen = strlen(inbuf)+1; - - descriptor = get_conv_handle(ic, from, to); - if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) { - if (converted_size) { - *converted_size = 0; - } - errno = EINVAL; - return -1; - } - - i_len=srclen; - o_len=destlen; - - retval = smb_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len); - - if (converted_size != NULL) - *converted_size = destlen-o_len; - return (retval != (ssize_t)-1); -} - - -/** - * Convert string from one encoding to another, making error checking etc - * - * @param src pointer to source string (multibyte or singlebyte) - * @param srclen length of the source string in bytes - * @param dest pointer to destination string (multibyte or singlebyte) - * @param destlen maximal length allowed for string - * @returns the number of bytes occupied in the destination - **/ -_PUBLIC_ bool convert_string_handle(struct smb_iconv_handle *ic, - charset_t from, charset_t to, - void const *src, size_t srclen, - void *dest, size_t destlen, size_t *converted_size) -{ - bool retval; - - retval = convert_string_error_handle(ic, from, to, src, srclen, dest, destlen, converted_size); - if(retval==false) { - const char *reason; - switch(errno) { - case EINVAL: - reason="Incomplete multibyte sequence"; - return false; - case E2BIG: - reason="No more room"; - if (from == CH_UNIX) { - DEBUG(0,("E2BIG: convert_string_handle(%s,%s): srclen=%d destlen=%d - '%s'\n", - charset_name(ic, from), charset_name(ic, to), - (int)srclen, (int)destlen, - (const char *)src)); - } else { - DEBUG(0,("E2BIG: convert_string_handle(%s,%s): srclen=%d destlen=%d\n", - charset_name(ic, from), charset_name(ic, to), - (int)srclen, (int)destlen)); - } - return false; - case EILSEQ: - reason="Illegal multibyte sequence"; - return false; - default: - return false; - } - } - return true; -} - -/** - * Convert between character sets, allocating a new buffer using talloc for the result. - * - * @param srclen length of source buffer. - * @param dest always set at least to NULL - * @note -1 is not accepted for srclen. - * - * @returns Size in bytes of the converted string; or -1 in case of error. - **/ - -_PUBLIC_ bool convert_string_talloc_handle(TALLOC_CTX *ctx, - struct smb_iconv_handle *ic, - charset_t from, charset_t to, - void const *src, size_t srclen, - void *dst, size_t *converted_size) -{ - void **dest = (void **)dst; - smb_iconv_t descriptor; - ssize_t ret; - - *dest = NULL; - - if (src == NULL || srclen == (size_t)-1 || srclen == 0) - return false; - - descriptor = get_conv_handle(ic, from, to); - - if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) { - /* conversion not supported, return -1*/ - DEBUG(3, ("convert_string_talloc_handle: conversion from %s to %s not supported!\n", - charset_name(ic, from), - charset_name(ic, to))); - return false; - } - - ret = iconv_talloc(ctx, descriptor, src, srclen, dest); - if (ret == -1) - return false; - if (converted_size != NULL) - *converted_size = ret; - return true; -} - diff --git a/lib/util/charset/convert_string.c b/lib/util/charset/convert_string.c index f1772f448c..41a0c75c10 100644 --- a/lib/util/charset/convert_string.c +++ b/lib/util/charset/convert_string.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "system/iconv.h" /** * @file @@ -387,7 +388,7 @@ bool convert_string_talloc_handle(TALLOC_CTX *ctx, struct smb_iconv_handle *ic, } /* +2 is for ucs2 null termination. */ - ob = (char *)TALLOC_REALLOC(ctx, ob, destlen + 2); + ob = talloc_realloc(ctx, ob, char, destlen + 2); if (!ob) { DEBUG(0, ("convert_string_talloc: realloc failed!\n")); @@ -428,7 +429,7 @@ bool convert_string_talloc_handle(TALLOC_CTX *ctx, struct smb_iconv_handle *ic, */ if (o_len > 1024) { /* We're shrinking here so we know the +2 is safe from wrap. */ - ob = (char *)TALLOC_REALLOC(ctx,ob,destlen + 2); + ob = talloc_realloc(ctx,ob, char, destlen + 2); } if (destlen && !ob) { diff --git a/lib/util/charset/util_unistr.c b/lib/util/charset/util_unistr.c index a1be501c7c..895d958deb 100644 --- a/lib/util/charset/util_unistr.c +++ b/lib/util/charset/util_unistr.c @@ -585,68 +585,3 @@ _PUBLIC_ ssize_t pull_string(char *dest, const void *src, size_t dest_len, size_ return -1; } } - - -/** - * Convert string from one encoding to another, making error checking etc - * - * @param src pointer to source string (multibyte or singlebyte) - * @param srclen length of the source string in bytes - * @param dest pointer to destination string (multibyte or singlebyte) - * @param destlen maximal length allowed for string - * @param converted_size the number of bytes occupied in the destination - * - * @returns true on success, false on fail. - **/ -_PUBLIC_ bool convert_string(charset_t from, charset_t to, - void const *src, size_t srclen, - void *dest, size_t destlen, - size_t *converted_size) -{ - return convert_string_handle(get_iconv_handle(), from, to, - src, srclen, - dest, destlen, converted_size); -} - -/** - * Convert string from one encoding to another, making error checking etc - * - * @param src pointer to source string (multibyte or singlebyte) - * @param srclen length of the source string in bytes - * @param dest pointer to destination string (multibyte or singlebyte) - * @param destlen maximal length allowed for string - * @param converted_size the number of bytes occupied in the destination - * - * @returns true on success, false on fail. - **/ -_PUBLIC_ bool convert_string_error(charset_t from, charset_t to, - void const *src, size_t srclen, - void *dest, size_t destlen, - size_t *converted_size) -{ - return convert_string_error_handle(get_iconv_handle(), from, to, - src, srclen, - dest, destlen, converted_size); -} - -/** - * Convert between character sets, allocating a new buffer using talloc for the result. - * - * @param srclen length of source buffer. - * @param dest always set at least to NULL - * @param converted_size Size in bytes of the converted string - * @note -1 is not accepted for srclen. - * - * @returns boolean indication whether the conversion succeeded - **/ - -_PUBLIC_ bool convert_string_talloc(TALLOC_CTX *ctx, - charset_t from, charset_t to, - void const *src, size_t srclen, - void *dest, size_t *converted_size) -{ - return convert_string_talloc_handle(ctx, get_iconv_handle(), - from, to, src, srclen, dest, - converted_size); -} - diff --git a/lib/util/charset/wscript_build b/lib/util/charset/wscript_build index 29e168dce1..80a649976b 100644 --- a/lib/util/charset/wscript_build +++ b/lib/util/charset/wscript_build @@ -3,7 +3,7 @@ if bld.env._SAMBA_BUILD_ == 4: bld.SAMBA_SUBSYSTEM('CHARSET', - source='charcnv.c util_unistr.c', + source='util_unistr.c', public_deps='CODEPOINTS', public_headers='charset.h', ) @@ -13,6 +13,6 @@ bld.SAMBA_SUBSYSTEM('ICONV_WRAPPER', public_deps='iconv replace talloc') bld.SAMBA_SUBSYSTEM('CODEPOINTS', - source='codepoints.c util_str.c util_unistr_w.c', + source='codepoints.c convert_string.c util_str.c util_unistr_w.c charcnv.c', deps='DYNCONFIG ICONV_WRAPPER' ) -- cgit From eee1ff2fb56f46fb3c6aa7dfe51583e3b489fb5d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 28 Apr 2011 10:48:43 +1000 Subject: lib/util/charset Add tests for srclen=-1 behaviour. This confirms that we do include a null terminator in all non-failed conversions. Andrew Bartlett Signed-off-by: Andrew Tridgell --- lib/util/charset/tests/convert_string.c | 443 ++++++++++++++++++++++++++++++++ 1 file changed, 443 insertions(+) (limited to 'lib/util') diff --git a/lib/util/charset/tests/convert_string.c b/lib/util/charset/tests/convert_string.c index 32fc11f527..bd140d59db 100644 --- a/lib/util/charset/tests/convert_string.c +++ b/lib/util/charset/tests/convert_string.c @@ -282,6 +282,191 @@ static bool test_gd_iso8859_cp850_handle(struct torture_context *tctx) return true; } +static bool test_gd_minus_1_handle(struct torture_context *tctx) +{ + struct smb_iconv_handle *iconv_handle; + DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64); + DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64); + DATA_BLOB gd_utf16le = base64_decode_data_blob(gd_utf16le_base64); + DATA_BLOB gd_output; + DATA_BLOB gd_utf8_terminated; + DATA_BLOB gd_cp850_terminated; + DATA_BLOB gd_utf16le_terminated; + + talloc_steal(tctx, gd_utf8.data); + talloc_steal(tctx, gd_cp850.data); + talloc_steal(tctx, gd_utf16le.data); + + iconv_handle = get_iconv_testing_handle(tctx, "CP850", "CP850", "UTF8"); + torture_assert(tctx, iconv_handle, "getting iconv handle"); + + gd_utf8_terminated = data_blob_talloc(tctx, NULL, gd_utf8.length + 1); + memcpy(gd_utf8_terminated.data, gd_utf8.data, gd_utf8.length); + gd_utf8_terminated.data[gd_utf8.length] = '\0'; + + gd_cp850_terminated = data_blob_talloc(tctx, NULL, gd_cp850.length + 1); + memcpy(gd_cp850_terminated.data, gd_cp850.data, gd_cp850.length); + gd_cp850_terminated.data[gd_cp850.length] = '\0'; + + gd_utf16le_terminated = data_blob_talloc(tctx, NULL, gd_utf16le.length + 2); + memcpy(gd_utf16le_terminated.data, gd_utf16le.data, gd_utf16le.length); + gd_utf16le_terminated.data[gd_utf16le.length] = '\0'; + gd_utf16le_terminated.data[gd_utf16le.length + 1] = '\0'; + + gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF8, CH_UTF16LE, + gd_utf8_terminated.data, -1, + (void *)gd_output.data, gd_output.length, &gd_output.length), + "conversion from UTF8 to UTF16LE null terminated"); + torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated"); + + gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10); + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF8, CH_UTF16LE, + gd_utf8_terminated.data, -1, + (void *)gd_output.data, gd_utf16le.length, &gd_output.length) == false, + "conversion from UTF8 to UTF16LE null terminated should fail"); + torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG"); + torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le, "conversion from UTF8 to UTF16LE null terminated"); + + gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10); + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF8, CH_UTF16LE, + gd_utf8_terminated.data, -1, + (void *)gd_output.data, gd_utf16le.length - 1, &gd_output.length) == false, + "conversion from UTF8 to UTF16LE null terminated should fail"); + torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG"); + + gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10); + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF8, CH_UTF16LE, + gd_utf8_terminated.data, -1, + (void *)gd_output.data, gd_utf16le.length - 2, &gd_output.length) == false, + "conversion from UTF8 to UTF16LE null terminated should fail"); + torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG"); + + gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10); + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF16LE, CH_UTF8, + gd_utf16le_terminated.data, -1, + (void *)gd_output.data, gd_output.length, &gd_output.length), + "conversion from UTF16LE to UTF8 null terminated"); + torture_assert_data_blob_equal(tctx, gd_output, gd_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated"); + + gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF16LE, CH_UTF8, + gd_utf16le_terminated.data, -1, + (void *)gd_output.data, gd_utf8.length, &gd_output.length) == false, + "conversion from UTF16LE to UTF8 null terminated should fail"); + torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG"); + torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF16LE to UTF8 null terminated"); + + gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF16LE, CH_UTF8, + gd_utf16le_terminated.data, -1, + (void *)gd_output.data, gd_utf8.length - 1, &gd_output.length) == false, + "conversion from UTF16LE to UTF8 null terminated should fail"); + torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG"); + + gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF16LE, CH_UTF8, + gd_utf16le_terminated.data, -1, + (void *)gd_output.data, gd_utf8.length - 2, &gd_output.length) == false, + "conversion from UTF16LE to UTF8 null terminated should fail"); + torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG"); + + gd_output = data_blob_talloc(tctx, NULL, gd_cp850.length + 10); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF16LE, CH_DOS, + gd_utf16le_terminated.data, -1, + (void *)gd_output.data, gd_output.length, &gd_output.length), + "conversion from UTF16LE to CP850 (dos) null terminated"); + torture_assert_data_blob_equal(tctx, gd_output, gd_cp850_terminated, "conversion from UTF16LE to CP850 (dos) null terminated"); + + /* Now null terminate the string early, the confirm we don't skip the NULL and convert any further */ + gd_utf8_terminated.data[3] = '\0'; + gd_utf8_terminated.length = 4; /* used for the comparison only */ + + gd_cp850_terminated.data[2] = '\0'; + gd_cp850_terminated.length = 3; /* used for the comparison only */ + + gd_utf16le_terminated.data[4] = '\0'; + gd_utf16le_terminated.data[5] = '\0'; + gd_utf16le_terminated.length = 6; /* used for the comparison only */ + + gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF8, CH_UTF16LE, + gd_utf8_terminated.data, -1, + (void *)gd_output.data, gd_output.length, &gd_output.length), + "conversion from UTF8 to UTF16LE null terminated"); + torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early"); + + gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF16LE, CH_UTF8, + gd_utf16le_terminated.data, -1, + (void *)gd_output.data, gd_output.length, &gd_output.length), + "conversion from UTF16LE to UTF8 null terminated"); + torture_assert_data_blob_equal(tctx, gd_output, gd_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated early"); + + gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_DOS, CH_UTF16LE, + gd_cp850_terminated.data, -1, + (void *)gd_output.data, gd_output.length, &gd_output.length), + "conversion from CP850 to UTF16LE null terminated"); + torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early"); + + gd_output = data_blob_talloc(tctx, NULL, gd_cp850.length + 10); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF16LE, CH_DOS, + gd_utf16le_terminated.data, -1, + (void *)gd_output.data, gd_output.length, &gd_output.length), + "conversion from UTF16LE to UTF8 null terminated"); + torture_assert_data_blob_equal(tctx, gd_output, gd_cp850_terminated, "conversion from UTF16LE to UTF8 null terminated early"); + + /* Now null terminate the string particularly early, the confirm we don't skip the NULL and convert any further */ + gd_utf8_terminated.data[1] = '\0'; + gd_utf8_terminated.length = 2; /* used for the comparison only */ + + gd_utf16le_terminated.data[2] = '\0'; + gd_utf16le_terminated.data[3] = '\0'; + gd_utf16le_terminated.length = 4; /* used for the comparison only */ + + gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, CH_UTF8, CH_UTF16LE, + gd_utf8_terminated.data, -1, + (void *)gd_output.data, gd_output.length, &gd_output.length), + "conversion from UTF8 to UTF16LE null terminated"); + torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated very early"); + + gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF16LE, CH_UTF8, + gd_utf16le_terminated.data, -1, + (void *)gd_output.data, gd_output.length, &gd_output.length), + "conversion from UTF16LE to UTF8 null terminated"); + torture_assert_data_blob_equal(tctx, gd_output, gd_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated very early"); + + return true; +} + static bool test_gd_ascii_handle(struct torture_context *tctx) { struct smb_iconv_handle *iconv_handle; @@ -472,6 +657,261 @@ static bool test_plato_english_iso8859_cp850_handle(struct torture_context *tctx return true; } +static bool test_plato_english_minus_1_handle(struct torture_context *tctx) +{ + struct smb_iconv_handle *iconv_handle; + DATA_BLOB plato_english_utf8 = data_blob_string_const(plato_english_ascii); + DATA_BLOB plato_english_utf16le = base64_decode_data_blob(plato_english_utf16le_base64); + DATA_BLOB plato_english_output; + DATA_BLOB plato_english_utf8_terminated; + DATA_BLOB plato_english_utf16le_terminated; + + talloc_steal(tctx, plato_english_utf16le.data); + + iconv_handle = get_iconv_testing_handle(tctx, "ISO8859-1", "CP850", "UTF8"); + torture_assert(tctx, iconv_handle, "getting iconv handle"); + + plato_english_utf8_terminated = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 1); + memcpy(plato_english_utf8_terminated.data, plato_english_utf8.data, plato_english_utf8.length); + plato_english_utf8_terminated.data[plato_english_utf8.length] = '\0'; + + plato_english_utf16le_terminated = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 2); + memcpy(plato_english_utf16le_terminated.data, plato_english_utf16le.data, plato_english_utf16le.length); + plato_english_utf16le_terminated.data[plato_english_utf16le.length] = '\0'; + plato_english_utf16le_terminated.data[plato_english_utf16le.length + 1] = '\0'; + + plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 10); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF8, CH_UTF16LE, + plato_english_utf8_terminated.data, -1, + (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length), + "conversion from UTF8 to UTF16LE null terminated"); + torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated"); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF8, CH_UTF16LE, + plato_english_utf8_terminated.data, -1, + (void *)plato_english_output.data, plato_english_utf16le.length, &plato_english_output.length) == false, + "conversion from UTF8 to UTF16LE null terminated should fail"); + torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG"); + torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le, "conversion from UTF8 to UTF16LE null terminated"); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF8, CH_UTF16LE, + plato_english_utf8_terminated.data, -1, + (void *)plato_english_output.data, plato_english_utf16le.length - 1, &plato_english_output.length) == false, + "conversion from UTF8 to UTF16LE null terminated should fail"); + torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG"); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF8, CH_UTF16LE, + plato_english_utf8_terminated.data, -1, + (void *)plato_english_output.data, plato_english_utf16le.length - 2, &plato_english_output.length) == false, + "conversion from UTF8 to UTF16LE null terminated should fail"); + torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG"); + + plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 10); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF16LE, CH_UTF8, + plato_english_utf16le_terminated.data, -1, + (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length), + "conversion from UTF16LE to UTF8 null terminated"); + torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated"); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF16LE, CH_UTF8, + plato_english_utf16le_terminated.data, -1, + (void *)plato_english_output.data, plato_english_utf8.length, &plato_english_output.length) == false, + "conversion from UTF16LE to UTF8 null terminated should fail"); + torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG"); + torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 null terminated"); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF16LE, CH_UTF8, + plato_english_utf16le_terminated.data, -1, + (void *)plato_english_output.data, plato_english_utf8.length - 1, &plato_english_output.length) == false, + "conversion from UTF16LE to UTF8 null terminated should fail"); + torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG"); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF16LE, CH_UTF8, + plato_english_utf16le_terminated.data, -1, + (void *)plato_english_output.data, plato_english_utf8.length - 2, &plato_english_output.length) == false, + "conversion from UTF16LE to UTF8 null terminated should fail"); + torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG"); + + /* Now null terminate the string early, the confirm we don't skip the NULL and convert any further */ + plato_english_utf8_terminated.data[3] = '\0'; + plato_english_utf8_terminated.length = 4; /* used for the comparison only */ + + plato_english_utf16le_terminated.data[6] = '\0'; + plato_english_utf16le_terminated.data[7] = '\0'; + plato_english_utf16le_terminated.length = 8; /* used for the comparison only */ + + plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 10); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF8, CH_UTF16LE, + plato_english_utf8_terminated.data, -1, + (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length), + "conversion from UTF8 to UTF16LE null terminated"); + torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early"); + + plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 10); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF16LE, CH_UTF8, + plato_english_utf16le_terminated.data, -1, + (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length), + "conversion from UTF16LE to UTF8 null terminated"); + torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated early"); + + + /* Now null terminate the string particularly early, the confirm we don't skip the NULL and convert any further */ + plato_english_utf8_terminated.data[1] = '\0'; + plato_english_utf8_terminated.length = 2; /* used for the comparison only */ + + plato_english_utf16le_terminated.data[2] = '\0'; + plato_english_utf16le_terminated.data[3] = '\0'; + plato_english_utf16le_terminated.length = 4; /* used for the comparison only */ + + plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 10); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, CH_UTF8, CH_UTF16LE, + plato_english_utf8_terminated.data, -1, + (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length), + "conversion from UTF8 to UTF16LE null terminated"); + torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated very early"); + + plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 10); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF16LE, CH_UTF8, + plato_english_utf16le_terminated.data, -1, + (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length), + "conversion from UTF16LE to UTF8 null terminated"); + torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated very early"); + + return true; +} + +static bool test_plato_minus_1_handle(struct torture_context *tctx) +{ + struct smb_iconv_handle *iconv_handle; + DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64); + DATA_BLOB plato_utf16le = base64_decode_data_blob(plato_utf16le_base64); + DATA_BLOB plato_output; + DATA_BLOB plato_utf8_terminated; + DATA_BLOB plato_utf16le_terminated; + + talloc_steal(tctx, plato_utf8.data); + talloc_steal(tctx, plato_utf16le.data); + + iconv_handle = get_iconv_testing_handle(tctx, "ISO8859-1", "CP850", "UTF8"); + torture_assert(tctx, iconv_handle, "getting iconv handle"); + + plato_utf8_terminated = data_blob_talloc(tctx, NULL, plato_utf8.length + 1); + memcpy(plato_utf8_terminated.data, plato_utf8.data, plato_utf8.length); + plato_utf8_terminated.data[plato_utf8.length] = '\0'; + + plato_utf16le_terminated = data_blob_talloc(tctx, NULL, plato_utf16le.length + 2); + memcpy(plato_utf16le_terminated.data, plato_utf16le.data, plato_utf16le.length); + plato_utf16le_terminated.data[plato_utf16le.length] = '\0'; + plato_utf16le_terminated.data[plato_utf16le.length + 1] = '\0'; + + plato_output = data_blob_talloc(tctx, NULL, plato_utf16le.length + 10); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF8, CH_UTF16LE, + plato_utf8_terminated.data, -1, + (void *)plato_output.data, plato_output.length, &plato_output.length), + "conversion from UTF8 to UTF16LE null terminated"); + torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated"); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF8, CH_UTF16LE, + plato_utf8_terminated.data, -1, + (void *)plato_output.data, plato_utf16le.length, &plato_output.length) == false, + "conversion from UTF8 to UTF16LE null terminated should fail"); + torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG"); + torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE null terminated"); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF8, CH_UTF16LE, + plato_utf8_terminated.data, -1, + (void *)plato_output.data, plato_utf16le.length - 1, &plato_output.length) == false, + "conversion from UTF8 to UTF16LE null terminated should fail"); + torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG"); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF8, CH_UTF16LE, + plato_utf8_terminated.data, -1, + (void *)plato_output.data, plato_utf16le.length - 2, &plato_output.length) == false, + "conversion from UTF8 to UTF16LE null terminated should fail"); + torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG"); + + plato_output = data_blob_talloc(tctx, NULL, plato_utf8.length + 10); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF16LE, CH_UTF8, + plato_utf16le_terminated.data, -1, + (void *)plato_output.data, plato_output.length, &plato_output.length), + "conversion from UTF16LE to UTF8 null terminated"); + torture_assert_data_blob_equal(tctx, plato_output, plato_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated"); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF16LE, CH_UTF8, + plato_utf16le_terminated.data, -1, + (void *)plato_output.data, plato_utf8.length, &plato_output.length) == false, + "conversion from UTF16LE to UTF8 null terminated should fail"); + torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG"); + torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to UTF8 null terminated"); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF16LE, CH_UTF8, + plato_utf16le_terminated.data, -1, + (void *)plato_output.data, plato_utf8.length - 1, &plato_output.length) == false, + "conversion from UTF16LE to UTF8 null terminated should fail"); + torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG"); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF16LE, CH_UTF8, + plato_utf16le_terminated.data, -1, + (void *)plato_output.data, plato_utf8.length - 2, &plato_output.length) == false, + "conversion from UTF16LE to UTF8 null terminated should fail"); + torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG"); + + /* Now null terminate the string early, the confirm we don't skip the NULL and convert any further */ + plato_utf8_terminated.data[5] = '\0'; + plato_utf8_terminated.length = 6; /* used for the comparison only */ + + plato_utf16le_terminated.data[4] = '\0'; + plato_utf16le_terminated.data[5] = '\0'; + plato_utf16le_terminated.length = 6; /* used for the comparison only */ + + plato_output = data_blob_talloc(tctx, NULL, plato_utf16le.length + 10); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF8, CH_UTF16LE, + plato_utf8_terminated.data, -1, + (void *)plato_output.data, plato_output.length, &plato_output.length), + "conversion from UTF8 to UTF16LE null terminated"); + torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early"); + + plato_output = data_blob_talloc(tctx, NULL, plato_utf8.length + 10); + + torture_assert(tctx, convert_string_error_handle(iconv_handle, + CH_UTF16LE, CH_UTF8, + plato_utf16le_terminated.data, -1, + (void *)plato_output.data, plato_output.length, &plato_output.length), + "conversion from UTF16LE to UTF8 null terminated"); + torture_assert_data_blob_equal(tctx, plato_output, plato_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated early"); + + return true; +} + static bool test_plato_cp850_utf8_handle(struct torture_context *tctx) { struct smb_iconv_handle *iconv_handle; @@ -1248,9 +1688,12 @@ struct torture_suite *torture_local_convert_string_handle(TALLOC_CTX *mem_ctx) struct torture_suite *suite = torture_suite_create(mem_ctx, "convert_string_handle"); torture_suite_add_simple_test(suite, "gd_ascii", test_gd_ascii_handle); + torture_suite_add_simple_test(suite, "gd_minus_1", test_gd_minus_1_handle); torture_suite_add_simple_test(suite, "gd_iso8859_cp850", test_gd_iso8859_cp850_handle); torture_suite_add_simple_test(suite, "plato_english_iso8859_cp850", test_plato_english_iso8859_cp850_handle); + torture_suite_add_simple_test(suite, "plato_english_minus_1", test_plato_english_minus_1_handle); torture_suite_add_simple_test(suite, "plato_cp850_utf8", test_plato_cp850_utf8_handle); + torture_suite_add_simple_test(suite, "plato_minus_1", test_plato_minus_1_handle); torture_suite_add_simple_test(suite, "plato_latin_cp850_utf8", test_plato_latin_cp850_utf8_handle); return suite; } -- cgit From d17f4352fe2493be433a21e2f47453968aafdc4d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 28 Apr 2011 10:50:06 +1000 Subject: lib/util/charset Make fast path from UTF16 to '8 bit' charsets clearer This breaks the fast path into handling for -1 and handling for specified lenghts, avoding branch operations on each character. Pair-Programmed-With: Andrew Bartlett Signed-off-by: Andrew Tridgell --- lib/util/charset/convert_string.c | 42 ++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 14 deletions(-) (limited to 'lib/util') diff --git a/lib/util/charset/convert_string.c b/lib/util/charset/convert_string.c index 41a0c75c10..8243e63a72 100644 --- a/lib/util/charset/convert_string.c +++ b/lib/util/charset/convert_string.c @@ -178,28 +178,29 @@ bool convert_string_error_handle(struct smb_iconv_handle *ic, size_t slen = srclen; size_t dlen = destlen; unsigned char lastp = '\0'; + bool ret; - /* If all characters are ascii, fast path here. */ - while (((slen == (size_t)-1) || (slen >= 1)) && dlen) { - if (slen >= 2 && ((lastp = *p) <= 0x7f) && (p[1] == 0)) { + if (slen == (size_t)-1) { + while (dlen && + ((lastp = *p) <= 0x7f) && (p[1] == 0)) { *q++ = *p; - if (slen != (size_t)-1) { - slen -= 2; - } p += 2; dlen--; retval++; if (!lastp) break; - } else { -#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS - goto general_case; -#else - bool ret = convert_string_internal(ic, from, to, p, slen, q, dlen, converted_size); - *converted_size += retval; - return ret; -#endif } + if (lastp != 0) goto slow_path; + } else { + while (slen >= 2 && dlen && + (*p <= 0x7f) && (p[1] == 0)) { + *q++ = *p; + slen -= 2; + p += 2; + dlen--; + retval++; + } + if (slen != 0) goto slow_path; } *converted_size = retval; @@ -213,6 +214,19 @@ bool convert_string_error_handle(struct smb_iconv_handle *ic, } } return true; + + slow_path: + /* come here when we hit a character we can't deal + * with in the fast path + */ +#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS + goto general_case; +#else + ret = convert_string_internal(ic, from, to, p, slen, q, dlen, converted_size); + *converted_size += retval; + return ret; +#endif + } else if (from != CH_UTF16LE && from != CH_UTF16BE && to == CH_UTF16LE) { const unsigned char *p = (const unsigned char *)src; unsigned char *q = (unsigned char *)dest; -- cgit From 790ab3e0dbd77ba2d08ef9c39d00f542fbe01358 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 28 Apr 2011 10:56:36 +1000 Subject: lib/util/charset Add copyright headers Autobuild-User: Andrew Bartlett Autobuild-Date: Thu Apr 28 04:13:44 CEST 2011 on sn-devel-104 --- lib/util/charset/convert_string.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/util') diff --git a/lib/util/charset/convert_string.c b/lib/util/charset/convert_string.c index 8243e63a72..51f9fec137 100644 --- a/lib/util/charset/convert_string.c +++ b/lib/util/charset/convert_string.c @@ -2,7 +2,8 @@ Unix SMB/CIFS implementation. Character set conversion Extensions Copyright (C) Igor Vergeichik 2001 - Copyright (C) Andrew Tridgell 2001 + Copyright (C) Andrew Tridgell 2001-2011 + Copyright (C) Andrew Bartlett 2011 Copyright (C) Simo Sorce 2001 Copyright (C) Martin Pool 2003 -- cgit From 0df4061cffd32d4a989c5fd177136c2cc3730e7c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 28 Apr 2011 11:41:31 +1000 Subject: lib/util/charset Merge talloc-based pull and push charset functions These were copied from source3/lib/charcnv.c Andrew Bartlett --- lib/util/charset/pull_push.c | 150 +++++++++++++++++++++++++++++++++++++++++ lib/util/charset/util_unistr.c | 94 -------------------------- lib/util/charset/wscript_build | 2 +- 3 files changed, 151 insertions(+), 95 deletions(-) create mode 100644 lib/util/charset/pull_push.c (limited to 'lib/util') diff --git a/lib/util/charset/pull_push.c b/lib/util/charset/pull_push.c new file mode 100644 index 0000000000..b7a5bcdc65 --- /dev/null +++ b/lib/util/charset/pull_push.c @@ -0,0 +1,150 @@ +/* + Unix SMB/CIFS implementation. + Character set conversion Extensions + Copyright (C) Igor Vergeichik 2001 + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Simo Sorce 2001 + Copyright (C) Martin Pool 2003 + + 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 . + +*/ + +#include "includes.h" +#include "system/locale.h" + +/** + * Copy a string from a unix char* src to a UCS2 destination, + * allocating a buffer using talloc(). + * + * @param dest always set at least to NULL + * @parm converted_size set to the number of bytes occupied by the string in + * the destination on success. + * + * @return true if new buffer was correctly allocated, and string was + * converted. + **/ +bool push_ucs2_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src, + size_t *converted_size) +{ + size_t src_len = strlen(src)+1; + + *dest = NULL; + return convert_string_talloc(ctx, CH_UNIX, CH_UTF16LE, src, src_len, + (void **)dest, converted_size); +} + +/** + * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer using talloc + * + * @param dest always set at least to NULL + * @parm converted_size set to the number of bytes occupied by the string in + * the destination on success. + * + * @return true if new buffer was correctly allocated, and string was + * converted. + **/ + +bool push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src, + size_t *converted_size) +{ + size_t src_len = strlen(src)+1; + + *dest = NULL; + return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len, + (void**)dest, converted_size); +} + +/** + * Copy a string from a unix char* src to an ASCII destination, + * allocating a buffer using talloc(). + * + * @param dest always set at least to NULL + * + * @param converted_size The number of bytes occupied by the string in the destination + * @returns boolean indicating if the conversion was successful + **/ +bool push_ascii_talloc(TALLOC_CTX *mem_ctx, char **dest, const char *src, size_t *converted_size) +{ + size_t src_len = strlen(src)+1; + + *dest = NULL; + return convert_string_talloc(mem_ctx, CH_UNIX, CH_DOS, src, src_len, + (void **)dest, converted_size); +} + +/** + * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer using talloc + * + * @param dest always set at least to NULL + * @parm converted_size set to the number of bytes occupied by the string in + * the destination on success. + * + * @return true if new buffer was correctly allocated, and string was + * converted. + **/ + +bool pull_ucs2_talloc(TALLOC_CTX *ctx, char **dest, const smb_ucs2_t *src, + size_t *converted_size) +{ + size_t src_len = (strlen_w(src)+1) * sizeof(smb_ucs2_t); + + *dest = NULL; + return convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, src, src_len, + (void **)dest, converted_size); +} + + +/** + * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc + * + * @param dest always set at least to NULL + * @parm converted_size set to the number of bytes occupied by the string in + * the destination on success. + * + * @return true if new buffer was correctly allocated, and string was + * converted. + **/ + +bool pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src, + size_t *converted_size) +{ + size_t src_len = strlen(src)+1; + + *dest = NULL; + return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len, + (void **)dest, converted_size); +} + + +/** + * Copy a string from a DOS src to a unix char * destination, allocating a buffer using talloc + * + * @param dest always set at least to NULL + * @parm converted_size set to the number of bytes occupied by the string in + * the destination on success. + * + * @return true if new buffer was correctly allocated, and string was + * converted. + **/ + +bool pull_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src, + size_t *converted_size) +{ + size_t src_len = strlen(src)+1; + + *dest = NULL; + return convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len, + (void **)dest, converted_size); +} diff --git a/lib/util/charset/util_unistr.c b/lib/util/charset/util_unistr.c index 895d958deb..a585022e89 100644 --- a/lib/util/charset/util_unistr.c +++ b/lib/util/charset/util_unistr.c @@ -296,23 +296,6 @@ static bool push_ascii(void *dest, const char *src, size_t dest_len, int flags, return convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len, converted_size); } -/** - * Copy a string from a unix char* src to an ASCII destination, - * allocating a buffer using talloc(). - * - * @param dest always set at least to NULL - * - * @returns The number of bytes occupied by the string in the destination - * or -1 in case of error. - **/ -_PUBLIC_ bool push_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src, size_t *converted_size) -{ - size_t src_len = strlen(src)+1; - *dest = NULL; - return convert_string_talloc(ctx, CH_UNIX, CH_DOS, src, src_len, (void **)dest, converted_size); -} - - /** * Copy a string from a dos codepage source to a unix char* destination. * @@ -410,38 +393,6 @@ static ssize_t push_ucs2(void *dest, const char *src, size_t dest_len, int flags } -/** - * Copy a string from a unix char* src to a UCS2 destination, - * allocating a buffer using talloc(). - * - * @param dest always set at least to NULL - * - * @returns The number of bytes occupied by the string in the destination - * or -1 in case of error. - **/ -_PUBLIC_ bool push_ucs2_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src, size_t *converted_size) -{ - size_t src_len = strlen(src)+1; - *dest = NULL; - return convert_string_talloc(ctx, CH_UNIX, CH_UTF16, src, src_len, (void **)dest, converted_size); -} - - -/** - * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer using talloc - * - * @param dest always set at least to NULL - * - * @returns The number of bytes occupied by the string in the destination - **/ - -_PUBLIC_ bool push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src, size_t *converted_size) -{ - size_t src_len = strlen(src)+1; - *dest = NULL; - return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len, (void **)dest, converted_size); -} - /** Copy a string from a ucs2 source to a unix char* destination. Flags can have: @@ -483,51 +434,6 @@ static size_t pull_ucs2(char *dest, const void *src, size_t dest_len, size_t src return src_len; } -/** - * Copy a string from a ASCII src to a unix char * destination, allocating a buffer using talloc - * - * @param dest always set at least to NULL - * - * @returns The number of bytes occupied by the string in the destination - **/ - -_PUBLIC_ bool pull_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src, size_t *converted_size) -{ - size_t src_len = strlen(src)+1; - *dest = NULL; - return convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len, (void **)dest, converted_size); -} - -/** - * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer using talloc - * - * @param dest always set at least to NULL - * - * @returns The number of bytes occupied by the string in the destination - **/ - -_PUBLIC_ bool pull_ucs2_talloc(TALLOC_CTX *ctx, char **dest, const smb_ucs2_t *src, size_t *converted_size) -{ - size_t src_len = utf16_len(src); - *dest = NULL; - return convert_string_talloc(ctx, CH_UTF16, CH_UNIX, src, src_len, (void **)dest, converted_size); -} - -/** - * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc - * - * @param dest always set at least to NULL - * - * @returns The number of bytes occupied by the string in the destination - **/ - -_PUBLIC_ bool pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src, size_t *converted_size) -{ - size_t src_len = strlen(src)+1; - *dest = NULL; - return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len, (void **)dest, converted_size); -} - /** Copy a string from a char* src to a unicode or ascii dos codepage destination choosing unicode or ascii based on the diff --git a/lib/util/charset/wscript_build b/lib/util/charset/wscript_build index 80a649976b..771ff5dc24 100644 --- a/lib/util/charset/wscript_build +++ b/lib/util/charset/wscript_build @@ -13,6 +13,6 @@ bld.SAMBA_SUBSYSTEM('ICONV_WRAPPER', public_deps='iconv replace talloc') bld.SAMBA_SUBSYSTEM('CODEPOINTS', - source='codepoints.c convert_string.c util_str.c util_unistr_w.c charcnv.c', + source='codepoints.c convert_string.c util_str.c util_unistr_w.c charcnv.c pull_push.c', deps='DYNCONFIG ICONV_WRAPPER' ) -- cgit From 9a9124b08760a6235059f517b9a138337754cd02 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 29 Apr 2011 13:19:41 +1000 Subject: lib/util/charset Move strstr_m() to the top level --- lib/util/charset/charset.h | 1 + lib/util/charset/util_str.c | 83 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) (limited to 'lib/util') diff --git a/lib/util/charset/charset.h b/lib/util/charset/charset.h index 1078035592..d027daa052 100644 --- a/lib/util/charset/charset.h +++ b/lib/util/charset/charset.h @@ -155,6 +155,7 @@ bool strhasupper_handle(struct smb_iconv_handle *ic, const char *string); char *strrchr_m(const char *s, char c); char *strchr_m(const char *s, char c); +char *strstr_m(const char *src, const char *findstr); bool push_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src, size_t *converted_size); bool push_ucs2_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src, size_t *converted_size); diff --git a/lib/util/charset/util_str.c b/lib/util/charset/util_str.c index e8f0b788b1..71a37787ae 100644 --- a/lib/util/charset/util_str.c +++ b/lib/util/charset/util_str.c @@ -5,6 +5,8 @@ Copyright (C) Simo Sorce 2001 Copyright (C) Andrew Bartlett 2011 Copyright (C) Jeremy Allison 1992-2007 + Copyright (C) Martin Pool 2003 + Copyright (C) James Peach 2006 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 @@ -473,3 +475,84 @@ _PUBLIC_ bool strhasupper(const char *string) struct smb_iconv_handle *ic = get_iconv_handle(); return strhasupper_handle(ic, string); } + +/*********************************************************************** + strstr_m - We convert via ucs2 for now. +***********************************************************************/ + +char *strstr_m(const char *src, const char *findstr) +{ + smb_ucs2_t *p; + smb_ucs2_t *src_w, *find_w; + const char *s; + char *s2; + char *retp; + + size_t converted_size, findstr_len = 0; + + /* for correctness */ + if (!findstr[0]) { + return (char*)src; + } + + /* Samba does single character findstr calls a *lot*. */ + if (findstr[1] == '\0') + return strchr_m(src, *findstr); + + /* 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) */ + + for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) { + if (*s == *findstr) { + if (!findstr_len) + findstr_len = strlen(findstr); + + if (strncmp(s, findstr, findstr_len) == 0) { + return (char *)s; + } + } + } + + if (!*s) + return NULL; + +#if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */ + /* 'make check' fails unless we do this */ + + /* With compose characters we must restart from the beginning. JRA. */ + s = src; +#endif + + if (!push_ucs2_talloc(talloc_tos(), &src_w, src, &converted_size)) { + DEBUG(0,("strstr_m: src malloc fail\n")); + return NULL; + } + + if (!push_ucs2_talloc(talloc_tos(), &find_w, findstr, &converted_size)) { + TALLOC_FREE(src_w); + DEBUG(0,("strstr_m: find malloc fail\n")); + return NULL; + } + + p = strstr_w(src_w, find_w); + + if (!p) { + TALLOC_FREE(src_w); + TALLOC_FREE(find_w); + return NULL; + } + + *p = 0; + if (!pull_ucs2_talloc(talloc_tos(), &s2, src_w, &converted_size)) { + TALLOC_FREE(src_w); + TALLOC_FREE(find_w); + DEBUG(0,("strstr_m: dest malloc fail\n")); + return NULL; + } + retp = (char *)(s+strlen(s2)); + TALLOC_FREE(src_w); + TALLOC_FREE(find_w); + TALLOC_FREE(s2); + return retp; +} -- cgit From 93ace5cc2484b53fc33d4689ccc286defbe2b728 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 29 Apr 2011 13:20:51 +1000 Subject: lib/util Re-merge the string_sub() and all_string_sub() from source3 Andrew Bartlett --- lib/util/substitute.c | 55 ++++++++++++++++++++++++++++++++++++++------------ lib/util/util.h | 2 ++ lib/util/wscript_build | 4 ++-- 3 files changed, 46 insertions(+), 15 deletions(-) (limited to 'lib/util') diff --git a/lib/util/substitute.c b/lib/util/substitute.c index 32945a7213..500d12777f 100644 --- a/lib/util/substitute.c +++ b/lib/util/substitute.c @@ -29,18 +29,20 @@ **/ /** - Substitute a string for a pattern in another string. Make sure there is + Substitute a string for a pattern in another string. Make sure there is enough room! - This routine looks for pattern in s and replaces it with - insert. It may do multiple replacements. + This routine looks for pattern in s and replaces it with + insert. It may do multiple replacements or just one. Any of " ; ' $ or ` in the insert string are replaced with _ if len==0 then the string cannot be extended. This is different from the old use of len==0 which was for no length checks to be done. **/ -_PUBLIC_ void string_sub(char *s, const char *pattern, const char *insert, size_t len) +static void string_sub2(char *s,const char *pattern, const char *insert, size_t len, + bool remove_unsafe_characters, bool replace_once, + bool allow_trailing_dollar) { char *p; ssize_t ls, lp, li, i; @@ -55,9 +57,10 @@ _PUBLIC_ void string_sub(char *s, const char *pattern, const char *insert, size_ if (len == 0) len = ls + 1; /* len is number of *bytes* */ - while (lp <= ls && (p = strstr(s, pattern))) { + while (lp <= ls && (p = strstr_m(s,pattern))) { if (ls + (li-lp) >= len) { - DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", + DEBUG(0,("ERROR: string overflow by " + "%d in string_sub(%.50s, %d)\n", (int)(ls + (li-lp) - len), pattern, (int)len)); break; @@ -67,25 +70,50 @@ _PUBLIC_ void string_sub(char *s, const char *pattern, const char *insert, size_ } for (i=0;i= len) { - DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", + DEBUG(0,("ERROR: string overflow by " + "%d in all_string_sub(%.50s, %d)\n", (int)(ls + (li-lp) - len), pattern, (int)len)); break; diff --git a/lib/util/util.h b/lib/util/util.h index 45779912f3..8bbaa0e393 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -284,6 +284,8 @@ _PUBLIC_ char *hex_encode_talloc(TALLOC_CTX *mem_ctx, const unsigned char *buff_ **/ _PUBLIC_ void string_sub(char *s,const char *pattern, const char *insert, size_t len); +_PUBLIC_ void string_sub_once(char *s, const char *pattern, + const char *insert, size_t len); _PUBLIC_ char *string_sub_talloc(TALLOC_CTX *mem_ctx, const char *s, const char *pattern, const char *insert); diff --git a/lib/util/wscript_build b/lib/util/wscript_build index f1bb9e7493..561dcc4379 100755 --- a/lib/util/wscript_build +++ b/lib/util/wscript_build @@ -5,11 +5,11 @@ common_util_sources = '''talloc_stack.c smb_threads.c xfile.c data_blob.c genrand.c fsusage.c blocking.c become_daemon.c signal.c system.c params.c util.c util_id.c util_net.c util_strlist.c idtree.c debug.c fault.c base64.c - util_str_common.c''' + util_str_common.c substitute.c''' common_util_headers = 'debug.h' common_util_public_deps = 'talloc pthread LIBCRYPTO' -s4_util_sources = '''dprintf.c ms_fnmatch.c parmlist.c substitute.c util_str.c''' +s4_util_sources = '''dprintf.c ms_fnmatch.c parmlist.c util_str.c''' s4_util_deps = 'DYNCONFIG' s4_util_public_deps = 'talloc CHARSET execinfo uid_wrapper' s4_util_public_headers = 'attr.h byteorder.h data_blob.h memory.h safe_string.h time.h talloc_stack.h xfile.h dlinklist.h util.h' -- cgit From bcd68837ee308aa4610a4c85783a4b64a349d4f9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 30 Apr 2011 13:10:18 +1000 Subject: lib/util Rename conv_str_size() -> conv_str_size_error() --- lib/util/util.h | 4 +--- lib/util/util_str.c | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'lib/util') diff --git a/lib/util/util.h b/lib/util/util.h index 8bbaa0e393..8dffece0da 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -371,12 +371,10 @@ _PUBLIC_ bool set_boolean(const char *boolean_string, bool *boolean); */ _PUBLIC_ bool conv_str_bool(const char * str, bool * val); -#if _SAMBA_BUILD_ == 4 /** * Convert a size specification like 16K into an integral number of bytes. **/ -_PUBLIC_ bool conv_str_size(const char * str, uint64_t * val); -#endif +_PUBLIC_ bool conv_str_size_error(const char * str, uint64_t * val); /** * Parse a uint64_t value from a string diff --git a/lib/util/util_str.c b/lib/util/util_str.c index cf1b07ff0f..cf3d60df8f 100644 --- a/lib/util/util_str.c +++ b/lib/util/util_str.c @@ -175,7 +175,7 @@ _PUBLIC_ bool conv_str_bool(const char * str, bool * val) /** * Convert a size specification like 16K into an integral number of bytes. **/ -_PUBLIC_ bool conv_str_size(const char * str, uint64_t * val) +_PUBLIC_ bool conv_str_size_error(const char * str, uint64_t * val) { char * end = NULL; unsigned long long lval; -- cgit From fbea52f74a80268446f45936a0cf40400aba8565 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 2 May 2011 15:23:08 +1000 Subject: lib/util Move more network utility functions from source3 into lib/util This will help with the merge of the interfaces layer. Andrew Bartlett --- lib/util/system.c | 72 ++++++++++++++++++++++++ lib/util/util.h | 14 ++++- lib/util/util_net.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/util/util_net.h | 35 ++++++++++++ 4 files changed, 275 insertions(+), 1 deletion(-) (limited to 'lib/util') diff --git a/lib/util/system.c b/lib/util/system.c index 9bf5de1a83..17c0553102 100644 --- a/lib/util/system.c +++ b/lib/util/system.c @@ -117,3 +117,75 @@ _PUBLIC_ pid_t sys_getpid(void) return mypid; } + + +_PUBLIC_ int sys_getpeereid( int s, uid_t *uid) +{ +#if defined(HAVE_PEERCRED) + struct ucred cred; + socklen_t cred_len = sizeof(struct ucred); + int ret; + + ret = getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void *)&cred, &cred_len); + if (ret != 0) { + return -1; + } + + if (cred_len != sizeof(struct ucred)) { + errno = EINVAL; + return -1; + } + + *uid = cred.uid; + return 0; +#else +#if defined(HAVE_GETPEEREID) + gid_t gid; + return getpeereid(s, uid, &gid); +#endif + errno = ENOSYS; + return -1; +#endif +} + +_PUBLIC_ int sys_getnameinfo(const struct sockaddr *psa, + int salen, + char *host, + size_t hostlen, + char *service, + size_t servlen, + int flags) +{ + /* + * For Solaris we must make sure salen is the + * correct length for the incoming sa_family. + */ + + if (salen == sizeof(struct sockaddr_storage)) { + salen = sizeof(struct sockaddr_in); +#if defined(HAVE_IPV6) + if (psa->sa_family == AF_INET6) { + salen = sizeof(struct sockaddr_in6); + } +#endif + } + return getnameinfo(psa, salen, host, hostlen, service, servlen, flags); +} + +_PUBLIC_ int sys_connect(int fd, const struct sockaddr * addr) +{ + socklen_t salen = (socklen_t)-1; + + if (addr->sa_family == AF_INET) { + salen = sizeof(struct sockaddr_in); + } else if (addr->sa_family == AF_UNIX) { + salen = sizeof(struct sockaddr_un); + } +#if defined(HAVE_IPV6) + else if (addr->sa_family == AF_INET6) { + salen = sizeof(struct sockaddr_in6); + } +#endif + + return connect(fd, addr, salen); +} diff --git a/lib/util/util.h b/lib/util/util.h index 8dffece0da..5ed8427498 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -131,8 +131,20 @@ _PUBLIC_ pid_t sys_fork(void); **/ _PUBLIC_ pid_t sys_getpid(void); -/* The following definitions come from lib/util/genrand.c */ +_PUBLIC_ int sys_getpeereid( int s, uid_t *uid); + +struct sockaddr; +_PUBLIC_ int sys_getnameinfo(const struct sockaddr *psa, + int salen, + char *host, + size_t hostlen, + char *service, + size_t servlen, + int flags); +_PUBLIC_ int sys_connect(int fd, const struct sockaddr * addr); + +/* The following definitions come from lib/util/genrand.c */ /** Copy any user given reseed data. **/ diff --git a/lib/util/util_net.c b/lib/util/util_net.c index 9c8f5c6d47..e80447128f 100644 --- a/lib/util/util_net.c +++ b/lib/util/util_net.c @@ -540,3 +540,158 @@ void set_sockaddr_port(struct sockaddr *psa, uint16_t port) } +/**************************************************************************** + Get a port number in host byte order from a sockaddr_storage. +****************************************************************************/ + +uint16_t get_sockaddr_port(const struct sockaddr_storage *pss) +{ + uint16_t port = 0; + + if (pss->ss_family != AF_INET) { +#if defined(HAVE_IPV6) + /* IPv6 */ + const struct sockaddr_in6 *sa6 = + (const struct sockaddr_in6 *)pss; + port = ntohs(sa6->sin6_port); +#endif + } else { + const struct sockaddr_in *sa = + (const struct sockaddr_in *)pss; + port = ntohs(sa->sin_port); + } + return port; +} + +/**************************************************************************** + Print out an IPv4 or IPv6 address from a struct sockaddr_storage. +****************************************************************************/ + +char *print_sockaddr_len(char *dest, + size_t destlen, + const struct sockaddr *psa, + socklen_t psalen) +{ + if (destlen > 0) { + dest[0] = '\0'; + } + (void)sys_getnameinfo(psa, + psalen, + dest, destlen, + NULL, 0, + NI_NUMERICHOST); + return dest; +} + +/**************************************************************************** + Print out an IPv4 or IPv6 address from a struct sockaddr_storage. +****************************************************************************/ + +char *print_sockaddr(char *dest, + size_t destlen, + const struct sockaddr_storage *psa) +{ + return print_sockaddr_len(dest, destlen, (struct sockaddr *)psa, + sizeof(struct sockaddr_storage)); +} + +/**************************************************************************** + Print out a canonical IPv4 or IPv6 address from a struct sockaddr_storage. +****************************************************************************/ + +char *print_canonical_sockaddr(TALLOC_CTX *ctx, + const struct sockaddr_storage *pss) +{ + char addr[INET6_ADDRSTRLEN]; + char *dest = NULL; + int ret; + + /* Linux getnameinfo() man pages says port is unitialized if + service name is NULL. */ + + ret = sys_getnameinfo((const struct sockaddr *)pss, + sizeof(struct sockaddr_storage), + addr, sizeof(addr), + NULL, 0, + NI_NUMERICHOST); + if (ret != 0) { + return NULL; + } + + if (pss->ss_family != AF_INET) { +#if defined(HAVE_IPV6) + dest = talloc_asprintf(ctx, "[%s]", addr); +#else + return NULL; +#endif + } else { + dest = talloc_asprintf(ctx, "%s", addr); + } + + return dest; +} + +/**************************************************************************** + Return the port number we've bound to on a socket. +****************************************************************************/ + +int get_socket_port(int fd) +{ + struct sockaddr_storage sa; + socklen_t length = sizeof(sa); + + if (fd == -1) { + return -1; + } + + if (getsockname(fd, (struct sockaddr *)&sa, &length) < 0) { + int level = (errno == ENOTCONN) ? 2 : 0; + DEBUG(level, ("getsockname failed. Error was %s\n", + strerror(errno))); + return -1; + } + +#if defined(HAVE_IPV6) + if (sa.ss_family == AF_INET6) { + return ntohs(((struct sockaddr_in6 *)&sa)->sin6_port); + } +#endif + if (sa.ss_family == AF_INET) { + return ntohs(((struct sockaddr_in *)&sa)->sin_port); + } + return -1; +} + +/**************************************************************************** + Return the string of an IP address (IPv4 or IPv6). +****************************************************************************/ + +static const char *get_socket_addr(int fd, char *addr_buf, size_t addr_len) +{ + struct sockaddr_storage sa; + socklen_t length = sizeof(sa); + + /* Ok, returning a hard coded IPv4 address + * is bogus, but it's just as bogus as a + * zero IPv6 address. No good choice here. + */ + + strlcpy(addr_buf, "0.0.0.0", addr_len); + + if (fd == -1) { + return addr_buf; + } + + if (getsockname(fd, (struct sockaddr *)&sa, &length) < 0) { + DEBUG(0,("getsockname failed. Error was %s\n", + strerror(errno) )); + return addr_buf; + } + + return print_sockaddr_len(addr_buf, addr_len, (struct sockaddr *)&sa, length); +} + +const char *client_socket_addr(int fd, char *addr, size_t addr_len) +{ + return get_socket_addr(fd, addr, addr_len); +} diff --git a/lib/util/util_net.h b/lib/util/util_net.h index 530311e5c8..71d1d1a6bd 100644 --- a/lib/util/util_net.h +++ b/lib/util/util_net.h @@ -50,6 +50,15 @@ void set_sockaddr_port(struct sockaddr *psa, uint16_t port); **/ _PUBLIC_ bool is_zero_ip_v4(struct in_addr ip); +void in_addr_to_sockaddr_storage(struct sockaddr_storage *ss, + struct in_addr ip); +#if defined(HAVE_IPV6) +/** + * Convert an IPv6 struct in_addr to a struct sockaddr_storage. + */ +void in6_addr_to_sockaddr_storage(struct sockaddr_storage *ss, + struct in6_addr ip); +#endif /** Are two IPs on the same subnet? **/ @@ -60,6 +69,11 @@ _PUBLIC_ bool same_net_v4(struct in_addr ip1,struct in_addr ip2,struct in_addr m **/ _PUBLIC_ bool is_ipaddress(const char *str); +bool is_broadcast_addr(const struct sockaddr *pss); +bool is_loopback_ip_v4(struct in_addr ip); +bool is_loopback_addr(const struct sockaddr *pss); +bool is_zero_addr(const struct sockaddr_storage *pss); +void zero_ip_v4(struct in_addr *ip); /** Interpret an internet address or name into an IP address in 4 byte form. **/ @@ -72,5 +86,26 @@ _PUBLIC_ struct in_addr interpret_addr2(const char *str); _PUBLIC_ bool is_ipaddress_v4(const char *str); +bool is_address_any(const struct sockaddr *psa); +bool same_net(const struct sockaddr *ip1, + const struct sockaddr *ip2, + const struct sockaddr *mask); +bool sockaddr_equal(const struct sockaddr *ip1, + const struct sockaddr *ip2); + +bool is_address_any(const struct sockaddr *psa); +uint16_t get_sockaddr_port(const struct sockaddr_storage *pss); +char *print_sockaddr_len(char *dest, + size_t destlen, + const struct sockaddr *psa, + socklen_t psalen); +char *print_sockaddr(char *dest, + size_t destlen, + const struct sockaddr_storage *psa); +char *print_canonical_sockaddr(TALLOC_CTX *ctx, + const struct sockaddr_storage *pss); +const char *client_name(int fd); +int get_socket_port(int fd); +const char *client_socket_addr(int fd, char *addr, size_t addr_len); #endif /* _SAMBA_UTIL_NET_H_ */ -- cgit From eea783e04cca45b1d3d9e5bb10556a2c8dc79b86 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 2 May 2011 16:23:40 +1000 Subject: lib/util Move set_socket_options() into common code. --- lib/util/util_net.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/util/util_net.h | 2 + 2 files changed, 163 insertions(+) (limited to 'lib/util') diff --git a/lib/util/util_net.c b/lib/util/util_net.c index e80447128f..a8a05da138 100644 --- a/lib/util/util_net.c +++ b/lib/util/util_net.c @@ -695,3 +695,164 @@ const char *client_socket_addr(int fd, char *addr, size_t addr_len) { return get_socket_addr(fd, addr, addr_len); } + + +enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON}; + +typedef struct smb_socket_option { + const char *name; + int level; + int option; + int value; + int opttype; +} smb_socket_option; + +static const smb_socket_option socket_options[] = { + {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL}, + {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL}, + {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL}, +#ifdef TCP_NODELAY + {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL}, +#endif +#ifdef TCP_KEEPCNT + {"TCP_KEEPCNT", IPPROTO_TCP, TCP_KEEPCNT, 0, OPT_INT}, +#endif +#ifdef TCP_KEEPIDLE + {"TCP_KEEPIDLE", IPPROTO_TCP, TCP_KEEPIDLE, 0, OPT_INT}, +#endif +#ifdef TCP_KEEPINTVL + {"TCP_KEEPINTVL", IPPROTO_TCP, TCP_KEEPINTVL, 0, OPT_INT}, +#endif +#ifdef IPTOS_LOWDELAY + {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON}, +#endif +#ifdef IPTOS_THROUGHPUT + {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON}, +#endif +#ifdef SO_REUSEPORT + {"SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, 0, OPT_BOOL}, +#endif +#ifdef SO_SNDBUF + {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT}, +#endif +#ifdef SO_RCVBUF + {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT}, +#endif +#ifdef SO_SNDLOWAT + {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT}, +#endif +#ifdef SO_RCVLOWAT + {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT}, +#endif +#ifdef SO_SNDTIMEO + {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT}, +#endif +#ifdef SO_RCVTIMEO + {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT}, +#endif +#ifdef TCP_FASTACK + {"TCP_FASTACK", IPPROTO_TCP, TCP_FASTACK, 0, OPT_INT}, +#endif +#ifdef TCP_QUICKACK + {"TCP_QUICKACK", IPPROTO_TCP, TCP_QUICKACK, 0, OPT_BOOL}, +#endif +#ifdef TCP_KEEPALIVE_THRESHOLD + {"TCP_KEEPALIVE_THRESHOLD", IPPROTO_TCP, TCP_KEEPALIVE_THRESHOLD, 0, OPT_INT}, +#endif +#ifdef TCP_KEEPALIVE_ABORT_THRESHOLD + {"TCP_KEEPALIVE_ABORT_THRESHOLD", IPPROTO_TCP, TCP_KEEPALIVE_ABORT_THRESHOLD, 0, OPT_INT}, +#endif + {NULL,0,0,0,0}}; + +/**************************************************************************** + Print socket options. +****************************************************************************/ + +static void print_socket_options(int s) +{ + int value; + socklen_t vlen = 4; + const smb_socket_option *p = &socket_options[0]; + + /* wrapped in if statement to prevent streams + * leak in SCO Openserver 5.0 */ + /* reported on samba-technical --jerry */ + if ( DEBUGLEVEL >= 5 ) { + DEBUG(5,("Socket options:\n")); + for (; p->name != NULL; p++) { + if (getsockopt(s, p->level, p->option, + (void *)&value, &vlen) == -1) { + DEBUGADD(5,("\tCould not test socket option %s.\n", + p->name)); + } else { + DEBUGADD(5,("\t%s = %d\n", + p->name,value)); + } + } + } + } + +/**************************************************************************** + Set user socket options. +****************************************************************************/ + +void set_socket_options(int fd, const char *options) +{ + TALLOC_CTX *ctx = talloc_new(NULL); + char *tok; + + while (next_token_talloc(ctx, &options, &tok," \t,")) { + int ret=0,i; + int value = 1; + char *p; + bool got_value = false; + + if ((p = strchr_m(tok,'='))) { + *p = 0; + value = atoi(p+1); + got_value = true; + } + + for (i=0;socket_options[i].name;i++) + if (strequal(socket_options[i].name,tok)) + break; + + if (!socket_options[i].name) { + DEBUG(0,("Unknown socket option %s\n",tok)); + continue; + } + + switch (socket_options[i].opttype) { + case OPT_BOOL: + case OPT_INT: + ret = setsockopt(fd,socket_options[i].level, + socket_options[i].option, + (char *)&value,sizeof(int)); + break; + + case OPT_ON: + if (got_value) + DEBUG(0,("syntax error - %s " + "does not take a value\n",tok)); + + { + int on = socket_options[i].value; + ret = setsockopt(fd,socket_options[i].level, + socket_options[i].option, + (char *)&on,sizeof(int)); + } + break; + } + + if (ret != 0) { + /* be aware that some systems like Solaris return + * EINVAL to a setsockopt() call when the client + * sent a RST previously - no need to worry */ + DEBUG(2,("Failed to set socket option %s (Error %s)\n", + tok, strerror(errno) )); + } + } + + TALLOC_FREE(ctx); + print_socket_options(fd); +} diff --git a/lib/util/util_net.h b/lib/util/util_net.h index 71d1d1a6bd..38b6d5a959 100644 --- a/lib/util/util_net.h +++ b/lib/util/util_net.h @@ -108,4 +108,6 @@ const char *client_name(int fd); int get_socket_port(int fd); const char *client_socket_addr(int fd, char *addr, size_t addr_len); +void set_socket_options(int fd, const char *options); + #endif /* _SAMBA_UTIL_NET_H_ */ -- cgit From 2742ec0e34c06ded2885aa2607f1c1729a57b034 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 3 May 2011 12:16:16 +1000 Subject: Remove strlower_m() and strupper_m() from source4 and common code. This function is problematic because a string may expand in size when changed into upper or lower case. This will then push characters off the end of the string in the s3 implementation, or panic in the former s4 implementation. Andrew Bartlett --- lib/util/charset/charset.h | 7 ---- lib/util/charset/util_unistr.c | 79 ------------------------------------------ 2 files changed, 86 deletions(-) (limited to 'lib/util') diff --git a/lib/util/charset/charset.h b/lib/util/charset/charset.h index d027daa052..e5fd596f8f 100644 --- a/lib/util/charset/charset.h +++ b/lib/util/charset/charset.h @@ -105,11 +105,6 @@ typedef struct smb_iconv_s { struct loadparm_context; struct smb_iconv_handle; -/* replace some string functions with multi-byte - versions */ -#define strlower(s) strlower_m(s) -#define strupper(s) strupper_m(s) - char *strchr_m(const char *s, char c); /** * Calculate the number of units (8 or 16-bit, depending on the @@ -137,8 +132,6 @@ int strcasecmp_m_handle(struct smb_iconv_handle *iconv_handle, const char *s1, const char *s2); int strcasecmp_m(const char *s1, const char *s2); size_t count_chars_m(const char *s, char c); -void strupper_m(char *s); -void strlower_m(char *s); char *strupper_talloc(TALLOC_CTX *ctx, const char *src); char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *src); char *strupper_talloc_n_handle(struct smb_iconv_handle *iconv_handle, diff --git a/lib/util/charset/util_unistr.c b/lib/util/charset/util_unistr.c index a585022e89..1915c73ad5 100644 --- a/lib/util/charset/util_unistr.c +++ b/lib/util/charset/util_unistr.c @@ -160,85 +160,6 @@ _PUBLIC_ char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *src) return strupper_talloc(ctx, src); } -/** - Convert a string to lower case. -**/ -_PUBLIC_ void strlower_m(char *s) -{ - char *d; - struct smb_iconv_handle *iconv_handle; - - /* 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 (*s && !(((uint8_t)*s) & 0x80)) { - *s = tolower((uint8_t)*s); - s++; - } - - if (!*s) - return; - - iconv_handle = get_iconv_handle(); - - d = s; - - while (*s) { - size_t c_size, c_size2; - codepoint_t c = next_codepoint_handle(iconv_handle, s, &c_size); - c_size2 = push_codepoint_handle(iconv_handle, d, tolower_m(c)); - if (c_size2 > c_size) { - DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strlower_m\n", - c, tolower_m(c), (int)c_size, (int)c_size2)); - smb_panic("codepoint expansion in strlower_m\n"); - } - s += c_size; - d += c_size2; - } - *d = 0; -} - -/** - Convert a string to UPPER case. -**/ -_PUBLIC_ void strupper_m(char *s) -{ - char *d; - struct smb_iconv_handle *iconv_handle; - - /* 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 (*s && !(((uint8_t)*s) & 0x80)) { - *s = toupper((uint8_t)*s); - s++; - } - - if (!*s) - return; - - iconv_handle = get_iconv_handle(); - - d = s; - - while (*s) { - size_t c_size, c_size2; - codepoint_t c = next_codepoint_handle(iconv_handle, s, &c_size); - c_size2 = push_codepoint_handle(iconv_handle, d, toupper_m(c)); - if (c_size2 > c_size) { - DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strupper_m\n", - c, toupper_m(c), (int)c_size, (int)c_size2)); - smb_panic("codepoint expansion in strupper_m\n"); - } - s += c_size; - d += c_size2; - } - *d = 0; -} - - /** Find the number of 'c' chars in a string **/ -- cgit From 80f1d49b61560f326fb55f2df09cc4f30e7a85ea Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 3 May 2011 12:29:12 +1000 Subject: lib/util/charset Use push_string and talloc_strupper/strlower from common code The only caller of push_string() (not to be confused with push_string_check()) in the common code was encode_pw_buffer(), and it didn't use the alignment or STR_UPPER flags. The talloc_strupper() and talloc_strlower() functions are tested in smbtorture, and are next_codepoint() based. Andrew Bartlett --- lib/util/charset/util_unistr.c | 10 +++++----- lib/util/charset/wscript_build | 17 +++++------------ 2 files changed, 10 insertions(+), 17 deletions(-) (limited to 'lib/util') diff --git a/lib/util/charset/util_unistr.c b/lib/util/charset/util_unistr.c index 1915c73ad5..e4ae65053c 100644 --- a/lib/util/charset/util_unistr.c +++ b/lib/util/charset/util_unistr.c @@ -194,7 +194,7 @@ _PUBLIC_ size_t count_chars_m(const char *s, char c) * @param dest_len the maximum length in bytes allowed in the * destination. If @p dest_len is -1 then no maximum is used. **/ -static bool push_ascii(void *dest, const char *src, size_t dest_len, int flags, size_t *converted_size) +static bool push_ascii_string(void *dest, const char *src, size_t dest_len, int flags, size_t *converted_size) { size_t src_len; bool ret; @@ -204,7 +204,7 @@ static bool push_ascii(void *dest, const char *src, size_t dest_len, int flags, if (tmpbuf == NULL) { return false; } - ret = push_ascii(dest, tmpbuf, dest_len, flags & ~STR_UPPER, converted_size); + ret = push_ascii_string(dest, tmpbuf, dest_len, flags & ~STR_UPPER, converted_size); talloc_free(tmpbuf); return ret; } @@ -232,7 +232,7 @@ static bool push_ascii(void *dest, const char *src, size_t dest_len, int flags, * @param src_len is the length of the source area in bytes. * @returns the number of bytes occupied by the string in @p src. **/ -static ssize_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t src_len, int flags) +static ssize_t pull_ascii_string(char *dest, const void *src, size_t dest_len, size_t src_len, int flags) { size_t size = 0; @@ -373,7 +373,7 @@ _PUBLIC_ ssize_t push_string(void *dest, const char *src, size_t dest_len, int f { if (flags & STR_ASCII) { size_t size = 0; - if (push_ascii(dest, src, dest_len, flags, &size)) { + if (push_ascii_string(dest, src, dest_len, flags, &size)) { return (ssize_t)size; } else { return (ssize_t)-1; @@ -404,7 +404,7 @@ _PUBLIC_ ssize_t push_string(void *dest, const char *src, size_t dest_len, int f _PUBLIC_ ssize_t pull_string(char *dest, const void *src, size_t dest_len, size_t src_len, int flags) { if (flags & STR_ASCII) { - return pull_ascii(dest, src, dest_len, src_len, flags); + return pull_ascii_string(dest, src, dest_len, src_len, flags); } else if (flags & STR_UNICODE) { return pull_ucs2(dest, src, dest_len, src_len, flags); } else { diff --git a/lib/util/charset/wscript_build b/lib/util/charset/wscript_build index 771ff5dc24..7623131146 100644 --- a/lib/util/charset/wscript_build +++ b/lib/util/charset/wscript_build @@ -1,18 +1,11 @@ #!/usr/bin/env python - -if bld.env._SAMBA_BUILD_ == 4: - bld.SAMBA_SUBSYSTEM('CHARSET', - source='util_unistr.c', - public_deps='CODEPOINTS', - public_headers='charset.h', - ) - bld.SAMBA_SUBSYSTEM('ICONV_WRAPPER', source='iconv.c', public_deps='iconv replace talloc') -bld.SAMBA_SUBSYSTEM('CODEPOINTS', - source='codepoints.c convert_string.c util_str.c util_unistr_w.c charcnv.c pull_push.c', - deps='DYNCONFIG ICONV_WRAPPER' - ) +bld.SAMBA_SUBSYSTEM('CHARSET', + public_headers='charset.h', + source='codepoints.c convert_string.c util_str.c util_unistr_w.c charcnv.c pull_push.c util_unistr.c', + deps='DYNCONFIG ICONV_WRAPPER' + ) -- cgit From d01f318179f9c2a0e6730642d21465b6dd69ea9f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 3 May 2011 15:33:31 +1000 Subject: s4: fix arguments to safe_strcpy() Found by the s3-derivied safe_strcpy() macro. Andrew Bartlett --- lib/util/tests/str.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'lib/util') diff --git a/lib/util/tests/str.c b/lib/util/tests/str.c index 6b38feaf43..b4c45e3751 100644 --- a/lib/util/tests/str.c +++ b/lib/util/tests/str.c @@ -25,7 +25,7 @@ static bool test_string_sub_simple(struct torture_context *tctx) { char tmp[100]; - safe_strcpy(tmp, "foobar", sizeof(tmp)); + safe_strcpy(tmp, "foobar", sizeof(tmp)-1); string_sub(tmp, "foo", "bar", sizeof(tmp)); torture_assert_str_equal(tctx, tmp, "barbar", "invalid sub"); return true; @@ -34,7 +34,7 @@ static bool test_string_sub_simple(struct torture_context *tctx) static bool test_string_sub_multiple(struct torture_context *tctx) { char tmp[100]; - safe_strcpy(tmp, "fooblafoo", sizeof(tmp)); + safe_strcpy(tmp, "fooblafoo", sizeof(tmp)-1); string_sub(tmp, "foo", "bar", sizeof(tmp)); torture_assert_str_equal(tctx, tmp, "barblabar", "invalid sub"); return true; @@ -43,7 +43,7 @@ static bool test_string_sub_multiple(struct torture_context *tctx) static bool test_string_sub_longer(struct torture_context *tctx) { char tmp[100]; - safe_strcpy(tmp, "foobla", sizeof(tmp)); + safe_strcpy(tmp, "foobla", sizeof(tmp)-1); string_sub(tmp, "foo", "blie", sizeof(tmp)); torture_assert_str_equal(tctx, tmp, "bliebla", "invalid sub"); return true; @@ -52,7 +52,7 @@ static bool test_string_sub_longer(struct torture_context *tctx) static bool test_string_sub_shorter(struct torture_context *tctx) { char tmp[100]; - safe_strcpy(tmp, "foobla", sizeof(tmp)); + safe_strcpy(tmp, "foobla", sizeof(tmp)-1); string_sub(tmp, "foo", "bl", sizeof(tmp)); torture_assert_str_equal(tctx, tmp, "blbla", "invalid sub"); return true; @@ -61,7 +61,7 @@ static bool test_string_sub_shorter(struct torture_context *tctx) static bool test_string_sub_special_char(struct torture_context *tctx) { char tmp[100]; - safe_strcpy(tmp, "foobla", sizeof(tmp)); + safe_strcpy(tmp, "foobla", sizeof(tmp)-1); string_sub(tmp, "foo", "%b;l", sizeof(tmp)); torture_assert_str_equal(tctx, tmp, "_b_lbla", "invalid sub"); return true; -- cgit From 86a62ab4345b8567a346587d2ddf575523d0b5f8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 3 May 2011 15:23:19 +1000 Subject: lib/util Use compiler-checked safe string macros in top level code. This brings the 'safe' macros to the top level code, and removes duplication of the safe_strcpy() and safe_strcat() functions. Andrew Bartlett --- lib/util/util.h | 6 ++++-- lib/util/util_str.c | 56 ++++++++++++++++++++++------------------------------- 2 files changed, 27 insertions(+), 35 deletions(-) (limited to 'lib/util') diff --git a/lib/util/util.h b/lib/util/util.h index 5ed8427498..45f1b9cd79 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -62,6 +62,8 @@ extern const char *panic_action; #include "lib/util/memory.h" +#include "lib/util/string_wrappers.h" + /** * Write backtrace to debug log */ @@ -248,13 +250,13 @@ _PUBLIC_ _PURE_ size_t count_chars(const char *s, char c); Safe string copy into a known length string. maxlength does not include the terminating zero. **/ -_PUBLIC_ char *safe_strcpy(char *dest,const char *src, size_t maxlength); +_PUBLIC_ char *safe_strcpy_fn(char *dest,const char *src, size_t maxlength); /** Safe string cat into a string. maxlength does not include the terminating zero. **/ -_PUBLIC_ char *safe_strcat(char *dest, const char *src, size_t maxlength); +_PUBLIC_ char *safe_strcat_fn(char *dest, const char *src, size_t maxlength); /** Routine to get hex characters and turn them into a 16 byte array. diff --git a/lib/util/util_str.c b/lib/util/util_str.c index cf3d60df8f..34dd5be56e 100644 --- a/lib/util/util_str.c +++ b/lib/util/util_str.c @@ -35,70 +35,60 @@ Safe string copy into a known length string. maxlength does not include the terminating zero. **/ -_PUBLIC_ char *safe_strcpy(char *dest,const char *src, size_t maxlength) + +_PUBLIC_ char *safe_strcpy_fn(char *dest, + const char *src, + size_t maxlength) { size_t len; if (!dest) { - DEBUG(0,("ERROR: NULL dest in safe_strcpy\n")); - return NULL; - } - -#ifdef DEVELOPER - /* We intentionally write out at the extremity of the destination - * string. If the destination is too short (e.g. pstrcpy into mallocd - * or fstring) then this should cause an error under a memory - * checker. */ - dest[maxlength] = '\0'; - if (PTR_DIFF(&len, dest) > 0) { /* check if destination is on the stack, ok if so */ - log_suspicious_usage("safe_strcpy", src); + smb_panic("ERROR: NULL dest in safe_strcpy"); } -#endif if (!src) { *dest = 0; return dest; - } + } - len = strlen(src); + len = strnlen(src, maxlength+1); if (len > maxlength) { - DEBUG(0,("ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s]\n", - (unsigned int)(len-maxlength), (unsigned)len, (unsigned)maxlength, src)); + DEBUG(0,("ERROR: string overflow by " + "%lu (%lu - %lu) in safe_strcpy [%.50s]\n", + (unsigned long)(len-maxlength), (unsigned long)len, + (unsigned long)maxlength, src)); len = maxlength; } - + memmove(dest, src, len); dest[len] = 0; return dest; -} +} /** Safe string cat into a string. maxlength does not include the terminating zero. **/ -_PUBLIC_ char *safe_strcat(char *dest, const char *src, size_t maxlength) +char *safe_strcat_fn(char *dest, + const char *src, + size_t maxlength) { size_t src_len, dest_len; if (!dest) { - DEBUG(0,("ERROR: NULL dest in safe_strcat\n")); - return NULL; + smb_panic("ERROR: NULL dest in safe_strcat"); } if (!src) return dest; - -#ifdef DEVELOPER - if (PTR_DIFF(&src_len, dest) > 0) { /* check if destination is on the stack, ok if so */ - log_suspicious_usage("safe_strcat", src); - } -#endif - src_len = strlen(src); - dest_len = strlen(dest); + + src_len = strnlen(src, maxlength + 1); + dest_len = strnlen(dest, maxlength + 1); if (src_len + dest_len > maxlength) { - DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n", + DEBUG(0,("ERROR: string overflow by %d " + "in safe_strcat [%.50s]\n", (int)(src_len + dest_len - maxlength), src)); if (maxlength > dest_len) { memcpy(&dest[dest_len], src, maxlength - dest_len); @@ -106,7 +96,7 @@ _PUBLIC_ char *safe_strcat(char *dest, const char *src, size_t maxlength) dest[maxlength] = 0; return NULL; } - + memcpy(&dest[dest_len], src, src_len); dest[dest_len + src_len] = 0; return dest; -- cgit From 2c32534d5ba5d009c48f377aa5aea8e77b4fa316 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 3 May 2011 12:59:36 +1000 Subject: lib/util Use lib/util/util_str.c in common, including strequal() strequal() is now implemented in terms of strcasecmp_m() which is tested in smbtorture and which does not talloc() for ASCII or non-ASCII comparions, and has an ASCII fast-path. Andrew Bartlett --- lib/util/util_str.c | 2 +- lib/util/wscript_build | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/util') diff --git a/lib/util/util_str.c b/lib/util/util_str.c index 34dd5be56e..9842f11653 100644 --- a/lib/util/util_str.c +++ b/lib/util/util_str.c @@ -236,6 +236,6 @@ _PUBLIC_ bool strequal(const char *s1, const char *s2) if (!s1 || !s2) return false; - return strcasecmp(s1,s2) == 0; + return strcasecmp_m(s1,s2) == 0; } diff --git a/lib/util/wscript_build b/lib/util/wscript_build index 561dcc4379..1abaf3dcd5 100755 --- a/lib/util/wscript_build +++ b/lib/util/wscript_build @@ -5,11 +5,11 @@ common_util_sources = '''talloc_stack.c smb_threads.c xfile.c data_blob.c genrand.c fsusage.c blocking.c become_daemon.c signal.c system.c params.c util.c util_id.c util_net.c util_strlist.c idtree.c debug.c fault.c base64.c - util_str_common.c substitute.c''' + util_str.c util_str_common.c substitute.c''' common_util_headers = 'debug.h' common_util_public_deps = 'talloc pthread LIBCRYPTO' -s4_util_sources = '''dprintf.c ms_fnmatch.c parmlist.c util_str.c''' +s4_util_sources = '''dprintf.c ms_fnmatch.c parmlist.c''' s4_util_deps = 'DYNCONFIG' s4_util_public_deps = 'talloc CHARSET execinfo uid_wrapper' s4_util_public_headers = 'attr.h byteorder.h data_blob.h memory.h safe_string.h time.h talloc_stack.h xfile.h dlinklist.h util.h' -- cgit From 92e490ac098ce54ff0db9f9234d4a4057435fe3a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 3 May 2011 15:35:18 +1000 Subject: lib/util make string_wrappers.h a public header This isn't a very good public header, but util.h includes it, so we don't have much choice in the short term. Andrew Bartlett Autobuild-User: Andrew Bartlett Autobuild-Date: Tue May 3 08:37:22 CEST 2011 on sn-devel-104 --- lib/util/wscript_build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/util') diff --git a/lib/util/wscript_build b/lib/util/wscript_build index 1abaf3dcd5..abdedb5775 100755 --- a/lib/util/wscript_build +++ b/lib/util/wscript_build @@ -12,7 +12,7 @@ common_util_public_deps = 'talloc pthread LIBCRYPTO' s4_util_sources = '''dprintf.c ms_fnmatch.c parmlist.c''' s4_util_deps = 'DYNCONFIG' s4_util_public_deps = 'talloc CHARSET execinfo uid_wrapper' -s4_util_public_headers = 'attr.h byteorder.h data_blob.h memory.h safe_string.h time.h talloc_stack.h xfile.h dlinklist.h util.h' +s4_util_public_headers = 'attr.h byteorder.h data_blob.h memory.h safe_string.h time.h talloc_stack.h xfile.h dlinklist.h util.h string_wrappers.h' s4_util_header_path = [ ('dlinklist.h util.h', '.'), ('*', 'util') ] if bld.env._SAMBA_BUILD_ == 3: -- cgit From 017e0c8d95fe8212b006e1c14aef8d96fed30674 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 3 May 2011 13:10:01 -0700 Subject: Fix simple uses of safe_strcpy -> strlcpy. Easy ones where we just remove -1. --- lib/util/fault.c | 2 +- lib/util/string_wrappers.h | 8 ++++---- lib/util/tests/str.c | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'lib/util') diff --git a/lib/util/fault.c b/lib/util/fault.c index 086dc33545..708dc670d1 100644 --- a/lib/util/fault.c +++ b/lib/util/fault.c @@ -119,7 +119,7 @@ static void smb_panic_default(const char *why) if (panic_action && *panic_action) { char pidstr[20]; char cmdstring[200]; - safe_strcpy(cmdstring, panic_action, sizeof(cmdstring)-1); + strlcpy(cmdstring, panic_action, sizeof(cmdstring)); snprintf(pidstr, sizeof(pidstr), "%d", (int) getpid()); all_string_sub(cmdstring, "%PID%", pidstr, sizeof(cmdstring)); DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmdstring)); diff --git a/lib/util/string_wrappers.h b/lib/util/string_wrappers.h index 75718e942b..4e4f3ec832 100644 --- a/lib/util/string_wrappers.h +++ b/lib/util/string_wrappers.h @@ -47,10 +47,10 @@ size_t __unsafe_string_function_usage_here_size_t__(void); /* String copy functions - macro hell below adds 'type checking' (limited, but the best we can do in C) */ -#define fstrcpy(d,s) safe_strcpy((d),(s),sizeof(fstring)-1) -#define fstrcat(d,s) safe_strcat((d),(s),sizeof(fstring)-1) -#define nstrcpy(d,s) safe_strcpy((d), (s),sizeof(nstring)-1) -#define unstrcpy(d,s) safe_strcpy((d), (s),sizeof(unstring)-1) +#define fstrcpy(d,s) strlcpy((d),(s) ? (s) : "",sizeof(fstring)) +#define fstrcat(d,s) strlcpy((d),(s) ? (s) : "",sizeof(fstring)) +#define nstrcpy(d,s) strlcpy((d), (s) ? (s) : "",sizeof(nstring)) +#define unstrcpy(d,s) strlcpy((d), (s) ? (s) : "",sizeof(unstring)) /* the addition of the DEVELOPER checks in safe_strcpy means we must * update a lot of code. To make this a little easier here are some diff --git a/lib/util/tests/str.c b/lib/util/tests/str.c index b4c45e3751..f9f3abf731 100644 --- a/lib/util/tests/str.c +++ b/lib/util/tests/str.c @@ -25,7 +25,7 @@ static bool test_string_sub_simple(struct torture_context *tctx) { char tmp[100]; - safe_strcpy(tmp, "foobar", sizeof(tmp)-1); + strlcpy(tmp, "foobar", sizeof(tmp)); string_sub(tmp, "foo", "bar", sizeof(tmp)); torture_assert_str_equal(tctx, tmp, "barbar", "invalid sub"); return true; @@ -34,7 +34,7 @@ static bool test_string_sub_simple(struct torture_context *tctx) static bool test_string_sub_multiple(struct torture_context *tctx) { char tmp[100]; - safe_strcpy(tmp, "fooblafoo", sizeof(tmp)-1); + strlcpy(tmp, "fooblafoo", sizeof(tmp)); string_sub(tmp, "foo", "bar", sizeof(tmp)); torture_assert_str_equal(tctx, tmp, "barblabar", "invalid sub"); return true; @@ -43,7 +43,7 @@ static bool test_string_sub_multiple(struct torture_context *tctx) static bool test_string_sub_longer(struct torture_context *tctx) { char tmp[100]; - safe_strcpy(tmp, "foobla", sizeof(tmp)-1); + strlcpy(tmp, "foobla", sizeof(tmp)); string_sub(tmp, "foo", "blie", sizeof(tmp)); torture_assert_str_equal(tctx, tmp, "bliebla", "invalid sub"); return true; @@ -52,7 +52,7 @@ static bool test_string_sub_longer(struct torture_context *tctx) static bool test_string_sub_shorter(struct torture_context *tctx) { char tmp[100]; - safe_strcpy(tmp, "foobla", sizeof(tmp)-1); + strlcpy(tmp, "foobla", sizeof(tmp)); string_sub(tmp, "foo", "bl", sizeof(tmp)); torture_assert_str_equal(tctx, tmp, "blbla", "invalid sub"); return true; @@ -61,7 +61,7 @@ static bool test_string_sub_shorter(struct torture_context *tctx) static bool test_string_sub_special_char(struct torture_context *tctx) { char tmp[100]; - safe_strcpy(tmp, "foobla", sizeof(tmp)-1); + strlcpy(tmp, "foobla", sizeof(tmp)); string_sub(tmp, "foo", "%b;l", sizeof(tmp)); torture_assert_str_equal(tctx, tmp, "_b_lbla", "invalid sub"); return true; -- cgit From 0c464df22b4d1a488ebe6ae889305a76d517f3d8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 3 May 2011 13:14:46 -0700 Subject: Change safe_strcpy_base to strlcpy_base. Note the size doesn't change here as the original macro auto-added the -1. --- lib/util/string_wrappers.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/util') diff --git a/lib/util/string_wrappers.h b/lib/util/string_wrappers.h index 4e4f3ec832..79119348c5 100644 --- a/lib/util/string_wrappers.h +++ b/lib/util/string_wrappers.h @@ -41,8 +41,8 @@ size_t __unsafe_string_function_usage_here_size_t__(void); #endif /* HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS */ -#define safe_strcpy_base(dest, src, base, size) \ - safe_strcpy(dest, src, size-PTR_DIFF(dest,base)-1) +#define strlcpy_base(dest, src, base, size) \ + strlcpy(dest, src, size-PTR_DIFF(dest,base)) /* String copy functions - macro hell below adds 'type checking' (limited, but the best we can do in C) */ -- cgit From 5fa6f390d1a4bdd3c82ced271e4db6c7241194f6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 3 May 2011 13:40:07 -0700 Subject: Remove overmalloc_safe_strcpy - can be simple strlcpy. --- lib/util/string_wrappers.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'lib/util') diff --git a/lib/util/string_wrappers.h b/lib/util/string_wrappers.h index 79119348c5..4a5f51d96b 100644 --- a/lib/util/string_wrappers.h +++ b/lib/util/string_wrappers.h @@ -56,14 +56,6 @@ size_t __unsafe_string_function_usage_here_size_t__(void); * update a lot of code. To make this a little easier here are some * functions that provide the lengths with less pain */ -/* overmalloc_safe_strcpy: DEPRECATED! Used when you know the - * destination buffer is longer than maxlength, but you don't know how - * long. This is not a good situation, because we can't do the normal - * sanity checks. Don't use in new code! */ - -#define overmalloc_safe_strcpy(dest,src,maxlength) \ - safe_strcpy_fn(dest,src,maxlength) - #ifdef HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS /* if the compiler will optimize out function calls, then use this to tell if we are -- cgit From df023b8657cab232df88d3656aa5d87676bb7254 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 3 May 2011 16:42:17 -0700 Subject: Tidy up some missing checks for NULL in strlcpy. --- lib/util/string_wrappers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/util') diff --git a/lib/util/string_wrappers.h b/lib/util/string_wrappers.h index 4a5f51d96b..80d0b9932a 100644 --- a/lib/util/string_wrappers.h +++ b/lib/util/string_wrappers.h @@ -42,7 +42,7 @@ size_t __unsafe_string_function_usage_here_size_t__(void); #endif /* HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS */ #define strlcpy_base(dest, src, base, size) \ - strlcpy(dest, src, size-PTR_DIFF(dest,base)) + strlcpy((dest), (src) ? (src) : "", (size)-PTR_DIFF((dest),(base))) /* String copy functions - macro hell below adds 'type checking' (limited, but the best we can do in C) */ -- cgit From ff215f5c89c91a22c910400c8ac81d82d7459ba0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 3 May 2011 16:43:27 -0700 Subject: I added them, so I get to kill them :-). Finally remove all uses of safe_strcpy and safe_strcat. Change to strlcpy, strlcat. Autobuild-User: Jeremy Allison Autobuild-Date: Wed May 4 22:14:14 CEST 2011 on sn-devel-104 --- lib/util/string_wrappers.h | 16 ----------- lib/util/util.h | 12 -------- lib/util/util_str.c | 71 ---------------------------------------------- 3 files changed, 99 deletions(-) (limited to 'lib/util') diff --git a/lib/util/string_wrappers.h b/lib/util/string_wrappers.h index 80d0b9932a..7baf3cb21b 100644 --- a/lib/util/string_wrappers.h +++ b/lib/util/string_wrappers.h @@ -52,26 +52,12 @@ size_t __unsafe_string_function_usage_here_size_t__(void); #define nstrcpy(d,s) strlcpy((d), (s) ? (s) : "",sizeof(nstring)) #define unstrcpy(d,s) strlcpy((d), (s) ? (s) : "",sizeof(unstring)) -/* the addition of the DEVELOPER checks in safe_strcpy means we must - * update a lot of code. To make this a little easier here are some - * functions that provide the lengths with less pain */ - #ifdef HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS /* if the compiler will optimize out function calls, then use this to tell if we are have the correct types (this works only where sizeof() returns the size of the buffer, not the size of the pointer). */ -#define safe_strcpy(d, s, max_len) \ - (CHECK_STRING_SIZE(d, max_len+1) \ - ? __unsafe_string_function_usage_here__() \ - : safe_strcpy_fn((d), (s), (max_len))) - -#define safe_strcat(d, s, max_len) \ - (CHECK_STRING_SIZE(d, max_len+1) \ - ? __unsafe_string_function_usage_here__() \ - : safe_strcat_fn((d), (s), (max_len))) - #define push_string_check(dest, src, dest_len, flags) \ (CHECK_STRING_SIZE(dest, dest_len) \ ? __unsafe_string_function_usage_here_size_t__() \ @@ -105,8 +91,6 @@ size_t __unsafe_string_function_usage_here_size_t__(void); #else -#define safe_strcpy safe_strcpy_fn -#define safe_strcat safe_strcat_fn #define push_string_check push_string_check_fn #define clistr_push clistr_push_fn #define clistr_pull clistr_pull_fn diff --git a/lib/util/util.h b/lib/util/util.h index 45f1b9cd79..64793022c0 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -246,18 +246,6 @@ _PUBLIC_ bool trim_string(char *s, const char *front, const char *back); **/ _PUBLIC_ _PURE_ size_t count_chars(const char *s, char c); -/** - Safe string copy into a known length string. maxlength does not - include the terminating zero. -**/ -_PUBLIC_ char *safe_strcpy_fn(char *dest,const char *src, size_t maxlength); - -/** - Safe string cat into a string. maxlength does not - include the terminating zero. -**/ -_PUBLIC_ char *safe_strcat_fn(char *dest, const char *src, size_t maxlength); - /** Routine to get hex characters and turn them into a 16 byte array. the array can be variable length, and any non-hex-numeric diff --git a/lib/util/util_str.c b/lib/util/util_str.c index 9842f11653..388d7887ef 100644 --- a/lib/util/util_str.c +++ b/lib/util/util_str.c @@ -31,77 +31,6 @@ * @brief String utilities. **/ -/** - Safe string copy into a known length string. maxlength does not - include the terminating zero. -**/ - -_PUBLIC_ char *safe_strcpy_fn(char *dest, - const char *src, - size_t maxlength) -{ - size_t len; - - if (!dest) { - smb_panic("ERROR: NULL dest in safe_strcpy"); - } - - if (!src) { - *dest = 0; - return dest; - } - - len = strnlen(src, maxlength+1); - - if (len > maxlength) { - DEBUG(0,("ERROR: string overflow by " - "%lu (%lu - %lu) in safe_strcpy [%.50s]\n", - (unsigned long)(len-maxlength), (unsigned long)len, - (unsigned long)maxlength, src)); - len = maxlength; - } - - memmove(dest, src, len); - dest[len] = 0; - return dest; -} - -/** - Safe string cat into a string. maxlength does not - include the terminating zero. -**/ -char *safe_strcat_fn(char *dest, - const char *src, - size_t maxlength) -{ - size_t src_len, dest_len; - - if (!dest) { - smb_panic("ERROR: NULL dest in safe_strcat"); - } - - if (!src) - return dest; - - src_len = strnlen(src, maxlength + 1); - dest_len = strnlen(dest, maxlength + 1); - - if (src_len + dest_len > maxlength) { - DEBUG(0,("ERROR: string overflow by %d " - "in safe_strcat [%.50s]\n", - (int)(src_len + dest_len - maxlength), src)); - if (maxlength > dest_len) { - memcpy(&dest[dest_len], src, maxlength - dest_len); - } - dest[maxlength] = 0; - return NULL; - } - - memcpy(&dest[dest_len], src, src_len); - dest[dest_len + src_len] = 0; - return dest; -} - /** format a string into length-prefixed dotted domain format, as used in NBT and in some ADS structures -- cgit From 1c714850d5068864b1f04a4211223dec11a30d67 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 4 May 2011 14:57:37 -0700 Subject: Clean up some const and other compiler warnings. Autobuild-User: Jeremy Allison Autobuild-Date: Thu May 5 00:59:40 CEST 2011 on sn-devel-104 --- lib/util/charset/util_str.c | 8 ++++---- lib/util/charset/util_unistr_w.c | 4 ++-- lib/util/util_net.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'lib/util') diff --git a/lib/util/charset/util_str.c b/lib/util/charset/util_str.c index 71a37787ae..4f4ca93cfd 100644 --- a/lib/util/charset/util_str.c +++ b/lib/util/charset/util_str.c @@ -329,7 +329,7 @@ _PUBLIC_ char *strchr_m(const char *src, char c) for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) { if (*s == c) - return (char *)s; + return discard_const_p(char, s); } if (!*s) @@ -397,7 +397,7 @@ _PUBLIC_ char *strrchr_m(const char *s, char c) break; } /* No - we have a match ! */ - return (char *)cp; + return discard_const_p(char , cp); } } while (cp-- != s); if (!got_mb) @@ -492,7 +492,7 @@ char *strstr_m(const char *src, const char *findstr) /* for correctness */ if (!findstr[0]) { - return (char*)src; + return discard_const_p(char, src); } /* Samba does single character findstr calls a *lot*. */ @@ -509,7 +509,7 @@ char *strstr_m(const char *src, const char *findstr) findstr_len = strlen(findstr); if (strncmp(s, findstr, findstr_len) == 0) { - return (char *)s; + return discard_const_p(char, s); } } } diff --git a/lib/util/charset/util_unistr_w.c b/lib/util/charset/util_unistr_w.c index a550e52776..22f22ab754 100644 --- a/lib/util/charset/util_unistr_w.c +++ b/lib/util/charset/util_unistr_w.c @@ -22,8 +22,8 @@ #include "includes.h" /* Copy into a smb_ucs2_t from a possibly unaligned buffer. Return the copied smb_ucs2_t */ -#define COPY_UCS2_CHAR(dest,src) (((unsigned char *)(dest))[0] = ((unsigned char *)(src))[0],\ - ((unsigned char *)(dest))[1] = ((unsigned char *)(src))[1], (dest)) +#define COPY_UCS2_CHAR(dest,src) (((unsigned char *)(dest))[0] = ((const unsigned char *)(src))[0],\ + ((unsigned char *)(dest))[1] = ((const unsigned char *)(src))[1], (dest)) /* return an ascii version of a ucs2 character */ diff --git a/lib/util/util_net.c b/lib/util/util_net.c index a8a05da138..7d678c9b14 100644 --- a/lib/util/util_net.c +++ b/lib/util/util_net.c @@ -591,7 +591,7 @@ char *print_sockaddr(char *dest, size_t destlen, const struct sockaddr_storage *psa) { - return print_sockaddr_len(dest, destlen, (struct sockaddr *)psa, + return print_sockaddr_len(dest, destlen, (const struct sockaddr *)psa, sizeof(struct sockaddr_storage)); } -- cgit From 4f41be356a4e6b311d30de3b2e36e4c33aa72ca3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 5 May 2011 10:41:59 -0700 Subject: Fix many const compiler warnings. --- lib/util/charset/util_str.c | 2 +- lib/util/charset/util_unistr_w.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/util') diff --git a/lib/util/charset/util_str.c b/lib/util/charset/util_str.c index 4f4ca93cfd..e76c1dbbf5 100644 --- a/lib/util/charset/util_str.c +++ b/lib/util/charset/util_str.c @@ -550,7 +550,7 @@ char *strstr_m(const char *src, const char *findstr) DEBUG(0,("strstr_m: dest malloc fail\n")); return NULL; } - retp = (char *)(s+strlen(s2)); + retp = discard_const_p(char, (s+strlen(s2))); TALLOC_FREE(src_w); TALLOC_FREE(find_w); TALLOC_FREE(s2); diff --git a/lib/util/charset/util_unistr_w.c b/lib/util/charset/util_unistr_w.c index 22f22ab754..5b61d52e7f 100644 --- a/lib/util/charset/util_unistr_w.c +++ b/lib/util/charset/util_unistr_w.c @@ -72,12 +72,12 @@ smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c) smb_ucs2_t cp; while (*(COPY_UCS2_CHAR(&cp,s))) { if (c == cp) { - return (smb_ucs2_t *)s; + return discard_const_p(smb_ucs2_t, s); } s++; } if (c == cp) { - return (smb_ucs2_t *)s; + return discard_const_p(smb_ucs2_t, s); } return NULL; @@ -104,7 +104,7 @@ smb_ucs2_t *strrchr_w(const smb_ucs2_t *s, smb_ucs2_t c) p += (len - 1); do { if (c == *(COPY_UCS2_CHAR(&cp,p))) { - return (smb_ucs2_t *)p; + return discard_const_p(smb_ucs2_t, p); } } while (p-- != s); return NULL; -- cgit From 14750139639b3531e57a3ca3f9e481d6e458dc06 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 4 May 2011 10:28:15 +1000 Subject: lib/util Move source3 tdb_wrap_open() into the common code. This #if _SAMBA_BUILD == 3 is very unfortunate, as it means that in the top level build, these options are not available for these databases. However, having two different tdb_wrap lists is a worse fate, so this will do for now. Andrew Bartlett --- lib/util/tdb_wrap.c | 194 +++++++++++++++++++++++++++++++++++++++++++++++++ lib/util/tdb_wrap.h | 42 +++++++++++ lib/util/util_tdb.h | 1 - lib/util/wscript_build | 10 +++ 4 files changed, 246 insertions(+), 1 deletion(-) create mode 100644 lib/util/tdb_wrap.c create mode 100644 lib/util/tdb_wrap.h (limited to 'lib/util') diff --git a/lib/util/tdb_wrap.c b/lib/util/tdb_wrap.c new file mode 100644 index 0000000000..c9562c6939 --- /dev/null +++ b/lib/util/tdb_wrap.c @@ -0,0 +1,194 @@ +/* + Unix SMB/CIFS implementation. + TDB wrap functions + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Jelmer Vernooij 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 + 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 . +*/ + +#include "includes.h" +#include +#include "lib/util/dlinklist.h" +#include "lib/util/tdb_wrap.h" +#include + +/* + Log tdb messages via DEBUG(). +*/ +static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level, + const char *format, ...) PRINTF_ATTRIBUTE(3,4); + +static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level, + const char *format, ...) +{ + va_list ap; + char *ptr = NULL; + int debuglevel = 0; + int ret; + + switch (level) { + case TDB_DEBUG_FATAL: + debuglevel = 0; + break; + case TDB_DEBUG_ERROR: + debuglevel = 1; + break; + case TDB_DEBUG_WARNING: + debuglevel = 2; + break; + case TDB_DEBUG_TRACE: + debuglevel = 5; + break; + default: + debuglevel = 0; + } + + va_start(ap, format); + ret = vasprintf(&ptr, format, ap); + va_end(ap); + + if (ret != -1) { + const char *name = tdb_name(tdb); + DEBUG(debuglevel, ("tdb(%s): %s", name ? name : "unnamed", ptr)); + free(ptr); + } +} + +struct tdb_wrap_private { + struct tdb_context *tdb; + const char *name; + struct tdb_wrap_private *next, *prev; +}; + +static struct tdb_wrap_private *tdb_list; + +/* destroy the last connection to a tdb */ +static int tdb_wrap_private_destructor(struct tdb_wrap_private *w) +{ + tdb_close(w->tdb); + DLIST_REMOVE(tdb_list, w); + return 0; +} + +static struct tdb_wrap_private *tdb_wrap_private_open(TALLOC_CTX *mem_ctx, + const char *name, + int hash_size, + int tdb_flags, + int open_flags, + mode_t mode) +{ + struct tdb_wrap_private *result; + struct tdb_logging_context log_ctx; + + result = talloc(mem_ctx, struct tdb_wrap_private); + if (result == NULL) { + return NULL; + } + result->name = talloc_strdup(result, name); + if (result->name == NULL) { + goto fail; + } + + log_ctx.log_fn = tdb_wrap_log; + +#if _SAMBA_BUILD_ == 3 + /* This #if _SAMBA_BUILD == 3 is very unfortunate, as it means + * that in the top level build, these options are not + * available for these databases. However, having two + * different tdb_wrap lists is a worse fate, so this will do + * for now */ + + if (!lp_use_mmap()) { + tdb_flags |= TDB_NOMMAP; + } + + if ((hash_size == 0) && (name != NULL)) { + const char *base; + base = strrchr_m(name, '/'); + + if (base != NULL) { + base += 1; + } else { + base = name; + } + hash_size = lp_parm_int(-1, "tdb_hashsize", base, 0); + } +#endif + + result->tdb = tdb_open_ex(name, hash_size, tdb_flags, + open_flags, mode, &log_ctx, NULL); + if (result->tdb == NULL) { + goto fail; + } + talloc_set_destructor(result, tdb_wrap_private_destructor); + DLIST_ADD(tdb_list, result); + return result; + +fail: + TALLOC_FREE(result); + return NULL; +} + +/* + wrapped connection to a tdb database + to close just talloc_free() the tdb_wrap pointer + */ +struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx, + const char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode) +{ + struct tdb_wrap *result; + struct tdb_wrap_private *w; + + result = talloc(mem_ctx, struct tdb_wrap); + if (result == NULL) { + return NULL; + } + + for (w=tdb_list;w;w=w->next) { + if (strcmp(name, w->name) == 0) { + break; + } + } + + if (w == NULL) { + w = tdb_wrap_private_open(result, name, hash_size, tdb_flags, + open_flags, mode); + } else { + /* + * Correctly use talloc_reference: The tdb will be + * closed when "w" is being freed. The caller never + * sees "w", so an incorrect use of talloc_free(w) + * instead of calling talloc_unlink is not possible. + * To avoid having to refcount ourselves, "w" will + * have multiple parents that hang off all the + * tdb_wrap's being returned from here. Those parents + * can be freed without problem. + */ + if (talloc_reference(result, w) == NULL) { + goto fail; + } + } + if (w == NULL) { + goto fail; + } + result->tdb = w->tdb; + return result; +fail: + TALLOC_FREE(result); + return NULL; +} + diff --git a/lib/util/tdb_wrap.h b/lib/util/tdb_wrap.h new file mode 100644 index 0000000000..1be2bb059d --- /dev/null +++ b/lib/util/tdb_wrap.h @@ -0,0 +1,42 @@ +/* + Unix SMB/CIFS implementation. + + database wrap headers + + Copyright (C) Andrew Tridgell 2004 + + 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 . +*/ + +/* IMPORTANT: tdb_wrap should be always preferred over tdb_context for end consumer functions + it's because if the code will be running inside smbd, then we must use the linked list + of open tdb files, to determine if the tdb we desire is already open + as otherwise, when you close the tdb (even on a different file descriptor), + ALL LOCKS are lost (due to a real screwup in the POSIX specification that nobody has been able to get fixed) +*/ + +#ifndef _TDB_WRAP_H_ +#define _TDB_WRAP_H_ + +#include + +struct tdb_wrap { + struct tdb_context *tdb; +}; + +struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx, + const char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode); + +#endif /* _TDB_WRAP_H_ */ diff --git a/lib/util/util_tdb.h b/lib/util/util_tdb.h index d2f6648462..c11a347e07 100644 --- a/lib/util/util_tdb.h +++ b/lib/util/util_tdb.h @@ -1,7 +1,6 @@ #ifndef _____LIB_UTIL_UTIL_TDB_H__ #define _____LIB_UTIL_UTIL_TDB_H__ - /*************************************************************** Make a TDB_DATA and keep the const warning in one place ****************************************************************/ diff --git a/lib/util/wscript_build b/lib/util/wscript_build index abdedb5775..59a2782b60 100755 --- a/lib/util/wscript_build +++ b/lib/util/wscript_build @@ -108,3 +108,13 @@ bld.SAMBA_SUBSYSTEM('UTIL_PW', local_include=False, public_deps='talloc' ) + + +bld.SAMBA_LIBRARY('tdb-wrap', + source='tdb_wrap.c', + deps='tdb talloc samba-util', + public_headers='tdb_wrap.h', + private_library=True, + local_include=False + ) + -- cgit From 3892112e7b3143f808932771a7b71f4fd335f8cb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 4 May 2011 20:53:33 +1000 Subject: lib/util Rename ms_fnmatch() to ms_fnmatch_protocol() to avoid dup symbol This verison of the function takes a protcol as argument to determine matching rules. Andrew Bartlett --- lib/util/ms_fnmatch.c | 6 +++--- lib/util/util.h | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'lib/util') diff --git a/lib/util/ms_fnmatch.c b/lib/util/ms_fnmatch.c index 73fb0e0966..d029fd6b00 100644 --- a/lib/util/ms_fnmatch.c +++ b/lib/util/ms_fnmatch.c @@ -154,7 +154,7 @@ static int ms_fnmatch_core(const char *p, const char *n, return -1; } -int ms_fnmatch(const char *pattern, const char *string, enum protocol_types protocol) +int ms_fnmatch_protocol(const char *pattern, const char *string, enum protocol_types protocol) { int ret, count, i; struct max_n *max_n = NULL; @@ -192,7 +192,7 @@ int ms_fnmatch(const char *pattern, const char *string, enum protocol_types prot p[i] = '<'; } } - ret = ms_fnmatch(p, string, PROTOCOL_NT1); + ret = ms_fnmatch_protocol(p, string, PROTOCOL_NT1); talloc_free(p); return ret; } @@ -217,5 +217,5 @@ int ms_fnmatch(const char *pattern, const char *string, enum protocol_types prot /** a generic fnmatch function - uses for non-CIFS pattern matching */ int gen_fnmatch(const char *pattern, const char *string) { - return ms_fnmatch(pattern, string, PROTOCOL_NT1); + return ms_fnmatch_protocol(pattern, string, PROTOCOL_NT1); } diff --git a/lib/util/util.h b/lib/util/util.h index 64793022c0..b91b2eb1fa 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -777,11 +777,12 @@ enum protocol_types { PROTOCOL_SMB2 }; -int ms_fnmatch(const char *pattern, const char *string, enum protocol_types protocol); +#endif + +int ms_fnmatch_protocol(const char *pattern, const char *string, enum protocol_types protocol); /** a generic fnmatch function - uses for non-CIFS pattern matching */ int gen_fnmatch(const char *pattern, const char *string); -#endif /* The following definitions come from lib/util/idtree.c */ -- cgit From 8f1810362df7ef9e5c394a9cba83cf0e7c04bd9e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 4 May 2011 20:57:12 +1000 Subject: lib/util Use lib/util/ms_fnmatch.c in common for gen_fnmatch() gen_fnmatch was a duplicate symbol in the top level build. gen_fnmatch() used for simple non-CIFS pattern matching, so selecting the lib/util implementation should not be a concern. Andrew Bartlett --- lib/util/wscript_build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/util') diff --git a/lib/util/wscript_build b/lib/util/wscript_build index 59a2782b60..fc5f4b5455 100755 --- a/lib/util/wscript_build +++ b/lib/util/wscript_build @@ -5,11 +5,11 @@ common_util_sources = '''talloc_stack.c smb_threads.c xfile.c data_blob.c genrand.c fsusage.c blocking.c become_daemon.c signal.c system.c params.c util.c util_id.c util_net.c util_strlist.c idtree.c debug.c fault.c base64.c - util_str.c util_str_common.c substitute.c''' + util_str.c util_str_common.c substitute.c ms_fnmatch.c''' common_util_headers = 'debug.h' common_util_public_deps = 'talloc pthread LIBCRYPTO' -s4_util_sources = '''dprintf.c ms_fnmatch.c parmlist.c''' +s4_util_sources = '''dprintf.c parmlist.c''' s4_util_deps = 'DYNCONFIG' s4_util_public_deps = 'talloc CHARSET execinfo uid_wrapper' s4_util_public_headers = 'attr.h byteorder.h data_blob.h memory.h safe_string.h time.h talloc_stack.h xfile.h dlinklist.h util.h string_wrappers.h' -- cgit From 8aae59a277fe4bf5a1a84cb4730e5772c9ffca8c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 4 May 2011 21:20:57 +1000 Subject: lib/util don't use enum protocol_types in ms_fnmatch_protocol This makes it easier to compile this in the top level with s3 and s4 headers. Andrew Bartlett Autobuild-User: Andrew Bartlett Autobuild-Date: Fri May 6 08:50:52 CEST 2011 on sn-devel-104 --- lib/util/ms_fnmatch.c | 2 +- lib/util/util.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/util') diff --git a/lib/util/ms_fnmatch.c b/lib/util/ms_fnmatch.c index d029fd6b00..1ba5888ca0 100644 --- a/lib/util/ms_fnmatch.c +++ b/lib/util/ms_fnmatch.c @@ -154,7 +154,7 @@ static int ms_fnmatch_core(const char *p, const char *n, return -1; } -int ms_fnmatch_protocol(const char *pattern, const char *string, enum protocol_types protocol) +int ms_fnmatch_protocol(const char *pattern, const char *string, int protocol) { int ret, count, i; struct max_n *max_n = NULL; diff --git a/lib/util/util.h b/lib/util/util.h index b91b2eb1fa..93b181b1fc 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -779,7 +779,7 @@ enum protocol_types { #endif -int ms_fnmatch_protocol(const char *pattern, const char *string, enum protocol_types protocol); +int ms_fnmatch_protocol(const char *pattern, const char *string, int protocol); /** a generic fnmatch function - uses for non-CIFS pattern matching */ int gen_fnmatch(const char *pattern, const char *string); -- cgit From f946668b7ad1ecc1990fa8ee0499c63c4aac6ea6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 May 2011 10:28:03 +0200 Subject: Improve debug messages when creating socket directories This makes clear what the permissions error and directory name actually is Andrew Bartlett --- lib/util/util.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/util') diff --git a/lib/util/util.c b/lib/util/util.c index d4a936fae9..7f30d436e8 100644 --- a/lib/util/util.c +++ b/lib/util/util.c @@ -152,7 +152,8 @@ _PUBLIC_ bool directory_create_or_exist(const char *dname, uid_t uid, } if ((st.st_mode & 0777) != dir_perms) { DEBUG(0, ("invalid permissions on directory " - "%s\n", dname)); + "'%s': has 0%o should be 0%o\n", dname, + (st.st_mode & 0777), dir_perms)); umask(old_umask); return false; } -- cgit From 0d93eb8f5501c348451a7d78e83516873d71cda0 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 10 May 2011 11:46:53 +0930 Subject: tdb_wrap.h: not a public header. It is a private library, and OpenChange has their own which they use, so it's not for them either. Signed-off-by: Rusty Russell Autobuild-User: Rusty Russell Autobuild-Date: Tue May 10 05:21:19 CEST 2011 on sn-devel-104 --- lib/util/wscript_build | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/util') diff --git a/lib/util/wscript_build b/lib/util/wscript_build index fc5f4b5455..740e68b6f0 100755 --- a/lib/util/wscript_build +++ b/lib/util/wscript_build @@ -113,7 +113,6 @@ bld.SAMBA_SUBSYSTEM('UTIL_PW', bld.SAMBA_LIBRARY('tdb-wrap', source='tdb_wrap.c', deps='tdb talloc samba-util', - public_headers='tdb_wrap.h', private_library=True, local_include=False ) -- cgit From 5db0cd55d4db9cc71f32dc0097e2f014c22967bc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 9 May 2011 17:43:45 +0200 Subject: lib/util/ Fix crash bug caused by gfree_debug() The issue is that we should reset the debug_num_classes to 0 when we un-initialise the debug system. Andrew Bartlett --- lib/util/debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/util') diff --git a/lib/util/debug.c b/lib/util/debug.c index b0a78823fc..c1b33de6d1 100644 --- a/lib/util/debug.c +++ b/lib/util/debug.c @@ -203,7 +203,7 @@ void gfree_debugsyms(void) TALLOC_FREE(format_bufr); - debug_num_classes = DBGC_MAX_FIXED; + debug_num_classes = 0; state.initialized = false; } -- cgit From f18cca9a0a690013eb609719c4798da9b0e1054b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 13 May 2011 10:26:20 +0200 Subject: lib/util/charset Move built-in charset modules to the top level This removes the 'charset' subsystem and allows these modules to be used across the whole of Samba. Andrew Bartlett --- lib/util/charset/CP437.c | 135 ++++++++ lib/util/charset/CP850.c | 121 ++++++++ lib/util/charset/charset.h | 2 +- lib/util/charset/charset_macosxfs.c | 604 ++++++++++++++++++++++++++++++++++++ lib/util/charset/weird.c | 134 ++++++++ lib/util/charset/wscript_build | 33 ++ 6 files changed, 1028 insertions(+), 1 deletion(-) create mode 100644 lib/util/charset/CP437.c create mode 100644 lib/util/charset/CP850.c create mode 100644 lib/util/charset/charset_macosxfs.c create mode 100644 lib/util/charset/weird.c (limited to 'lib/util') diff --git a/lib/util/charset/CP437.c b/lib/util/charset/CP437.c new file mode 100644 index 0000000000..1e478d678f --- /dev/null +++ b/lib/util/charset/CP437.c @@ -0,0 +1,135 @@ +/* + * Conversion table for CP437 charset also known as IBM437 + * + * Copyright (C) Alexander Bokovoy 2003 + * + * Conversion tables are generated using GNU libc 2.2.5's + * localedata/charmaps/IBM437 table and source/script/gen-8bit-gap.sh script + * + * 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 . + */ + +#include "includes.h" + +static const uint16_t to_ucs2[256] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, + 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, + 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, + 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0, +}; + +static const struct charset_gap_table from_idx[] = { + { 0x0000, 0x007f, 0 }, + { 0x00a0, 0x00c9, -32 }, + { 0x00d1, 0x00ff, -39 }, + { 0x0192, 0x0192, -185 }, + { 0x0393, 0x0398, -697 }, + { 0x03a3, 0x03a9, -707 }, + { 0x03b1, 0x03b5, -714 }, + { 0x03c0, 0x03c6, -724 }, + { 0x207f, 0x207f, -8076 }, + { 0x20a7, 0x20a7, -8115 }, + { 0x2219, 0x221e, -8484 }, + { 0x2229, 0x2229, -8494 }, + { 0x2248, 0x2248, -8524 }, + { 0x2261, 0x2265, -8548 }, + { 0x2310, 0x2310, -8718 }, + { 0x2320, 0x2321, -8733 }, + { 0x2500, 0x2502, -9211 }, + { 0x250c, 0x251c, -9220 }, + { 0x2524, 0x2524, -9227 }, + { 0x252c, 0x252c, -9234 }, + { 0x2534, 0x2534, -9241 }, + { 0x253c, 0x253c, -9248 }, + { 0x2550, 0x256c, -9267 }, + { 0x2580, 0x2593, -9286 }, + { 0x25a0, 0x25a0, -9298 }, + { 0xffff, 0xffff, 0 } +}; + +static const unsigned char from_ucs2[] = { + + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0xff, 0xad, 0x9b, 0x9c, 0x00, 0x9d, 0x00, 0x00, + 0x00, 0x00, 0xa6, 0xae, 0xaa, 0x00, 0x00, 0x00, + 0xf8, 0xf1, 0xfd, 0x00, 0x00, 0xe6, 0x00, 0xfa, + 0x00, 0x00, 0xa7, 0xaf, 0xac, 0xab, 0x00, 0xa8, + 0x00, 0x00, 0x00, 0x00, 0x8e, 0x8f, 0x92, 0x80, + 0x00, 0x90, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x99, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, + 0xe1, 0x85, 0xa0, 0x83, 0x00, 0x84, 0x86, 0x91, + 0x87, 0x8a, 0x82, 0x88, 0x89, 0x8d, 0xa1, 0x8c, + 0x8b, 0x00, 0xa4, 0x95, 0xa2, 0x93, 0x00, 0x94, + 0xf6, 0x00, 0x97, 0xa3, 0x96, 0x81, 0x00, 0x00, + 0x98, 0x9f, 0xe2, 0x00, 0x00, 0x00, 0x00, 0xe9, + 0xe4, 0x00, 0x00, 0xe8, 0x00, 0x00, 0xea, 0xe0, + 0x00, 0x00, 0xeb, 0xee, 0xe3, 0x00, 0x00, 0xe5, + 0xe7, 0x00, 0xed, 0xfc, 0x9e, 0xf9, 0xfb, 0x00, + 0x00, 0x00, 0xec, 0xef, 0xf7, 0xf0, 0x00, 0x00, + 0xf3, 0xf2, 0xa9, 0xf4, 0xf5, 0xc4, 0x00, 0xb3, + 0xda, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, + 0xc0, 0x00, 0x00, 0x00, 0xd9, 0x00, 0x00, 0x00, + 0xc3, 0xb4, 0xc2, 0xc1, 0xc5, 0xcd, 0xba, 0xd5, + 0xd6, 0xc9, 0xb8, 0xb7, 0xbb, 0xd4, 0xd3, 0xc8, + 0xbe, 0xbd, 0xbc, 0xc6, 0xc7, 0xcc, 0xb5, 0xb6, + 0xb9, 0xd1, 0xd2, 0xcb, 0xcf, 0xd0, 0xca, 0xd8, + 0xd7, 0xce, 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, + 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00, + 0x00, 0x00, 0xde, 0xb0, 0xb1, 0xb2, 0xfe, +}; + +SMB_GENERATE_CHARSET_MODULE_8_BIT_GAP(CP437) diff --git a/lib/util/charset/CP850.c b/lib/util/charset/CP850.c new file mode 100644 index 0000000000..87a76f4cdf --- /dev/null +++ b/lib/util/charset/CP850.c @@ -0,0 +1,121 @@ +/* + * Conversion table for CP850 charset also known as IBM850. + * + * Copyright (C) Alexander Bokovoy 2003 + * + * Conversion tables are generated using GNU libc 2.2.5's + * localedata/charmaps/IBM850 table and source/script/gen-8bit-gap.sh script + * + * 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 . + */ + +#include "includes.h" + +static const uint16_t to_ucs2[256] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, + 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, + 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, + 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, + 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580, + 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, + 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4, + 0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, + 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0, +}; + +static const struct charset_gap_table from_idx[] = { + /* start, end, idx */ + { 0x0000, 0x007f, 0 }, + { 0x00a0, 0x00ff, -32 }, + { 0x0131, 0x0131, -81 }, + { 0x0192, 0x0192, -177 }, + { 0x2017, 0x2017, -7989 }, + { 0x2500, 0x2502, -9245 }, + { 0x250c, 0x251c, -9254 }, + { 0x2524, 0x2524, -9261 }, + { 0x252c, 0x252c, -9268 }, + { 0x2534, 0x2534, -9275 }, + { 0x253c, 0x253c, -9282 }, + { 0x2550, 0x256c, -9301 }, + { 0x2580, 0x2588, -9320 }, + { 0x2591, 0x2593, -9328 }, + { 0x25a0, 0x25a0, -9340 }, + { 0xffff, 0xffff, 0 } +}; +static const unsigned char from_ucs2[] = { + + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0xff, 0xad, 0xbd, 0x9c, 0xcf, 0xbe, 0xdd, 0xf5, + 0xf9, 0xb8, 0xa6, 0xae, 0xaa, 0xf0, 0xa9, 0xee, + 0xf8, 0xf1, 0xfd, 0xfc, 0xef, 0xe6, 0xf4, 0xfa, + 0xf7, 0xfb, 0xa7, 0xaf, 0xac, 0xab, 0xf3, 0xa8, + 0xb7, 0xb5, 0xb6, 0xc7, 0x8e, 0x8f, 0x92, 0x80, + 0xd4, 0x90, 0xd2, 0xd3, 0xde, 0xd6, 0xd7, 0xd8, + 0xd1, 0xa5, 0xe3, 0xe0, 0xe2, 0xe5, 0x99, 0x9e, + 0x9d, 0xeb, 0xe9, 0xea, 0x9a, 0xed, 0xe8, 0xe1, + 0x85, 0xa0, 0x83, 0xc6, 0x84, 0x86, 0x91, 0x87, + 0x8a, 0x82, 0x88, 0x89, 0x8d, 0xa1, 0x8c, 0x8b, + 0xd0, 0xa4, 0x95, 0xa2, 0x93, 0xe4, 0x94, 0xf6, + 0x9b, 0x97, 0xa3, 0x96, 0x81, 0xec, 0xe7, 0x98, + 0xd5, 0x9f, 0xf2, 0xc4, 0x00, 0xb3, 0xda, 0x00, + 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, + 0x00, 0x00, 0xd9, 0x00, 0x00, 0x00, 0xc3, 0xb4, + 0xc2, 0xc1, 0xc5, 0xcd, 0xba, 0x00, 0x00, 0xc9, + 0x00, 0x00, 0xbb, 0x00, 0x00, 0xc8, 0x00, 0x00, + 0xbc, 0x00, 0x00, 0xcc, 0x00, 0x00, 0xb9, 0x00, + 0x00, 0xcb, 0x00, 0x00, 0xca, 0x00, 0x00, 0xce, + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, + 0xdb, 0xb0, 0xb1, 0xb2, 0xfe, +}; + +SMB_GENERATE_CHARSET_MODULE_8_BIT_GAP(CP850) + diff --git a/lib/util/charset/charset.h b/lib/util/charset/charset.h index e5fd596f8f..a7e554204b 100644 --- a/lib/util/charset/charset.h +++ b/lib/util/charset/charset.h @@ -279,7 +279,7 @@ static size_t CHARSETNAME ## _push(void *cd, const char **inbuf, size_t *inbytes int i; \ int done = 0; \ \ - uint16 ch = SVAL(*inbuf,0); \ + uint16_t ch = SVAL(*inbuf,0); \ \ for (i=0; from_idx[i].start != 0xffff; i++) { \ if ((from_idx[i].start <= ch) && (from_idx[i].end >= ch)) { \ diff --git a/lib/util/charset/charset_macosxfs.c b/lib/util/charset/charset_macosxfs.c new file mode 100644 index 0000000000..8c2fdc7776 --- /dev/null +++ b/lib/util/charset/charset_macosxfs.c @@ -0,0 +1,604 @@ +/* + Unix SMB/CIFS implementation. + Samba charset module for Mac OS X/Darwin + Copyright (C) Benjamin Riefenstahl 2003 + + 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 . +*/ + +/* + * modules/charset_macosxfs.c + * + * A Samba charset module to use on Mac OS X/Darwin as the filesystem + * and display encoding. + * + * Actually two implementations are provided here. The default + * implementation is based on the official CFString API. The other is + * based on internal CFString APIs as defined in the OpenDarwin + * source. + */ + +#include "includes.h" + +/* + * Include OS frameworks. These are only needed in this module. + */ +#include + +/* + * See if autoconf has found us the internal headers in some form. + */ +#if HAVE_COREFOUNDATION_CFSTRINGENCODINGCONVERTER_H +# include +# include +# define USE_INTERNAL_API 1 +#elif HAVE_CFSTRINGENCODINGCONVERTER_H +# include +# include +# define USE_INTERNAL_API 1 +#endif + +/* + * Compile time configuration: Do we want debug output? + */ +/* #define DEBUG_STRINGS 1 */ + +/* + * A simple, but efficient memory provider for our buffers. + */ +static inline void *resize_buffer (void *buffer, size_t *size, size_t newsize) +{ + if (newsize > *size) { + *size = newsize + 128; + buffer = SMB_REALLOC(buffer, *size); + } + return buffer; +} + +/* + * While there is a version of OpenDarwin for intel, the usual case is + * big-endian PPC. So we need byte swapping to handle the + * little-endian byte order of the network protocol. We also need an + * additional dynamic buffer to do this work for incoming data blocks, + * because we have to consider the original data as constant. + * + * We abstract the differences away by providing a simple facade with + * these functions/macros: + * + * le_to_native(dst,src,len) + * native_to_le(cp,len) + * set_ucbuffer_with_le(buffer,bufsize,data,size) + * set_ucbuffer_with_le_copy(buffer,bufsize,data,size,reserve) + */ +#ifdef WORDS_BIGENDIAN + +static inline void swap_bytes (char * dst, const char * src, size_t len) +{ + const char *srcend = src + len; + while (src < srcend) { + dst[0] = src[1]; + dst[1] = src[0]; + dst += 2; + src += 2; + } +} +static inline void swap_bytes_inplace (char * cp, size_t len) +{ + char temp; + char *end = cp + len; + while (cp < end) { + temp = cp[1]; + cp[1] = cp[0]; + cp[0] = temp; + cp += 2; + } +} + +#define le_to_native(dst,src,len) swap_bytes(dst,src,len) +#define native_to_le(cp,len) swap_bytes_inplace(cp,len) +#define set_ucbuffer_with_le(buffer,bufsize,data,size) \ + set_ucbuffer_with_le_copy(buffer,bufsize,data,size,0) + +#else /* ! WORDS_BIGENDIAN */ + +#define le_to_native(dst,src,len) memcpy(dst,src,len) +#define native_to_le(cp,len) /* nothing */ +#define set_ucbuffer_with_le(buffer,bufsize,data,size) \ + (((void)(bufsize)),(UniChar*)(data)) + +#endif + +static inline UniChar *set_ucbuffer_with_le_copy ( + UniChar *buffer, size_t *bufsize, + const void *data, size_t size, size_t reserve) +{ + buffer = resize_buffer(buffer, bufsize, size+reserve); + le_to_native((char*)buffer,data,size); + return buffer; +} + + +/* + * A simple hexdump function for debugging error conditions. + */ +#define debug_out(s) DEBUG(0,(s)) + +#ifdef DEBUG_STRINGS + +static void hexdump( const char * label, const char * s, size_t len ) +{ + size_t restlen = len; + debug_out("<<<<<<<\n"); + debug_out(label); + debug_out("\n"); + while (restlen > 0) { + char line[100]; + size_t i, j; + char * d = line; +#undef sprintf + d += sprintf(d, "%04X ", (unsigned)(len-restlen)); + *d++ = ' '; + for( i = 0; i= 0x7F || !isprint(s[i])) + *d++ = '.'; + else + *d++ = s[i]; + } + *d++ = '\n'; + *d = 0; + restlen -= i; + s += i; + debug_out(line); + } + debug_out(">>>>>>>\n"); +} + +#else /* !DEBUG_STRINGS */ + +#define hexdump(label,s,len) /* nothing */ + +#endif + + +#if !USE_INTERNAL_API + +/* + * An implementation based on documented Mac OS X APIs. + * + * This does a certain amount of memory management, creating and + * manipulating CFString objects. We try to minimize the impact by + * keeping those objects around and re-using them. We also use + * external backing store for the CFStrings where this is possible and + * benficial. + * + * The Unicode normalizations forms available at this level are + * generic, not specifically for the file system. So they may not be + * perfect fits. + */ +static size_t macosxfs_encoding_pull( + void *cd, /* Encoder handle */ + char **inbuf, size_t *inbytesleft, /* Script string */ + char **outbuf, size_t *outbytesleft) /* UTF-16-LE string */ +{ + static const int script_code = kCFStringEncodingUTF8; + static CFMutableStringRef cfstring = NULL; + size_t outsize; + CFRange range; + + (void) cd; /* UNUSED */ + + if (0 == *inbytesleft) { + return 0; + } + + if (NULL == cfstring) { + /* + * A version with an external backing store as in the + * push function should have been more efficient, but + * testing shows, that it is actually slower (!). + * Maybe kCFAllocatorDefault gets shortcut evaluation + * internally, while kCFAllocatorNull doesn't. + */ + cfstring = CFStringCreateMutable(kCFAllocatorDefault,0); + } + + /* + * Three methods of appending to a CFString, choose the most + * efficient. + */ + if (0 == (*inbuf)[*inbytesleft-1]) { + CFStringAppendCString(cfstring, *inbuf, script_code); + } else if (*inbytesleft <= 255) { + Str255 buffer; + buffer[0] = *inbytesleft; + memcpy(buffer+1, *inbuf, buffer[0]); + CFStringAppendPascalString(cfstring, buffer, script_code); + } else { + /* + * We would like to use a fixed buffer and a loop + * here, but than we can't garantee that the input is + * well-formed UTF-8, as we are supposed to do. + */ + static char *buffer = NULL; + static size_t buflen = 0; + buffer = resize_buffer(buffer, &buflen, *inbytesleft+1); + memcpy(buffer, *inbuf, *inbytesleft); + buffer[*inbytesleft] = 0; + CFStringAppendCString(cfstring, *inbuf, script_code); + } + + /* + * Compose characters, using the non-canonical composition + * form. + */ + CFStringNormalize(cfstring, kCFStringNormalizationFormC); + + outsize = CFStringGetLength(cfstring); + range = CFRangeMake(0,outsize); + + if (outsize == 0) { + /* + * HACK: smbd/mangle_hash2.c:is_legal_name() expects + * errors here. That function will always pass 2 + * characters. smbd/open.c:check_for_pipe() cuts a + * patchname to 10 characters blindly. Suppress the + * debug output in those cases. + */ + if(2 != *inbytesleft && 10 != *inbytesleft) { + debug_out("String conversion: " + "An unknown error occurred\n"); + hexdump("UTF8->UTF16LE (old) input", + *inbuf, *inbytesleft); + } + errno = EILSEQ; /* Not sure, but this is what we have + * actually seen. */ + return -1; + } + if (outsize*2 > *outbytesleft) { + CFStringDelete(cfstring, range); + debug_out("String conversion: " + "Output buffer too small\n"); + hexdump("UTF8->UTF16LE (old) input", + *inbuf, *inbytesleft); + errno = E2BIG; + return -1; + } + + CFStringGetCharacters(cfstring, range, (UniChar*)*outbuf); + CFStringDelete(cfstring, range); + + native_to_le(*outbuf, outsize*2); + + /* + * Add a converted null byte, if the CFString conversions + * prevented that until now. + */ + if (0 == (*inbuf)[*inbytesleft-1] && + (0 != (*outbuf)[outsize*2-1] || 0 != (*outbuf)[outsize*2-2])) { + + if ((outsize*2+2) > *outbytesleft) { + debug_out("String conversion: " + "Output buffer too small\n"); + hexdump("UTF8->UTF16LE (old) input", + *inbuf, *inbytesleft); + errno = E2BIG; + return -1; + } + + (*outbuf)[outsize*2] = (*outbuf)[outsize*2+1] = 0; + outsize += 2; + } + + *inbuf += *inbytesleft; + *inbytesleft = 0; + *outbuf += outsize*2; + *outbytesleft -= outsize*2; + + return 0; +} + +static size_t macosxfs_encoding_push( + void *cd, /* Encoder handle */ + char **inbuf, size_t *inbytesleft, /* UTF-16-LE string */ + char **outbuf, size_t *outbytesleft) /* Script string */ +{ + static const int script_code = kCFStringEncodingUTF8; + static CFMutableStringRef cfstring = NULL; + static UniChar *buffer = NULL; + static size_t buflen = 0; + CFIndex outsize, cfsize, charsconverted; + + (void) cd; /* UNUSED */ + + if (0 == *inbytesleft) { + return 0; + } + + /* + * We need a buffer that can hold 4 times the original data, + * because that is the theoretical maximum that decomposition + * can create currently (in Unicode 4.0). + */ + buffer = set_ucbuffer_with_le_copy( + buffer, &buflen, *inbuf, *inbytesleft, 3 * *inbytesleft); + + if (NULL == cfstring) { + cfstring = CFStringCreateMutableWithExternalCharactersNoCopy( + kCFAllocatorDefault, + buffer, *inbytesleft/2, buflen/2, + kCFAllocatorNull); + } else { + CFStringSetExternalCharactersNoCopy( + cfstring, + buffer, *inbytesleft/2, buflen/2); + } + + /* + * Decompose characters, using the non-canonical decomposition + * form. + * + * NB: This isn't exactly what HFS+ wants (see note on + * kCFStringEncodingUseHFSPlusCanonical in + * CFStringEncodingConverter.h), but AFAIK it's the best that + * the official API can do. + */ + CFStringNormalize(cfstring, kCFStringNormalizationFormD); + + cfsize = CFStringGetLength(cfstring); + charsconverted = CFStringGetBytes( + cfstring, CFRangeMake(0,cfsize), + script_code, 0, False, + *outbuf, *outbytesleft, &outsize); + + if (0 == charsconverted) { + debug_out("String conversion: " + "Buffer too small or not convertable\n"); + hexdump("UTF16LE->UTF8 (old) input", + *inbuf, *inbytesleft); + errno = EILSEQ; /* Probably more likely. */ + return -1; + } + + /* + * Add a converted null byte, if the CFString conversions + * prevented that until now. + */ + if (0 == (*inbuf)[*inbytesleft-1] && 0 == (*inbuf)[*inbytesleft-2] && + (0 != (*outbuf)[outsize-1])) { + + if (((size_t)outsize+1) > *outbytesleft) { + debug_out("String conversion: " + "Output buffer too small\n"); + hexdump("UTF16LE->UTF8 (old) input", + *inbuf, *inbytesleft); + errno = E2BIG; + return -1; + } + + (*outbuf)[outsize] = 0; + ++outsize; + } + + *inbuf += *inbytesleft; + *inbytesleft = 0; + *outbuf += outsize; + *outbytesleft -= outsize; + + return 0; +} + +#else /* USE_INTERNAL_API */ + +/* + * An implementation based on internal code as known from the + * OpenDarwin CVS. + * + * This code doesn't need much memory management because it uses + * functions that operate on the raw memory directly. + * + * The push routine here is faster and more compatible with HFS+ than + * the other implementation above. The pull routine is only faster + * for some strings, slightly slower for others. The pull routine + * looses because it has to iterate over the data twice, once to + * decode UTF-8 and than to do the character composition required by + * Windows. + */ +static size_t macosxfs_encoding_pull( + void *cd, /* Encoder handle */ + char **inbuf, size_t *inbytesleft, /* Script string */ + char **outbuf, size_t *outbytesleft) /* UTF-16-LE string */ +{ + static const int script_code = kCFStringEncodingUTF8; + UInt32 srcCharsUsed = 0; + UInt32 dstCharsUsed = 0; + UInt32 result; + uint32_t dstDecomposedUsed = 0; + uint32_t dstPrecomposedUsed = 0; + + (void) cd; /* UNUSED */ + + if (0 == *inbytesleft) { + return 0; + } + + result = CFStringEncodingBytesToUnicode( + script_code, kCFStringEncodingComposeCombinings, + *inbuf, *inbytesleft, &srcCharsUsed, + (UniChar*)*outbuf, *outbytesleft, &dstCharsUsed); + + switch(result) { + case kCFStringEncodingConversionSuccess: + if (*inbytesleft == srcCharsUsed) + break; + else + ; /*fall through*/ + case kCFStringEncodingInsufficientOutputBufferLength: + debug_out("String conversion: " + "Output buffer too small\n"); + hexdump("UTF8->UTF16LE (new) input", + *inbuf, *inbytesleft); + errno = E2BIG; + return -1; + case kCFStringEncodingInvalidInputStream: + /* + * HACK: smbd/mangle_hash2.c:is_legal_name() expects + * errors here. That function will always pass 2 + * characters. smbd/open.c:check_for_pipe() cuts a + * patchname to 10 characters blindly. Suppress the + * debug output in those cases. + */ + if(2 != *inbytesleft && 10 != *inbytesleft) { + debug_out("String conversion: " + "Invalid input sequence\n"); + hexdump("UTF8->UTF16LE (new) input", + *inbuf, *inbytesleft); + } + errno = EILSEQ; + return -1; + case kCFStringEncodingConverterUnavailable: + debug_out("String conversion: " + "Unknown encoding\n"); + hexdump("UTF8->UTF16LE (new) input", + *inbuf, *inbytesleft); + errno = EINVAL; + return -1; + } + + /* + * It doesn't look like CFStringEncodingBytesToUnicode() can + * produce precomposed characters (flags=ComposeCombinings + * doesn't do it), so we need another pass over the data here. + * We can do this in-place, as the string can only get + * shorter. + * + * (Actually in theory there should be an internal + * decomposition and reordering before the actual composition + * step. But we should be able to rely on that we always get + * fully decomposed strings for input, so this can't create + * problems in reality.) + */ + CFUniCharPrecompose( + (const UTF16Char *)*outbuf, dstCharsUsed, &dstDecomposedUsed, + (UTF16Char *)*outbuf, dstCharsUsed, &dstPrecomposedUsed); + + native_to_le(*outbuf, dstPrecomposedUsed*2); + + *inbuf += srcCharsUsed; + *inbytesleft -= srcCharsUsed; + *outbuf += dstPrecomposedUsed*2; + *outbytesleft -= dstPrecomposedUsed*2; + + return 0; +} + +static size_t macosxfs_encoding_push( + void *cd, /* Encoder handle */ + char **inbuf, size_t *inbytesleft, /* UTF-16-LE string */ + char **outbuf, size_t *outbytesleft) /* Script string */ +{ + static const int script_code = kCFStringEncodingUTF8; + static UniChar *buffer = NULL; + static size_t buflen = 0; + UInt32 srcCharsUsed=0, dstCharsUsed=0, result; + + (void) cd; /* UNUSED */ + + if (0 == *inbytesleft) { + return 0; + } + + buffer = set_ucbuffer_with_le( + buffer, &buflen, *inbuf, *inbytesleft); + + result = CFStringEncodingUnicodeToBytes( + script_code, kCFStringEncodingUseHFSPlusCanonical, + buffer, *inbytesleft/2, &srcCharsUsed, + *outbuf, *outbytesleft, &dstCharsUsed); + + switch(result) { + case kCFStringEncodingConversionSuccess: + if (*inbytesleft/2 == srcCharsUsed) + break; + else + ; /*fall through*/ + case kCFStringEncodingInsufficientOutputBufferLength: + debug_out("String conversion: " + "Output buffer too small\n"); + hexdump("UTF16LE->UTF8 (new) input", + *inbuf, *inbytesleft); + errno = E2BIG; + return -1; + case kCFStringEncodingInvalidInputStream: + /* + * HACK: smbd/open.c:check_for_pipe():is_legal_name() + * cuts a pathname to 10 characters blindly. Suppress + * the debug output in those cases. + */ + if(10 != *inbytesleft) { + debug_out("String conversion: " + "Invalid input sequence\n"); + hexdump("UTF16LE->UTF8 (new) input", + *inbuf, *inbytesleft); + } + errno = EILSEQ; + return -1; + case kCFStringEncodingConverterUnavailable: + debug_out("String conversion: " + "Unknown encoding\n"); + hexdump("UTF16LE->UTF8 (new) input", + *inbuf, *inbytesleft); + errno = EINVAL; + return -1; + } + + *inbuf += srcCharsUsed*2; + *inbytesleft -= srcCharsUsed*2; + *outbuf += dstCharsUsed; + *outbytesleft -= dstCharsUsed; + + return 0; +} + +#endif /* USE_INTERNAL_API */ + +/* + * For initialization, actually install the encoding as "macosxfs". + */ +static struct charset_functions macosxfs_encoding_functions = { + "MACOSXFS", macosxfs_encoding_pull, macosxfs_encoding_push +}; + +NTSTATUS charset_macosxfs_init(void) +{ + if (!smb_register_charset(&macosxfs_encoding_functions)) { + return NT_STATUS_INTERNAL_ERROR; + } + return NT_STATUS_OK; +} + +/* eof */ diff --git a/lib/util/charset/weird.c b/lib/util/charset/weird.c new file mode 100644 index 0000000000..5db8cdcecd --- /dev/null +++ b/lib/util/charset/weird.c @@ -0,0 +1,134 @@ +/* + Unix SMB/CIFS implementation. + Samba module with developer tools + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Jelmer Vernooij 2002 + + 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 . +*/ + +#include "includes.h" + +static struct { + char from; + const char *to; + int len; +} weird_table[] = { + {'q', "^q^", 3}, + {'Q', "^Q^", 3}, + {0, NULL} +}; + +static size_t weird_pull(void *cd, const char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft) +{ + while (*inbytesleft >= 1 && *outbytesleft >= 2) { + int i; + int done = 0; + for (i=0;weird_table[i].from;i++) { + if (strncmp((*inbuf), + weird_table[i].to, + weird_table[i].len) == 0) { + if (*inbytesleft < weird_table[i].len) { + DEBUG(0,("ERROR: truncated weird string\n")); + /* smb_panic("weird_pull"); */ + + } else { + (*outbuf)[0] = weird_table[i].from; + (*outbuf)[1] = 0; + (*inbytesleft) -= weird_table[i].len; + (*outbytesleft) -= 2; + (*inbuf) += weird_table[i].len; + (*outbuf) += 2; + done = 1; + break; + } + } + } + if (done) continue; + (*outbuf)[0] = (*inbuf)[0]; + (*outbuf)[1] = 0; + (*inbytesleft) -= 1; + (*outbytesleft) -= 2; + (*inbuf) += 1; + (*outbuf) += 2; + } + + if (*inbytesleft > 0) { + errno = E2BIG; + return -1; + } + + return 0; +} + +static size_t weird_push(void *cd, const char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft) +{ + int ir_count=0; + + while (*inbytesleft >= 2 && *outbytesleft >= 1) { + int i; + int done=0; + for (i=0;weird_table[i].from;i++) { + if ((*inbuf)[0] == weird_table[i].from && + (*inbuf)[1] == 0) { + if (*outbytesleft < weird_table[i].len) { + DEBUG(0,("No room for weird character\n")); + /* smb_panic("weird_push"); */ + } else { + memcpy(*outbuf, weird_table[i].to, + weird_table[i].len); + (*inbytesleft) -= 2; + (*outbytesleft) -= weird_table[i].len; + (*inbuf) += 2; + (*outbuf) += weird_table[i].len; + done = 1; + break; + } + } + } + if (done) continue; + + (*outbuf)[0] = (*inbuf)[0]; + if ((*inbuf)[1]) ir_count++; + (*inbytesleft) -= 2; + (*outbytesleft) -= 1; + (*inbuf) += 2; + (*outbuf) += 1; + } + + if (*inbytesleft == 1) { + errno = EINVAL; + return -1; + } + + if (*inbytesleft > 1) { + errno = E2BIG; + return -1; + } + + return ir_count; +} + +struct charset_functions weird_functions = {"WEIRD", weird_pull, weird_push}; + +NTSTATUS charset_weird_init(void); +NTSTATUS charset_weird_init(void) +{ + if (!smb_register_charset(&weird_functions)) { + return NT_STATUS_INTERNAL_ERROR; + } + return NT_STATUS_OK; +} diff --git a/lib/util/charset/wscript_build b/lib/util/charset/wscript_build index 7623131146..3b29ace6d3 100644 --- a/lib/util/charset/wscript_build +++ b/lib/util/charset/wscript_build @@ -9,3 +9,36 @@ bld.SAMBA_SUBSYSTEM('CHARSET', source='codepoints.c convert_string.c util_str.c util_unistr_w.c charcnv.c pull_push.c util_unistr.c', deps='DYNCONFIG ICONV_WRAPPER' ) + +bld.SAMBA_MODULE('charset_weird', + subsystem='CHARSET', + source='weird.c', + init_function='', + deps='samba-util', + internal_module=bld.SAMBA3_IS_STATIC_MODULE('charset_weird'), + enabled=bld.SAMBA3_IS_ENABLED_MODULE('charset_weird')) + +bld.SAMBA_MODULE('charset_CP850', + subsystem='CHARSET', + source='CP850.c', + init_function='', + deps='samba-util', + internal_module=bld.SAMBA3_IS_STATIC_MODULE('charset_CP850'), + enabled=bld.SAMBA3_IS_ENABLED_MODULE('charset_CP850')) + +bld.SAMBA_MODULE('charset_CP437', + subsystem='CHARSET', + source='CP437.c', + init_function='', + deps='samba-util', + internal_module=bld.SAMBA3_IS_STATIC_MODULE('charset_CP437'), + enabled=bld.SAMBA3_IS_ENABLED_MODULE('charset_CP437')) + +bld.SAMBA_MODULE('charset_macosxfs', + subsystem='CHARSET', + source='charset_macosxfs.c', + init_function='', + internal_module=bld.SAMBA3_IS_STATIC_MODULE('charset_macosxfs'), + enabled=bld.SAMBA3_IS_ENABLED_MODULE('charset_macosxfs')) + + -- cgit From 115d0ecf88a5cae2d684264f570892fb763d54d2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 14 May 2011 17:39:40 +0200 Subject: Use ZERO_STRUCTP in util_net --- lib/util/util_net.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/util') diff --git a/lib/util/util_net.c b/lib/util/util_net.c index 7d678c9b14..98eef3bd8b 100644 --- a/lib/util/util_net.c +++ b/lib/util/util_net.c @@ -405,7 +405,7 @@ bool is_zero_addr(const struct sockaddr_storage *pss) */ void zero_ip_v4(struct in_addr *ip) { - memset(ip, '\0', sizeof(struct in_addr)); + ZERO_STRUCTP(ip); } /** @@ -415,7 +415,7 @@ void in_addr_to_sockaddr_storage(struct sockaddr_storage *ss, struct in_addr ip) { struct sockaddr_in *sa = (struct sockaddr_in *)ss; - memset(ss, '\0', sizeof(*ss)); + ZERO_STRUCTP(ss); sa->sin_family = AF_INET; sa->sin_addr = ip; } -- cgit From 00922404011769e4b981ca1cc2c2404c022770a0 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 17 May 2011 15:08:40 +0200 Subject: lib/util/charset: fix the toplevel MacOS X build. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guenther Autobuild-User: Günther Deschner Autobuild-Date: Tue May 17 16:16:59 CEST 2011 on sn-devel-104 --- lib/util/charset/charset_macosxfs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/util') diff --git a/lib/util/charset/charset_macosxfs.c b/lib/util/charset/charset_macosxfs.c index 8c2fdc7776..4d2ba5b6ff 100644 --- a/lib/util/charset/charset_macosxfs.c +++ b/lib/util/charset/charset_macosxfs.c @@ -30,6 +30,7 @@ */ #include "includes.h" +#undef realloc /* * Include OS frameworks. These are only needed in this module. @@ -61,7 +62,7 @@ static inline void *resize_buffer (void *buffer, size_t *size, size_t newsize) { if (newsize > *size) { *size = newsize + 128; - buffer = SMB_REALLOC(buffer, *size); + buffer = realloc(buffer, *size); } return buffer; } @@ -372,7 +373,7 @@ static size_t macosxfs_encoding_push( cfsize = CFStringGetLength(cfstring); charsconverted = CFStringGetBytes( cfstring, CFRangeMake(0,cfsize), - script_code, 0, False, + script_code, 0, false, *outbuf, *outbytesleft, &outsize); if (0 == charsconverted) { -- cgit From d25370fb477dd733fae6c1ee1a67e32a78236779 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 16 May 2011 15:47:49 -0700 Subject: Don't evaluate the src argument to fstrcpy/fstrcat/nstrcpy/unstrcpy twice. Prevents side-effects when src is a function call. --- lib/util/string_wrappers.h | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) (limited to 'lib/util') diff --git a/lib/util/string_wrappers.h b/lib/util/string_wrappers.h index 7baf3cb21b..37384fc5a3 100644 --- a/lib/util/string_wrappers.h +++ b/lib/util/string_wrappers.h @@ -42,15 +42,35 @@ size_t __unsafe_string_function_usage_here_size_t__(void); #endif /* HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS */ #define strlcpy_base(dest, src, base, size) \ - strlcpy((dest), (src) ? (src) : "", (size)-PTR_DIFF((dest),(base))) +do { \ + const char *_strlcpy_base_src = (const char *)src; \ + strlcpy((dest), _strlcpy_base_src? _strlcpy_base_src : "", (size)-PTR_DIFF((dest),(base))); \ +} while (0) /* String copy functions - macro hell below adds 'type checking' (limited, but the best we can do in C) */ -#define fstrcpy(d,s) strlcpy((d),(s) ? (s) : "",sizeof(fstring)) -#define fstrcat(d,s) strlcpy((d),(s) ? (s) : "",sizeof(fstring)) -#define nstrcpy(d,s) strlcpy((d), (s) ? (s) : "",sizeof(nstring)) -#define unstrcpy(d,s) strlcpy((d), (s) ? (s) : "",sizeof(unstring)) +#define fstrcpy(d,s) \ +do { \ + const char *_fstrcpy_src = (const char *)(s); \ + strlcpy((d),_fstrcpy_src ? _fstrcpy_src : "",sizeof(fstring)); \ +} while (0) + +#define fstrcat(d,s) \ +do { \ + const char *_fstrcat_src = (const char *)(s); \ + strlcat((d),_fstrcat_src ? _fstrcat_src : "",sizeof(fstring)); \ +} while (0) +#define nstrcpy(d,s) \ +do { \ + const char *_nstrcpy_src = (const char *)(s); \ + strlcpy((d),_nstrcpy_src ? _nstrcpy_src : "",sizeof(fstring)); \ +} while (0) +#define unstrcpy(d,s) \ +do { \ + const char *_unstrcpy_src = (const char *)(s); \ + strlcpy((d),_unstrcpy_src ? _unstrcpy_src : "",sizeof(fstring)); \ +} while (0) #ifdef HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS -- cgit From 3c8de7dd66390c00542118ec3aaa84e1e20956cb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 18 May 2011 11:51:37 +1000 Subject: lib/util/charset Don't allow invalid 'dos charset = utf8' No DOS client used UTF8, and this creates subtle, difficult to disagnose breakage of schannel (domain membership). Andrew Bartlett --- lib/util/charset/codepoints.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/util') diff --git a/lib/util/charset/codepoints.c b/lib/util/charset/codepoints.c index 5e8ac64ed4..71611bfc4c 100644 --- a/lib/util/charset/codepoints.c +++ b/lib/util/charset/codepoints.c @@ -290,6 +290,11 @@ _PUBLIC_ struct smb_iconv_handle *smb_iconv_handle_reinit(TALLOC_CTX *mem_ctx, talloc_set_destructor(ret, close_iconv_handle); + if (strcasecmp(dos_charset, "UTF8") == 0 || strcasecmp(dos_charset, "UTF-8") == 0) { + DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not be UTF8, using (default value) CP850 instead\n")); + dos_charset = "CP850"; + } + ret->dos_charset = talloc_strdup(ret->child_ctx, dos_charset); ret->unix_charset = talloc_strdup(ret->child_ctx, unix_charset); ret->display_charset = talloc_strdup(ret->child_ctx, display_charset); -- cgit From 57f41ef150b82523aeb23cde63c1f8731a061edb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 18 May 2011 13:57:26 +1000 Subject: lib/util/charset use talloc_stackframe() rather than talloc_tos() This is common code, and we can't assume a talloc_stackframe() so we must create it. Andrew Bartlett --- lib/util/charset/util_str.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'lib/util') diff --git a/lib/util/charset/util_str.c b/lib/util/charset/util_str.c index e76c1dbbf5..80e5bde354 100644 --- a/lib/util/charset/util_str.c +++ b/lib/util/charset/util_str.c @@ -487,9 +487,10 @@ char *strstr_m(const char *src, const char *findstr) const char *s; char *s2; char *retp; - size_t converted_size, findstr_len = 0; + TALLOC_CTX *frame; /* Only set up in the iconv case */ + /* for correctness */ if (!findstr[0]) { return discard_const_p(char, src); @@ -524,35 +525,34 @@ char *strstr_m(const char *src, const char *findstr) s = src; #endif - if (!push_ucs2_talloc(talloc_tos(), &src_w, src, &converted_size)) { + frame = talloc_stackframe(); + + if (!push_ucs2_talloc(frame, &src_w, src, &converted_size)) { DEBUG(0,("strstr_m: src malloc fail\n")); + TALLOC_FREE(frame); return NULL; } - if (!push_ucs2_talloc(talloc_tos(), &find_w, findstr, &converted_size)) { - TALLOC_FREE(src_w); + if (!push_ucs2_talloc(frame, &find_w, findstr, &converted_size)) { DEBUG(0,("strstr_m: find malloc fail\n")); + TALLOC_FREE(frame); return NULL; } p = strstr_w(src_w, find_w); if (!p) { - TALLOC_FREE(src_w); - TALLOC_FREE(find_w); + TALLOC_FREE(frame); return NULL; } *p = 0; - if (!pull_ucs2_talloc(talloc_tos(), &s2, src_w, &converted_size)) { - TALLOC_FREE(src_w); - TALLOC_FREE(find_w); + if (!pull_ucs2_talloc(frame, &s2, src_w, &converted_size)) { + TALLOC_FREE(frame); DEBUG(0,("strstr_m: dest malloc fail\n")); return NULL; } retp = discard_const_p(char, (s+strlen(s2))); - TALLOC_FREE(src_w); - TALLOC_FREE(find_w); - TALLOC_FREE(s2); + TALLOC_FREE(frame); return retp; } -- cgit From f19ab5d334e3fb15761fb009e5de876dfc6ea785 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 18 May 2011 23:57:10 +1000 Subject: lib/util/charset: Remove unused strcasecmp_w and strncasecmp_w Autobuild-User: Andrew Bartlett Autobuild-Date: Wed May 18 17:22:15 CEST 2011 on sn-devel-104 --- lib/util/charset/util_unistr_w.c | 32 -------------------------------- 1 file changed, 32 deletions(-) (limited to 'lib/util') diff --git a/lib/util/charset/util_unistr_w.c b/lib/util/charset/util_unistr_w.c index 5b61d52e7f..3fbed7f67c 100644 --- a/lib/util/charset/util_unistr_w.c +++ b/lib/util/charset/util_unistr_w.c @@ -234,38 +234,6 @@ static int strncmp_w(const smb_ucs2_t *a, const smb_ucs2_t *b, size_t len) return (len - n)?(*(COPY_UCS2_CHAR(&cpa,a)) - *(COPY_UCS2_CHAR(&cpb,b))):0; } -/******************************************************************* - Case insensitive string comparison. -********************************************************************/ - -int strcasecmp_w(const smb_ucs2_t *a, const smb_ucs2_t *b) -{ - smb_ucs2_t cpa, cpb; - - while ((*COPY_UCS2_CHAR(&cpb,b)) && toupper_m(*(COPY_UCS2_CHAR(&cpa,a))) == toupper_m(cpb)) { - a++; - b++; - } - return (tolower_m(*(COPY_UCS2_CHAR(&cpa,a))) - tolower_m(*(COPY_UCS2_CHAR(&cpb,b)))); -} - -/******************************************************************* - Case insensitive string comparison, length limited. -********************************************************************/ - -int strncasecmp_w(const smb_ucs2_t *a, const smb_ucs2_t *b, size_t len) -{ - smb_ucs2_t cpa, cpb; - size_t n = 0; - - while ((n < len) && *COPY_UCS2_CHAR(&cpb,b) && (toupper_m(*(COPY_UCS2_CHAR(&cpa,a))) == toupper_m(cpb))) { - a++; - b++; - n++; - } - return (len - n)?(tolower_m(*(COPY_UCS2_CHAR(&cpa,a))) - tolower_m(*(COPY_UCS2_CHAR(&cpb,b)))):0; -} - /* The *_wa() functions take a combination of 7 bit ascii and wide characters They are used so that you can use string -- cgit From ede98c0e5190bf59461703629d5a4742ad8e044f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 14 May 2011 19:49:36 +0200 Subject: lib/util Add Volker's asn1_Integer test into code that runs in 'make test' The comfychair test harness isn't hooked up, and with the current infrustructure C code is better tested directly here. Andrew Bartlett --- lib/util/tests/asn1_tests.c | 94 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) (limited to 'lib/util') diff --git a/lib/util/tests/asn1_tests.c b/lib/util/tests/asn1_tests.c index ac8ca538f8..3ee64c3f7a 100644 --- a/lib/util/tests/asn1_tests.c +++ b/lib/util/tests/asn1_tests.c @@ -4,6 +4,8 @@ util_asn1 testing Copyright (C) Kamen Mazdrashki 2009 + Copyright (C) Volker Lendecke 2004 + Copyright (C) Andrew Bartlett 2011 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 @@ -103,6 +105,55 @@ static const struct oid_data partial_oid_data_ok[] = { }, }; +static const struct { + DATA_BLOB blob; + int value; +} integer_tests[] = { + { + .blob = {"\x02\x01\x00", 3}, + .value = 0 + }, + { + .blob = {"\x02\x01\x7f", 3}, + .value = 127 + }, + { + .blob = {"\x02\x02\x00\x80", 4}, + .value = 128 + }, + { + .blob = {"\x02\x02\x01\x00", 4}, + .value = 256 + }, + { + .blob = {"\x02\x01\x80", 3}, + .value = -128 + }, + { + .blob = {"\x02\x02\xff\x7f", 4}, + .value = -129 + }, + { + .blob = {"\x02\x01\xff", 3}, + .value = -1 + }, + { + .blob = {"\x02\x02\xff\x01", 4}, + .value = -255 + }, + { + .blob = {"\x02\x02\x00\xff", 4}, + .value = 255 + }, + { + .blob = {"\x02\x04\x80\x00\x00\x00", 6}, + .value = 0x80000000 + }, + { + .blob = {"\x02\x04\x7f\xff\xff\xff", 6}, + .value = 0x7fffffff + } +}; /* Testing ber_write_OID_String() function */ static bool test_ber_write_OID_String(struct torture_context *tctx) @@ -260,6 +311,46 @@ static bool test_ber_read_partial_OID_String(struct torture_context *tctx) return true; } +/* + * Testing asn1_read_Integer and asn1_write_Integer functions, + * inspired by Love Hornquist Astrand + */ + +static bool test_asn1_Integer(struct torture_context *tctx) +{ + int i; + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_new(tctx); + + for (i = 0; i < ARRAY_SIZE(integer_tests); i++) { + ASN1_DATA *data; + DATA_BLOB blob; + int val; + + data = asn1_init(mem_ctx); + if (!data) { + return -1; + } + + asn1_write_Integer(data, integer_tests[i].value); + + blob.data = data->data; + blob.length = data->length; + torture_assert_data_blob_equal(tctx, blob, integer_tests[i].blob, "asn1_write_Integer gave incorrect result"); + + asn1_load(data, blob); + torture_assert(tctx, asn1_read_Integer(data, &val), "asn1_write_Integer output could not be read by asn1_read_Integer()"); + + torture_assert_int_equal(tctx, val, integer_tests[i].value, + "readback of asn1_write_Integer output by asn1_read_Integer() failed"); + } + + talloc_free(mem_ctx); + + return true; +} + /* LOCAL-ASN1 test suite creation */ struct torture_suite *torture_local_util_asn1(TALLOC_CTX *mem_ctx) @@ -278,5 +369,8 @@ struct torture_suite *torture_local_util_asn1(TALLOC_CTX *mem_ctx) torture_suite_add_simple_test(suite, "ber_read_partial_OID_String", test_ber_read_partial_OID_String); + torture_suite_add_simple_test(suite, "asn1_Integer", + test_asn1_Integer); + return suite; } -- cgit From e719dfd4dc178f001a5f804fb1ac4e587574415f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 May 2011 12:47:31 -0700 Subject: Fix our asn.1 parser to handle negative numbers. Autobuild-User: Jeremy Allison Autobuild-Date: Tue May 24 22:57:16 CEST 2011 on sn-devel-104 --- lib/util/asn1.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'lib/util') diff --git a/lib/util/asn1.c b/lib/util/asn1.c index b716da63c0..c23bf65b8d 100644 --- a/lib/util/asn1.c +++ b/lib/util/asn1.c @@ -885,10 +885,19 @@ bool asn1_read_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blo bool asn1_read_implicit_Integer(struct asn1_data *data, int *i) { uint8_t b; + bool first_byte = true; *i = 0; while (!data->has_error && asn1_tag_remaining(data)>0) { if (!asn1_read_uint8(data, &b)) return false; + if (first_byte) { + if (b & 0x80) { + /* Number is negative. + Set i to -1 for sign extend. */ + *i = -1; + } + first_byte = false; + } *i = (*i << 8) + b; } return !data->has_error; -- cgit From 0f8018676a6cb33238d506338d4fbb8b683550d3 Mon Sep 17 00:00:00 2001 From: Sean Finney Date: Fri, 20 May 2011 08:12:08 +0000 Subject: Fix numerous missing dependencies in WAF build scripts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the recent consolidation of code between s3 and s4, a number of new dependencies have been implicitly introduced. For example, previous s3 code gained an implicit dependency on talloc after the charset related consolidation (lib/util/charset/charset.h now includes talloc.h). When building against the embedded version of talloc this isn't a problem since the paths are automatically added to the search path, but when building against the external libraries build failures will occur for all components that don't directly or indirectly include talloc as a dependency. Since charset.h is included from util.h, which in turn is included from includes.h, this means most of the codebase (s3 and s4) has such an undeclared dependency. Therefore, samba-util-common and samba-util have been added as dependencies to the s3 and s4 code respectively, for all cases where the source would otherwise fail to build. Additionally, a few other dependencies are added in specific wscript_build files to address similar dependency-related problems. https://bugzilla.samba.org/show_bug.cgi?id=8128 Signed-off-by: Sean Finney Signed-off-by: Matthias Dieter Wallnöfer Signed-off-by: Andrew Bartlett Autobuild-User: Matthias Dieter Wallnöfer Autobuild-Date: Wed May 25 19:22:13 CEST 2011 on sn-devel-104 --- lib/util/charset/wscript_build | 4 ++-- lib/util/wscript_build | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/util') diff --git a/lib/util/charset/wscript_build b/lib/util/charset/wscript_build index 3b29ace6d3..1f2c8dfa7a 100644 --- a/lib/util/charset/wscript_build +++ b/lib/util/charset/wscript_build @@ -7,8 +7,8 @@ bld.SAMBA_SUBSYSTEM('ICONV_WRAPPER', bld.SAMBA_SUBSYSTEM('CHARSET', public_headers='charset.h', source='codepoints.c convert_string.c util_str.c util_unistr_w.c charcnv.c pull_push.c util_unistr.c', - deps='DYNCONFIG ICONV_WRAPPER' - ) + deps='DYNCONFIG ICONV_WRAPPER', + public_deps='talloc') bld.SAMBA_MODULE('charset_weird', subsystem='CHARSET', diff --git a/lib/util/wscript_build b/lib/util/wscript_build index 740e68b6f0..3092b6ccbb 100755 --- a/lib/util/wscript_build +++ b/lib/util/wscript_build @@ -8,10 +8,10 @@ common_util_sources = '''talloc_stack.c smb_threads.c xfile.c data_blob.c util_str.c util_str_common.c substitute.c ms_fnmatch.c''' common_util_headers = 'debug.h' -common_util_public_deps = 'talloc pthread LIBCRYPTO' +common_util_public_deps = 'talloc pthread LIBCRYPTO CHARSET' s4_util_sources = '''dprintf.c parmlist.c''' s4_util_deps = 'DYNCONFIG' -s4_util_public_deps = 'talloc CHARSET execinfo uid_wrapper' +s4_util_public_deps = 'talloc execinfo uid_wrapper' s4_util_public_headers = 'attr.h byteorder.h data_blob.h memory.h safe_string.h time.h talloc_stack.h xfile.h dlinklist.h util.h string_wrappers.h' s4_util_header_path = [ ('dlinklist.h util.h', '.'), ('*', 'util') ] -- cgit From 52399f3177515fce777d85288650ff89f9028dc9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 31 May 2011 10:41:42 +1000 Subject: lib/util Move sys_memalign into lib/util/system.c --- lib/util/system.c | 39 +++++++++++++++++++++++++++++++++++++++ lib/util/util.h | 2 ++ 2 files changed, 41 insertions(+) (limited to 'lib/util') diff --git a/lib/util/system.c b/lib/util/system.c index 17c0553102..1e80f1a88a 100644 --- a/lib/util/system.c +++ b/lib/util/system.c @@ -22,6 +22,8 @@ #include "system/network.h" #include "system/filesys.h" +#undef malloc + /* The idea is that this file will eventually have wrappers around all important system calls in samba. The aims are: @@ -37,6 +39,42 @@ expansions/etc make sense to the OS should be acceptable to Samba. */ +/******************************************************************* + A wrapper for memalign +********************************************************************/ + +void *sys_memalign( size_t align, size_t size ) +{ +#if defined(HAVE_POSIX_MEMALIGN) + void *p = NULL; + int ret = posix_memalign( &p, align, size ); + if ( ret == 0 ) + return p; + + return NULL; +#elif defined(HAVE_MEMALIGN) + return memalign( align, size ); +#else + /* On *BSD systems memaligns doesn't exist, but memory will + * be aligned on allocations of > pagesize. */ +#if defined(SYSCONF_SC_PAGESIZE) + size_t pagesize = (size_t)sysconf(_SC_PAGESIZE); +#elif defined(HAVE_GETPAGESIZE) + size_t pagesize = (size_t)getpagesize(); +#else + size_t pagesize = (size_t)-1; +#endif + if (pagesize == (size_t)-1) { + DEBUG(0,("memalign functionalaity not available on this platform!\n")); + return NULL; + } + if (size < pagesize) { + size = pagesize; + } + return malloc(size); +#endif +} + /************************************************************************** A wrapper for gethostbyname() that tries avoids looking up hostnames in the root domain, which can cause dial-on-demand links to come up for no @@ -189,3 +227,4 @@ _PUBLIC_ int sys_connect(int fd, const struct sockaddr * addr) return connect(fd, addr, salen); } + diff --git a/lib/util/util.h b/lib/util/util.h index 93b181b1fc..d1c5e82bdd 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -115,6 +115,8 @@ void CatchChildLeaveStatus(void); /* The following definitions come from lib/util/system.c */ +void *sys_memalign( size_t align, size_t size ); + /************************************************************************** A wrapper for gethostbyname() that tries avoids looking up hostnames in the root domain, which can cause dial-on-demand links to come up for no -- cgit From 56e72337b01216dc7cba418f040a5cc928e5fc6f Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 1 Jun 2011 11:21:15 +0930 Subject: lib/util/time.c: timeval_current_ofs_msec Several places want "milliseconds from current time", and several were simply doing "msec * 1000" which can (and does in one place) result in a usec value over 1 a million. Using a helper to do this is safer and more readable. Signed-off-by: Rusty Russell --- lib/util/time.c | 9 +++++++++ lib/util/time.h | 5 +++++ 2 files changed, 14 insertions(+) (limited to 'lib/util') diff --git a/lib/util/time.c b/lib/util/time.c index 4843fc9697..de1553aff8 100644 --- a/lib/util/time.c +++ b/lib/util/time.c @@ -579,6 +579,15 @@ _PUBLIC_ struct timeval timeval_current_ofs(uint32_t secs, uint32_t usecs) return timeval_add(&tv, secs, usecs); } +/** + return a timeval milliseconds into the future +*/ +_PUBLIC_ struct timeval timeval_current_ofs_msec(uint32_t msecs) +{ + struct timeval tv = timeval_current(); + return timeval_add(&tv, msecs / 1000, (msecs % 1000) * 1000); +} + /** compare two timeval structures. Return -1 if tv1 < tv2 diff --git a/lib/util/time.h b/lib/util/time.h index 3a406340f4..4e4f72f71f 100644 --- a/lib/util/time.h +++ b/lib/util/time.h @@ -212,6 +212,11 @@ struct timeval timeval_sum(const struct timeval *tv1, */ _PUBLIC_ struct timeval timeval_current_ofs(uint32_t secs, uint32_t usecs); +/** + return a timeval milliseconds into the future +*/ +_PUBLIC_ struct timeval timeval_current_ofs_msec(uint32_t msecs); + /** compare two timeval structures. Return -1 if tv1 < tv2 -- cgit From 0204ae6229bae3573b3194c3f657c8f385c0b940 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 1 Jun 2011 11:24:51 +0930 Subject: lib/util/time.c: timeval_current_ofs_usec Several places want "microseconds from current time", and several were simply handing "usecs" values which could be over a million. Using a helper to do this is safer and more readable. I didn't replace any obviously correct callers (ie. constants). I also renamed wait_nsec in source3/lib/util_sock.c; it's actually microseconds not nanoseconds (introduced with this code in Volker's 19b783cc Async wrapper for open_socket_out_send/recv). Signed-off-by: Rusty Russell --- lib/util/time.c | 9 +++++++++ lib/util/time.h | 5 +++++ 2 files changed, 14 insertions(+) (limited to 'lib/util') diff --git a/lib/util/time.c b/lib/util/time.c index de1553aff8..d8fd4a3dfc 100644 --- a/lib/util/time.c +++ b/lib/util/time.c @@ -588,6 +588,15 @@ _PUBLIC_ struct timeval timeval_current_ofs_msec(uint32_t msecs) return timeval_add(&tv, msecs / 1000, (msecs % 1000) * 1000); } +/** + return a timeval microseconds into the future +*/ +_PUBLIC_ struct timeval timeval_current_ofs_usec(uint32_t usecs) +{ + struct timeval tv = timeval_current(); + return timeval_add(&tv, usecs / 1000000, usecs % 1000000); +} + /** compare two timeval structures. Return -1 if tv1 < tv2 diff --git a/lib/util/time.h b/lib/util/time.h index 4e4f72f71f..1f7f57db77 100644 --- a/lib/util/time.h +++ b/lib/util/time.h @@ -217,6 +217,11 @@ _PUBLIC_ struct timeval timeval_current_ofs(uint32_t secs, uint32_t usecs); */ _PUBLIC_ struct timeval timeval_current_ofs_msec(uint32_t msecs); +/** + return a timeval microseconds into the future +*/ +_PUBLIC_ struct timeval timeval_current_ofs_usec(uint32_t usecs); + /** compare two timeval structures. Return -1 if tv1 < tv2 -- cgit From f0901792324425804592ac7032e3853b4d4c7829 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Thu, 2 Jun 2011 10:10:39 -0700 Subject: Fix warning messages on Freebsd 4.6.2. Signed-off-by: Jeremy Allison --- lib/util/debug_s3.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/util') diff --git a/lib/util/debug_s3.h b/lib/util/debug_s3.h index 96b8ed74d9..9e5211b19b 100644 --- a/lib/util/debug_s3.h +++ b/lib/util/debug_s3.h @@ -17,6 +17,8 @@ along with this program. If not, see . */ +#include "librpc/gen_ndr/server_id.h" + struct messaging_context; struct server_id; void debug_message(struct messaging_context *msg_ctx, void *private_data, uint32_t msg_type, struct server_id src, DATA_BLOB *data); -- cgit From 74a7e68925c27b0bce26a4f6775b3d08ba1767e0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 2 Jun 2011 17:10:17 +1000 Subject: ipv6: always try to convert as a numeric address first This avoids unnecessary name lookups, plus it fixes a problem with using interpret_string_addr*() with the wildcard IPv6 address --- lib/util/util_net.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'lib/util') diff --git a/lib/util/util_net.c b/lib/util/util_net.c index 98eef3bd8b..57a0b1e40c 100644 --- a/lib/util/util_net.c +++ b/lib/util/util_net.c @@ -54,6 +54,15 @@ bool interpret_string_addr_internal(struct addrinfo **ppres, /* By default make sure it supports TCP. */ hints.ai_socktype = SOCK_STREAM; + + /* always try as a numeric host first. This prevents unnecessary name + * lookups, and also ensures we accept IPv6 addresses */ + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + ret = getaddrinfo(str, NULL, &hints, ppres); + if (ret == 0) { + return true; + } + hints.ai_flags = flags; /* Linux man page on getaddrinfo() says port will be -- cgit From b81eac1e2b47b0f3885cfe8bb251eeb6245706f9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 6 Jun 2011 10:11:13 +1000 Subject: util-net: added is_ipaddress_v6() --- lib/util/util_net.c | 15 ++++++++++++--- lib/util/util_net.h | 1 + 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'lib/util') diff --git a/lib/util/util_net.c b/lib/util/util_net.c index 57a0b1e40c..64aa674d8b 100644 --- a/lib/util/util_net.c +++ b/lib/util/util_net.c @@ -306,10 +306,10 @@ bool is_ipaddress_v4(const char *str) } /** - * Return true if a string could be an IPv4 or IPv6 address. + * Return true if a string could be a IPv6 address. */ -bool is_ipaddress(const char *str) +bool is_ipaddress_v6(const char *str) { #if defined(HAVE_IPV6) int ret = -1; @@ -337,7 +337,16 @@ bool is_ipaddress(const char *str) } } #endif - return is_ipaddress_v4(str); + return false; +} + +/** + * Return true if a string could be an IPv4 or IPv6 address. + */ + +bool is_ipaddress(const char *str) +{ + return is_ipaddress_v4(str) || is_ipaddress_v6(str); } /** diff --git a/lib/util/util_net.h b/lib/util/util_net.h index 38b6d5a959..fc2776a32b 100644 --- a/lib/util/util_net.h +++ b/lib/util/util_net.h @@ -85,6 +85,7 @@ _PUBLIC_ uint32_t interpret_addr(const char *str); _PUBLIC_ struct in_addr interpret_addr2(const char *str); _PUBLIC_ bool is_ipaddress_v4(const char *str); +_PUBLIC_ bool is_ipaddress_v6(const char *str); bool is_address_any(const struct sockaddr *psa); bool same_net(const struct sockaddr *ip1, -- cgit From de46ad9084aff4384f33660acf91da3b81554a88 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 6 Jun 2011 14:37:06 +1000 Subject: lib/util use modules_path(), data_path() and shlib_ext() from source3 This brings these helpful utility functions in common, as they are not based on either loadparm system. (The 'modules dir' parameter from Samba4 will shortly be removed, so there is no loss in functionality) Andrew Bartlett --- lib/util/util.h | 26 +++++++++++++++++++++ lib/util/util_paths.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ lib/util/wscript_build | 2 +- 3 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 lib/util/util_paths.c (limited to 'lib/util') diff --git a/lib/util/util.h b/lib/util/util.h index d1c5e82bdd..e89c4ac997 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -891,4 +891,30 @@ int samba_runcmd_recv(struct tevent_req *req, int *perrno); void samba_start_debugger(void); #endif +/** + * @brief Returns an absolute path to a file in the Samba modules directory. + * + * @param name File to find, relative to MODULESDIR. + * + * @retval Pointer to a string containing the full path. + **/ +char *modules_path(TALLOC_CTX *mem_ctx, const char *name); + +/** + * @brief Returns an absolute path to a file in the Samba data directory. + * + * @param name File to find, relative to CODEPAGEDIR. + * + * @retval Pointer to a talloc'ed string containing the full path. + **/ +char *data_path(TALLOC_CTX *mem_ctx, const char *name); + +/** + * @brief Returns the platform specific shared library extension. + * + * @retval Pointer to a const char * containing the extension. + **/ +const char *shlib_ext(void); + + #endif /* _SAMBA_UTIL_H_ */ diff --git a/lib/util/util_paths.c b/lib/util/util_paths.c new file mode 100644 index 0000000000..0baa6801c5 --- /dev/null +++ b/lib/util/util_paths.c @@ -0,0 +1,63 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Jeremy Allison 2001-2007 + Copyright (C) Simo Sorce 2001 + Copyright (C) Jim McDonough 2003 + Copyright (C) James Peach 2006 + + 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 . +*/ + +#include "includes.h" +#include "dynconfig/dynconfig.h" + +/** + * @brief Returns an absolute path to a file in the Samba modules directory. + * + * @param name File to find, relative to MODULESDIR. + * + * @retval Pointer to a string containing the full path. + **/ + +char *modules_path(TALLOC_CTX *mem_ctx, const char *name) +{ + return talloc_asprintf(mem_ctx, "%s/%s", get_dyn_MODULESDIR(), name); +} + +/** + * @brief Returns an absolute path to a file in the Samba data directory. + * + * @param name File to find, relative to CODEPAGEDIR. + * + * @retval Pointer to a talloc'ed string containing the full path. + **/ + +char *data_path(TALLOC_CTX *mem_ctx, const char *name) +{ + return talloc_asprintf(mem_ctx, "%s/%s", get_dyn_CODEPAGEDIR(), name); +} + +/** + * @brief Returns the platform specific shared library extension. + * + * @retval Pointer to a const char * containing the extension. + **/ + +const char *shlib_ext(void) +{ + return get_dyn_SHLIBEXT(); +} + diff --git a/lib/util/wscript_build b/lib/util/wscript_build index 3092b6ccbb..8ce30eb689 100755 --- a/lib/util/wscript_build +++ b/lib/util/wscript_build @@ -4,7 +4,7 @@ common_util_sources = '''talloc_stack.c smb_threads.c xfile.c data_blob.c util_file.c time.c rbtree.c rfc1738.c select.c genrand.c fsusage.c blocking.c become_daemon.c signal.c system.c params.c util.c util_id.c util_net.c - util_strlist.c idtree.c debug.c fault.c base64.c + util_strlist.c util_paths.c idtree.c debug.c fault.c base64.c util_str.c util_str_common.c substitute.c ms_fnmatch.c''' common_util_headers = 'debug.h' -- cgit From 16b1c77644217796f70a3a0bf1d95c245f9ee2d9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 8 Jun 2011 14:05:55 +1000 Subject: lib/util Bring procid_str() into lib/util as server_id_string() This is needed for OpenChange, which prints Samba struct server_id values in debug messages. Andrew Bartlett --- lib/util/server_id.c | 36 ++++++++++++++++++++++++++++++++++++ lib/util/util.h | 2 ++ lib/util/wscript_build | 3 ++- 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 lib/util/server_id.c (limited to 'lib/util') diff --git a/lib/util/server_id.c b/lib/util/server_id.c new file mode 100644 index 0000000000..a67c40eb19 --- /dev/null +++ b/lib/util/server_id.c @@ -0,0 +1,36 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Andrew Bartlett 2011 + + 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 . +*/ + +#include "includes.h" +#include "librpc/gen_ndr/server_id.h" + +char *server_id_str(TALLOC_CTX *mem_ctx, const struct server_id *id) +{ + if (id->vnn == NONCLUSTER_VNN && id->task_id == 0) { + return talloc_asprintf(mem_ctx, + "%llu", + (unsigned long long)id->pid); + } else { + return talloc_asprintf(mem_ctx, + "%u:%llu:%u", + (unsigned)id->vnn, + (unsigned long long)id->pid, + (unsigned)id->task_id); + } +} diff --git a/lib/util/util.h b/lib/util/util.h index e89c4ac997..e50cc38a2f 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -916,5 +916,7 @@ char *data_path(TALLOC_CTX *mem_ctx, const char *name); **/ const char *shlib_ext(void); +struct server_id; +char *server_id_str(TALLOC_CTX *mem_ctx, const struct server_id *id); #endif /* _SAMBA_UTIL_H_ */ diff --git a/lib/util/wscript_build b/lib/util/wscript_build index 8ce30eb689..6c4bb37884 100755 --- a/lib/util/wscript_build +++ b/lib/util/wscript_build @@ -5,7 +5,8 @@ common_util_sources = '''talloc_stack.c smb_threads.c xfile.c data_blob.c genrand.c fsusage.c blocking.c become_daemon.c signal.c system.c params.c util.c util_id.c util_net.c util_strlist.c util_paths.c idtree.c debug.c fault.c base64.c - util_str.c util_str_common.c substitute.c ms_fnmatch.c''' + util_str.c util_str_common.c substitute.c ms_fnmatch.c + server_id.c''' common_util_headers = 'debug.h' common_util_public_deps = 'talloc pthread LIBCRYPTO CHARSET' -- cgit From daf79e33c7e8873345fb4a251f1e880fd767df19 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 9 Jun 2011 11:18:15 +1000 Subject: server_id: Change format to vnn:pid.task_id, pid.task_id or pid This helps ensure the string cannot be ambiguous, while also ensuring that it remains simple in the non-cluster case. The asymmetry of reading get_my_vnn() but writing based on NONCLUSTER_VNN is acceptable because in the non-clustered case, they are equal, and in the clustered case we will print the full string. Andrew Bartlett --- lib/util/server_id.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'lib/util') diff --git a/lib/util/server_id.c b/lib/util/server_id.c index a67c40eb19..195deeac7c 100644 --- a/lib/util/server_id.c +++ b/lib/util/server_id.c @@ -26,9 +26,14 @@ char *server_id_str(TALLOC_CTX *mem_ctx, const struct server_id *id) return talloc_asprintf(mem_ctx, "%llu", (unsigned long long)id->pid); + } else if (id->vnn == NONCLUSTER_VNN) { + return talloc_asprintf(mem_ctx, + "%llu.%u", + (unsigned long long)id->pid, + (unsigned)id->task_id); } else { return talloc_asprintf(mem_ctx, - "%u:%llu:%u", + "%u:%llu.%u", (unsigned)id->vnn, (unsigned long long)id->pid, (unsigned)id->task_id); -- cgit From a602cb2a0a0bc19121232444117486d8286e0af9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 10 Jun 2011 14:59:23 +0200 Subject: lib/util/data_blob.h: fix licence/copyright Guenther --- lib/util/data_blob.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/util') diff --git a/lib/util/data_blob.h b/lib/util/data_blob.h index 83e6cd5f09..558ade9248 100644 --- a/lib/util/data_blob.h +++ b/lib/util/data_blob.h @@ -1,7 +1,10 @@ /* Unix SMB/CIFS implementation. DATA BLOB - + + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Andrew Bartlett 2001 + 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 -- cgit From 74610109ac3140713140038d10df644024796907 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 10 Jun 2011 14:59:35 +0200 Subject: lib/util/time.h: fix licence/copyright Guenther --- lib/util/time.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'lib/util') diff --git a/lib/util/time.h b/lib/util/time.h index 1f7f57db77..6a473f6ba1 100644 --- a/lib/util/time.h +++ b/lib/util/time.h @@ -1,7 +1,12 @@ /* Unix SMB/CIFS implementation. time utility functions - + + Copyright (C) Andrew Tridgell 1992-2004 + Copyright (C) Stefan (metze) Metzmacher 2002 + Copyright (C) Jeremy Allison 2007 + Copyright (C) Andrew Bartlett 2011 + 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 -- cgit From 4fe4487cd9391cac813ab94d7002eac6dc722f4c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 10 Jun 2011 14:59:48 +0200 Subject: lib/util/util_ldb.h: fix licence/copyright Guenther --- lib/util/util_ldb.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'lib/util') diff --git a/lib/util/util_ldb.h b/lib/util/util_ldb.h index d2bc3b0ff7..66916443c3 100644 --- a/lib/util/util_ldb.h +++ b/lib/util/util_ldb.h @@ -1,3 +1,26 @@ +/* + Unix SMB/CIFS implementation. + + common share info functions + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Tim Potter 2004 + + 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 . +*/ + + #ifndef __LIB_UTIL_UTIL_LDB_H__ #define __LIB_UTIL_UTIL_LDB_H__ -- cgit From eaa400216570403e67f7f06db509ce90fba02c13 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 10 Jun 2011 14:59:58 +0200 Subject: lib/util/util_tdb.h: fix licence/copyright Guenther --- lib/util/util_tdb.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'lib/util') diff --git a/lib/util/util_tdb.h b/lib/util/util_tdb.h index c11a347e07..c563f0d4b6 100644 --- a/lib/util/util_tdb.h +++ b/lib/util/util_tdb.h @@ -1,3 +1,24 @@ +/* + Unix SMB/CIFS implementation. + + tdb utility functions + + Copyright (C) Andrew Tridgell 1992-2006 + + 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 . +*/ + #ifndef _____LIB_UTIL_UTIL_TDB_H__ #define _____LIB_UTIL_UTIL_TDB_H__ -- cgit From d228fc35f38b77877f0fd07b415df87d4ccdb812 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 10 Jun 2011 15:00:10 +0200 Subject: lib/util/wrap_xattr.h: fix licence/copyright Guenther --- lib/util/wrap_xattr.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'lib/util') diff --git a/lib/util/wrap_xattr.h b/lib/util/wrap_xattr.h index 64b28d250c..745b93d764 100644 --- a/lib/util/wrap_xattr.h +++ b/lib/util/wrap_xattr.h @@ -1,3 +1,24 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - xattr support using filesystem xattrs + + Copyright (C) Andrew Tridgell 2004 + + 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 . +*/ + #ifndef __LIB_UTIL_WRAP_XATTR_H__ #define __LIB_UTIL_WRAP_XATTR_H__ -- cgit From 530e4cac2e93177923080daa5ec1bac2c65d269b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 11 Jun 2011 09:49:12 +1000 Subject: s3-param Remove 'time offset' from smb.conf This strange parameter is apparently very rarely used, and it seems to me that on modern networks, if clients don't have correct clocks and DST offsets, that many other things (Kerberos) start to fail pretty quickly, and time and DST tables tend to be internet delivered anyway. Autobuild-User: Andrew Bartlett Autobuild-Date: Sat Jun 11 03:54:45 CEST 2011 on sn-devel-104 --- lib/util/tests/time.c | 18 ------------------ lib/util/time.c | 4 +--- lib/util/time.h | 3 --- 3 files changed, 1 insertion(+), 24 deletions(-) (limited to 'lib/util') diff --git a/lib/util/tests/time.c b/lib/util/tests/time.c index 592f88f88b..a8b26762e3 100644 --- a/lib/util/tests/time.c +++ b/lib/util/tests/time.c @@ -81,29 +81,11 @@ static bool test_timestring(struct torture_context *tctx) return true; } -static bool test_get_time_zone(struct torture_context *tctx) -{ - time_t t = time(NULL); - int old_extra_time_offset = extra_time_offset; - int old_offset, new_offset; - /* test that extra_time_offset works */ - - old_offset = get_time_zone(t); - extra_time_offset = 42; - new_offset = get_time_zone(t); - extra_time_offset = old_extra_time_offset; - torture_assert_int_equal(tctx, old_offset+60*42, new_offset, - "time offset not used"); - return true; -} - - struct torture_suite *torture_local_util_time(TALLOC_CTX *mem_ctx) { struct torture_suite *suite = torture_suite_create(mem_ctx, "time"); torture_suite_add_simple_test(suite, "null_time", test_null_time); - torture_suite_add_simple_test(suite, "get_time_zone", test_get_time_zone); torture_suite_add_simple_test(suite, "null_nttime", test_null_nttime); torture_suite_add_simple_test(suite, "http_timestring", test_http_timestring); diff --git a/lib/util/time.c b/lib/util/time.c index d8fd4a3dfc..31aa05cd0f 100644 --- a/lib/util/time.c +++ b/lib/util/time.c @@ -738,8 +738,6 @@ static int tm_diff(struct tm *a, struct tm *b) } -int extra_time_offset=0; - /** return the UTC offset in seconds west of UTC, or 0 if it cannot be determined */ @@ -753,7 +751,7 @@ _PUBLIC_ int get_time_zone(time_t t) tm = localtime(&t); if (!tm) return 0; - return tm_diff(&tm_utc,tm)+60*extra_time_offset; + return tm_diff(&tm_utc,tm); } struct timespec nt_time_to_unix_timespec(NTTIME *nt) diff --git a/lib/util/time.h b/lib/util/time.h index 6a473f6ba1..204c261c1d 100644 --- a/lib/util/time.h +++ b/lib/util/time.h @@ -300,7 +300,4 @@ struct timespec convert_time_t_to_timespec(time_t t); bool null_timespec(struct timespec ts); -/** Extra minutes to add to the normal GMT to local time conversion. */ -extern int extra_time_offset; - #endif /* _SAMBA_TIME_H_ */ -- cgit From b07e4933b7ed4b2452cfdd9d223eecb8c0b74fec Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 17 Jun 2011 14:22:28 +1000 Subject: talloc: added talloc_stackframe_exists() This can be used to tell if a talloc stackframe is currently available. Callers can use this to decide if they will use talloc_tos() or instead use an alternative strategy. This gives us a way to safely have calls to talloc_tos() in common code that may end up in external libraries, as long as all talloc_tos() calls in these pieces of common code check first that a stackframe is available. --- lib/util/talloc_stack.c | 17 +++++++++++++++++ lib/util/talloc_stack.h | 8 ++++++++ 2 files changed, 25 insertions(+) (limited to 'lib/util') diff --git a/lib/util/talloc_stack.c b/lib/util/talloc_stack.c index 8e559cc20f..16e9d745d3 100644 --- a/lib/util/talloc_stack.c +++ b/lib/util/talloc_stack.c @@ -188,3 +188,20 @@ TALLOC_CTX *talloc_tos(void) return ts->talloc_stack[ts->talloc_stacksize-1]; } + +/* + * return true if a talloc stackframe exists + * this can be used to prevent memory leaks for code that can + * optionally use a talloc stackframe (eg. nt_errstr()) + */ + +bool talloc_stackframe_exists(void) +{ + struct talloc_stackframe *ts = + (struct talloc_stackframe *)SMB_THREAD_GET_TLS(global_ts); + + if (ts == NULL || ts->talloc_stacksize == 0) { + return false; + } + return true; +} diff --git a/lib/util/talloc_stack.h b/lib/util/talloc_stack.h index 0e8fab3759..ec0c1c6f37 100644 --- a/lib/util/talloc_stack.h +++ b/lib/util/talloc_stack.h @@ -53,4 +53,12 @@ TALLOC_CTX *talloc_stackframe_pool(size_t poolsize); TALLOC_CTX *talloc_tos(void); +/* + * return true if a talloc stackframe exists + * this can be used to prevent memory leaks for code that can + * optionally use a talloc stackframe (eg. nt_errstr()) + */ + +bool talloc_stackframe_exists(void); + #endif -- cgit From 0e4c358e2710580d5aeb439d767c87aaf4c0f2f3 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 20 Jun 2011 18:40:25 +0930 Subject: tdb_compat.h: divert every tdb build and includes to tdb_compat We change all the headers and wscript files to use tdb_compat; this means we have one place to decide whether to use TDB1 or TDB2. Signed-off-by: Rusty Russell --- lib/util/tdb_wrap.c | 2 -- lib/util/tdb_wrap.h | 2 +- lib/util/util_tdb.c | 2 +- lib/util/wscript_build | 4 ++-- 4 files changed, 4 insertions(+), 6 deletions(-) (limited to 'lib/util') diff --git a/lib/util/tdb_wrap.c b/lib/util/tdb_wrap.c index c9562c6939..b19b4fe67f 100644 --- a/lib/util/tdb_wrap.c +++ b/lib/util/tdb_wrap.c @@ -20,10 +20,8 @@ */ #include "includes.h" -#include #include "lib/util/dlinklist.h" #include "lib/util/tdb_wrap.h" -#include /* Log tdb messages via DEBUG(). diff --git a/lib/util/tdb_wrap.h b/lib/util/tdb_wrap.h index 1be2bb059d..6f9f3834d4 100644 --- a/lib/util/tdb_wrap.h +++ b/lib/util/tdb_wrap.h @@ -29,7 +29,7 @@ #ifndef _TDB_WRAP_H_ #define _TDB_WRAP_H_ -#include +#include "tdb_compat.h" struct tdb_wrap { struct tdb_context *tdb; diff --git a/lib/util/util_tdb.c b/lib/util/util_tdb.c index 4a81678808..33615854bd 100644 --- a/lib/util/util_tdb.c +++ b/lib/util/util_tdb.c @@ -20,7 +20,7 @@ */ #include "includes.h" -#include +#include "../lib/tdb_compat/tdb_compat.h" #include "../lib/util/util_tdb.h" /* these are little tdb utility functions that are meant to make diff --git a/lib/util/wscript_build b/lib/util/wscript_build index 6c4bb37884..a094fa3b54 100755 --- a/lib/util/wscript_build +++ b/lib/util/wscript_build @@ -76,7 +76,7 @@ bld.SAMBA_LIBRARY('wrap_xattr', bld.SAMBA_LIBRARY('UTIL_TDB', source='util_tdb.c', local_include=False, - public_deps='tdb talloc', + public_deps='tdb_compat talloc', private_library=True ) @@ -113,7 +113,7 @@ bld.SAMBA_SUBSYSTEM('UTIL_PW', bld.SAMBA_LIBRARY('tdb-wrap', source='tdb_wrap.c', - deps='tdb talloc samba-util', + deps='tdb_compat talloc samba-util', private_library=True, local_include=False ) -- cgit From 058c4f84924c07b88ccaf3d617f3abff797a7cc8 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 20 Jun 2011 18:40:31 +0930 Subject: tdb_fetch_compat: use instead of tdb_fetch. This is a noop for tdb1. Signed-off-by: Rusty Russell --- lib/util/util_tdb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/util') diff --git a/lib/util/util_tdb.c b/lib/util/util_tdb.c index 33615854bd..2dd5f9dd5f 100644 --- a/lib/util/util_tdb.c +++ b/lib/util/util_tdb.c @@ -111,7 +111,7 @@ int32_t tdb_fetch_int32_byblob(struct tdb_context *tdb, TDB_DATA key) TDB_DATA data; int32_t ret; - data = tdb_fetch(tdb, key); + data = tdb_fetch_compat(tdb, key); if (!data.dptr || data.dsize != sizeof(int32_t)) { SAFE_FREE(data.dptr); return -1; @@ -168,7 +168,7 @@ bool tdb_fetch_uint32_byblob(struct tdb_context *tdb, TDB_DATA key, uint32_t *va { TDB_DATA data; - data = tdb_fetch(tdb, key); + data = tdb_fetch_compat(tdb, key); if (!data.dptr || data.dsize != sizeof(uint32_t)) { SAFE_FREE(data.dptr); return false; @@ -240,7 +240,7 @@ TDB_DATA tdb_fetch_bystring(struct tdb_context *tdb, const char *keystr) { TDB_DATA key = string_term_tdb_data(keystr); - return tdb_fetch(tdb, key); + return tdb_fetch_compat(tdb, key); } /**************************************************************************** -- cgit From 1078eb21c49d707ddeef2257353f35c10d131b9f Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 20 Jun 2011 18:40:31 +0930 Subject: tdb_delete: check returns for 0, not -1. TDB2 returns a negative error number on failure. This is compatible if we always check for != 0 instead of == -1. Signed-off-by: Rusty Russell --- lib/util/util_tdb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/util') diff --git a/lib/util/util_tdb.h b/lib/util/util_tdb.h index c563f0d4b6..92b88bacb4 100644 --- a/lib/util/util_tdb.h +++ b/lib/util/util_tdb.h @@ -111,7 +111,7 @@ int tdb_store_bystring(struct tdb_context *tdb, const char *keystr, TDB_DATA dat TDB_DATA tdb_fetch_bystring(struct tdb_context *tdb, const char *keystr); /**************************************************************************** - Delete an entry using a null terminated string key. + Delete an entry using a null terminated string key. 0 on success, -ve on err. ****************************************************************************/ int tdb_delete_bystring(struct tdb_context *tdb, const char *keystr); -- cgit From 6bc59d77b64d1ecbe5c906ed2fa80a7b8ca5d420 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 20 Jun 2011 18:40:31 +0930 Subject: tdb_store: check returns for 0, not -1. TDB2 returns a negative error number on failure. This is compatible if we always check for != 0 instead of == -1. Signed-off-by: Rusty Russell --- lib/util/util_tdb.c | 14 +++++++------- lib/util/util_tdb.h | 10 +++++----- 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'lib/util') diff --git a/lib/util/util_tdb.c b/lib/util/util_tdb.c index 2dd5f9dd5f..304239f951 100644 --- a/lib/util/util_tdb.c +++ b/lib/util/util_tdb.c @@ -133,7 +133,7 @@ int32_t tdb_fetch_int32(struct tdb_context *tdb, const char *keystr) } /**************************************************************************** - Store a int32_t value by an arbitrary blob key, return 0 on success, -1 on failure. + Store a int32_t value by an arbitrary blob key, return 0 on success, -ve on failure. Input is int32_t in native byte order. Output in tdb is in little-endian. ****************************************************************************/ @@ -150,7 +150,7 @@ int tdb_store_int32_byblob(struct tdb_context *tdb, TDB_DATA key, int32_t v) } /**************************************************************************** - Store a int32_t value by string key, return 0 on success, -1 on failure. + Store a int32_t value by string key, return 0 on success, -ve on failure. Input is int32_t in native byte order. Output in tdb is in little-endian. ****************************************************************************/ @@ -190,7 +190,7 @@ bool tdb_fetch_uint32(struct tdb_context *tdb, const char *keystr, uint32_t *val } /**************************************************************************** - Store a uint32_t value by an arbitrary blob key, return 0 on success, -1 on failure. + Store a uint32_t value by an arbitrary blob key, return true on success, false on failure. Input is uint32_t in native byte order. Output in tdb is in little-endian. ****************************************************************************/ @@ -204,14 +204,14 @@ bool tdb_store_uint32_byblob(struct tdb_context *tdb, TDB_DATA key, uint32_t val data.dptr = (unsigned char *)&v_store; data.dsize = sizeof(uint32_t); - if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) + if (tdb_store(tdb, key, data, TDB_REPLACE) != 0) ret = false; return ret; } /**************************************************************************** - Store a uint32_t value by string key, return 0 on success, -1 on failure. + Store a uint32_t value by string key, return true on success, false on failure. Input is uint32_t in native byte order. Output in tdb is in little-endian. ****************************************************************************/ @@ -220,7 +220,7 @@ bool tdb_store_uint32(struct tdb_context *tdb, const char *keystr, uint32_t valu return tdb_store_uint32_byblob(tdb, string_term_tdb_data(keystr), value); } /**************************************************************************** - Store a buffer by a null terminated string key. Return 0 on success, -1 + Store a buffer by a null terminated string key. Return 0 on success, -ve on failure. ****************************************************************************/ @@ -284,7 +284,7 @@ int32_t tdb_change_int32_atomic(struct tdb_context *tdb, const char *keystr, int /* Increment value for storage and return next time */ val += change_val; - if (tdb_store_int32(tdb, keystr, val) == -1) + if (tdb_store_int32(tdb, keystr, val) != 0) goto err_out; ret = 0; diff --git a/lib/util/util_tdb.h b/lib/util/util_tdb.h index 92b88bacb4..edffa058d7 100644 --- a/lib/util/util_tdb.h +++ b/lib/util/util_tdb.h @@ -63,13 +63,13 @@ int32_t tdb_fetch_int32_byblob(struct tdb_context *tdb, TDB_DATA key); int32_t tdb_fetch_int32(struct tdb_context *tdb, const char *keystr); /**************************************************************************** - Store a int32_t value by an arbitrary blob key, return 0 on success, -1 on failure. + Store a int32_t value by an arbitrary blob key, return 0 on success, -ve on failure. Input is int32_t in native byte order. Output in tdb is in little-endian. ****************************************************************************/ int tdb_store_int32_byblob(struct tdb_context *tdb, TDB_DATA key, int32_t v); /**************************************************************************** - Store a int32_t value by string key, return 0 on success, -1 on failure. + Store a int32_t value by string key, return 0 on success, -ve on failure. Input is int32_t in native byte order. Output in tdb is in little-endian. ****************************************************************************/ int tdb_store_int32(struct tdb_context *tdb, const char *keystr, int32_t v); @@ -87,19 +87,19 @@ bool tdb_fetch_uint32_byblob(struct tdb_context *tdb, TDB_DATA key, uint32_t *va bool tdb_fetch_uint32(struct tdb_context *tdb, const char *keystr, uint32_t *value); /**************************************************************************** - Store a uint32_t value by an arbitrary blob key, return 0 on success, -1 on failure. + Store a uint32_t value by an arbitrary blob key, return true on success, false on failure. Input is uint32_t in native byte order. Output in tdb is in little-endian. ****************************************************************************/ bool tdb_store_uint32_byblob(struct tdb_context *tdb, TDB_DATA key, uint32_t value); /**************************************************************************** - Store a uint32_t value by string key, return 0 on success, -1 on failure. + Store a uint32_t value by string key, return true on success, false on failure. Input is uint32_t in native byte order. Output in tdb is in little-endian. ****************************************************************************/ bool tdb_store_uint32(struct tdb_context *tdb, const char *keystr, uint32_t value); /**************************************************************************** - Store a buffer by a null terminated string key. Return 0 on success, -1 + Store a buffer by a null terminated string key. Return 0 on success, -ve on failure. ****************************************************************************/ int tdb_store_bystring(struct tdb_context *tdb, const char *keystr, TDB_DATA data, int flags); -- cgit From ca1936fbb26af0ee8d0421ae6a4e07a0f62311d9 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 20 Jun 2011 18:40:32 +0930 Subject: tdb_compat: use tdb_open_compat. This is a helper for the common case of opening a tdb with a logging function, but it doesn't do all the work, since TDB1 and TDB2's log functions are different types. Signed-off-by: Rusty Russell --- lib/util/tdb_wrap.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) (limited to 'lib/util') diff --git a/lib/util/tdb_wrap.c b/lib/util/tdb_wrap.c index b19b4fe67f..71aea5e36c 100644 --- a/lib/util/tdb_wrap.c +++ b/lib/util/tdb_wrap.c @@ -23,6 +23,31 @@ #include "lib/util/dlinklist.h" #include "lib/util/tdb_wrap.h" +/* FIXME: TDB2 does this internally, so no need to wrap multiple opens! */ +#if BUILD_TDB2 +static void tdb_wrap_log(struct tdb_context *tdb, + enum tdb_log_level level, + const char *message, + void *unused) +{ + int dl; + const char *name = tdb_name(tdb); + + switch (level) { + case TDB_LOG_USE_ERROR: + case TDB_LOG_ERROR: + dl = 0; + break; + case TDB_LOG_WARNING: + dl = 2; + break; + default: + dl = 0; + } + + DEBUG(dl, ("tdb(%s): %s", name ? name : "unnamed", message)); +} +#else /* Log tdb messages via DEBUG(). */ @@ -64,6 +89,7 @@ static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level, free(ptr); } } +#endif struct tdb_wrap_private { struct tdb_context *tdb; @@ -89,7 +115,6 @@ static struct tdb_wrap_private *tdb_wrap_private_open(TALLOC_CTX *mem_ctx, mode_t mode) { struct tdb_wrap_private *result; - struct tdb_logging_context log_ctx; result = talloc(mem_ctx, struct tdb_wrap_private); if (result == NULL) { @@ -100,8 +125,6 @@ static struct tdb_wrap_private *tdb_wrap_private_open(TALLOC_CTX *mem_ctx, goto fail; } - log_ctx.log_fn = tdb_wrap_log; - #if _SAMBA_BUILD_ == 3 /* This #if _SAMBA_BUILD == 3 is very unfortunate, as it means * that in the top level build, these options are not @@ -126,8 +149,8 @@ static struct tdb_wrap_private *tdb_wrap_private_open(TALLOC_CTX *mem_ctx, } #endif - result->tdb = tdb_open_ex(name, hash_size, tdb_flags, - open_flags, mode, &log_ctx, NULL); + result->tdb = tdb_open_compat(name, hash_size, tdb_flags, + open_flags, mode, tdb_wrap_log, NULL); if (result->tdb == NULL) { goto fail; } -- cgit From d925b327f4703cc141c0a7f3eec912dba8440880 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 20 Jun 2011 18:40:33 +0930 Subject: tdb_compat: Higher level API fixes. My previous patches fixed up all direct TDB callers, but there are a few utility functions and the db_context functions which are still using the old -1 / 0 return codes. It's clearer to fix up all the callers of these too, so everywhere is consistent: non-zero means an error. Signed-off-by: Rusty Russell --- lib/util/util_tdb.c | 8 ++++---- lib/util/util_tdb.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'lib/util') diff --git a/lib/util/util_tdb.c b/lib/util/util_tdb.c index 304239f951..02c7095f66 100644 --- a/lib/util/util_tdb.c +++ b/lib/util/util_tdb.c @@ -57,7 +57,7 @@ TDB_DATA string_term_tdb_data(const char *string) } /**************************************************************************** - Lock a chain by string. Return -1 if lock failed. + Lock a chain by string. Return non-zero if lock failed. ****************************************************************************/ int tdb_lock_bystring(struct tdb_context *tdb, const char *keyval) @@ -79,7 +79,7 @@ void tdb_unlock_bystring(struct tdb_context *tdb, const char *keyval) } /**************************************************************************** - Read lock a chain by string. Return -1 if lock failed. + Read lock a chain by string. Return non-zero if lock failed. ****************************************************************************/ int tdb_read_lock_bystring(struct tdb_context *tdb, const char *keyval) @@ -263,7 +263,7 @@ int32_t tdb_change_int32_atomic(struct tdb_context *tdb, const char *keystr, int int32_t val; int32_t ret = -1; - if (tdb_lock_bystring(tdb, keystr) == -1) + if (tdb_lock_bystring(tdb, keystr) != 0) return -1; if ((val = tdb_fetch_int32(tdb, keystr)) == -1) { @@ -304,7 +304,7 @@ bool tdb_change_uint32_atomic(struct tdb_context *tdb, const char *keystr, uint3 uint32_t val; bool ret = false; - if (tdb_lock_bystring(tdb, keystr) == -1) + if (tdb_lock_bystring(tdb, keystr) != 0) return false; if (!tdb_fetch_uint32(tdb, keystr, &val)) { diff --git a/lib/util/util_tdb.h b/lib/util/util_tdb.h index edffa058d7..2d805d7d20 100644 --- a/lib/util/util_tdb.h +++ b/lib/util/util_tdb.h @@ -31,7 +31,7 @@ TDB_DATA string_tdb_data(const char *string); TDB_DATA string_term_tdb_data(const char *string); /**************************************************************************** - Lock a chain by string. Return -1 if lock failed. + Lock a chain by string. Return non-zero if lock failed. ****************************************************************************/ int tdb_lock_bystring(struct tdb_context *tdb, const char *keyval); @@ -41,7 +41,7 @@ int tdb_lock_bystring(struct tdb_context *tdb, const char *keyval); void tdb_unlock_bystring(struct tdb_context *tdb, const char *keyval); /**************************************************************************** - Read lock a chain by string. Return -1 if lock failed. + Read lock a chain by string. Return non-zero if lock failed. ****************************************************************************/ int tdb_read_lock_bystring(struct tdb_context *tdb, const char *keyval); -- cgit From f3d6b742b18589306e0f19cc52e06f108fc1268e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 20 Jun 2011 15:02:46 +1000 Subject: lib/util Make unused d_vfprintf() static --- lib/util/dprintf.c | 2 +- lib/util/util.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'lib/util') diff --git a/lib/util/dprintf.c b/lib/util/dprintf.c index e9a15dcbe6..c7c701bcfa 100644 --- a/lib/util/dprintf.c +++ b/lib/util/dprintf.c @@ -45,7 +45,7 @@ void d_set_iconv(smb_iconv_t cd) display_cd = cd; } -_PUBLIC_ int d_vfprintf(FILE *f, const char *format, va_list ap) +static int d_vfprintf(FILE *f, const char *format, va_list ap) { char *p, *p2; int ret, clen; diff --git a/lib/util/util.h b/lib/util/util.h index e50cc38a2f..f4861a6fcf 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -214,7 +214,6 @@ _PUBLIC_ char** generate_unique_strs(TALLOC_CTX *mem_ctx, size_t len, #if _SAMBA_BUILD_ == 4 _PUBLIC_ void d_set_iconv(smb_iconv_t); -_PUBLIC_ int d_vfprintf(FILE *f, const char *format, va_list ap) PRINTF_ATTRIBUTE(2,0); _PUBLIC_ int d_fprintf(FILE *f, const char *format, ...) PRINTF_ATTRIBUTE(2,3); _PUBLIC_ int d_printf(const char *format, ...) PRINTF_ATTRIBUTE(1,2); _PUBLIC_ void display_set_stderr(void); -- cgit From f83fca1c576e094e2a852cc466bd9110c05fe731 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 20 Jun 2011 19:56:50 +1000 Subject: lib/util: Use common d_printf() in the whole codebase This removes the lang_tdb based varient, the only user of the lang_tdb code is SWAT, which calls that directly. 'net' and 'pam_winbind' are internationalised using gettext. Andrew Bartlett --- lib/util/dprintf.c | 44 +++++++++++++++++++++++--------------------- lib/util/util.h | 3 --- lib/util/wscript_build | 4 ++-- 3 files changed, 25 insertions(+), 26 deletions(-) (limited to 'lib/util') diff --git a/lib/util/dprintf.c b/lib/util/dprintf.c index c7c701bcfa..c79989b517 100644 --- a/lib/util/dprintf.c +++ b/lib/util/dprintf.c @@ -33,22 +33,15 @@ #include "includes.h" #include "system/locale.h" -#include "param/param.h" static smb_iconv_t display_cd = (smb_iconv_t)-1; -void d_set_iconv(smb_iconv_t cd) -{ - if (display_cd != (smb_iconv_t)-1) - talloc_free(display_cd); - - display_cd = cd; -} - static int d_vfprintf(FILE *f, const char *format, va_list ap) { char *p, *p2; - int ret, clen; + int ret; + size_t clen; + bool cret; va_list ap2; /* If there's nothing to convert, take a shortcut */ @@ -56,15 +49,14 @@ static int d_vfprintf(FILE *f, const char *format, va_list ap) return vfprintf(f, format, ap); } - /* do any message translations */ va_copy(ap2, ap); ret = vasprintf(&p, format, ap2); va_end(ap2); if (ret <= 0) return ret; - clen = iconv_talloc(NULL, display_cd, p, ret, (void **)&p2); - if (clen == -1) { + cret = convert_string_talloc(NULL, CH_UTF8, CH_DISPLAY, p, ret, (void **)&p2, &clen); + if (!cret) { /* the string can't be converted - do the best we can, filling in non-printing chars with '?' */ int i; @@ -100,15 +92,25 @@ _PUBLIC_ int d_fprintf(FILE *f, const char *format, ...) return ret; } -_PUBLIC_ int d_printf(const char *format, ...) +static FILE *outfile; + +_PUBLIC_ int d_printf(const char *format, ...) { int ret; - va_list ap; - - va_start(ap, format); - ret = d_vfprintf(stdout, format, ap); - va_end(ap); - - return ret; + va_list ap; + + if (!outfile) outfile = stdout; + + va_start(ap, format); + ret = d_vfprintf(outfile, format, ap); + va_end(ap); + + return ret; } +/* interactive programs need a way of tell d_*() to write to stderr instead + of stdout */ +void display_set_stderr(void) +{ + outfile = stderr; +} diff --git a/lib/util/util.h b/lib/util/util.h index f4861a6fcf..c715440186 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -211,13 +211,10 @@ _PUBLIC_ char** generate_unique_strs(TALLOC_CTX *mem_ctx, size_t len, uint32_t num); /* The following definitions come from lib/util/dprintf.c */ -#if _SAMBA_BUILD_ == 4 -_PUBLIC_ void d_set_iconv(smb_iconv_t); _PUBLIC_ int d_fprintf(FILE *f, const char *format, ...) PRINTF_ATTRIBUTE(2,3); _PUBLIC_ int d_printf(const char *format, ...) PRINTF_ATTRIBUTE(1,2); _PUBLIC_ void display_set_stderr(void); -#endif /* The following definitions come from lib/util/util_str.c */ diff --git a/lib/util/wscript_build b/lib/util/wscript_build index a094fa3b54..8046a8ba07 100755 --- a/lib/util/wscript_build +++ b/lib/util/wscript_build @@ -6,11 +6,11 @@ common_util_sources = '''talloc_stack.c smb_threads.c xfile.c data_blob.c signal.c system.c params.c util.c util_id.c util_net.c util_strlist.c util_paths.c idtree.c debug.c fault.c base64.c util_str.c util_str_common.c substitute.c ms_fnmatch.c - server_id.c''' + server_id.c dprintf.c''' common_util_headers = 'debug.h' common_util_public_deps = 'talloc pthread LIBCRYPTO CHARSET' -s4_util_sources = '''dprintf.c parmlist.c''' +s4_util_sources = '''parmlist.c''' s4_util_deps = 'DYNCONFIG' s4_util_public_deps = 'talloc execinfo uid_wrapper' s4_util_public_headers = 'attr.h byteorder.h data_blob.h memory.h safe_string.h time.h talloc_stack.h xfile.h dlinklist.h util.h string_wrappers.h' -- cgit From d18491a7bdad69b8035eb7cda4d203cb792742f6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 20 Jun 2011 20:43:42 +1000 Subject: lib/util: allow parmlist.c to compile under s3 includes.h --- lib/util/parmlist.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/util') diff --git a/lib/util/parmlist.c b/lib/util/parmlist.c index 6658fa7e33..0f2f3af8ee 100644 --- a/lib/util/parmlist.c +++ b/lib/util/parmlist.c @@ -20,6 +20,8 @@ #include "../lib/util/dlinklist.h" #include "../lib/util/parmlist.h" +#undef strcasecmp + struct parmlist_entry *parmlist_get(struct parmlist *ctx, const char *name) { struct parmlist_entry *e; -- cgit From 5db74b9607f4a5fc5ecaa8be0d744222cd55153c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 20 Jun 2011 20:36:46 +1000 Subject: lib/util Remove samba-util-common! All of this code is now in common, so we don't need the second '-common' library any more! Andrew Bartlett --- lib/util/wscript_build | 56 +++++++++++--------------------------------------- 1 file changed, 12 insertions(+), 44 deletions(-) (limited to 'lib/util') diff --git a/lib/util/wscript_build b/lib/util/wscript_build index 8046a8ba07..bdc9d10150 100755 --- a/lib/util/wscript_build +++ b/lib/util/wscript_build @@ -1,57 +1,25 @@ #!/usr/bin/env python -common_util_sources = '''talloc_stack.c smb_threads.c xfile.c data_blob.c +bld.SAMBA_LIBRARY('samba-util', + source='''talloc_stack.c smb_threads.c xfile.c data_blob.c util_file.c time.c rbtree.c rfc1738.c select.c genrand.c fsusage.c blocking.c become_daemon.c signal.c system.c params.c util.c util_id.c util_net.c util_strlist.c util_paths.c idtree.c debug.c fault.c base64.c util_str.c util_str_common.c substitute.c ms_fnmatch.c - server_id.c dprintf.c''' - -common_util_headers = 'debug.h' -common_util_public_deps = 'talloc pthread LIBCRYPTO CHARSET' -s4_util_sources = '''parmlist.c''' -s4_util_deps = 'DYNCONFIG' -s4_util_public_deps = 'talloc execinfo uid_wrapper' -s4_util_public_headers = 'attr.h byteorder.h data_blob.h memory.h safe_string.h time.h talloc_stack.h xfile.h dlinklist.h util.h string_wrappers.h' -s4_util_header_path = [ ('dlinklist.h util.h', '.'), ('*', 'util') ] - -if bld.env._SAMBA_BUILD_ == 3: - # as we move files into common between samba-util and samba-util3, move them here. - # Both samba-util and samba-util3 depend on this private library - bld.SAMBA_LIBRARY('samba-util-common', - source=common_util_sources, - public_deps=common_util_public_deps, - # until we get all the dependencies in this library in common - # we need to allow this library to be built with unresolved symbols - allow_undefined_symbols=True, - local_include=False, - public_headers=common_util_headers, - header_path= [('*', 'util') ], - private_library=True - ) - -else: - bld.SAMBA_LIBRARY('samba-util', - source=s4_util_sources + " " + common_util_sources, - deps=s4_util_deps, - public_deps=s4_util_public_deps + ' ' + common_util_public_deps, - public_headers=s4_util_public_headers + ' ' + common_util_headers, - header_path= s4_util_header_path, - local_include=False, - vnum='0.0.1', - pc_files='samba-util.pc' - ) - - # dummy subsystem for avoid wider deps changes. - bld.SAMBA_SUBSYSTEM('samba-util-common', - source=[], - deps='samba-util', - local_include=False,) + server_id.c dprintf.c parmlist.c''', + deps='DYNCONFIG', + public_deps='talloc execinfo uid_wrapper pthread LIBCRYPTO CHARSET', + public_headers='debug.h attr.h byteorder.h data_blob.h memory.h safe_string.h time.h talloc_stack.h xfile.h dlinklist.h util.h string_wrappers.h', + header_path= [ ('dlinklist.h util.h', '.'), ('*', 'util') ], + local_include=False, + vnum='0.0.1', + pc_files='samba-util.pc' + ) bld.SAMBA_LIBRARY('asn1util', source='asn1.c', - deps='talloc samba-util-common', + deps='talloc samba-util', private_library=True, local_include=False) -- cgit From bf83b641e265a7b1523545294c268c6708999d2a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 21 Jun 2011 12:51:30 +1000 Subject: lib/util Remove display_cd from d_printf() The setting of the display charset is now done by convert_string_talloc() selecting the right charset based on CH_DISPLAY. Andrew Bartlett Signed-off-by: Andrew Tridgell --- lib/util/dprintf.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'lib/util') diff --git a/lib/util/dprintf.c b/lib/util/dprintf.c index c79989b517..a77eed84f5 100644 --- a/lib/util/dprintf.c +++ b/lib/util/dprintf.c @@ -34,8 +34,6 @@ #include "includes.h" #include "system/locale.h" -static smb_iconv_t display_cd = (smb_iconv_t)-1; - static int d_vfprintf(FILE *f, const char *format, va_list ap) { char *p, *p2; @@ -44,11 +42,6 @@ static int d_vfprintf(FILE *f, const char *format, va_list ap) bool cret; va_list ap2; - /* If there's nothing to convert, take a shortcut */ - if (display_cd == (smb_iconv_t)-1) { - return vfprintf(f, format, ap); - } - va_copy(ap2, ap); ret = vasprintf(&p, format, ap2); va_end(ap2); -- cgit From e00b1fa2b032012e741d94f3fe0057d6ea53bf4c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 21 Jun 2011 12:53:12 +1000 Subject: lib/util: Restore CH_UNIX as source charset for d_printf() I'm changed this during the change to use the d_printf() code in common, but should not have. However, there is a puzzle: What is the right source charset? Translated strings in our .mo and .msg files are in UTF8, but strings such as file names on remote servers are in UNIX (whatever that is). I can't see how this actually works properly when either CH_DISPLAY or CH_UNIX are other than UTF8! Andrew Bartlett Signed-off-by: Andrew Tridgell --- lib/util/dprintf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/util') diff --git a/lib/util/dprintf.c b/lib/util/dprintf.c index a77eed84f5..376eb4c75e 100644 --- a/lib/util/dprintf.c +++ b/lib/util/dprintf.c @@ -48,7 +48,7 @@ static int d_vfprintf(FILE *f, const char *format, va_list ap) if (ret <= 0) return ret; - cret = convert_string_talloc(NULL, CH_UTF8, CH_DISPLAY, p, ret, (void **)&p2, &clen); + cret = convert_string_talloc(NULL, CH_UNIX, CH_DISPLAY, p, ret, (void **)&p2, &clen); if (!cret) { /* the string can't be converted - do the best we can, filling in non-printing chars with '?' */ -- cgit From 125a2ff262aa312df20eec68802fd5f8a47f492f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 22 Jun 2011 09:52:31 +1000 Subject: lib/util/charset: Remove 'display charset' As discussed in 'CH_DISPLAY and gettext' on the samba-technical list: http://lists.samba.org/archive/samba-technical/2011-June/078190.html Setting this to a value other than 'unix charset' does not make sense, as any system where the filesytem charset does not equal the terminal charset will already have problems with programs as simple as 'ls'. It also means that our output could not be pasted as our input in interactive programs or onto our command line, as we never did translate in the DISPLAY -> UNIX direction. The d_printf() calls are retained in case we need to revisit this, and to support display_set_stderr(). Andrew Bartlett --- lib/util/charset/charset.h | 6 +- lib/util/charset/codepoints.c | 12 +--- lib/util/charset/tests/convert_string.c | 110 ++++++++++++++++---------------- lib/util/charset/util_str.c | 1 - lib/util/dprintf.c | 35 +--------- 5 files changed, 61 insertions(+), 103 deletions(-) (limited to 'lib/util') diff --git a/lib/util/charset/charset.h b/lib/util/charset/charset.h index a7e554204b..b36c461003 100644 --- a/lib/util/charset/charset.h +++ b/lib/util/charset/charset.h @@ -28,7 +28,7 @@ #include /* this defines the charset types used in samba */ -typedef enum {CH_UTF16LE=0, CH_UTF16=0, CH_UNIX, CH_DISPLAY, CH_DOS, CH_UTF8, CH_UTF16BE, CH_UTF16MUNGED} charset_t; +typedef enum {CH_UTF16LE=0, CH_UTF16=0, CH_UNIX, CH_DOS, CH_UTF8, CH_UTF16BE, CH_UTF16MUNGED} charset_t; #define NUM_CHARSETS 7 @@ -182,8 +182,7 @@ extern struct smb_iconv_handle *global_iconv_handle; struct smb_iconv_handle *get_iconv_handle(void); struct smb_iconv_handle *get_iconv_testing_handle(TALLOC_CTX *mem_ctx, const char *dos_charset, - const char *unix_charset, - const char *display_charset); + const char *unix_charset); smb_iconv_t get_conv_handle(struct smb_iconv_handle *ic, charset_t from, charset_t to); const char *charset_name(struct smb_iconv_handle *ic, charset_t ch); @@ -212,7 +211,6 @@ int codepoint_cmpi(codepoint_t c1, codepoint_t c2); struct smb_iconv_handle *smb_iconv_handle_reinit(TALLOC_CTX *mem_ctx, const char *dos_charset, const char *unix_charset, - const char *display_charset, bool native_iconv, struct smb_iconv_handle *old_ic); diff --git a/lib/util/charset/codepoints.c b/lib/util/charset/codepoints.c index 71611bfc4c..305bfd717f 100644 --- a/lib/util/charset/codepoints.c +++ b/lib/util/charset/codepoints.c @@ -168,17 +168,16 @@ struct smb_iconv_handle *get_iconv_handle(void) { if (global_iconv_handle == NULL) global_iconv_handle = smb_iconv_handle_reinit(talloc_autofree_context(), - "ASCII", "UTF-8", "ASCII", true, NULL); + "ASCII", "UTF-8", true, NULL); return global_iconv_handle; } struct smb_iconv_handle *get_iconv_testing_handle(TALLOC_CTX *mem_ctx, const char *dos_charset, - const char *unix_charset, - const char *display_charset) + const char *unix_charset) { return smb_iconv_handle_reinit(mem_ctx, - dos_charset, unix_charset, display_charset, true, NULL); + dos_charset, unix_charset, true, NULL); } /** @@ -190,7 +189,6 @@ const char *charset_name(struct smb_iconv_handle *ic, charset_t ch) case CH_UTF16: return "UTF-16LE"; case CH_UNIX: return ic->unix_charset; case CH_DOS: return ic->dos_charset; - case CH_DISPLAY: return ic->display_charset; case CH_UTF8: return "UTF8"; case CH_UTF16BE: return "UTF-16BE"; case CH_UTF16MUNGED: return "UTF16_MUNGED"; @@ -261,14 +259,11 @@ static const char *map_locale(const char *charset) _PUBLIC_ struct smb_iconv_handle *smb_iconv_handle_reinit(TALLOC_CTX *mem_ctx, const char *dos_charset, const char *unix_charset, - const char *display_charset, bool native_iconv, struct smb_iconv_handle *old_ic) { struct smb_iconv_handle *ret; - display_charset = map_locale(display_charset); - if (old_ic != NULL) { ret = old_ic; close_iconv_handle(ret); @@ -297,7 +292,6 @@ _PUBLIC_ struct smb_iconv_handle *smb_iconv_handle_reinit(TALLOC_CTX *mem_ctx, ret->dos_charset = talloc_strdup(ret->child_ctx, dos_charset); ret->unix_charset = talloc_strdup(ret->child_ctx, unix_charset); - ret->display_charset = talloc_strdup(ret->child_ctx, display_charset); ret->native_iconv = native_iconv; return ret; diff --git a/lib/util/charset/tests/convert_string.c b/lib/util/charset/tests/convert_string.c index bd140d59db..9a5d974fe3 100644 --- a/lib/util/charset/tests/convert_string.c +++ b/lib/util/charset/tests/convert_string.c @@ -105,7 +105,7 @@ static bool test_gd_iso8859_cp850_handle(struct torture_context *tctx) talloc_steal(tctx, gd_iso8859_1.data); talloc_steal(tctx, gd_utf16le.data); - iconv_handle = get_iconv_testing_handle(tctx, "ISO8859-1", "CP850", "UTF8"); + iconv_handle = get_iconv_testing_handle(tctx, "ISO8859-1", "CP850"); torture_assert(tctx, iconv_handle, "getting iconv handle"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, @@ -199,11 +199,11 @@ static bool test_gd_iso8859_cp850_handle(struct torture_context *tctx) torture_assert_data_blob_equal(tctx, gd_output, gd_cp850, "conversion from UTF8 to (unix charset) CP850 incorrect"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, - CH_UTF8, CH_DISPLAY, + CH_UTF8, CH_UTF8, gd_utf8.data, gd_utf8.length, (void *)&gd_output.data, &gd_output.length), - "conversion from UTF8 to (display charset) UTF8"); - torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF8 to (display charset) UTF8 incorrect"); + "conversion from UTF8 to UTF8"); + torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF8 to UTF8 incorrect"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, CH_UTF16LE, CH_DOS, @@ -227,11 +227,11 @@ static bool test_gd_iso8859_cp850_handle(struct torture_context *tctx) torture_assert_data_blob_equal(tctx, gd_output, gd_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, - CH_UTF16LE, CH_DISPLAY, + CH_UTF16LE, CH_UTF8, gd_utf16le.data, gd_utf16le.length, (void *)&gd_output.data, &gd_output.length), - "conversion from UTF16LE to (display charset) UTF8"); - torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF16LE to (display charset) UTF8 incorrect"); + "conversion from UTF16LE to UTF8"); + torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF16LE to UTF8 incorrect"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, CH_DOS, CH_DOS, @@ -248,11 +248,11 @@ static bool test_gd_iso8859_cp850_handle(struct torture_context *tctx) torture_assert_data_blob_equal(tctx, gd_output, gd_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, - CH_DOS, CH_DISPLAY, + CH_DOS, CH_UTF8, gd_iso8859_1.data, gd_iso8859_1.length, (void *)&gd_output.data, &gd_output.length), - "conversion from (dos charset) ISO8859-1 to (display charset) UTF8"); - torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF16LE to (display charset) UTF8 incorrect"); + "conversion from (dos charset) ISO8859-1 to UTF8"); + torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF16LE to UTF8 incorrect"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, CH_DOS, CH_UTF16LE, @@ -265,7 +265,7 @@ static bool test_gd_iso8859_cp850_handle(struct torture_context *tctx) (const char *)gd_iso8859_1.data, CH_DOS, CH_UTF16LE), gd_output.length / 2, - "checking strlen_m_ext of round trip conversion of UTF16 latin charset greek to display charset UTF8 and back again"); + "checking strlen_m_ext of round trip conversion of UTF16 latin charset greek to UTF8 and back again"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, CH_DOS, CH_UTF8, @@ -297,7 +297,7 @@ static bool test_gd_minus_1_handle(struct torture_context *tctx) talloc_steal(tctx, gd_cp850.data); talloc_steal(tctx, gd_utf16le.data); - iconv_handle = get_iconv_testing_handle(tctx, "CP850", "CP850", "UTF8"); + iconv_handle = get_iconv_testing_handle(tctx, "CP850", "CP850"); torture_assert(tctx, iconv_handle, "getting iconv handle"); gd_utf8_terminated = data_blob_talloc(tctx, NULL, gd_utf8.length + 1); @@ -481,7 +481,7 @@ static bool test_gd_ascii_handle(struct torture_context *tctx) talloc_steal(tctx, gd_iso8859_1.data); talloc_steal(tctx, gd_utf16le.data); - iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "UTF8", "UTF8"); + iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "UTF8"); torture_assert(tctx, iconv_handle, "getting iconv handle"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, @@ -550,7 +550,7 @@ static bool test_plato_english_iso8859_cp850_handle(struct torture_context *tctx talloc_steal(tctx, plato_english_utf16le.data); - iconv_handle = get_iconv_testing_handle(tctx, "ISO8859-1", "CP850", "UTF8"); + iconv_handle = get_iconv_testing_handle(tctx, "ISO8859-1", "CP850"); torture_assert(tctx, iconv_handle, "getting iconv handle"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, @@ -568,11 +568,11 @@ static bool test_plato_english_iso8859_cp850_handle(struct torture_context *tctx torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_cp850, "conversion from UTF8 to (unix charset) CP850 incorrect"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, - CH_UTF8, CH_DISPLAY, + CH_UTF8, CH_UTF8, plato_english_utf8.data, plato_english_utf8.length, (void *)&plato_english_output.data, &plato_english_output.length), - "conversion from UTF8 to (display charset) UTF8"); - torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF8 to (display charset) UTF8 incorrect"); + "conversion from UTF8 to UTF8"); + torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF8 to UTF8 incorrect"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, CH_UTF16LE, CH_DOS, @@ -621,11 +621,11 @@ static bool test_plato_english_iso8859_cp850_handle(struct torture_context *tctx torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, - CH_UTF16LE, CH_DISPLAY, + CH_UTF16LE, CH_UTF8, plato_english_utf16le.data, plato_english_utf16le.length, (void *)&plato_english_output.data, &plato_english_output.length), - "conversion from UTF16LE to (display charset) UTF8"); - torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to (display charset) UTF8 incorrect"); + "conversion from UTF16LE to UTF8"); + torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 incorrect"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, CH_DOS, CH_DOS, @@ -642,11 +642,11 @@ static bool test_plato_english_iso8859_cp850_handle(struct torture_context *tctx torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, - CH_DOS, CH_DISPLAY, + CH_DOS, CH_UTF8, plato_english_iso8859_1.data, plato_english_iso8859_1.length, (void *)&plato_english_output.data, &plato_english_output.length), - "conversion from (dos charset) ISO8859-1 to (display charset) UTF8"); - torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to (display charset) UTF8 incorrect"); + "conversion from (dos charset) ISO8859-1 to UTF8"); + torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 incorrect"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, CH_DOS, CH_UTF16LE, @@ -668,7 +668,7 @@ static bool test_plato_english_minus_1_handle(struct torture_context *tctx) talloc_steal(tctx, plato_english_utf16le.data); - iconv_handle = get_iconv_testing_handle(tctx, "ISO8859-1", "CP850", "UTF8"); + iconv_handle = get_iconv_testing_handle(tctx, "ISO8859-1", "CP850"); torture_assert(tctx, iconv_handle, "getting iconv handle"); plato_english_utf8_terminated = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 1); @@ -809,7 +809,7 @@ static bool test_plato_minus_1_handle(struct torture_context *tctx) talloc_steal(tctx, plato_utf8.data); talloc_steal(tctx, plato_utf16le.data); - iconv_handle = get_iconv_testing_handle(tctx, "ISO8859-1", "CP850", "UTF8"); + iconv_handle = get_iconv_testing_handle(tctx, "ISO8859-1", "CP850"); torture_assert(tctx, iconv_handle, "getting iconv handle"); plato_utf8_terminated = data_blob_talloc(tctx, NULL, plato_utf8.length + 1); @@ -923,7 +923,7 @@ static bool test_plato_cp850_utf8_handle(struct torture_context *tctx) talloc_steal(tctx, plato_utf8.data); talloc_steal(tctx, plato_utf16le.data); - iconv_handle = get_iconv_testing_handle(tctx, "CP850", "UTF8", "UTF8"); + iconv_handle = get_iconv_testing_handle(tctx, "CP850", "UTF8"); torture_assert(tctx, iconv_handle, "creating iconv handle"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, @@ -1008,11 +1008,11 @@ static bool test_plato_cp850_utf8_handle(struct torture_context *tctx) torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF8 to (unix charset) UTF8 incorrect"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, - CH_UTF8, CH_DISPLAY, + CH_UTF8, CH_UTF8, plato_utf8.data, plato_utf8.length, (void *)&plato_output.data, &plato_output.length), "conversion of UTF16 ancient greek to unix charset UTF8 failed"); - torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF8 to (display charset) UTF8 incorrect"); + torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF8 to UTF8 incorrect"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, CH_UTF16LE, CH_DOS, @@ -1067,39 +1067,39 @@ static bool test_plato_cp850_utf8_handle(struct torture_context *tctx) "conversion of UTF16 ancient greek to UTF8 failed"); torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to UTF8 incorrect"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, - CH_UTF16LE, CH_DISPLAY, + CH_UTF16LE, CH_UTF8, plato_utf16le.data, plato_utf16le.length, (void *)&plato_output.data, &plato_output.length), - "conversion of UTF16 ancient greek to display charset UTF8 failed"); - torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to (display charset) UTF8 incorrect"); + "conversion of UTF16 ancient greek to UTF8 failed"); + torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to UTF8 incorrect"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, - CH_DISPLAY, CH_UTF16LE, + CH_UTF8, CH_UTF16LE, plato_output.data, plato_output.length, (void *)&plato_output2.data, &plato_output2.length), - "round trip conversion of UTF16 ancient greek to display charset UTF8 and back again failed"); + "round trip conversion of UTF16 ancient greek to UTF8 and back again failed"); torture_assert_data_blob_equal(tctx, plato_output2, plato_utf16le, - "round trip conversion of UTF16 ancient greek to display charset UTF8 and back again failed"); + "round trip conversion of UTF16 ancient greek to UTF8 and back again failed"); torture_assert_int_equal(tctx, strlen_m_ext_handle(iconv_handle, (const char *)plato_output.data, - CH_DISPLAY, CH_UTF16LE), + CH_UTF8, CH_UTF16LE), plato_output2.length / 2, - "checking strlen_m_ext of round trip conversion of UTF16 latin charset greek to display charset UTF8 and back again"); + "checking strlen_m_ext of round trip conversion of UTF16 latin charset greek to UTF8 and back again"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, - CH_DISPLAY, CH_UTF8, + CH_UTF8, CH_UTF8, plato_output.data, plato_output.length, (void *)&plato_output2.data, &plato_output2.length), - "conversion of display charset UTF8 to UTF8"); + "conversion of UTF8 to UTF8"); torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8, - "conversion of display charset UTF8 to UTF8"); + "conversion of UTF8 to UTF8"); torture_assert_int_equal(tctx, strlen_m_ext_handle(iconv_handle, (const char *)plato_output.data, - CH_DISPLAY, CH_UTF8), + CH_UTF8, CH_UTF8), plato_output2.length, - "checking strlen_m_ext of conversion of display charset UTF8 to UTF8"); + "checking strlen_m_ext of conversion of UTF8 to UTF8"); return true; } @@ -1114,7 +1114,7 @@ static bool test_plato_latin_cp850_utf8_handle(struct torture_context *tctx) talloc_steal(tctx, plato_latin_utf8.data); talloc_steal(tctx, plato_latin_utf16le.data); - iconv_handle = get_iconv_testing_handle(tctx, "CP850", "UTF8", "UTF8"); + iconv_handle = get_iconv_testing_handle(tctx, "CP850", "UTF8"); torture_assert(tctx, iconv_handle, "creating iconv handle"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, @@ -1131,11 +1131,11 @@ static bool test_plato_latin_cp850_utf8_handle(struct torture_context *tctx) torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF8 to (unix charset) UTF8 incorrect"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, - CH_UTF8, CH_DISPLAY, + CH_UTF8, CH_UTF8, plato_latin_utf8.data, plato_latin_utf8.length, (void *)&plato_latin_output.data, &plato_latin_output.length), "conversion of UTF16 latin charset greek to unix charset UTF8 failed"); - torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF8 to (display charset) UTF8 incorrect"); + torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF8 to UTF8 incorrect"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, CH_UTF16LE, CH_DOS, @@ -1151,25 +1151,25 @@ static bool test_plato_latin_cp850_utf8_handle(struct torture_context *tctx) torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF16LE to (unix charset) CP850 incorrect"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, - CH_UTF16LE, CH_DISPLAY, + CH_UTF16LE, CH_UTF8, plato_latin_utf16le.data, plato_latin_utf16le.length, (void *)&plato_latin_output.data, &plato_latin_output.length), - "conversion of UTF16 latin charset greek to display charset UTF8 failed"); - torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF16LE to (display charset) UTF8 incorrect"); + "conversion of UTF16 latin charset greek to UTF8 failed"); + torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF16LE to UTF8 incorrect"); torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle, - CH_DISPLAY, CH_UTF16LE, + CH_UTF8, CH_UTF16LE, plato_latin_output.data, plato_latin_output.length, (void *)&plato_latin_output2.data, &plato_latin_output2.length), - "round trip conversion of UTF16 latin charset greek to display charset UTF8 and back again failed"); + "round trip conversion of UTF16 latin charset greek to UTF8 and back again failed"); torture_assert_data_blob_equal(tctx, plato_latin_output2, plato_latin_utf16le, - "round trip conversion of UTF16 latin charset greek to display charset UTF8 and back again failed"); + "round trip conversion of UTF16 latin charset greek to UTF8 and back again failed"); torture_assert_int_equal(tctx, strlen_m_ext_handle(iconv_handle, (const char *)plato_latin_output.data, - CH_DISPLAY, CH_UTF16LE), + CH_UTF8, CH_UTF16LE), plato_latin_output2.length / 2, - "checking strlen_m_ext of round trip conversion of UTF16 latin charset greek to display charset UTF8 and back again"); + "checking strlen_m_ext of round trip conversion of UTF16 latin charset greek to UTF8 and back again"); return true; } @@ -1182,7 +1182,7 @@ static bool test_gd_case_utf8_handle(struct torture_context *tctx) char *gd_lower, *gd_upper; talloc_steal(tctx, gd_utf8.data); - iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "UTF8", "UTF8"); + iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "UTF8"); torture_assert(tctx, iconv_handle, "getting utf8 iconv handle"); torture_assert(tctx, @@ -1245,7 +1245,7 @@ static bool test_gd_case_cp850_handle(struct torture_context *tctx) char *gd_lower, *gd_upper; talloc_steal(tctx, gd_cp850.data); - iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "CP850", "CP850"); + iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "CP850"); torture_assert(tctx, iconv_handle, "getting cp850 iconv handle"); torture_assert(tctx, @@ -1306,7 +1306,7 @@ static bool test_plato_case_utf8_handle(struct torture_context *tctx) char *plato_lower, *plato_upper; talloc_steal(tctx, plato_utf8.data); - iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "UTF8", "UTF8"); + iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "UTF8"); torture_assert(tctx, iconv_handle, "getting utf8 iconv handle"); torture_assert(tctx, diff --git a/lib/util/charset/util_str.c b/lib/util/charset/util_str.c index 80e5bde354..688ab5a0a1 100644 --- a/lib/util/charset/util_str.c +++ b/lib/util/charset/util_str.c @@ -169,7 +169,6 @@ _PUBLIC_ size_t strlen_m_ext_handle(struct smb_iconv_handle *ic, switch (dst_charset) { case CH_DOS: case CH_UNIX: - case CH_DISPLAY: smb_panic("cannot call strlen_m_ext() with a variable dest charset (must be UTF16* or UTF8)"); default: break; diff --git a/lib/util/dprintf.c b/lib/util/dprintf.c index 376eb4c75e..90ca36c1ae 100644 --- a/lib/util/dprintf.c +++ b/lib/util/dprintf.c @@ -36,40 +36,7 @@ static int d_vfprintf(FILE *f, const char *format, va_list ap) { - char *p, *p2; - int ret; - size_t clen; - bool cret; - va_list ap2; - - va_copy(ap2, ap); - ret = vasprintf(&p, format, ap2); - va_end(ap2); - - if (ret <= 0) return ret; - - cret = convert_string_talloc(NULL, CH_UNIX, CH_DISPLAY, p, ret, (void **)&p2, &clen); - if (!cret) { - /* the string can't be converted - do the best we can, - filling in non-printing chars with '?' */ - int i; - for (i=0;i Date: Wed, 22 Jun 2011 09:58:59 +1000 Subject: lib/util/charset: Remove autodetection of charset from LOCALE In the past, our LOCALE would set the display charset of Samba. The display charset has now been removed. This patch removes the support code that detected the locale from the environment. We cannot safely have 'unix charset' follow the locale (at it creates files on disk and entries in databases that must not vary), so this code is unused. As an example, imagine a database is manipulated in the administrator's locale, and then read by smbd starting up in the system default locale. Or smbd restarted by the administrator rather than a startup script. Both of these situations could corrupt databases or filenames on disk. Andrew Bartlett --- lib/util/charset/codepoints.c | 31 ------------------------------- 1 file changed, 31 deletions(-) (limited to 'lib/util') diff --git a/lib/util/charset/codepoints.c b/lib/util/charset/codepoints.c index 305bfd717f..8cc33a9782 100644 --- a/lib/util/charset/codepoints.c +++ b/lib/util/charset/codepoints.c @@ -217,37 +217,6 @@ static int close_iconv_handle(struct smb_iconv_handle *data) return 0; } -static const char *map_locale(const char *charset) -{ - if (strcmp(charset, "LOCALE") != 0) { - return charset; - } -#if defined(HAVE_NL_LANGINFO) && defined(CODESET) - { - const char *ln; - smb_iconv_t handle; - - ln = nl_langinfo(CODESET); - if (ln == NULL) { - DEBUG(1,("Unable to determine charset for LOCALE - using ASCII\n")); - return "ASCII"; - } - /* Check whether the charset name is supported - by iconv */ - handle = smb_iconv_open(ln, "UCS-2LE"); - if (handle == (smb_iconv_t) -1) { - DEBUG(5,("Locale charset '%s' unsupported, using ASCII instead\n", ln)); - return "ASCII"; - } else { - DEBUG(5,("Substituting charset '%s' for LOCALE\n", ln)); - smb_iconv_close(handle); - } - return ln; - } -#endif - return "ASCII"; -} - /* the old_ic is passed in here as the smb_iconv_handle structure is used as a global pointer in some places (eg. python modules). We -- cgit