2 Unix SMB/CIFS implementation.
3 Character set conversion Extensions
4 Copyright (C) Igor Vergeichik <iverg@mail.ru> 2001
5 Copyright (C) Andrew Tridgell 2001
6 Copyright (C) Simo Sorce 2001
7 Copyright (C) Martin Pool 2003
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 * @brief Character-set conversion routines built on our iconv.
31 * @note Samba's internal character set (at least in the 3.0 series)
32 * is always the same as the one for the Unix filesystem. It is
33 * <b>not</b> necessarily UTF-8 and may be different on machines that
34 * need i18n filenames to be compatible with Unix software. It does
35 * have to be a superset of ASCII. All multibyte sequences must start
36 * with a byte with the high bit set.
42 static smb_iconv_t conv_handles[NUM_CHARSETS][NUM_CHARSETS];
43 static BOOL conv_silent; /* Should we do a debug if the conversion fails ? */
46 * Return the name of a charset to give to iconv().
48 static const char *charset_name(charset_t ch)
50 const char *ret = NULL;
52 if (ch == CH_UCS2) ret = "UCS-2LE";
53 else if (ch == CH_UNIX) ret = lp_unix_charset();
54 else if (ch == CH_DOS) ret = lp_dos_charset();
55 else if (ch == CH_DISPLAY) ret = lp_display_charset();
56 else if (ch == CH_UTF8) ret = "UTF8";
58 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
59 if (ret && !strcmp(ret, "LOCALE")) {
60 const char *ln = NULL;
63 setlocale(LC_ALL, "");
65 ln = nl_langinfo(CODESET);
67 /* Check whether the charset name is supported
69 smb_iconv_t handle = smb_iconv_open(ln,"UCS-2LE");
70 if (handle == (smb_iconv_t) -1) {
71 DEBUG(5,("Locale charset '%s' unsupported, using ASCII instead\n", ln));
74 DEBUG(5,("Substituting charset '%s' for LOCALE\n", ln));
75 smb_iconv_close(handle);
82 if (!ret || !*ret) ret = "ASCII";
86 void lazy_initialize_conv(void)
88 static int initialized = False;
98 * Initialize iconv conversion descriptors.
100 * This is called the first time it is needed, and also called again
101 * every time the configuration is reloaded, because the charset or
102 * codepage might have changed.
104 void init_iconv(void)
107 BOOL did_reload = False;
109 /* so that charset_name() works we need to get the UNIX<->UCS2 going
111 if (!conv_handles[CH_UNIX][CH_UCS2])
112 conv_handles[CH_UNIX][CH_UCS2] = smb_iconv_open("UCS-2LE", "ASCII");
114 if (!conv_handles[CH_UCS2][CH_UNIX])
115 conv_handles[CH_UCS2][CH_UNIX] = smb_iconv_open("ASCII", "UCS-2LE");
117 for (c1=0;c1<NUM_CHARSETS;c1++) {
118 for (c2=0;c2<NUM_CHARSETS;c2++) {
119 const char *n1 = charset_name((charset_t)c1);
120 const char *n2 = charset_name((charset_t)c2);
121 if (conv_handles[c1][c2] &&
122 strcmp(n1, conv_handles[c1][c2]->from_name) == 0 &&
123 strcmp(n2, conv_handles[c1][c2]->to_name) == 0)
128 if (conv_handles[c1][c2])
129 smb_iconv_close(conv_handles[c1][c2]);
131 conv_handles[c1][c2] = smb_iconv_open(n2,n1);
132 if (conv_handles[c1][c2] == (smb_iconv_t)-1) {
133 DEBUG(0,("Conversion from %s to %s not supported\n",
134 charset_name((charset_t)c1), charset_name((charset_t)c2)));
135 conv_handles[c1][c2] = NULL;
141 /* XXX: Does this really get called every time the dos
142 * codepage changes? */
143 /* XXX: Is the did_reload test too strict? */
145 init_doschar_table();
152 * Convert string from one encoding to another, making error checking etc
153 * Slow path version - uses (slow) iconv.
155 * @param src pointer to source string (multibyte or singlebyte)
156 * @param srclen length of the source string in bytes
157 * @param dest pointer to destination string (multibyte or singlebyte)
158 * @param destlen maximal length allowed for string
159 * @returns the number of bytes occupied in the destination
161 * Ensure the srclen contains the terminating zero.
165 static size_t convert_string_internal(charset_t from, charset_t to,
166 void const *src, size_t srclen,
167 void *dest, size_t destlen)
171 const char* inbuf = (const char*)src;
172 char* outbuf = (char*)dest;
173 smb_iconv_t descriptor;
175 lazy_initialize_conv();
177 descriptor = conv_handles[from][to];
179 if (srclen == (size_t)-1) {
180 if (from == CH_UCS2) {
181 srclen = (strlen_w((const smb_ucs2_t *)src)+1) * 2;
183 srclen = strlen((const char *)src)+1;
188 if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
190 DEBUG(0,("convert_string_internal: Conversion not supported.\n"));
199 retval = smb_iconv(descriptor, (char **)&inbuf, &i_len, &outbuf, &o_len);
200 if(retval==(size_t)-1) {
201 const char *reason="unknown error";
204 reason="Incomplete multibyte sequence";
206 DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
209 reason="No more room";
211 DEBUG(3, ("convert_string_internal: Required %lu, available %lu\n",
212 (unsigned long)srclen, (unsigned long)destlen));
213 /* we are not sure we need srclen bytes,
214 may be more, may be less.
215 We only know we need more than destlen
219 reason="Illegal multibyte sequence";
221 DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
225 DEBUG(0,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
228 /* smb_panic(reason); */
230 return destlen-o_len;
235 * Conversion not supported. This is actually an error, but there are so
236 * many misconfigured iconv systems and smb.conf's out there we can't just
237 * fail. Do a very bad conversion instead.... JRA.
241 if (o_len == 0 || i_len == 0)
242 return destlen - o_len;
244 if (from == CH_UCS2 && to != CH_UCS2) {
245 /* Can't convert from ucs2 to multibyte. Just truncate this char to ascii. */
247 return destlen - o_len;
258 if (o_len == 0 || i_len == 0)
259 return destlen - o_len;
261 /* Keep trying with the next char... */
264 } else if (from != CH_UCS2 && to == CH_UCS2) {
265 /* Can't convert to ucs2 - just widen by adding zero. */
267 return destlen - o_len;
269 outbuf[0] = inbuf[0];
278 if (o_len == 0 || i_len == 0)
279 return destlen - o_len;
281 /* Keep trying with the next char... */
284 } else if (from != CH_UCS2 && to != CH_UCS2) {
285 /* Failed multibyte to multibyte. Just copy 1 char and
287 outbuf[0] = inbuf[0];
295 if (o_len == 0 || i_len == 0)
296 return destlen - o_len;
298 /* Keep trying with the next char... */
302 /* Keep compiler happy.... */
303 return destlen - o_len;
309 * Convert string from one encoding to another, making error checking etc
310 * Fast path version - handles ASCII first.
312 * @param src pointer to source string (multibyte or singlebyte)
313 * @param srclen length of the source string in bytes, or -1 for nul terminated.
314 * @param dest pointer to destination string (multibyte or singlebyte)
315 * @param destlen maximal length allowed for string - *NEVER* -1.
316 * @returns the number of bytes occupied in the destination
318 * Ensure the srclen contains the terminating zero.
320 * This function has been hand-tuned to provide a fast path.
321 * Don't change unless you really know what you are doing. JRA.
324 size_t convert_string(charset_t from, charset_t to,
325 void const *src, size_t srclen,
326 void *dest, size_t destlen)
329 * NB. We deliberately don't do a strlen here if srclen == -1.
330 * This is very expensive over millions of calls and is taken
331 * care of in the slow path in convert_string_internal. JRA.
335 SMB_ASSERT(destlen != (size_t)-1);
341 if (from != CH_UCS2 && to != CH_UCS2) {
342 const unsigned char *p = (const unsigned char *)src;
343 unsigned char *q = (unsigned char *)dest;
344 size_t slen = srclen;
345 size_t dlen = destlen;
349 /* If all characters are ascii, fast path here. */
350 while (slen && dlen) {
351 if ((lastp = *p) <= 0x7f) {
353 if (slen != (size_t)-1) {
361 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
364 return retval + convert_string_internal(from, to, p, slen, q, dlen);
369 } else if (from == CH_UCS2 && to != CH_UCS2) {
370 const unsigned char *p = (const unsigned char *)src;
371 unsigned char *q = (unsigned char *)dest;
373 size_t slen = srclen;
374 size_t dlen = destlen;
377 /* If all characters are ascii, fast path here. */
378 while (((slen == (size_t)-1) || (slen >= 2)) && dlen) {
379 if (((lastp = *p) <= 0x7f) && (p[1] == 0)) {
381 if (slen != (size_t)-1) {
390 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
393 return retval + convert_string_internal(from, to, p, slen, q, dlen);
398 } else if (from != CH_UCS2 && to == CH_UCS2) {
399 const unsigned char *p = (const unsigned char *)src;
400 unsigned char *q = (unsigned char *)dest;
402 size_t slen = srclen;
403 size_t dlen = destlen;
406 /* If all characters are ascii, fast path here. */
407 while (slen && (dlen >= 2)) {
408 if ((lastp = *p) <= 0x7F) {
411 if (slen != (size_t)-1) {
419 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
422 return retval + convert_string_internal(from, to, p, slen, q, dlen);
429 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
432 return convert_string_internal(from, to, src, srclen, dest, destlen);
436 * Convert between character sets, allocating a new buffer for the result.
438 * @param ctx TALLOC_CTX to use to allocate with. If NULL use malloc.
439 * @param srclen length of source buffer.
440 * @param dest always set at least to NULL
441 * @note -1 is not accepted for srclen.
443 * @returns Size in bytes of the converted string; or -1 in case of error.
445 * Ensure the srclen contains the terminating zero.
447 * I hate the goto's in this function. It's embarressing.....
448 * There has to be a cleaner way to do this. JRA.
451 size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
452 void const *src, size_t srclen, void **dest)
454 size_t i_len, o_len, destlen = MAX(srclen, 512);
456 const char *inbuf = (const char *)src;
457 char *outbuf = NULL, *ob = NULL;
458 smb_iconv_t descriptor;
462 if (src == NULL || srclen == (size_t)-1)
467 lazy_initialize_conv();
469 descriptor = conv_handles[from][to];
471 if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
473 DEBUG(0,("convert_string_allocate: Conversion not supported.\n"));
479 if ((destlen*2) < destlen) {
480 /* wrapped ! abort. */
482 DEBUG(0, ("convert_string_allocate: destlen wrapped !\n"));
487 destlen = destlen * 2;
491 ob = (char *)talloc_realloc(ctx, ob, destlen);
493 ob = (char *)Realloc(ob, destlen);
496 DEBUG(0, ("convert_string_allocate: realloc failed!\n"));
508 retval = smb_iconv(descriptor,
509 (char **)&inbuf, &i_len,
511 if(retval == (size_t)-1) {
512 const char *reason="unknown error";
515 reason="Incomplete multibyte sequence";
517 DEBUG(3,("convert_string_allocate: Conversion error: %s(%s)\n",reason,inbuf));
522 reason="Illegal multibyte sequence";
524 DEBUG(3,("convert_string_allocate: Conversion error: %s(%s)\n",reason,inbuf));
528 DEBUG(0,("Conversion error: %s(%s)\n",reason,inbuf));
529 /* smb_panic(reason); */
535 destlen = destlen - o_len;
537 *dest = (char *)talloc_realloc(ctx,ob,destlen);
539 *dest = (char *)Realloc(ob,destlen);
540 if (destlen && !*dest) {
541 DEBUG(0, ("convert_string_allocate: out of memory!\n"));
552 * Conversion not supported. This is actually an error, but there are so
553 * many misconfigured iconv systems and smb.conf's out there we can't just
554 * fail. Do a very bad conversion instead.... JRA.
558 if (o_len == 0 || i_len == 0)
561 if (from == CH_UCS2 && to != CH_UCS2) {
562 /* Can't convert from ucs2 to multibyte. Just truncate this char to ascii. */
576 if (o_len == 0 || i_len == 0)
579 /* Keep trying with the next char... */
582 } else if (from != CH_UCS2 && to == CH_UCS2) {
583 /* Can't convert to ucs2 - just widen by adding zero. */
587 outbuf[0] = inbuf[0];
596 if (o_len == 0 || i_len == 0)
599 /* Keep trying with the next char... */
602 } else if (from != CH_UCS2 && to != CH_UCS2) {
603 /* Failed multibyte to multibyte. Just copy 1 char and
605 outbuf[0] = inbuf[0];
613 if (o_len == 0 || i_len == 0)
616 /* Keep trying with the next char... */
620 /* Keep compiler happy.... */
627 * Convert between character sets, allocating a new buffer using talloc for the result.
629 * @param srclen length of source buffer.
630 * @param dest always set at least to NULL
631 * @note -1 is not accepted for srclen.
633 * @returns Size in bytes of the converted string; or -1 in case of error.
635 static size_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to,
636 void const *src, size_t srclen, void **dest)
641 dest_len=convert_string_allocate(ctx, from, to, src, srclen, dest);
642 if (dest_len == (size_t)-1)
649 size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
654 size = push_ucs2_allocate(&buffer, src);
656 smb_panic("failed to create UCS2 buffer");
658 if (!strupper_w(buffer) && (dest == src)) {
663 size = convert_string(CH_UCS2, CH_UNIX, buffer, size, dest, destlen);
669 strdup() a unix string to upper case.
673 char *strdup_upper(const char *s)
676 const unsigned char *p = (const unsigned char *)s;
677 unsigned char *q = (unsigned char *)out_buffer;
679 /* this is quite a common operation, so we want it to be
680 fast. We optimise for the ascii case, knowing that all our
681 supported multi-byte character sets are ascii-compatible
682 (ie. they match for the first 128 chars) */
691 if (p - ( const unsigned char *)s >= sizeof(pstring))
699 size = convert_string(CH_UNIX, CH_UCS2, s, -1, buffer, sizeof(buffer));
706 size = convert_string(CH_UCS2, CH_UNIX, buffer, -1, out_buffer, sizeof(out_buffer));
712 return strdup(out_buffer);
715 size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
718 smb_ucs2_t *buffer = NULL;
720 size = convert_string_allocate(NULL, CH_UNIX, CH_UCS2, src, srclen,
722 if (size == -1 || !buffer) {
723 smb_panic("failed to create UCS2 buffer");
725 if (!strlower_w(buffer) && (dest == src)) {
729 size = convert_string(CH_UCS2, CH_UNIX, buffer, size, dest, destlen);
735 strdup() a unix string to lower case.
738 char *strdup_lower(const char *s)
741 smb_ucs2_t *buffer = NULL;
744 size = push_ucs2_allocate(&buffer, s);
745 if (size == -1 || !buffer) {
751 size = pull_ucs2_allocate(&out_buffer, buffer);
761 static size_t ucs2_align(const void *base_ptr, const void *p, int flags)
763 if (flags & (STR_NOALIGN|STR_ASCII))
765 return PTR_DIFF(p, base_ptr) & 1;
770 * Copy a string from a char* unix src to a dos codepage string destination.
772 * @return the number of bytes occupied by the string in the destination.
774 * @param flags can include
776 * <dt>STR_TERMINATE</dt> <dd>means include the null termination</dd>
777 * <dt>STR_UPPER</dt> <dd>means uppercase in the destination</dd>
780 * @param dest_len the maximum length in bytes allowed in the
781 * destination. If @p dest_len is -1 then no maximum is used.
783 size_t push_ascii(void *dest, const char *src, size_t dest_len, int flags)
785 size_t src_len = strlen(src);
788 /* treat a pstring as "unlimited" length */
789 if (dest_len == (size_t)-1)
790 dest_len = sizeof(pstring);
792 if (flags & STR_UPPER) {
793 pstrcpy(tmpbuf, src);
798 if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII))
801 return convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len);
804 size_t push_ascii_fstring(void *dest, const char *src)
806 return push_ascii(dest, src, sizeof(fstring), STR_TERMINATE);
809 size_t push_ascii_pstring(void *dest, const char *src)
811 return push_ascii(dest, src, sizeof(pstring), STR_TERMINATE);
814 size_t push_ascii_nstring(void *dest, const char *src)
816 return push_ascii(dest, src, sizeof(nstring), STR_TERMINATE);
820 * Copy a string from a dos codepage source to a unix char* destination.
822 * The resulting string in "dest" is always null terminated.
824 * @param flags can have:
826 * <dt>STR_TERMINATE</dt>
827 * <dd>STR_TERMINATE means the string in @p src
828 * is null terminated, and src_len is ignored.</dd>
831 * @param src_len is the length of the source area in bytes.
832 * @returns the number of bytes occupied by the string in @p src.
834 size_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
838 if (dest_len == (size_t)-1)
839 dest_len = sizeof(pstring);
841 if (flags & STR_TERMINATE) {
842 if (src_len == (size_t)-1) {
843 src_len = strlen(src) + 1;
845 size_t len = strnlen(src, src_len);
852 ret = convert_string(CH_DOS, CH_UNIX, src, src_len, dest, dest_len);
855 dest[MIN(ret, dest_len-1)] = 0;
862 size_t pull_ascii_pstring(char *dest, const void *src)
864 return pull_ascii(dest, src, sizeof(pstring), -1, STR_TERMINATE);
867 size_t pull_ascii_fstring(char *dest, const void *src)
869 return pull_ascii(dest, src, sizeof(fstring), -1, STR_TERMINATE);
872 size_t pull_ascii_nstring(char *dest, const void *src)
874 return pull_ascii(dest, src, sizeof(nstring), sizeof(nstring), STR_TERMINATE);
878 * Copy a string from a char* src to a unicode destination.
880 * @returns the number of bytes occupied by the string in the destination.
882 * @param flags can have:
885 * <dt>STR_TERMINATE <dd>means include the null termination.
886 * <dt>STR_UPPER <dd>means uppercase in the destination.
887 * <dt>STR_NOALIGN <dd>means don't do alignment.
890 * @param dest_len is the maximum length allowed in the
891 * destination. If dest_len is -1 then no maxiumum is used.
894 size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags)
899 /* treat a pstring as "unlimited" length */
900 if (dest_len == (size_t)-1)
901 dest_len = sizeof(pstring);
903 if (flags & STR_TERMINATE)
904 src_len = (size_t)-1;
906 src_len = strlen(src);
908 if (ucs2_align(base_ptr, dest, flags)) {
910 dest = (void *)((char *)dest + 1);
916 /* ucs2 is always a multiple of 2 bytes */
919 len += convert_string(CH_UNIX, CH_UCS2, src, src_len, dest, dest_len);
921 if (flags & STR_UPPER) {
922 smb_ucs2_t *dest_ucs2 = dest;
924 for (i = 0; i < (dest_len / 2) && dest_ucs2[i]; i++) {
925 smb_ucs2_t v = toupper_w(dest_ucs2[i]);
926 if (v != dest_ucs2[i]) {
937 * Copy a string from a unix char* src to a UCS2 destination,
938 * allocating a buffer using talloc().
940 * @param dest always set at least to NULL
942 * @returns The number of bytes occupied by the string in the destination
943 * or -1 in case of error.
945 size_t push_ucs2_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src)
947 size_t src_len = strlen(src)+1;
950 return convert_string_talloc(ctx, CH_UNIX, CH_UCS2, src, src_len, (void **)dest);
955 * Copy a string from a unix char* src to a UCS2 destination, allocating a buffer
957 * @param dest always set at least to NULL
959 * @returns The number of bytes occupied by the string in the destination
960 * or -1 in case of error.
963 size_t push_ucs2_allocate(smb_ucs2_t **dest, const char *src)
965 size_t src_len = strlen(src)+1;
968 return convert_string_allocate(NULL, CH_UNIX, CH_UCS2, src, src_len, (void **)dest);
972 Copy a string from a char* src to a UTF-8 destination.
973 Return the number of bytes occupied by the string in the destination
975 STR_TERMINATE means include the null termination
976 STR_UPPER means uppercase in the destination
977 dest_len is the maximum length allowed in the destination. If dest_len
978 is -1 then no maxiumum is used.
981 static size_t push_utf8(void *dest, const char *src, size_t dest_len, int flags)
983 size_t src_len = strlen(src);
986 /* treat a pstring as "unlimited" length */
987 if (dest_len == (size_t)-1)
988 dest_len = sizeof(pstring);
990 if (flags & STR_UPPER) {
991 pstrcpy(tmpbuf, src);
996 if (flags & STR_TERMINATE)
999 return convert_string(CH_UNIX, CH_UTF8, src, src_len, dest, dest_len);
1002 size_t push_utf8_fstring(void *dest, const char *src)
1004 return push_utf8(dest, src, sizeof(fstring), STR_TERMINATE);
1008 * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer using talloc
1010 * @param dest always set at least to NULL
1012 * @returns The number of bytes occupied by the string in the destination
1015 size_t push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
1017 size_t src_len = strlen(src)+1;
1020 return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len, (void**)dest);
1024 * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer
1026 * @param dest always set at least to NULL
1028 * @returns The number of bytes occupied by the string in the destination
1031 size_t push_utf8_allocate(char **dest, const char *src)
1033 size_t src_len = strlen(src)+1;
1036 return convert_string_allocate(NULL, CH_UNIX, CH_UTF8, src, src_len, (void **)dest);
1040 Copy a string from a ucs2 source to a unix char* destination.
1042 STR_TERMINATE means the string in src is null terminated.
1043 STR_NOALIGN means don't try to align.
1044 if STR_TERMINATE is set then src_len is ignored if it is -1.
1045 src_len is the length of the source area in bytes
1046 Return the number of bytes occupied by the string in src.
1047 The resulting string in "dest" is always null terminated.
1050 size_t pull_ucs2(const void *base_ptr, char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
1054 if (dest_len == (size_t)-1)
1055 dest_len = sizeof(pstring);
1057 if (ucs2_align(base_ptr, src, flags)) {
1058 src = (const void *)((const char *)src + 1);
1059 if (src_len != (size_t)-1)
1063 if (flags & STR_TERMINATE) {
1064 /* src_len -1 is the default for null terminated strings. */
1065 if (src_len != (size_t)-1) {
1066 size_t len = strnlen_w(src, src_len/2);
1067 if (len < src_len/2)
1073 /* ucs2 is always a multiple of 2 bytes */
1074 if (src_len != (size_t)-1)
1077 ret = convert_string(CH_UCS2, CH_UNIX, src, src_len, dest, dest_len);
1079 if (src_len == (size_t)-1)
1083 dest[MIN(ret, dest_len-1)] = 0;
1090 size_t pull_ucs2_pstring(char *dest, const void *src)
1092 return pull_ucs2(NULL, dest, src, sizeof(pstring), -1, STR_TERMINATE);
1095 size_t pull_ucs2_fstring(char *dest, const void *src)
1097 return pull_ucs2(NULL, dest, src, sizeof(fstring), -1, STR_TERMINATE);
1101 * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer using talloc
1103 * @param dest always set at least to NULL
1105 * @returns The number of bytes occupied by the string in the destination
1108 size_t pull_ucs2_talloc(TALLOC_CTX *ctx, char **dest, const smb_ucs2_t *src)
1110 size_t src_len = (strlen_w(src)+1) * sizeof(smb_ucs2_t);
1112 return convert_string_talloc(ctx, CH_UCS2, CH_UNIX, src, src_len, (void **)dest);
1116 * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer
1118 * @param dest always set at least to NULL
1120 * @returns The number of bytes occupied by the string in the destination
1123 size_t pull_ucs2_allocate(char **dest, const smb_ucs2_t *src)
1125 size_t src_len = (strlen_w(src)+1) * sizeof(smb_ucs2_t);
1127 return convert_string_allocate(NULL, CH_UCS2, CH_UNIX, src, src_len, (void **)dest);
1131 * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc
1133 * @param dest always set at least to NULL
1135 * @returns The number of bytes occupied by the string in the destination
1138 size_t pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
1140 size_t src_len = strlen(src)+1;
1142 return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len, (void **)dest);
1146 * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer
1148 * @param dest always set at least to NULL
1150 * @returns The number of bytes occupied by the string in the destination
1153 size_t pull_utf8_allocate(char **dest, const char *src)
1155 size_t src_len = strlen(src)+1;
1157 return convert_string_allocate(NULL, CH_UTF8, CH_UNIX, src, src_len, (void **)dest);
1161 Copy a string from a char* src to a unicode or ascii
1162 dos codepage destination choosing unicode or ascii based on the
1163 flags in the SMB buffer starting at base_ptr.
1164 Return the number of bytes occupied by the string in the destination.
1166 STR_TERMINATE means include the null termination.
1167 STR_UPPER means uppercase in the destination.
1168 STR_ASCII use ascii even with unicode packet.
1169 STR_NOALIGN means don't do alignment.
1170 dest_len is the maximum length allowed in the destination. If dest_len
1171 is -1 then no maxiumum is used.
1174 size_t push_string_fn(const char *function, unsigned int line, const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags)
1177 /* We really need to zero fill here, not clobber
1178 * region, as we want to ensure that valgrind thinks
1179 * all of the outgoing buffer has been written to
1180 * so a send() or write() won't trap an error.
1184 if (dest_len != (size_t)-1)
1185 clobber_region(function, line, dest, dest_len);
1187 if (dest_len != (size_t)-1)
1188 memset(dest, '\0', dest_len);
1192 if (!(flags & STR_ASCII) && \
1193 ((flags & STR_UNICODE || \
1194 (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) {
1195 return push_ucs2(base_ptr, dest, src, dest_len, flags);
1197 return push_ascii(dest, src, dest_len, flags);
1202 Copy a string from a unicode or ascii source (depending on
1203 the packet flags) to a char* destination.
1205 STR_TERMINATE means the string in src is null terminated.
1206 STR_UNICODE means to force as unicode.
1207 STR_ASCII use ascii even with unicode packet.
1208 STR_NOALIGN means don't do alignment.
1209 if STR_TERMINATE is set then src_len is ignored is it is -1
1210 src_len is the length of the source area in bytes.
1211 Return the number of bytes occupied by the string in src.
1212 The resulting string in "dest" is always null terminated.
1215 size_t pull_string_fn(const char *function, unsigned int line, const void *base_ptr, char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
1218 if (dest_len != (size_t)-1)
1219 clobber_region(function, line, dest, dest_len);
1222 if (!(flags & STR_ASCII) && \
1223 ((flags & STR_UNICODE || \
1224 (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) {
1225 return pull_ucs2(base_ptr, dest, src, dest_len, src_len, flags);
1227 return pull_ascii(dest, src, dest_len, src_len, flags);
1230 size_t align_string(const void *base_ptr, const char *p, int flags)
1232 if (!(flags & STR_ASCII) && \
1233 ((flags & STR_UNICODE || \
1234 (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) {
1235 return ucs2_align(base_ptr, p, flags);