diff options
Diffstat (limited to 'source3/lib/charcnv.c')
-rw-r--r-- | source3/lib/charcnv.c | 822 |
1 files changed, 742 insertions, 80 deletions
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index 049390f2a4..cdfca8eb97 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -1,8 +1,9 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. + Unix SMB/CIFS implementation. Character set conversion Extensions - Copyright (C) Andrew Tridgell 1992-1994 + Copyright (C) Igor Vergeichik <iverg@mail.ru> 2001 + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Simo Sorce 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 @@ -20,107 +21,768 @@ */ #include "includes.h" -extern int DEBUGLEVEL; -static char cvtbuf[1024]; +static pstring cvtbuf; -static mapsinited = 0; +static smb_iconv_t conv_handles[NUM_CHARSETS][NUM_CHARSETS]; -static char unix2dos[256]; -static char dos2unix[256]; +/**************************************************************************** +return the name of a charset to give to iconv() +****************************************************************************/ +static char *charset_name(charset_t ch) +{ + char *ret = NULL; + + if (ch == CH_UCS2) ret = "UCS-2LE"; + 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(); + else if (ch == CH_UTF8) ret = "UTF8"; + + if (!ret || !*ret) ret = "ASCII"; + return ret; +} + + +static void lazy_initialize_conv(void) +{ + static int initialized = False; + + if (!initialized) { + initialized = True; + load_case_tables(); + init_iconv(); + init_valid_table(); + } +} + +/**************************************************************************** + Initialize iconv conversion descriptors +****************************************************************************/ +void init_iconv(void) +{ + int c1, c2; + BOOL did_reload = False; + + /* 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"); + } + if (!conv_handles[CH_UCS2][CH_UNIX]) { + conv_handles[CH_UCS2][CH_UNIX] = smb_iconv_open("ASCII", "UCS-2LE"); + } + + + for (c1=0;c1<NUM_CHARSETS;c1++) { + for (c2=0;c2<NUM_CHARSETS;c2++) { + char *n1 = charset_name((charset_t)c1); + char *n2 = charset_name((charset_t)c2); + if (conv_handles[c1][c2] && + strcmp(n1, conv_handles[c1][c2]->from_name) == 0 && + strcmp(n2, conv_handles[c1][c2]->to_name) == 0) continue; + + did_reload = True; + + if (conv_handles[c1][c2]) { + smb_iconv_close(conv_handles[c1][c2]); + } + conv_handles[c1][c2] = smb_iconv_open(n2,n1); + if (conv_handles[c1][c2] == (smb_iconv_t)-1) { + DEBUG(0,("Conversion from %s to %s not supported\n", + charset_name((charset_t)c1), charset_name((charset_t)c2))); + conv_handles[c1][c2] = NULL; + } + } + } + + if (did_reload) { + init_valid_table(); + } +} + +/** + * Convert string from one encoding to another, making error checking etc + * + * @param descriptor conversion descriptor, created in init_iconv() + * @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 + * @retval the number of bytes occupied in the destination + **/ +size_t convert_string(charset_t from, charset_t to, + void const *src, size_t srclen, + void *dest, size_t destlen) +{ + size_t i_len, o_len; + size_t retval; + const char* inbuf = (const char*)src; + char* outbuf = (char*)dest; + smb_iconv_t descriptor; + + if (srclen == -1) srclen = strlen(src)+1; -static void initmaps() { - int k; + lazy_initialize_conv(); - for (k = 0; k < 256; k++) unix2dos[k] = k; - for (k = 0; k < 256; k++) dos2unix[k] = k; + descriptor = conv_handles[from][to]; - mapsinited = 1; + if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) { + /* conversion not supported, use as is */ + int len = MIN(srclen,destlen); + memcpy(dest,src,len); + return len; + } + + i_len=srclen; + o_len=destlen; + retval = smb_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len); + if(retval==-1) + { + char *reason="unknown error"; + switch(errno) + { case EINVAL: reason="Incomplete multibyte sequence"; break; + case E2BIG: reason="No more room"; + DEBUG(0, ("Required %d, available %d\n", + srclen, destlen)); + /* we are not sure we need srclen bytes, + may be more, may be less. + We only know we need more than destlen + bytes ---simo */ + + + break; + case EILSEQ: reason="Illegal multibyte sequence"; break; + } + /* smb_panic(reason); */ + } + return destlen-o_len; } -static void update_map(char * str) { - char *p; +/** + * Convert between character sets, allocating a new buffer for the result. + * + * @param srclen length of source buffer. + * @param dest always set at least to NULL + * @note -1 is not accepted for srclen. + * + * @retval Size in bytes of the converted string; or -1 in case of error. + **/ +size_t convert_string_allocate(charset_t from, charset_t to, + void const *src, size_t srclen, void **dest) +{ + size_t i_len, o_len, destlen; + size_t retval; + const char *inbuf = (const char *)src; + char *outbuf, *ob; + smb_iconv_t descriptor; + + *dest = NULL; + + if (src == NULL || srclen == -1) return -1; + + lazy_initialize_conv(); - for (p = str; *p; p++) { - if (p[1]) { - unix2dos[(unsigned char)*p] = p[1]; - dos2unix[(unsigned char)p[1]] = *p; - p++; - } - } + descriptor = conv_handles[from][to]; + + if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) { + /* conversion not supported, return -1*/ + DEBUG(3, ("convert_string_allocate: conversion not supported!\n")); + return -1; + } + + destlen = MAX(srclen, 512); + outbuf = NULL; +convert: + destlen = destlen * 2; + ob = (char *)realloc(outbuf, destlen); + if (!ob) { + DEBUG(0, ("convert_string_allocate: realloc failed!\n")); + SAFE_FREE(outbuf); + return -1; + } + else outbuf = ob; + i_len = srclen; + o_len = destlen; + retval = smb_iconv(descriptor, + &inbuf, &i_len, + &outbuf, &o_len); + if(retval == -1) + { + char *reason="unknown error"; + switch(errno) + { + case EINVAL: + reason="Incomplete multibyte sequence"; + break; + case E2BIG: + goto convert; + case EILSEQ: + reason="Illegal multibyte sequence"; + break; + } + DEBUG(0,("Conversion error: %s(%s)\n",reason,inbuf)); + /* smb_panic(reason); */ + return -1; + } + + destlen = destlen - o_len; + *dest = (char *)Realloc(ob,destlen); + if (!*dest) { + DEBUG(0, ("convert_string_allocate: out of memory!\n")); + SAFE_FREE(ob); + return -1; + } + + return destlen; } -static void initiso() { +/** + * 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. + * + * @retval Size in bytes of the converted string; or -1 in case of error. + **/ +size_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to, + void const *src, size_t srclen, void **dest) +{ + void *ob; + size_t dest_len; - if (!mapsinited) initmaps(); + *dest = NULL; + dest_len=convert_string_allocate(from, to, src, srclen, (void **)&ob); + if (dest_len == -1) + return -1; + *dest = talloc_strdup(ctx, (char *)ob); + SAFE_FREE(ob); + if (*dest == NULL) + return -1; + return dest_len; +} - update_map("\241\255\242\233\243\234\244\236\245\235\246\272\247\025\250\251"); - update_map("\251\273\252\246\253\256\254\252\255\274\256\310\257\257\260\370"); - update_map("\261\361\262\375\263\264\264\265\265\266\266\024\267\371\270\267"); - update_map("\271\270\272\247\273\275\274\254\275\253\276\276\277\250\200\277"); - update_map("\301\300\302\301\303\302\304\216\305\217\306\222\307\200\310\303"); - update_map("\311\220\312\305\313\306\314\307\315\315\316\317\317\320\320\311"); - update_map("\321\245\322\321\323\322\324\323\325\324\326\231\327\312\330\325"); - update_map("\331\326\332\327\333\330\334\232\335\313\336\314\337\341\340\205"); - update_map("\341\240\342\203\343\331\344\204\345\206\346\221\347\207\350\212"); - update_map("\351\202\352\210\353\211\354\215\355\241\356\214\357\213\360\316"); - update_map("\361\244\362\225\363\242\364\223\365\332\366\224\367\366\370\362"); - update_map("\371\227\372\243\373\226\374\201\375\304\376\263\377\230"); +int unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen) +{ + int size; + smb_ucs2_t *buffer=(smb_ucs2_t*)cvtbuf; + size=convert_string(CH_UNIX, CH_UCS2, src, srclen, buffer, sizeof(cvtbuf)); + if (!strupper_w(buffer) && (dest == src)) return srclen; + return convert_string(CH_UCS2, CH_UNIX, buffer, size, dest, destlen); } -/* - * Convert unix to dos - */ -char * -unix2dos_format(char *str,BOOL overwrite) +int unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen) { - char *p; - char *dp; + int size; + smb_ucs2_t *buffer=(smb_ucs2_t*)cvtbuf; + size=convert_string(CH_UNIX, CH_UCS2, src, srclen, buffer, sizeof(cvtbuf)); + if (!strlower_w(buffer) && (dest == src)) return srclen; + return convert_string(CH_UCS2, CH_UNIX, buffer, size, dest, destlen); +} + - if (!mapsinited) initmaps(); - if (overwrite) { - for (p = str; *p; p++) *p = unix2dos[(unsigned char)*p]; - return str; - } else { - for (p = str, dp = cvtbuf; *p; p++,dp++) *dp = unix2dos[(unsigned char)*p]; - *dp = 0; - return cvtbuf; - } +int ucs2_align(const void *base_ptr, const void *p, int flags) +{ + if (flags & (STR_NOALIGN|STR_ASCII)) return 0; + return PTR_DIFF(p, base_ptr) & 1; } -/* - * Convert dos to unix - */ -char * -dos2unix_format (char *str, BOOL overwrite) + +/**************************************************************************** +copy a string from a char* unix src to a dos codepage string destination +return the number of bytes occupied by the string in the destination +flags can have: + STR_TERMINATE means include the null termination + STR_UPPER means uppercase in the destination +dest_len is the maximum length allowed in the destination. If dest_len +is -1 then no maxiumum is used +****************************************************************************/ +int push_ascii(void *dest, const char *src, int dest_len, int flags) { - char *p; - char *dp; + int src_len = strlen(src); + pstring tmpbuf; - if (!mapsinited) initmaps(); - if (overwrite) { - for (p = str; *p; p++) *p = dos2unix[(unsigned char)*p]; - return str; - } else { - for (p = str, dp = cvtbuf; *p; p++,dp++) *dp = dos2unix[(unsigned char)*p]; - *dp = 0; - return cvtbuf; - } + /* treat a pstring as "unlimited" length */ + if (dest_len == -1) { + dest_len = sizeof(pstring); + } + + if (flags & STR_UPPER) { + pstrcpy(tmpbuf, src); + strupper(tmpbuf); + src = tmpbuf; + } + + if (flags & STR_TERMINATE) { + src_len++; + } + + return convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len); } +int push_ascii_fstring(void *dest, const char *src) +{ + return push_ascii(dest, src, sizeof(fstring), STR_TERMINATE); +} -/* - * Interpret character set. - */ -int -interpret_character_set (char *str, int def) +int push_ascii_pstring(void *dest, const char *src) { + return push_ascii(dest, src, sizeof(pstring), STR_TERMINATE); +} + +int push_pstring(void *dest, const char *src) +{ + return push_ascii(dest, src, sizeof(pstring), STR_TERMINATE); +} + + +/**************************************************************************** +copy a string from a dos codepage source to a unix char* destination +flags can have: + STR_TERMINATE means the string in src is null terminated +if STR_TERMINATE is set then src_len is ignored +src_len is the length of the source area in bytes +return the number of bytes occupied by the string in src +the resulting string in "dest" is always null terminated +****************************************************************************/ +int pull_ascii(char *dest, const void *src, int dest_len, int src_len, int flags) +{ + int ret; + + if (dest_len == -1) { + dest_len = sizeof(pstring); + } + + if (flags & STR_TERMINATE) src_len = strlen(src)+1; + + ret = convert_string(CH_DOS, CH_UNIX, src, src_len, dest, dest_len); + + if (dest_len) dest[MIN(ret, dest_len-1)] = 0; + + return src_len; +} + +int pull_ascii_pstring(char *dest, const void *src) +{ + return pull_ascii(dest, src, sizeof(pstring), -1, STR_TERMINATE); +} + +int pull_ascii_fstring(char *dest, const void *src) +{ + return pull_ascii(dest, src, sizeof(fstring), -1, STR_TERMINATE); +} + +/**************************************************************************** +copy a string from a char* src to a unicode destination +return the number of bytes occupied by the string in the destination +flags can have: + STR_TERMINATE means include the null termination + STR_UPPER means uppercase in the destination + STR_NOALIGN means don't do alignment +dest_len is the maximum length allowed in the destination. If dest_len +is -1 then no maxiumum is used +****************************************************************************/ +int push_ucs2(const void *base_ptr, void *dest, const char *src, int dest_len, int flags) +{ + int len=0; + int src_len = strlen(src); + pstring tmpbuf; + + /* treat a pstring as "unlimited" length */ + if (dest_len == -1) { + dest_len = sizeof(pstring); + } + + if (flags & STR_UPPER) { + pstrcpy(tmpbuf, src); + strupper(tmpbuf); + src = tmpbuf; + } + + if (flags & STR_TERMINATE) { + src_len++; + } + + if (ucs2_align(base_ptr, dest, flags)) { + *(char *)dest = 0; + dest = (void *)((char *)dest + 1); + if (dest_len) dest_len--; + len++; + } + + /* ucs2 is always a multiple of 2 bytes */ + dest_len &= ~1; + + len += convert_string(CH_UNIX, CH_UCS2, src, src_len, dest, dest_len); + return len; +} + +/** + * 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 + * + * @retval The number of bytes occupied by the string in the destination + **/ +int push_ucs2_talloc(TALLOC_CTX *ctx, void **dest, const char *src) +{ + int src_len = strlen(src)+1; + + *dest = NULL; + return convert_string_talloc(ctx, CH_UNIX, CH_UCS2, src, src_len, dest); +} + +/** + * Copy a string from a unix char* src to a UCS2 destination, allocating a buffer + * + * @param dest always set at least to NULL + * + * @retval The number of bytes occupied by the string in the destination + **/ +int push_ucs2_allocate(void **dest, const char *src) +{ + int src_len = strlen(src)+1; + + *dest = NULL; + return convert_string_allocate(CH_UNIX, CH_UCS2, src, src_len, dest); +} + +/**************************************************************************** +copy a string from a char* src to a UTF-8 destination +return the number of bytes occupied by the string in the destination +flags can have: + STR_TERMINATE means include the null termination + STR_UPPER means uppercase in the destination +dest_len is the maximum length allowed in the destination. If dest_len +is -1 then no maxiumum is used +****************************************************************************/ +int push_utf8(void *dest, const char *src, int dest_len, int flags) +{ + int src_len = strlen(src); + pstring tmpbuf; + + /* treat a pstring as "unlimited" length */ + if (dest_len == -1) { + dest_len = sizeof(pstring); + } - if (strequal (str, "iso8859-1")) { - initiso(); - return def; - } else { - DEBUG(0,("unrecognized character set\n")); - } - return def; + if (flags & STR_UPPER) { + pstrcpy(tmpbuf, src); + strupper(tmpbuf); + src = tmpbuf; + } + + if (flags & STR_TERMINATE) { + src_len++; + } + + return convert_string(CH_UNIX, CH_UTF8, src, src_len, dest, dest_len); +} + +int push_utf8_fstring(void *dest, const char *src) +{ + return push_utf8(dest, src, sizeof(fstring), STR_TERMINATE); +} + +int push_utf8_pstring(void *dest, const char *src) +{ + return push_utf8(dest, src, sizeof(pstring), STR_TERMINATE); +} + +/** + * 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 + * + * @retval The number of bytes occupied by the string in the destination + **/ +int push_utf8_talloc(TALLOC_CTX *ctx, void **dest, const char *src) +{ + int src_len = strlen(src)+1; + + *dest = NULL; + return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len, dest); +} + +/** + * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer + * + * @param dest always set at least to NULL + * + * @retval The number of bytes occupied by the string in the destination + **/ +int push_utf8_allocate(void **dest, const char *src) +{ + int src_len = strlen(src)+1; + + *dest = NULL; + return convert_string_allocate(CH_UNIX, CH_UTF8, src, src_len, dest); +} + +/**************************************************************************** +copy a string from a ucs2 source to a unix char* destination +flags can have: + STR_TERMINATE means the string in src is null terminated + STR_NOALIGN means don't try to align +if STR_TERMINATE is set then src_len is ignored +src_len is the length of the source area in bytes +return the number of bytes occupied by the string in src +the resulting string in "dest" is always null terminated +****************************************************************************/ +int pull_ucs2(const void *base_ptr, char *dest, const void *src, int dest_len, int src_len, int flags) +{ + int ret; + + if (dest_len == -1) { + dest_len = sizeof(pstring); + } + + if (ucs2_align(base_ptr, src, flags)) { + src = (const void *)((const char *)src + 1); + if (src_len > 0) src_len--; + } + + if (flags & STR_TERMINATE) src_len = strlen_w(src)*2+2; + + /* ucs2 is always a multiple of 2 bytes */ + src_len &= ~1; + + ret = convert_string(CH_UCS2, CH_UNIX, src, src_len, dest, dest_len); + if (dest_len) dest[MIN(ret, dest_len-1)] = 0; + + return src_len; +} + +int pull_ucs2_pstring(char *dest, const void *src) +{ + return pull_ucs2(NULL, dest, src, sizeof(pstring), -1, STR_TERMINATE); +} + +int pull_ucs2_fstring(char *dest, const void *src) +{ + return pull_ucs2(NULL, dest, src, sizeof(fstring), -1, STR_TERMINATE); +} + +/** + * 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 + * + * @retval The number of bytes occupied by the string in the destination + **/ +int pull_ucs2_talloc(TALLOC_CTX *ctx, void **dest, const char *src) +{ + int src_len = strlen(src)+1; + *dest = NULL; + return convert_string_talloc(ctx, CH_UCS2, CH_UNIX, src, src_len, dest); +} + +/** + * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer + * + * @param dest always set at least to NULL + * + * @retval The number of bytes occupied by the string in the destination + **/ +int pull_ucs2_allocate(void **dest, const char *src) +{ + int src_len = strlen(src)+1; + *dest = NULL; + return convert_string_allocate(CH_UCS2, CH_UNIX, src, src_len, dest); +} + +/**************************************************************************** +copy a string from a utf-8 source to a unix char* destination +flags can have: + STR_TERMINATE means the string in src is null terminated +if STR_TERMINATE is set then src_len is ignored +src_len is the length of the source area in bytes +return the number of bytes occupied by the string in src +the resulting string in "dest" is always null terminated +****************************************************************************/ +int pull_utf8(char *dest, const void *src, int dest_len, int src_len, int flags) +{ + int ret; + + if (dest_len == -1) { + dest_len = sizeof(pstring); + } + + if (flags & STR_TERMINATE) src_len = strlen(src)+1; + + ret = convert_string(CH_UTF8, CH_UNIX, src, src_len, dest, dest_len); + if (dest_len) dest[MIN(ret, dest_len-1)] = 0; + + return src_len; +} + +int pull_utf8_pstring(char *dest, const void *src) +{ + return pull_utf8(dest, src, sizeof(pstring), -1, STR_TERMINATE); +} + +int pull_utf8_fstring(char *dest, const void *src) +{ + return pull_utf8(dest, src, sizeof(fstring), -1, STR_TERMINATE); +} + +/** + * 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 + * + * @retval The number of bytes occupied by the string in the destination + **/ +int pull_utf8_talloc(TALLOC_CTX *ctx, void **dest, const char *src) +{ + int src_len = strlen(src)+1; + *dest = NULL; + return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len, dest); +} + +/** + * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer + * + * @param dest always set at least to NULL + * + * @retval The number of bytes occupied by the string in the destination + **/ +int pull_utf8_allocate(void **dest, const char *src) +{ + int src_len = strlen(src)+1; + *dest = NULL; + return convert_string_allocate(CH_UTF8, CH_UNIX, src, src_len, dest); +} + +/**************************************************************************** +copy a string from a char* src to a unicode or ascii +dos codepage destination choosing unicode or ascii based on the +flags in the SMB buffer starting at base_ptr +return the number of bytes occupied by the string in the destination +flags can have: + STR_TERMINATE means include the null termination + STR_UPPER means uppercase in the destination + STR_ASCII use ascii even with unicode packet + STR_NOALIGN means don't do alignment +dest_len is the maximum length allowed in the destination. If dest_len +is -1 then no maxiumum is used +****************************************************************************/ +int push_string(const void *base_ptr, void *dest, const char *src, int dest_len, int flags) +{ + if (!(flags & STR_ASCII) && \ + ((flags & STR_UNICODE || \ + (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) { + return push_ucs2(base_ptr, dest, src, dest_len, flags); + } + return push_ascii(dest, src, dest_len, flags); +} + + +/**************************************************************************** +copy a string from a unicode or ascii source (depending on +the packet flags) to a char* destination +flags can have: + STR_TERMINATE means the string in src is null terminated + STR_UNICODE means to force as unicode + STR_ASCII use ascii even with unicode packet + STR_NOALIGN means don't do alignment +if STR_TERMINATE is set then src_len is ignored +src_len is the length of the source area in bytes +return the number of bytes occupied by the string in src +the resulting string in "dest" is always null terminated +****************************************************************************/ +int pull_string(const void *base_ptr, char *dest, const void *src, int dest_len, int src_len, + int flags) +{ + if (!(flags & STR_ASCII) && \ + ((flags & STR_UNICODE || \ + (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) { + return pull_ucs2(base_ptr, dest, src, dest_len, src_len, flags); + } + return pull_ascii(dest, src, dest_len, src_len, flags); +} + +int align_string(const void *base_ptr, const char *p, int flags) +{ + if (!(flags & STR_ASCII) && \ + ((flags & STR_UNICODE || \ + (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) { + return ucs2_align(base_ptr, p, flags); + } + return 0; +} + + + +/**************************************************************************** +convert from ucs2 to unix charset and return the +allocated and converted string or NULL if an error occurred. +you must provide a zero terminated string. +the returning string will be zero terminated. +****************************************************************************/ +char *acnv_u2ux(const smb_ucs2_t *src) +{ + size_t slen; + size_t dlen; + void *dest; + + slen = (strlen_w(src) + 1) * sizeof(smb_ucs2_t); + dlen = convert_string_allocate(CH_UCS2, CH_UNIX, src, slen, &dest); + if (dlen == -1) return NULL; + else return dest; +} + +/**************************************************************************** +convert from unix to ucs2 charset and return the +allocated and converted string or NULL if an error occurred. +you must provide a zero terminated string. +the returning string will be zero terminated. +****************************************************************************/ +smb_ucs2_t *acnv_uxu2(const char *src) +{ + size_t slen; + size_t dlen; + void *dest; + + slen = strlen(src) + 1; + dlen = convert_string_allocate(CH_UNIX, CH_UCS2, src, slen, &dest); + if (dlen == -1) return NULL; + else return dest; +} + +/**************************************************************************** +convert from ucs2 to dos charset and return the +allocated and converted string or NULL if an error occurred. +you must provide a zero terminated string. +the returning string will be zero terminated. +****************************************************************************/ +char *acnv_u2dos(const smb_ucs2_t *src) +{ + size_t slen; + size_t dlen; + void *dest; + + slen = (strlen_w(src) + 1) * sizeof(smb_ucs2_t); + dlen = convert_string_allocate(CH_UCS2, CH_DOS, src, slen, &dest); + if (dlen == -1) return NULL; + else return dest; +} + +/**************************************************************************** +convert from dos to ucs2 charset and return the +allocated and converted string or NULL if an error occurred. +you must provide a zero terminated string. +the returning string will be zero terminated. +****************************************************************************/ +smb_ucs2_t *acnv_dosu2(const char *src) +{ + size_t slen; + size_t dlen; + void *dest; + + slen = strlen(src) + 1; + dlen = convert_string_allocate(CH_DOS, CH_UCS2, src, slen, &dest); + if (dlen == -1) return NULL; + else return dest; } |