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;
187 if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
189 DEBUG(0,("convert_string_internal: Conversion not supported.\n"));
195 retval = smb_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len);
196 if(retval==(size_t)-1) {
197 const char *reason="unknown error";
200 reason="Incomplete multibyte sequence";
202 DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
205 reason="No more room";
207 DEBUG(3, ("convert_string_internal: Required %lu, available %lu\n",
208 (unsigned long)srclen, (unsigned long)destlen));
209 /* we are not sure we need srclen bytes,
210 may be more, may be less.
211 We only know we need more than destlen
215 reason="Illegal multibyte sequence";
217 DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
221 DEBUG(0,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
224 /* smb_panic(reason); */
226 return destlen-o_len;
230 /* conversion not supported, use as is */
232 size_t len = MIN(srclen,destlen);
234 memcpy(dest,src,len);
240 * Convert string from one encoding to another, making error checking etc
241 * Fast path version - handles ASCII first.
243 * @param src pointer to source string (multibyte or singlebyte)
244 * @param srclen length of the source string in bytes
245 * @param dest pointer to destination string (multibyte or singlebyte)
246 * @param destlen maximal length allowed for string
247 * @returns the number of bytes occupied in the destination
249 * Ensure the srclen contains the terminating zero.
251 * This function has been hand-tuned to provide a fast path.
252 * Don't change unless you really know what you are doing. JRA.
255 size_t convert_string(charset_t from, charset_t to,
256 void const *src, size_t srclen,
257 void *dest, size_t destlen)
260 * NB. We deliberately don't do a strlen here is srclen == -1.
261 * This is very expensive over millions of calls and is taken
262 * care of in the slow path in convert_string_internal. JRA.
268 if (from != CH_UCS2 && to != CH_UCS2) {
269 const unsigned char *p = (const unsigned char *)src;
270 unsigned char *q = (unsigned char *)dest;
271 size_t slen = srclen;
272 size_t dlen = destlen;
276 /* If all characters are ascii, fast path here. */
277 while (slen && dlen) {
278 if ((lastp = *p) <= 0x7f) {
280 if (slen != (size_t)-1) {
288 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
291 return retval + convert_string_internal(from, to, p, slen, q, dlen);
296 } else if (from == CH_UCS2 && to != CH_UCS2) {
297 const unsigned char *p = (const unsigned char *)src;
298 unsigned char *q = (unsigned char *)dest;
300 size_t slen = srclen;
301 size_t dlen = destlen;
304 /* If all characters are ascii, fast path here. */
305 while ((slen >= 2) && dlen) {
306 if (((lastp = *p) <= 0x7f) && (p[1] == 0)) {
308 if (slen != (size_t)-1) {
317 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
320 return retval + convert_string_internal(from, to, p, slen, q, dlen);
325 } else if (from != CH_UCS2 && to == CH_UCS2) {
326 const unsigned char *p = (const unsigned char *)src;
327 unsigned char *q = (unsigned char *)dest;
329 size_t slen = srclen;
330 size_t dlen = destlen;
333 /* If all characters are ascii, fast path here. */
334 while (slen && (dlen >= 2)) {
335 if ((lastp = *p) <= 0x7F) {
338 if (slen != (size_t)-1) {
346 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
349 return retval + convert_string_internal(from, to, p, slen, q, dlen);
356 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
359 return convert_string_internal(from, to, src, srclen, dest, destlen);
363 * Convert between character sets, allocating a new buffer for the result.
365 * @param ctx TALLOC_CTX to use to allocate with. If NULL use malloc.
366 * @param srclen length of source buffer.
367 * @param dest always set at least to NULL
368 * @note -1 is not accepted for srclen.
370 * @returns Size in bytes of the converted string; or -1 in case of error.
372 * Ensure the srclen contains the terminating zero.
375 size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
376 void const *src, size_t srclen, void **dest)
378 size_t i_len, o_len, destlen = MAX(srclen, 512);
380 const char *inbuf = (const char *)src;
381 char *outbuf = NULL, *ob = NULL;
382 smb_iconv_t descriptor;
386 if (src == NULL || srclen == (size_t)-1)
391 lazy_initialize_conv();
393 descriptor = conv_handles[from][to];
395 if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
397 DEBUG(0,("convert_string_allocate: Conversion not supported.\n"));
402 if ((destlen*2) < destlen) {
403 /* wrapped ! abort. */
405 DEBUG(0, ("convert_string_allocate: destlen wrapped !\n"));
410 destlen = destlen * 2;
414 ob = (char *)talloc_realloc(ctx, ob, destlen);
416 ob = (char *)Realloc(ob, destlen);
419 DEBUG(0, ("convert_string_allocate: realloc failed!\n"));
428 retval = smb_iconv(descriptor,
431 if(retval == (size_t)-1) {
432 const char *reason="unknown error";
435 reason="Incomplete multibyte sequence";
437 DEBUG(3,("convert_string_allocate: Conversion error: %s(%s)\n",reason,inbuf));
442 reason="Illegal multibyte sequence";
444 DEBUG(3,("convert_string_allocate: Conversion error: %s(%s)\n",reason,inbuf));
448 DEBUG(0,("Conversion error: %s(%s)\n",reason,inbuf));
449 /* smb_panic(reason); */
453 destlen = destlen - o_len;
455 *dest = (char *)talloc_realloc(ctx,ob,destlen);
457 *dest = (char *)Realloc(ob,destlen);
458 if (destlen && !*dest) {
459 DEBUG(0, ("convert_string_allocate: out of memory!\n"));
469 /* conversion not supported, use as is */
471 if (srclen && (destlen != srclen)) {
474 ob = (char *)talloc_realloc(ctx, ob, destlen);
476 ob = (char *)Realloc(ob, destlen);
478 DEBUG(0, ("convert_string_allocate: realloc failed!\n"));
485 memcpy(ob,(const char *)src,srclen);
493 * Convert between character sets, allocating a new buffer using talloc for the result.
495 * @param srclen length of source buffer.
496 * @param dest always set at least to NULL
497 * @note -1 is not accepted for srclen.
499 * @returns Size in bytes of the converted string; or -1 in case of error.
501 static size_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to,
502 void const *src, size_t srclen, void **dest)
507 dest_len=convert_string_allocate(ctx, from, to, src, srclen, dest);
508 if (dest_len == (size_t)-1)
515 size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
520 size = push_ucs2_allocate(&buffer, src);
522 smb_panic("failed to create UCS2 buffer");
524 if (!strupper_w(buffer) && (dest == src)) {
529 size = convert_string(CH_UCS2, CH_UNIX, buffer, size, dest, destlen);
535 strdup() a unix string to upper case.
539 char *strdup_upper(const char *s)
542 const unsigned char *p = (const unsigned char *)s;
543 unsigned char *q = (unsigned char *)out_buffer;
545 /* this is quite a common operation, so we want it to be
546 fast. We optimise for the ascii case, knowing that all our
547 supported multi-byte character sets are ascii-compatible
548 (ie. they match for the first 128 chars) */
557 if (p - ( const unsigned char *)s >= sizeof(pstring))
565 size = convert_string(CH_UNIX, CH_UCS2, s, -1, buffer, sizeof(buffer));
572 size = convert_string(CH_UCS2, CH_UNIX, buffer, -1, out_buffer, sizeof(out_buffer));
578 return strdup(out_buffer);
581 size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
586 size = convert_string_allocate(NULL, CH_UNIX, CH_UCS2, src, srclen,
589 smb_panic("failed to create UCS2 buffer");
591 if (!strlower_w(buffer) && (dest == src)) {
595 size = convert_string(CH_UCS2, CH_UNIX, buffer, size, dest, destlen);
601 strdup() a unix string to lower case.
604 char *strdup_lower(const char *s)
610 size = push_ucs2_allocate(&buffer, s);
617 size = pull_ucs2_allocate(&out_buffer, buffer);
627 static size_t ucs2_align(const void *base_ptr, const void *p, int flags)
629 if (flags & (STR_NOALIGN|STR_ASCII))
631 return PTR_DIFF(p, base_ptr) & 1;
636 * Copy a string from a char* unix src to a dos codepage string destination.
638 * @return the number of bytes occupied by the string in the destination.
640 * @param flags can include
642 * <dt>STR_TERMINATE</dt> <dd>means include the null termination</dd>
643 * <dt>STR_UPPER</dt> <dd>means uppercase in the destination</dd>
646 * @param dest_len the maximum length in bytes allowed in the
647 * destination. If @p dest_len is -1 then no maximum is used.
649 size_t push_ascii(void *dest, const char *src, size_t dest_len, int flags)
651 size_t src_len = strlen(src);
654 /* treat a pstring as "unlimited" length */
655 if (dest_len == (size_t)-1)
656 dest_len = sizeof(pstring);
658 if (flags & STR_UPPER) {
659 pstrcpy(tmpbuf, src);
664 if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII))
667 return convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len);
670 size_t push_ascii_fstring(void *dest, const char *src)
672 return push_ascii(dest, src, sizeof(fstring), STR_TERMINATE);
675 size_t push_ascii_pstring(void *dest, const char *src)
677 return push_ascii(dest, src, sizeof(pstring), STR_TERMINATE);
680 size_t push_ascii_nstring(void *dest, const char *src)
682 return push_ascii(dest, src, sizeof(nstring), STR_TERMINATE);
686 * Copy a string from a dos codepage source to a unix char* destination.
688 * The resulting string in "dest" is always null terminated.
690 * @param flags can have:
692 * <dt>STR_TERMINATE</dt>
693 * <dd>STR_TERMINATE means the string in @p src
694 * is null terminated, and src_len is ignored.</dd>
697 * @param src_len is the length of the source area in bytes.
698 * @returns the number of bytes occupied by the string in @p src.
700 size_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
704 if (dest_len == (size_t)-1)
705 dest_len = sizeof(pstring);
707 if (flags & STR_TERMINATE) {
708 if (src_len == (size_t)-1) {
709 src_len = strlen(src) + 1;
711 size_t len = strnlen(src, src_len);
718 ret = convert_string(CH_DOS, CH_UNIX, src, src_len, dest, dest_len);
721 dest[MIN(ret, dest_len-1)] = 0;
728 size_t pull_ascii_pstring(char *dest, const void *src)
730 return pull_ascii(dest, src, sizeof(pstring), -1, STR_TERMINATE);
733 size_t pull_ascii_fstring(char *dest, const void *src)
735 return pull_ascii(dest, src, sizeof(fstring), -1, STR_TERMINATE);
738 size_t pull_ascii_nstring(char *dest, const void *src)
740 return pull_ascii(dest, src, sizeof(nstring), sizeof(nstring), STR_TERMINATE);
744 * Copy a string from a char* src to a unicode destination.
746 * @returns the number of bytes occupied by the string in the destination.
748 * @param flags can have:
751 * <dt>STR_TERMINATE <dd>means include the null termination.
752 * <dt>STR_UPPER <dd>means uppercase in the destination.
753 * <dt>STR_NOALIGN <dd>means don't do alignment.
756 * @param dest_len is the maximum length allowed in the
757 * destination. If dest_len is -1 then no maxiumum is used.
760 size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags)
765 /* treat a pstring as "unlimited" length */
766 if (dest_len == (size_t)-1)
767 dest_len = sizeof(pstring);
769 if (flags & STR_TERMINATE)
770 src_len = (size_t)-1;
772 src_len = strlen(src);
774 if (ucs2_align(base_ptr, dest, flags)) {
776 dest = (void *)((char *)dest + 1);
782 /* ucs2 is always a multiple of 2 bytes */
785 len += convert_string(CH_UNIX, CH_UCS2, src, src_len, dest, dest_len);
787 if (flags & STR_UPPER) {
788 smb_ucs2_t *dest_ucs2 = dest;
790 for (i = 0; i < (dest_len / 2) && dest_ucs2[i]; i++) {
791 smb_ucs2_t v = toupper_w(dest_ucs2[i]);
792 if (v != dest_ucs2[i]) {
803 * Copy a string from a unix char* src to a UCS2 destination,
804 * allocating a buffer using talloc().
806 * @param dest always set at least to NULL
808 * @returns The number of bytes occupied by the string in the destination
809 * or -1 in case of error.
811 size_t push_ucs2_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src)
813 size_t src_len = strlen(src)+1;
816 return convert_string_talloc(ctx, CH_UNIX, CH_UCS2, src, src_len, (void **)dest);
821 * Copy a string from a unix char* src to a UCS2 destination, allocating a buffer
823 * @param dest always set at least to NULL
825 * @returns The number of bytes occupied by the string in the destination
826 * or -1 in case of error.
829 size_t push_ucs2_allocate(smb_ucs2_t **dest, const char *src)
831 size_t src_len = strlen(src)+1;
834 return convert_string_allocate(NULL, CH_UNIX, CH_UCS2, src, src_len, (void **)dest);
838 Copy a string from a char* src to a UTF-8 destination.
839 Return the number of bytes occupied by the string in the destination
841 STR_TERMINATE means include the null termination
842 STR_UPPER means uppercase in the destination
843 dest_len is the maximum length allowed in the destination. If dest_len
844 is -1 then no maxiumum is used.
847 static size_t push_utf8(void *dest, const char *src, size_t dest_len, int flags)
849 size_t src_len = strlen(src);
852 /* treat a pstring as "unlimited" length */
853 if (dest_len == (size_t)-1)
854 dest_len = sizeof(pstring);
856 if (flags & STR_UPPER) {
857 pstrcpy(tmpbuf, src);
862 if (flags & STR_TERMINATE)
865 return convert_string(CH_UNIX, CH_UTF8, src, src_len, dest, dest_len);
868 size_t push_utf8_fstring(void *dest, const char *src)
870 return push_utf8(dest, src, sizeof(fstring), STR_TERMINATE);
874 * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer using talloc
876 * @param dest always set at least to NULL
878 * @returns The number of bytes occupied by the string in the destination
881 size_t push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
883 size_t src_len = strlen(src)+1;
886 return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len, (void**)dest);
890 * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer
892 * @param dest always set at least to NULL
894 * @returns The number of bytes occupied by the string in the destination
897 size_t push_utf8_allocate(char **dest, const char *src)
899 size_t src_len = strlen(src)+1;
902 return convert_string_allocate(NULL, CH_UNIX, CH_UTF8, src, src_len, (void **)dest);
906 Copy a string from a ucs2 source to a unix char* destination.
908 STR_TERMINATE means the string in src is null terminated.
909 STR_NOALIGN means don't try to align.
910 if STR_TERMINATE is set then src_len is ignored if it is -1.
911 src_len is the length of the source area in bytes
912 Return the number of bytes occupied by the string in src.
913 The resulting string in "dest" is always null terminated.
916 size_t pull_ucs2(const void *base_ptr, char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
920 if (dest_len == (size_t)-1)
921 dest_len = sizeof(pstring);
923 if (ucs2_align(base_ptr, src, flags)) {
924 src = (const void *)((const char *)src + 1);
929 if (flags & STR_TERMINATE) {
930 /* src_len -1 is the default for null terminated strings. */
931 if (src_len != (size_t)-1) {
932 size_t len = strnlen_w(src, src_len/2);
939 /* ucs2 is always a multiple of 2 bytes */
940 if (src_len != (size_t)-1)
943 ret = convert_string(CH_UCS2, CH_UNIX, src, src_len, dest, dest_len);
945 dest[MIN(ret, dest_len-1)] = 0;
952 size_t pull_ucs2_pstring(char *dest, const void *src)
954 return pull_ucs2(NULL, dest, src, sizeof(pstring), -1, STR_TERMINATE);
957 size_t pull_ucs2_fstring(char *dest, const void *src)
959 return pull_ucs2(NULL, dest, src, sizeof(fstring), -1, STR_TERMINATE);
963 * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer using talloc
965 * @param dest always set at least to NULL
967 * @returns The number of bytes occupied by the string in the destination
970 size_t pull_ucs2_talloc(TALLOC_CTX *ctx, char **dest, const smb_ucs2_t *src)
972 size_t src_len = (strlen_w(src)+1) * sizeof(smb_ucs2_t);
974 return convert_string_talloc(ctx, CH_UCS2, CH_UNIX, src, src_len, (void **)dest);
978 * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer
980 * @param dest always set at least to NULL
982 * @returns The number of bytes occupied by the string in the destination
985 size_t pull_ucs2_allocate(char **dest, const smb_ucs2_t *src)
987 size_t src_len = (strlen_w(src)+1) * sizeof(smb_ucs2_t);
989 return convert_string_allocate(NULL, CH_UCS2, CH_UNIX, src, src_len, (void **)dest);
993 * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc
995 * @param dest always set at least to NULL
997 * @returns The number of bytes occupied by the string in the destination
1000 size_t pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
1002 size_t src_len = strlen(src)+1;
1004 return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len, (void **)dest);
1008 * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer
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 pull_utf8_allocate(void **dest, const char *src)
1017 size_t src_len = strlen(src)+1;
1019 return convert_string_allocate(NULL, CH_UTF8, CH_UNIX, src, src_len, dest);
1023 Copy a string from a char* src to a unicode or ascii
1024 dos codepage destination choosing unicode or ascii based on the
1025 flags in the SMB buffer starting at base_ptr.
1026 Return the number of bytes occupied by the string in the destination.
1028 STR_TERMINATE means include the null termination.
1029 STR_UPPER means uppercase in the destination.
1030 STR_ASCII use ascii even with unicode packet.
1031 STR_NOALIGN means don't do alignment.
1032 dest_len is the maximum length allowed in the destination. If dest_len
1033 is -1 then no maxiumum is used.
1036 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)
1039 /* We really need to zero fill here, not clobber
1040 * region, as we want to ensure that valgrind thinks
1041 * all of the outgoing buffer has been written to
1042 * so a send() or write() won't trap an error.
1046 if (dest_len != (size_t)-1)
1047 clobber_region(function, line, dest, dest_len);
1049 if (dest_len != (size_t)-1)
1050 memset(dest, '\0', dest_len);
1054 if (!(flags & STR_ASCII) && \
1055 ((flags & STR_UNICODE || \
1056 (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) {
1057 return push_ucs2(base_ptr, dest, src, dest_len, flags);
1059 return push_ascii(dest, src, dest_len, flags);
1064 Copy a string from a unicode or ascii source (depending on
1065 the packet flags) to a char* destination.
1067 STR_TERMINATE means the string in src is null terminated.
1068 STR_UNICODE means to force as unicode.
1069 STR_ASCII use ascii even with unicode packet.
1070 STR_NOALIGN means don't do alignment.
1071 if STR_TERMINATE is set then src_len is ignored is it is -1
1072 src_len is the length of the source area in bytes.
1073 Return the number of bytes occupied by the string in src.
1074 The resulting string in "dest" is always null terminated.
1077 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)
1080 if (dest_len != (size_t)-1)
1081 clobber_region(function, line, dest, dest_len);
1084 if (!(flags & STR_ASCII) && \
1085 ((flags & STR_UNICODE || \
1086 (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) {
1087 return pull_ucs2(base_ptr, dest, src, dest_len, src_len, flags);
1089 return pull_ascii(dest, src, dest_len, src_len, flags);
1092 size_t align_string(const void *base_ptr, const char *p, int flags)
1094 if (!(flags & STR_ASCII) && \
1095 ((flags & STR_UNICODE || \
1096 (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) {
1097 return ucs2_align(base_ptr, p, flags);