msrpc).
this was easier than I expected!
*/
/* this defines the charset types used in samba */
-typedef enum {CH_UCS2=0, CH_UNIX=1, CH_DISPLAY=2, CH_DOS=3, CH_UTF8=4} charset_t;
+typedef enum {CH_UCS2=0, CH_UNIX=1, CH_DISPLAY=2, CH_DOS=3, CH_UTF8=4, CH_UCS2BE=5} charset_t;
-#define NUM_CHARSETS 5
+#define NUM_CHARSETS 6
/*
* for each charset we have a function that pulls from that charset to
else if (ch == CH_DOS) ret = lp_dos_charset();
else if (ch == CH_DISPLAY) ret = lp_display_charset();
else if (ch == CH_UTF8) ret = "UTF8";
+ else if (ch == CH_UCS2BE) ret = "UCS-2BE";
if (!ret || !*ret) ret = "ASCII";
return ret;
* @sa Samba Developers Guide
**/
-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 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 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 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_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[] = {
{"UCS-2LE", iconv_copy, iconv_copy},
+ {"UCS-2BE", iconv_swab, iconv_swab},
{"UTF8", utf8_pull, utf8_push},
{"ASCII", ascii_pull, ascii_push},
{"UCS2-HEX", ucs2hex_pull, ucs2hex_push},
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, const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
uint32 len1, ofs, len2;
uint16 len3;
int ret;
+ int chset = CH_UCS2;
if (!(ndr_flags & NDR_SCALARS)) {
return NT_STATUS_OK;
}
+ if (ndr->flags & LIBNDR_FLAG_BIGENDIAN) {
+ chset = CH_UCS2BE;
+ }
+
switch (ndr->flags & LIBNDR_STRING_FLAGS) {
case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
break;
}
NDR_PULL_NEED_BYTES(ndr, len2*2);
- ret = convert_string_talloc(ndr->mem_ctx, CH_UCS2, CH_UNIX,
+ ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX,
ndr->data+ndr->offset,
len2*2,
(const void **)&as);
*s = talloc_strdup(ndr->mem_ctx, "");
break;
}
- ret = convert_string_talloc(ndr->mem_ctx, CH_UCS2, CH_UNIX,
+ ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX,
ndr->data+ndr->offset,
len1*2,
(const void **)&as);
if (len1*2+2 <= ndr->data_size - ndr->offset) {
len1++;
}
- ret = convert_string_talloc(ndr->mem_ctx, CH_UCS2, CH_UNIX,
+ ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX,
ndr->data+ndr->offset,
len1*2,
(const void **)s);
{
ssize_t s_len, c_len;
int ret;
+ int chset = CH_UCS2;
if (!(ndr_flags & NDR_SCALARS)) {
return NT_STATUS_OK;
}
+
+ if (ndr->flags & LIBNDR_FLAG_BIGENDIAN) {
+ chset = CH_UCS2BE;
+ }
s_len = s?strlen(s):0;
c_len = s?strlen_m(s):0;
NDR_CHECK(ndr_push_uint32(ndr, 0));
NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2);
- ret = convert_string(CH_UNIX, CH_UCS2,
+ ret = convert_string(CH_UNIX, chset,
s, s_len+1,
ndr->data+ndr->offset, c_len*2 + 2);
if (ret == -1) {
NDR_CHECK(ndr_push_uint32(ndr, 0));
NDR_CHECK(ndr_push_uint32(ndr, c_len));
NDR_PUSH_NEED_BYTES(ndr, c_len*2);
- ret = convert_string(CH_UNIX, CH_UCS2,
+ ret = convert_string(CH_UNIX, chset,
s, s_len,
ndr->data+ndr->offset, c_len*2);
if (ret == -1) {
case LIBNDR_FLAG_STR_SIZE4:
NDR_CHECK(ndr_push_uint32(ndr, c_len + 1));
NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2);
- ret = convert_string(CH_UNIX, CH_UCS2,
+ ret = convert_string(CH_UNIX, chset,
s, s_len + 1,
ndr->data+ndr->offset, c_len*2 + 2);
if (ret == -1) {
case LIBNDR_FLAG_STR_NULLTERM:
NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2);
- ret = convert_string(CH_UNIX, CH_UCS2,
+ ret = convert_string(CH_UNIX, chset,
s, s_len+1,
ndr->data+ndr->offset, c_len*2 + 2);
if (ret == -1) {