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 ? */
44 /* Unsafe unix charsets which could contain '\\' as second byte of mb character */
45 static const char *conv_unsafe_charsets
[] = {
49 /* Global variable which is set to True in init_iconv() if unix charset is unsafe
50 w.r.t. '\\' in second byte of mb character. Otherwise it is set to False.
52 BOOL is_unix_charset_unsafe
;
55 * Return the name of a charset to give to iconv().
57 static const char *charset_name(charset_t ch
)
59 const char *ret
= NULL
;
61 if (ch
== CH_UCS2
) ret
= "UCS-2LE";
62 else if (ch
== CH_UNIX
) ret
= lp_unix_charset();
63 else if (ch
== CH_DOS
) ret
= lp_dos_charset();
64 else if (ch
== CH_DISPLAY
) ret
= lp_display_charset();
65 else if (ch
== CH_UTF8
) ret
= "UTF8";
67 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
68 if (ret
&& !strcmp(ret
, "LOCALE")) {
69 const char *ln
= NULL
;
72 setlocale(LC_ALL
, "");
74 ln
= nl_langinfo(CODESET
);
76 /* Check whether the charset name is supported
78 smb_iconv_t handle
= smb_iconv_open(ln
,"UCS-2LE");
79 if (handle
== (smb_iconv_t
) -1) {
80 DEBUG(5,("Locale charset '%s' unsupported, using ASCII instead\n", ln
));
83 DEBUG(5,("Substituting charset '%s' for LOCALE\n", ln
));
84 smb_iconv_close(handle
);
91 if (!ret
|| !*ret
) ret
= "ASCII";
95 void lazy_initialize_conv(void)
97 static int initialized
= False
;
107 * Initialize iconv conversion descriptors.
109 * This is called the first time it is needed, and also called again
110 * every time the configuration is reloaded, because the charset or
111 * codepage might have changed.
113 void init_iconv(void)
116 BOOL did_reload
= False
;
117 const char **unsafe_charset
= conv_unsafe_charsets
;
119 /* so that charset_name() works we need to get the UNIX<->UCS2 going
121 if (!conv_handles
[CH_UNIX
][CH_UCS2
])
122 conv_handles
[CH_UNIX
][CH_UCS2
] = smb_iconv_open("UCS-2LE", "ASCII");
124 if (!conv_handles
[CH_UCS2
][CH_UNIX
])
125 conv_handles
[CH_UCS2
][CH_UNIX
] = smb_iconv_open("ASCII", "UCS-2LE");
127 for (c1
=0;c1
<NUM_CHARSETS
;c1
++) {
128 for (c2
=0;c2
<NUM_CHARSETS
;c2
++) {
129 const char *n1
= charset_name((charset_t
)c1
);
130 const char *n2
= charset_name((charset_t
)c2
);
131 if (conv_handles
[c1
][c2
] &&
132 strcmp(n1
, conv_handles
[c1
][c2
]->from_name
) == 0 &&
133 strcmp(n2
, conv_handles
[c1
][c2
]->to_name
) == 0)
138 if (conv_handles
[c1
][c2
])
139 smb_iconv_close(conv_handles
[c1
][c2
]);
141 conv_handles
[c1
][c2
] = smb_iconv_open(n2
,n1
);
142 if (conv_handles
[c1
][c2
] == (smb_iconv_t
)-1) {
143 DEBUG(0,("Conversion from %s to %s not supported\n",
144 charset_name((charset_t
)c1
), charset_name((charset_t
)c2
)));
145 conv_handles
[c1
][c2
] = NULL
;
151 /* XXX: Does this really get called every time the dos
152 * codepage changes? */
153 /* XXX: Is the did_reload test too strict? */
155 init_doschar_table();
160 while(*unsafe_charset
&& strcmp(*unsafe_charset
, conv_handles
[CH_UCS2
][CH_UNIX
]->to_name
)) {
164 if (*unsafe_charset
) {
165 is_unix_charset_unsafe
= True
;
167 is_unix_charset_unsafe
= False
;
172 * Convert string from one encoding to another, making error checking etc
173 * Slow path version - uses (slow) iconv.
175 * @param src pointer to source string (multibyte or singlebyte)
176 * @param srclen length of the source string in bytes
177 * @param dest pointer to destination string (multibyte or singlebyte)
178 * @param destlen maximal length allowed for string
179 * @param allow_bad_conv determines if a "best effort" conversion is acceptable (never returns errors)
180 * @returns the number of bytes occupied in the destination
182 * Ensure the srclen contains the terminating zero.
186 static size_t convert_string_internal(charset_t from
, charset_t to
,
187 void const *src
, size_t srclen
,
188 void *dest
, size_t destlen
, BOOL allow_bad_conv
)
192 const char* inbuf
= (const char*)src
;
193 char* outbuf
= (char*)dest
;
194 smb_iconv_t descriptor
;
196 lazy_initialize_conv();
198 descriptor
= conv_handles
[from
][to
];
200 if (srclen
== (size_t)-1) {
201 if (from
== CH_UCS2
) {
202 srclen
= (strlen_w((const smb_ucs2_t
*)src
)+1) * 2;
204 srclen
= strlen((const char *)src
)+1;
209 if (descriptor
== (smb_iconv_t
)-1 || descriptor
== (smb_iconv_t
)0) {
211 DEBUG(0,("convert_string_internal: Conversion not supported.\n"));
220 retval
= smb_iconv(descriptor
, (char **)&inbuf
, &i_len
, &outbuf
, &o_len
);
221 if(retval
==(size_t)-1) {
222 const char *reason
="unknown error";
225 reason
="Incomplete multibyte sequence";
227 DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason
,inbuf
));
232 reason
="No more room";
234 DEBUG(3, ("convert_string_internal: Required %lu, available %lu\n",
235 (unsigned long)srclen
, (unsigned long)destlen
));
236 /* we are not sure we need srclen bytes,
237 may be more, may be less.
238 We only know we need more than destlen
242 reason
="Illegal multibyte sequence";
244 DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason
,inbuf
));
250 DEBUG(0,("convert_string_internal: Conversion error: %s(%s)\n",reason
,inbuf
));
253 /* smb_panic(reason); */
255 return destlen
-o_len
;
260 * Conversion not supported. This is actually an error, but there are so
261 * many misconfigured iconv systems and smb.conf's out there we can't just
262 * fail. Do a very bad conversion instead.... JRA.
266 if (o_len
== 0 || i_len
== 0)
267 return destlen
- o_len
;
269 if (from
== CH_UCS2
&& to
!= CH_UCS2
) {
270 /* Can't convert from ucs2 to multibyte. Just truncate this char to ascii. */
272 return destlen
- o_len
;
283 if (o_len
== 0 || i_len
== 0)
284 return destlen
- o_len
;
286 /* Keep trying with the next char... */
289 } else if (from
!= CH_UCS2
&& to
== CH_UCS2
) {
290 /* Can't convert to ucs2 - just widen by adding zero. */
292 return destlen
- o_len
;
294 outbuf
[0] = inbuf
[0];
303 if (o_len
== 0 || i_len
== 0)
304 return destlen
- o_len
;
306 /* Keep trying with the next char... */
309 } else if (from
!= CH_UCS2
&& to
!= CH_UCS2
) {
310 /* Failed multibyte to multibyte. Just copy 1 char and
312 outbuf
[0] = inbuf
[0];
320 if (o_len
== 0 || i_len
== 0)
321 return destlen
- o_len
;
323 /* Keep trying with the next char... */
327 /* Keep compiler happy.... */
328 return destlen
- o_len
;
334 * Convert string from one encoding to another, making error checking etc
335 * Fast path version - handles ASCII first.
337 * @param src pointer to source string (multibyte or singlebyte)
338 * @param srclen length of the source string in bytes, or -1 for nul terminated.
339 * @param dest pointer to destination string (multibyte or singlebyte)
340 * @param destlen maximal length allowed for string - *NEVER* -1.
341 * @param allow_bad_conv determines if a "best effort" conversion is acceptable (never returns errors)
342 * @returns the number of bytes occupied in the destination
344 * Ensure the srclen contains the terminating zero.
346 * This function has been hand-tuned to provide a fast path.
347 * Don't change unless you really know what you are doing. JRA.
350 size_t convert_string(charset_t from
, charset_t to
,
351 void const *src
, size_t srclen
,
352 void *dest
, size_t destlen
, BOOL allow_bad_conv
)
355 * NB. We deliberately don't do a strlen here if srclen == -1.
356 * This is very expensive over millions of calls and is taken
357 * care of in the slow path in convert_string_internal. JRA.
361 SMB_ASSERT(destlen
!= (size_t)-1);
367 if (from
!= CH_UCS2
&& to
!= CH_UCS2
) {
368 const unsigned char *p
= (const unsigned char *)src
;
369 unsigned char *q
= (unsigned char *)dest
;
370 size_t slen
= srclen
;
371 size_t dlen
= destlen
;
375 /* If all characters are ascii, fast path here. */
376 while (slen
&& dlen
) {
377 if ((lastp
= *p
) <= 0x7f) {
379 if (slen
!= (size_t)-1) {
387 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
390 return retval
+ convert_string_internal(from
, to
, p
, slen
, q
, dlen
, allow_bad_conv
);
395 } else if (from
== CH_UCS2
&& to
!= CH_UCS2
) {
396 const unsigned char *p
= (const unsigned char *)src
;
397 unsigned char *q
= (unsigned char *)dest
;
399 size_t slen
= srclen
;
400 size_t dlen
= destlen
;
403 /* If all characters are ascii, fast path here. */
404 while (((slen
== (size_t)-1) || (slen
>= 2)) && dlen
) {
405 if (((lastp
= *p
) <= 0x7f) && (p
[1] == 0)) {
407 if (slen
!= (size_t)-1) {
416 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
419 return retval
+ convert_string_internal(from
, to
, p
, slen
, q
, dlen
, allow_bad_conv
);
424 } else if (from
!= CH_UCS2
&& to
== CH_UCS2
) {
425 const unsigned char *p
= (const unsigned char *)src
;
426 unsigned char *q
= (unsigned char *)dest
;
428 size_t slen
= srclen
;
429 size_t dlen
= destlen
;
432 /* If all characters are ascii, fast path here. */
433 while (slen
&& (dlen
>= 2)) {
434 if ((lastp
= *p
) <= 0x7F) {
437 if (slen
!= (size_t)-1) {
445 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
448 return retval
+ convert_string_internal(from
, to
, p
, slen
, q
, dlen
, allow_bad_conv
);
455 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
458 return convert_string_internal(from
, to
, src
, srclen
, dest
, destlen
, allow_bad_conv
);
462 * Convert between character sets, allocating a new buffer for the result.
464 * @param ctx TALLOC_CTX to use to allocate with. If NULL use malloc.
465 * @param srclen length of source buffer.
466 * @param dest always set at least to NULL
467 * @note -1 is not accepted for srclen.
469 * @returns Size in bytes of the converted string; or -1 in case of error.
471 * Ensure the srclen contains the terminating zero.
473 * I hate the goto's in this function. It's embarressing.....
474 * There has to be a cleaner way to do this. JRA.
477 size_t convert_string_allocate(TALLOC_CTX
*ctx
, charset_t from
, charset_t to
,
478 void const *src
, size_t srclen
, void **dest
, BOOL allow_bad_conv
)
480 size_t i_len
, o_len
, destlen
= MAX(srclen
, 512);
482 const char *inbuf
= (const char *)src
;
483 char *outbuf
= NULL
, *ob
= NULL
;
484 smb_iconv_t descriptor
;
488 if (src
== NULL
|| srclen
== (size_t)-1)
493 lazy_initialize_conv();
495 descriptor
= conv_handles
[from
][to
];
497 if (descriptor
== (smb_iconv_t
)-1 || descriptor
== (smb_iconv_t
)0) {
499 DEBUG(0,("convert_string_allocate: Conversion not supported.\n"));
507 if ((destlen
*2) < destlen
) {
508 /* wrapped ! abort. */
510 DEBUG(0, ("convert_string_allocate: destlen wrapped !\n"));
515 destlen
= destlen
* 2;
519 ob
= (char *)talloc_realloc(ctx
, ob
, destlen
);
521 ob
= (char *)Realloc(ob
, destlen
);
524 DEBUG(0, ("convert_string_allocate: realloc failed!\n"));
536 retval
= smb_iconv(descriptor
,
537 (char **)&inbuf
, &i_len
,
539 if(retval
== (size_t)-1) {
540 const char *reason
="unknown error";
543 reason
="Incomplete multibyte sequence";
545 DEBUG(3,("convert_string_allocate: Conversion error: %s(%s)\n",reason
,inbuf
));
552 reason
="Illegal multibyte sequence";
554 DEBUG(3,("convert_string_allocate: Conversion error: %s(%s)\n",reason
,inbuf
));
560 DEBUG(0,("Conversion error: %s(%s)\n",reason
,inbuf
));
561 /* smb_panic(reason); */
567 destlen
= destlen
- o_len
;
569 *dest
= (char *)talloc_realloc(ctx
,ob
,destlen
);
571 *dest
= (char *)Realloc(ob
,destlen
);
572 if (destlen
&& !*dest
) {
573 DEBUG(0, ("convert_string_allocate: out of memory!\n"));
584 * Conversion not supported. This is actually an error, but there are so
585 * many misconfigured iconv systems and smb.conf's out there we can't just
586 * fail. Do a very bad conversion instead.... JRA.
590 if (o_len
== 0 || i_len
== 0)
593 if (from
== CH_UCS2
&& to
!= CH_UCS2
) {
594 /* Can't convert from ucs2 to multibyte. Just truncate this char to ascii. */
608 if (o_len
== 0 || i_len
== 0)
611 /* Keep trying with the next char... */
614 } else if (from
!= CH_UCS2
&& to
== CH_UCS2
) {
615 /* Can't convert to ucs2 - just widen by adding zero. */
619 outbuf
[0] = inbuf
[0];
628 if (o_len
== 0 || i_len
== 0)
631 /* Keep trying with the next char... */
634 } else if (from
!= CH_UCS2
&& to
!= CH_UCS2
) {
635 /* Failed multibyte to multibyte. Just copy 1 char and
637 outbuf
[0] = inbuf
[0];
645 if (o_len
== 0 || i_len
== 0)
648 /* Keep trying with the next char... */
652 /* Keep compiler happy.... */
659 * Convert between character sets, allocating a new buffer using talloc for the result.
661 * @param srclen length of source buffer.
662 * @param dest always set at least to NULL
663 * @note -1 is not accepted for srclen.
665 * @returns Size in bytes of the converted string; or -1 in case of error.
667 static size_t convert_string_talloc(TALLOC_CTX
*ctx
, charset_t from
, charset_t to
,
668 void const *src
, size_t srclen
, void **dest
, BOOL allow_bad_conv
)
673 dest_len
=convert_string_allocate(ctx
, from
, to
, src
, srclen
, dest
, allow_bad_conv
);
674 if (dest_len
== (size_t)-1)
681 size_t unix_strupper(const char *src
, size_t srclen
, char *dest
, size_t destlen
)
686 size
= push_ucs2_allocate(&buffer
, src
);
687 if (size
== (size_t)-1) {
688 smb_panic("failed to create UCS2 buffer");
690 if (!strupper_w(buffer
) && (dest
== src
)) {
695 size
= convert_string(CH_UCS2
, CH_UNIX
, buffer
, size
, dest
, destlen
, True
);
701 strdup() a unix string to upper case.
705 char *strdup_upper(const char *s
)
708 const unsigned char *p
= (const unsigned char *)s
;
709 unsigned char *q
= (unsigned char *)out_buffer
;
711 /* this is quite a common operation, so we want it to be
712 fast. We optimise for the ascii case, knowing that all our
713 supported multi-byte character sets are ascii-compatible
714 (ie. they match for the first 128 chars) */
723 if (p
- ( const unsigned char *)s
>= sizeof(pstring
))
731 size
= convert_string(CH_UNIX
, CH_UCS2
, s
, -1, buffer
, sizeof(buffer
), True
);
732 if (size
== (size_t)-1) {
738 size
= convert_string(CH_UCS2
, CH_UNIX
, buffer
, -1, out_buffer
, sizeof(out_buffer
), True
);
739 if (size
== (size_t)-1) {
744 return strdup(out_buffer
);
747 size_t unix_strlower(const char *src
, size_t srclen
, char *dest
, size_t destlen
)
750 smb_ucs2_t
*buffer
= NULL
;
752 size
= convert_string_allocate(NULL
, CH_UNIX
, CH_UCS2
, src
, srclen
,
753 (void **) &buffer
, True
);
754 if (size
== (size_t)-1 || !buffer
) {
755 smb_panic("failed to create UCS2 buffer");
757 if (!strlower_w(buffer
) && (dest
== src
)) {
761 size
= convert_string(CH_UCS2
, CH_UNIX
, buffer
, size
, dest
, destlen
, True
);
767 strdup() a unix string to lower case.
770 char *strdup_lower(const char *s
)
773 smb_ucs2_t
*buffer
= NULL
;
776 size
= push_ucs2_allocate(&buffer
, s
);
777 if (size
== -1 || !buffer
) {
783 size
= pull_ucs2_allocate(&out_buffer
, buffer
);
786 if (size
== (size_t)-1) {
793 static size_t ucs2_align(const void *base_ptr
, const void *p
, int flags
)
795 if (flags
& (STR_NOALIGN
|STR_ASCII
))
797 return PTR_DIFF(p
, base_ptr
) & 1;
802 * Copy a string from a char* unix src to a dos codepage string destination.
804 * @return the number of bytes occupied by the string in the destination.
806 * @param flags can include
808 * <dt>STR_TERMINATE</dt> <dd>means include the null termination</dd>
809 * <dt>STR_UPPER</dt> <dd>means uppercase in the destination</dd>
812 * @param dest_len the maximum length in bytes allowed in the
813 * destination. If @p dest_len is -1 then no maximum is used.
815 size_t push_ascii(void *dest
, const char *src
, size_t dest_len
, int flags
)
817 size_t src_len
= strlen(src
);
820 /* treat a pstring as "unlimited" length */
821 if (dest_len
== (size_t)-1)
822 dest_len
= sizeof(pstring
);
824 if (flags
& STR_UPPER
) {
825 pstrcpy(tmpbuf
, src
);
830 if (flags
& (STR_TERMINATE
| STR_TERMINATE_ASCII
))
833 return convert_string(CH_UNIX
, CH_DOS
, src
, src_len
, dest
, dest_len
, True
);
836 size_t push_ascii_fstring(void *dest
, const char *src
)
838 return push_ascii(dest
, src
, sizeof(fstring
), STR_TERMINATE
);
841 size_t push_ascii_pstring(void *dest
, const char *src
)
843 return push_ascii(dest
, src
, sizeof(pstring
), STR_TERMINATE
);
846 /********************************************************************
847 Push an nstring - ensure null terminated. Written by
848 moriyama@miraclelinux.com (MORIYAMA Masayuki).
849 ********************************************************************/
851 size_t push_ascii_nstring(void *dest
, const char *src
)
853 size_t i
, buffer_len
, dest_len
;
857 buffer_len
= push_ucs2_allocate(&buffer
, src
);
858 if (buffer_len
== (size_t)-1) {
859 smb_panic("failed to create UCS2 buffer");
863 for (i
= 0; buffer
[i
] != 0 && (i
< buffer_len
); i
++) {
864 unsigned char mb
[10];
865 /* Convert one smb_ucs2_t character at a time. */
866 size_t mb_len
= convert_string(CH_UCS2
, CH_DOS
, buffer
+i
, sizeof(smb_ucs2_t
), mb
, sizeof(mb
), False
);
867 if ((mb_len
!= (size_t)-1) && (dest_len
+ mb_len
<= MAX_NETBIOSNAME_LEN
- 1)) {
868 memcpy((char *)dest
+ dest_len
, mb
, mb_len
);
875 ((char *)dest
)[dest_len
] = '\0';
883 * Copy a string from a dos codepage source to a unix char* destination.
885 * The resulting string in "dest" is always null terminated.
887 * @param flags can have:
889 * <dt>STR_TERMINATE</dt>
890 * <dd>STR_TERMINATE means the string in @p src
891 * is null terminated, and src_len is ignored.</dd>
894 * @param src_len is the length of the source area in bytes.
895 * @returns the number of bytes occupied by the string in @p src.
897 size_t pull_ascii(char *dest
, const void *src
, size_t dest_len
, size_t src_len
, int flags
)
901 if (dest_len
== (size_t)-1)
902 dest_len
= sizeof(pstring
);
904 if (flags
& STR_TERMINATE
) {
905 if (src_len
== (size_t)-1) {
906 src_len
= strlen(src
) + 1;
908 size_t len
= strnlen(src
, src_len
);
915 ret
= convert_string(CH_DOS
, CH_UNIX
, src
, src_len
, dest
, dest_len
, True
);
916 if (ret
== (size_t)-1) {
921 dest
[MIN(ret
, dest_len
-1)] = 0;
928 size_t pull_ascii_pstring(char *dest
, const void *src
)
930 return pull_ascii(dest
, src
, sizeof(pstring
), -1, STR_TERMINATE
);
933 size_t pull_ascii_fstring(char *dest
, const void *src
)
935 return pull_ascii(dest
, src
, sizeof(fstring
), -1, STR_TERMINATE
);
938 /* When pulling an nstring it can expand into a larger size (dos cp -> utf8). Cope with this. */
940 size_t pull_ascii_nstring(char *dest
, size_t dest_len
, const void *src
)
942 return pull_ascii(dest
, src
, dest_len
, sizeof(nstring
), STR_TERMINATE
);
946 * Copy a string from a char* src to a unicode destination.
948 * @returns the number of bytes occupied by the string in the destination.
950 * @param flags can have:
953 * <dt>STR_TERMINATE <dd>means include the null termination.
954 * <dt>STR_UPPER <dd>means uppercase in the destination.
955 * <dt>STR_NOALIGN <dd>means don't do alignment.
958 * @param dest_len is the maximum length allowed in the
959 * destination. If dest_len is -1 then no maxiumum is used.
962 size_t push_ucs2(const void *base_ptr
, void *dest
, const char *src
, size_t dest_len
, int flags
)
968 /* treat a pstring as "unlimited" length */
969 if (dest_len
== (size_t)-1)
970 dest_len
= sizeof(pstring
);
972 if (flags
& STR_TERMINATE
)
973 src_len
= (size_t)-1;
975 src_len
= strlen(src
);
977 if (ucs2_align(base_ptr
, dest
, flags
)) {
979 dest
= (void *)((char *)dest
+ 1);
985 /* ucs2 is always a multiple of 2 bytes */
988 ret
= convert_string(CH_UNIX
, CH_UCS2
, src
, src_len
, dest
, dest_len
, True
);
989 if (ret
== (size_t)-1) {
995 if (flags
& STR_UPPER
) {
996 smb_ucs2_t
*dest_ucs2
= dest
;
998 for (i
= 0; i
< (dest_len
/ 2) && dest_ucs2
[i
]; i
++) {
999 smb_ucs2_t v
= toupper_w(dest_ucs2
[i
]);
1000 if (v
!= dest_ucs2
[i
]) {
1011 * Copy a string from a unix char* src to a UCS2 destination,
1012 * allocating a buffer using talloc().
1014 * @param dest always set at least to NULL
1016 * @returns The number of bytes occupied by the string in the destination
1017 * or -1 in case of error.
1019 size_t push_ucs2_talloc(TALLOC_CTX
*ctx
, smb_ucs2_t
**dest
, const char *src
)
1021 size_t src_len
= strlen(src
)+1;
1024 return convert_string_talloc(ctx
, CH_UNIX
, CH_UCS2
, src
, src_len
, (void **)dest
, True
);
1029 * Copy a string from a unix char* src to a UCS2 destination, allocating a buffer
1031 * @param dest always set at least to NULL
1033 * @returns The number of bytes occupied by the string in the destination
1034 * or -1 in case of error.
1037 size_t push_ucs2_allocate(smb_ucs2_t
**dest
, const char *src
)
1039 size_t src_len
= strlen(src
)+1;
1042 return convert_string_allocate(NULL
, CH_UNIX
, CH_UCS2
, src
, src_len
, (void **)dest
, True
);
1046 Copy a string from a char* src to a UTF-8 destination.
1047 Return the number of bytes occupied by the string in the destination
1049 STR_TERMINATE means include the null termination
1050 STR_UPPER means uppercase in the destination
1051 dest_len is the maximum length allowed in the destination. If dest_len
1052 is -1 then no maxiumum is used.
1055 static size_t push_utf8(void *dest
, const char *src
, size_t dest_len
, int flags
)
1057 size_t src_len
= strlen(src
);
1060 /* treat a pstring as "unlimited" length */
1061 if (dest_len
== (size_t)-1)
1062 dest_len
= sizeof(pstring
);
1064 if (flags
& STR_UPPER
) {
1065 pstrcpy(tmpbuf
, src
);
1070 if (flags
& STR_TERMINATE
)
1073 return convert_string(CH_UNIX
, CH_UTF8
, src
, src_len
, dest
, dest_len
, True
);
1076 size_t push_utf8_fstring(void *dest
, const char *src
)
1078 return push_utf8(dest
, src
, sizeof(fstring
), STR_TERMINATE
);
1082 * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer using talloc
1084 * @param dest always set at least to NULL
1086 * @returns The number of bytes occupied by the string in the destination
1089 size_t push_utf8_talloc(TALLOC_CTX
*ctx
, char **dest
, const char *src
)
1091 size_t src_len
= strlen(src
)+1;
1094 return convert_string_talloc(ctx
, CH_UNIX
, CH_UTF8
, src
, src_len
, (void**)dest
, True
);
1098 * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer
1100 * @param dest always set at least to NULL
1102 * @returns The number of bytes occupied by the string in the destination
1105 size_t push_utf8_allocate(char **dest
, const char *src
)
1107 size_t src_len
= strlen(src
)+1;
1110 return convert_string_allocate(NULL
, CH_UNIX
, CH_UTF8
, src
, src_len
, (void **)dest
, True
);
1114 Copy a string from a ucs2 source to a unix char* destination.
1116 STR_TERMINATE means the string in src is null terminated.
1117 STR_NOALIGN means don't try to align.
1118 if STR_TERMINATE is set then src_len is ignored if it is -1.
1119 src_len is the length of the source area in bytes
1120 Return the number of bytes occupied by the string in src.
1121 The resulting string in "dest" is always null terminated.
1124 size_t pull_ucs2(const void *base_ptr
, char *dest
, const void *src
, size_t dest_len
, size_t src_len
, int flags
)
1128 if (dest_len
== (size_t)-1)
1129 dest_len
= sizeof(pstring
);
1131 if (ucs2_align(base_ptr
, src
, flags
)) {
1132 src
= (const void *)((const char *)src
+ 1);
1133 if (src_len
!= (size_t)-1)
1137 if (flags
& STR_TERMINATE
) {
1138 /* src_len -1 is the default for null terminated strings. */
1139 if (src_len
!= (size_t)-1) {
1140 size_t len
= strnlen_w(src
, src_len
/2);
1141 if (len
< src_len
/2)
1147 /* ucs2 is always a multiple of 2 bytes */
1148 if (src_len
!= (size_t)-1)
1151 ret
= convert_string(CH_UCS2
, CH_UNIX
, src
, src_len
, dest
, dest_len
, True
);
1152 if (ret
== (size_t)-1) {
1156 if (src_len
== (size_t)-1)
1160 dest
[MIN(ret
, dest_len
-1)] = 0;
1167 size_t pull_ucs2_pstring(char *dest
, const void *src
)
1169 return pull_ucs2(NULL
, dest
, src
, sizeof(pstring
), -1, STR_TERMINATE
);
1172 size_t pull_ucs2_fstring(char *dest
, const void *src
)
1174 return pull_ucs2(NULL
, dest
, src
, sizeof(fstring
), -1, STR_TERMINATE
);
1178 * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer using talloc
1180 * @param dest always set at least to NULL
1182 * @returns The number of bytes occupied by the string in the destination
1185 size_t pull_ucs2_talloc(TALLOC_CTX
*ctx
, char **dest
, const smb_ucs2_t
*src
)
1187 size_t src_len
= (strlen_w(src
)+1) * sizeof(smb_ucs2_t
);
1189 return convert_string_talloc(ctx
, CH_UCS2
, CH_UNIX
, src
, src_len
, (void **)dest
, True
);
1193 * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer
1195 * @param dest always set at least to NULL
1197 * @returns The number of bytes occupied by the string in the destination
1200 size_t pull_ucs2_allocate(char **dest
, const smb_ucs2_t
*src
)
1202 size_t src_len
= (strlen_w(src
)+1) * sizeof(smb_ucs2_t
);
1204 return convert_string_allocate(NULL
, CH_UCS2
, CH_UNIX
, src
, src_len
, (void **)dest
, True
);
1208 * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc
1210 * @param dest always set at least to NULL
1212 * @returns The number of bytes occupied by the string in the destination
1215 size_t pull_utf8_talloc(TALLOC_CTX
*ctx
, char **dest
, const char *src
)
1217 size_t src_len
= strlen(src
)+1;
1219 return convert_string_talloc(ctx
, CH_UTF8
, CH_UNIX
, src
, src_len
, (void **)dest
, True
);
1223 * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer
1225 * @param dest always set at least to NULL
1227 * @returns The number of bytes occupied by the string in the destination
1230 size_t pull_utf8_allocate(char **dest
, const char *src
)
1232 size_t src_len
= strlen(src
)+1;
1234 return convert_string_allocate(NULL
, CH_UTF8
, CH_UNIX
, src
, src_len
, (void **)dest
, True
);
1238 Copy a string from a char* src to a unicode or ascii
1239 dos codepage destination choosing unicode or ascii based on the
1240 flags in the SMB buffer starting at base_ptr.
1241 Return the number of bytes occupied by the string in the destination.
1243 STR_TERMINATE means include the null termination.
1244 STR_UPPER means uppercase in the destination.
1245 STR_ASCII use ascii even with unicode packet.
1246 STR_NOALIGN means don't do alignment.
1247 dest_len is the maximum length allowed in the destination. If dest_len
1248 is -1 then no maxiumum is used.
1251 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
)
1254 /* We really need to zero fill here, not clobber
1255 * region, as we want to ensure that valgrind thinks
1256 * all of the outgoing buffer has been written to
1257 * so a send() or write() won't trap an error.
1261 if (dest_len
!= (size_t)-1)
1262 clobber_region(function
, line
, dest
, dest_len
);
1264 if (dest_len
!= (size_t)-1)
1265 memset(dest
, '\0', dest_len
);
1269 if (!(flags
& STR_ASCII
) && \
1270 ((flags
& STR_UNICODE
|| \
1271 (SVAL(base_ptr
, smb_flg2
) & FLAGS2_UNICODE_STRINGS
)))) {
1272 return push_ucs2(base_ptr
, dest
, src
, dest_len
, flags
);
1274 return push_ascii(dest
, src
, dest_len
, flags
);
1279 Copy a string from a unicode or ascii source (depending on
1280 the packet flags) to a char* destination.
1282 STR_TERMINATE means the string in src is null terminated.
1283 STR_UNICODE means to force as unicode.
1284 STR_ASCII use ascii even with unicode packet.
1285 STR_NOALIGN means don't do alignment.
1286 if STR_TERMINATE is set then src_len is ignored is it is -1
1287 src_len is the length of the source area in bytes.
1288 Return the number of bytes occupied by the string in src.
1289 The resulting string in "dest" is always null terminated.
1292 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
)
1295 if (dest_len
!= (size_t)-1)
1296 clobber_region(function
, line
, dest
, dest_len
);
1299 if (!(flags
& STR_ASCII
) && \
1300 ((flags
& STR_UNICODE
|| \
1301 (SVAL(base_ptr
, smb_flg2
) & FLAGS2_UNICODE_STRINGS
)))) {
1302 return pull_ucs2(base_ptr
, dest
, src
, dest_len
, src_len
, flags
);
1304 return pull_ascii(dest
, src
, dest_len
, src_len
, flags
);
1307 size_t align_string(const void *base_ptr
, const char *p
, int flags
)
1309 if (!(flags
& STR_ASCII
) && \
1310 ((flags
& STR_UNICODE
|| \
1311 (SVAL(base_ptr
, smb_flg2
) & FLAGS2_UNICODE_STRINGS
)))) {
1312 return ucs2_align(base_ptr
, p
, flags
);