summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2004-08-30 21:35:43 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:52:32 -0500
commit651daa4b4256455b26b0affcdc45fe328b128c99 (patch)
tree90abd017d3dd931fb128aecef300e6424b9f8179 /source3
parentf1688d61df13aacb0e512fd16504cc94f803d808 (diff)
downloadsamba-651daa4b4256455b26b0affcdc45fe328b128c99.tar.gz
samba-651daa4b4256455b26b0affcdc45fe328b128c99.tar.bz2
samba-651daa4b4256455b26b0affcdc45fe328b128c99.zip
r2114: Shameless theft of iconv commit from Samba4 to keep the two libs more in sync :-).
try to cope with a wider range of UTF-16 characters when we are using an external libiconv library. Jeremy. (This used to be commit 5d04cd6804f6fc3b556e7c3b53fa0d7af39797c1)
Diffstat (limited to 'source3')
-rw-r--r--source3/include/charset.h9
-rw-r--r--source3/include/smb.h6
-rw-r--r--source3/lib/charcnv.c10
-rw-r--r--source3/lib/iconv.c79
-rw-r--r--source3/modules/weird.c4
5 files changed, 69 insertions, 39 deletions
diff --git a/source3/include/charset.h b/source3/include/charset.h
index 7a9b12ef55..c5d03a62e8 100644
--- a/source3/include/charset.h
+++ b/source3/include/charset.h
@@ -31,9 +31,9 @@ typedef enum {CH_UCS2=0, CH_UNIX=1, CH_DISPLAY=2, CH_DOS=3, CH_UTF8=4} charset_t
struct charset_functions {
const char *name;
- size_t (*pull)(void *, char **inbuf, size_t *inbytesleft,
+ size_t (*pull)(void *, const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft);
- size_t (*push)(void *, char **inbuf, size_t *inbytesleft,
+ size_t (*push)(void *, const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft);
struct charset_functions *prev, *next;
};
@@ -57,7 +57,7 @@ struct charset_gap_table {
*
* */
#define SMB_GENERATE_CHARSET_MODULE_8_BIT_GAP(CHARSETNAME) \
-static size_t CHARSETNAME ## _push(void *cd, char **inbuf, size_t *inbytesleft, \
+static size_t CHARSETNAME ## _push(void *cd, const char **inbuf, size_t *inbytesleft, \
char **outbuf, size_t *outbytesleft) \
{ \
while (*inbytesleft >= 2 && *outbytesleft >= 1) { \
@@ -97,7 +97,7 @@ static size_t CHARSETNAME ## _push(void *cd, char **inbuf, size_t *inbytesleft,
return 0; \
} \
\
-static size_t CHARSETNAME ## _pull(void *cd, char **inbuf, size_t *inbytesleft, \
+static size_t CHARSETNAME ## _pull(void *cd, const char **inbuf, size_t *inbytesleft, \
char **outbuf, size_t *outbytesleft) \
{ \
while (*inbytesleft >= 1 && *outbytesleft >= 2) { \
@@ -124,4 +124,3 @@ NTSTATUS charset_ ## CHARSETNAME ## _init(void) \
return smb_register_charset(& CHARSETNAME ## _functions); \
} \
-
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 32dba0cf78..7317fd16b0 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -1658,11 +1658,11 @@ struct unix_error_map {
/* generic iconv conversion structure */
typedef struct {
- size_t (*direct)(void *cd, char **inbuf, size_t *inbytesleft,
+ size_t (*direct)(void *cd, const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft);
- size_t (*pull)(void *cd, char **inbuf, size_t *inbytesleft,
+ size_t (*pull)(void *cd, const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft);
- size_t (*push)(void *cd, char **inbuf, size_t *inbytesleft,
+ size_t (*push)(void *cd, const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft);
void *cd_direct, *cd_pull, *cd_push;
char *from_name, *to_name;
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c
index 6cbf7562b0..21d34f30cb 100644
--- a/source3/lib/charcnv.c
+++ b/source3/lib/charcnv.c
@@ -56,7 +56,7 @@ static const char *charset_name(charset_t ch)
{
const char *ret = NULL;
- if (ch == CH_UCS2) ret = "UCS-2LE";
+ if (ch == CH_UCS2) ret = "UTF-16LE";
else if (ch == CH_UNIX) ret = lp_unix_charset();
else if (ch == CH_DOS) ret = lp_dos_charset();
else if (ch == CH_DISPLAY) ret = lp_display_charset();
@@ -116,10 +116,10 @@ void init_iconv(void)
/* so that charset_name() works we need to get the UNIX<->UCS2 going
first */
if (!conv_handles[CH_UNIX][CH_UCS2])
- conv_handles[CH_UNIX][CH_UCS2] = smb_iconv_open("UCS-2LE", "ASCII");
+ conv_handles[CH_UNIX][CH_UCS2] = smb_iconv_open(charset_name(CH_UCS2), "ASCII");
if (!conv_handles[CH_UCS2][CH_UNIX])
- conv_handles[CH_UCS2][CH_UNIX] = smb_iconv_open("ASCII", "UCS-2LE");
+ conv_handles[CH_UCS2][CH_UNIX] = smb_iconv_open("ASCII", charset_name(CH_UCS2));
for (c1=0;c1<NUM_CHARSETS;c1++) {
for (c2=0;c2<NUM_CHARSETS;c2++) {
@@ -216,7 +216,7 @@ static size_t convert_string_internal(charset_t from, charset_t to,
again:
- retval = smb_iconv(descriptor, (char **)&inbuf, &i_len, &outbuf, &o_len);
+ retval = smb_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len);
if(retval==(size_t)-1) {
const char *reason="unknown error";
switch(errno) {
@@ -531,7 +531,7 @@ size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
again:
retval = smb_iconv(descriptor,
- (char **)&inbuf, &i_len,
+ &inbuf, &i_len,
&outbuf, &o_len);
if(retval == (size_t)-1) {
const char *reason="unknown error";
diff --git a/source3/lib/iconv.c b/source3/lib/iconv.c
index 4c9ecf992e..e10e42328c 100644
--- a/source3/lib/iconv.c
+++ b/source3/lib/iconv.c
@@ -51,18 +51,25 @@
* @sa Samba Developers Guide
**/
-static size_t ascii_pull(void *,char **, size_t *, char **, size_t *);
-static size_t ascii_push(void *,char **, size_t *, char **, size_t *);
-static size_t latin1_push(void *,char **, size_t *, char **, size_t *);
-static size_t utf8_pull(void *,char **, size_t *, char **, size_t *);
-static size_t utf8_push(void *,char **, size_t *, char **, size_t *);
-static size_t ucs2hex_pull(void *,char **, size_t *, char **, size_t *);
-static size_t ucs2hex_push(void *,char **, size_t *, char **, size_t *);
-static size_t iconv_copy(void *,char **, size_t *, char **, size_t *);
+static size_t ascii_pull(void *,const char **, size_t *, char **, size_t *);
+static size_t ascii_push(void *,const char **, size_t *, char **, size_t *);
+static size_t latin1_push(void *,const char **, size_t *, char **, size_t *);
+static size_t utf8_pull(void *,const char **, size_t *, char **, size_t *);
+static size_t utf8_push(void *,const char **, size_t *, char **, size_t *);
+static size_t ucs2hex_pull(void *,const char **, size_t *, char **, size_t *);
+static size_t ucs2hex_push(void *,const char **, size_t *, char **, size_t *);
+static size_t iconv_copy(void *,const char **, size_t *, char **, size_t *);
+static size_t iconv_swab (void *,const char **, size_t *, char **, size_t *);
static struct charset_functions builtin_functions[] = {
+ /* windows is really neither UCS-2 not UTF-16 */
{"UCS-2LE", iconv_copy, iconv_copy},
+ {"UTF-16LE", iconv_copy, iconv_copy},
+ {"UCS-2BE", iconv_swab, iconv_swab},
+
+ /* we include the UTF-8 alias to cope with differing locale settings */
{"UTF8", utf8_pull, utf8_push},
+ {"UTF-8", utf8_pull, utf8_push},
{"ASCII", ascii_pull, ascii_push},
{"646", ascii_pull, ascii_push},
{"ISO-8859-1", ascii_pull, latin1_push},
@@ -122,12 +129,12 @@ static void lazy_initialize_iconv(void)
this ensures that we don't have a shift state remaining for
character sets like SJIS */
static size_t sys_iconv(void *cd,
- char **inbuf, size_t *inbytesleft,
+ const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
#ifdef HAVE_NATIVE_ICONV
size_t ret = iconv((iconv_t)cd,
- inbuf, inbytesleft,
+ (char **)inbuf, inbytesleft,
outbuf, outbytesleft);
if (ret == (size_t)-1) {
int saved_errno = errno;
@@ -148,7 +155,7 @@ static size_t sys_iconv(void *cd,
* enough that Samba works on systems that don't have iconv.
**/
size_t smb_iconv(smb_iconv_t cd,
- char **inbuf, size_t *inbytesleft,
+ const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
char cvtbuf[2048];
@@ -158,7 +165,7 @@ size_t smb_iconv(smb_iconv_t cd,
/* in many cases we can go direct */
if (cd->direct) {
return cd->direct(cd->cd_direct,
- (char **)inbuf, inbytesleft, outbuf, outbytesleft);
+ inbuf, inbytesleft, outbuf, outbytesleft);
}
@@ -168,14 +175,14 @@ size_t smb_iconv(smb_iconv_t cd,
bufsize = sizeof(cvtbuf);
if (cd->pull(cd->cd_pull,
- (char **)inbuf, inbytesleft, &bufp, &bufsize) == -1
+ inbuf, inbytesleft, &bufp, &bufsize) == -1
&& errno != E2BIG) return -1;
bufp = cvtbuf;
bufsize = sizeof(cvtbuf) - bufsize;
if (cd->push(cd->cd_push,
- &bufp, &bufsize,
+ (const char **)&bufp, &bufsize,
outbuf, outbytesleft) == -1) return -1;
}
@@ -313,7 +320,7 @@ int smb_iconv_close (smb_iconv_t cd)
multi-byte character set support for english users
***********************************************************************/
-static size_t ascii_pull(void *cd, char **inbuf, size_t *inbytesleft,
+static size_t ascii_pull(void *cd, const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
while (*inbytesleft >= 1 && *outbytesleft >= 2) {
@@ -333,7 +340,7 @@ static size_t ascii_pull(void *cd, char **inbuf, size_t *inbytesleft,
return 0;
}
-static size_t ascii_push(void *cd, char **inbuf, size_t *inbytesleft,
+static size_t ascii_push(void *cd, const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
int ir_count=0;
@@ -360,7 +367,7 @@ static size_t ascii_push(void *cd, char **inbuf, size_t *inbytesleft,
return ir_count;
}
-static size_t latin1_push(void *cd, char **inbuf, size_t *inbytesleft,
+static size_t latin1_push(void *cd, const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
int ir_count=0;
@@ -387,7 +394,7 @@ static size_t latin1_push(void *cd, char **inbuf, size_t *inbytesleft,
return ir_count;
}
-static size_t ucs2hex_pull(void *cd, char **inbuf, size_t *inbytesleft,
+static size_t ucs2hex_pull(void *cd, const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
while (*inbytesleft >= 1 && *outbytesleft >= 2) {
@@ -430,7 +437,7 @@ static size_t ucs2hex_pull(void *cd, char **inbuf, size_t *inbytesleft,
return 0;
}
-static size_t ucs2hex_push(void *cd, char **inbuf, size_t *inbytesleft,
+static size_t ucs2hex_push(void *cd, const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
while (*inbytesleft >= 2 && *outbytesleft >= 1) {
@@ -471,8 +478,32 @@ static size_t ucs2hex_push(void *cd, char **inbuf, size_t *inbytesleft,
return 0;
}
+static size_t iconv_swab(void *cd, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ int n;
+
+ n = MIN(*inbytesleft, *outbytesleft);
+
+ swab(*inbuf, *outbuf, (n&~1));
+ if (n&1) {
+ (*outbuf)[n-1] = 0;
+ }
+
+ (*inbytesleft) -= n;
+ (*outbytesleft) -= n;
+ (*inbuf) += n;
+ (*outbuf) += n;
+
+ if (*inbytesleft > 0) {
+ errno = E2BIG;
+ return -1;
+ }
+
+ return 0;
+}
-static size_t iconv_copy(void *cd, char **inbuf, size_t *inbytesleft,
+static size_t iconv_copy(void *cd, const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
int n;
@@ -494,11 +525,11 @@ static size_t iconv_copy(void *cd, char **inbuf, size_t *inbytesleft,
return 0;
}
-static size_t utf8_pull(void *cd, char **inbuf, size_t *inbytesleft,
+static size_t utf8_pull(void *cd, const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
while (*inbytesleft >= 1 && *outbytesleft >= 2) {
- unsigned char *c = (unsigned char *)*inbuf;
+ const unsigned char *c = (const unsigned char *)*inbuf;
unsigned char *uc = (unsigned char *)*outbuf;
int len = 1;
@@ -541,12 +572,12 @@ badseq:
return -1;
}
-static size_t utf8_push(void *cd, char **inbuf, size_t *inbytesleft,
+static size_t utf8_push(void *cd, const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
while (*inbytesleft >= 2 && *outbytesleft >= 1) {
unsigned char *c = (unsigned char *)*outbuf;
- unsigned char *uc = (unsigned char *)*inbuf;
+ const unsigned char *uc = (const unsigned char *)*inbuf;
int len=1;
if (uc[1] & 0xf8) {
diff --git a/source3/modules/weird.c b/source3/modules/weird.c
index 444853f383..3c59fd9d61 100644
--- a/source3/modules/weird.c
+++ b/source3/modules/weird.c
@@ -31,7 +31,7 @@ static struct {
{0, NULL}
};
-static size_t weird_pull(void *cd, char **inbuf, size_t *inbytesleft,
+static size_t weird_pull(void *cd, const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
while (*inbytesleft >= 1 && *outbytesleft >= 2) {
@@ -74,7 +74,7 @@ static size_t weird_pull(void *cd, char **inbuf, size_t *inbytesleft,
return 0;
}
-static size_t weird_push(void *cd, char **inbuf, size_t *inbytesleft,
+static size_t weird_push(void *cd, const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
int ir_count=0;