s3: Use cli_writeall instead of cli_write
[Samba.git] / source3 / lib / charcnv.c
blobfd6cefe7e5e8585c8288b26d8f99e395b503b844
1 /*
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 3 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, see <http://www.gnu.org/licenses/>.
23 #include "includes.h"
25 /* We can parameterize this if someone complains.... JRA. */
27 char lp_failed_convert_char(void)
29 return '_';
32 /**
33 * @file
35 * @brief Character-set conversion routines built on our iconv.
37 * @note Samba's internal character set (at least in the 3.0 series)
38 * is always the same as the one for the Unix filesystem. It is
39 * <b>not</b> necessarily UTF-8 and may be different on machines that
40 * need i18n filenames to be compatible with Unix software. It does
41 * have to be a superset of ASCII. All multibyte sequences must start
42 * with a byte with the high bit set.
44 * @sa lib/iconv.c
48 static bool conv_silent; /* Should we do a debug if the conversion fails ? */
49 static bool initialized;
51 void lazy_initialize_conv(void)
53 if (!initialized) {
54 load_case_tables_library();
55 init_iconv();
56 initialized = true;
60 /**
61 * Destroy global objects allocated by init_iconv()
62 **/
63 void gfree_charcnv(void)
65 TALLOC_FREE(global_iconv_convenience);
66 initialized = false;
69 /**
70 * Initialize iconv conversion descriptors.
72 * This is called the first time it is needed, and also called again
73 * every time the configuration is reloaded, because the charset or
74 * codepage might have changed.
75 **/
76 void init_iconv(void)
78 global_iconv_convenience = smb_iconv_convenience_reinit(NULL, lp_dos_charset(),
79 lp_unix_charset(), lp_display_charset(),
80 true, global_iconv_convenience);
83 /**
84 * Convert string from one encoding to another, making error checking etc
85 * Slow path version - uses (slow) iconv.
87 * @param src pointer to source string (multibyte or singlebyte)
88 * @param srclen length of the source string in bytes
89 * @param dest pointer to destination string (multibyte or singlebyte)
90 * @param destlen maximal length allowed for string
91 * @param allow_bad_conv determines if a "best effort" conversion is acceptable (never returns errors)
92 * @returns the number of bytes occupied in the destination
94 * Ensure the srclen contains the terminating zero.
96 **/
98 static size_t convert_string_internal(charset_t from, charset_t to,
99 void const *src, size_t srclen,
100 void *dest, size_t destlen, bool allow_bad_conv)
102 size_t i_len, o_len;
103 size_t retval;
104 const char* inbuf = (const char*)src;
105 char* outbuf = (char*)dest;
106 smb_iconv_t descriptor;
107 struct smb_iconv_convenience *ic;
109 lazy_initialize_conv();
110 ic = get_iconv_convenience();
111 descriptor = get_conv_handle(ic, from, to);
113 if (srclen == (size_t)-1) {
114 if (from == CH_UTF16LE || from == CH_UTF16BE) {
115 srclen = (strlen_w((const smb_ucs2_t *)src)+1) * 2;
116 } else {
117 srclen = strlen((const char *)src)+1;
122 if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
123 if (!conv_silent)
124 DEBUG(0,("convert_string_internal: Conversion not supported.\n"));
125 return (size_t)-1;
128 i_len=srclen;
129 o_len=destlen;
131 again:
133 retval = smb_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len);
134 if(retval==(size_t)-1) {
135 const char *reason="unknown error";
136 switch(errno) {
137 case EINVAL:
138 reason="Incomplete multibyte sequence";
139 if (!conv_silent)
140 DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
141 if (allow_bad_conv)
142 goto use_as_is;
143 return (size_t)-1;
144 case E2BIG:
145 reason="No more room";
146 if (!conv_silent) {
147 if (from == CH_UNIX) {
148 DEBUG(3,("E2BIG: convert_string(%s,%s): srclen=%u destlen=%u - '%s'\n",
149 charset_name(ic, from), charset_name(ic, to),
150 (unsigned int)srclen, (unsigned int)destlen, (const char *)src));
151 } else {
152 DEBUG(3,("E2BIG: convert_string(%s,%s): srclen=%u destlen=%u\n",
153 charset_name(ic, from), charset_name(ic, to),
154 (unsigned int)srclen, (unsigned int)destlen));
157 break;
158 case EILSEQ:
159 reason="Illegal multibyte sequence";
160 if (!conv_silent)
161 DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
162 if (allow_bad_conv)
163 goto use_as_is;
165 return (size_t)-1;
166 default:
167 if (!conv_silent)
168 DEBUG(0,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
169 return (size_t)-1;
171 /* smb_panic(reason); */
173 return destlen-o_len;
175 use_as_is:
178 * Conversion not supported. This is actually an error, but there are so
179 * many misconfigured iconv systems and smb.conf's out there we can't just
180 * fail. Do a very bad conversion instead.... JRA.
184 if (o_len == 0 || i_len == 0)
185 return destlen - o_len;
187 if (((from == CH_UTF16LE)||(from == CH_UTF16BE)) &&
188 ((to != CH_UTF16LE)||(to != CH_UTF16BE))) {
189 /* Can't convert from utf16 any endian to multibyte.
190 Replace with the default fail char.
192 if (i_len < 2)
193 return destlen - o_len;
194 if (i_len >= 2) {
195 *outbuf = lp_failed_convert_char();
197 outbuf++;
198 o_len--;
200 inbuf += 2;
201 i_len -= 2;
204 if (o_len == 0 || i_len == 0)
205 return destlen - o_len;
207 /* Keep trying with the next char... */
208 goto again;
210 } else if (from != CH_UTF16LE && from != CH_UTF16BE && to == CH_UTF16LE) {
211 /* Can't convert to UTF16LE - just widen by adding the
212 default fail char then zero.
214 if (o_len < 2)
215 return destlen - o_len;
217 outbuf[0] = lp_failed_convert_char();
218 outbuf[1] = '\0';
220 inbuf++;
221 i_len--;
223 outbuf += 2;
224 o_len -= 2;
226 if (o_len == 0 || i_len == 0)
227 return destlen - o_len;
229 /* Keep trying with the next char... */
230 goto again;
232 } else if (from != CH_UTF16LE && from != CH_UTF16BE &&
233 to != CH_UTF16LE && to != CH_UTF16BE) {
234 /* Failed multibyte to multibyte. Just copy the default fail char and
235 try again. */
236 outbuf[0] = lp_failed_convert_char();
238 inbuf++;
239 i_len--;
241 outbuf++;
242 o_len--;
244 if (o_len == 0 || i_len == 0)
245 return destlen - o_len;
247 /* Keep trying with the next char... */
248 goto again;
250 } else {
251 /* Keep compiler happy.... */
252 return destlen - o_len;
258 * Convert string from one encoding to another, making error checking etc
259 * Fast path version - handles ASCII first.
261 * @param src pointer to source string (multibyte or singlebyte)
262 * @param srclen length of the source string in bytes, or -1 for nul terminated.
263 * @param dest pointer to destination string (multibyte or singlebyte)
264 * @param destlen maximal length allowed for string - *NEVER* -1.
265 * @param allow_bad_conv determines if a "best effort" conversion is acceptable (never returns errors)
266 * @returns the number of bytes occupied in the destination
268 * Ensure the srclen contains the terminating zero.
270 * This function has been hand-tuned to provide a fast path.
271 * Don't change unless you really know what you are doing. JRA.
274 size_t convert_string(charset_t from, charset_t to,
275 void const *src, size_t srclen,
276 void *dest, size_t destlen, bool allow_bad_conv)
279 * NB. We deliberately don't do a strlen here if srclen == -1.
280 * This is very expensive over millions of calls and is taken
281 * care of in the slow path in convert_string_internal. JRA.
284 #ifdef DEVELOPER
285 SMB_ASSERT(destlen != (size_t)-1);
286 #endif
288 if (srclen == 0)
289 return 0;
291 if (from != CH_UTF16LE && from != CH_UTF16BE && to != CH_UTF16LE && to != CH_UTF16BE) {
292 const unsigned char *p = (const unsigned char *)src;
293 unsigned char *q = (unsigned char *)dest;
294 size_t slen = srclen;
295 size_t dlen = destlen;
296 unsigned char lastp = '\0';
297 size_t retval = 0;
299 /* If all characters are ascii, fast path here. */
300 while (slen && dlen) {
301 if ((lastp = *p) <= 0x7f) {
302 *q++ = *p++;
303 if (slen != (size_t)-1) {
304 slen--;
306 dlen--;
307 retval++;
308 if (!lastp)
309 break;
310 } else {
311 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
312 goto general_case;
313 #else
314 size_t ret = convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv);
315 if (ret == (size_t)-1) {
316 return ret;
318 return retval + ret;
319 #endif
322 if (!dlen) {
323 /* Even if we fast path we should note if we ran out of room. */
324 if (((slen != (size_t)-1) && slen) ||
325 ((slen == (size_t)-1) && lastp)) {
326 errno = E2BIG;
329 return retval;
330 } else if (from == CH_UTF16LE && to != CH_UTF16LE) {
331 const unsigned char *p = (const unsigned char *)src;
332 unsigned char *q = (unsigned char *)dest;
333 size_t retval = 0;
334 size_t slen = srclen;
335 size_t dlen = destlen;
336 unsigned char lastp = '\0';
338 /* If all characters are ascii, fast path here. */
339 while (((slen == (size_t)-1) || (slen >= 2)) && dlen) {
340 if (((lastp = *p) <= 0x7f) && (p[1] == 0)) {
341 *q++ = *p;
342 if (slen != (size_t)-1) {
343 slen -= 2;
345 p += 2;
346 dlen--;
347 retval++;
348 if (!lastp)
349 break;
350 } else {
351 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
352 goto general_case;
353 #else
354 size_t ret = convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv);
355 if (ret == (size_t)-1) {
356 return ret;
358 return retval + ret;
359 #endif
362 if (!dlen) {
363 /* Even if we fast path we should note if we ran out of room. */
364 if (((slen != (size_t)-1) && slen) ||
365 ((slen == (size_t)-1) && lastp)) {
366 errno = E2BIG;
369 return retval;
370 } else if (from != CH_UTF16LE && from != CH_UTF16BE && to == CH_UTF16LE) {
371 const unsigned char *p = (const unsigned char *)src;
372 unsigned char *q = (unsigned char *)dest;
373 size_t retval = 0;
374 size_t slen = srclen;
375 size_t dlen = destlen;
376 unsigned char lastp = '\0';
378 /* If all characters are ascii, fast path here. */
379 while (slen && (dlen >= 2)) {
380 if ((lastp = *p) <= 0x7F) {
381 *q++ = *p++;
382 *q++ = '\0';
383 if (slen != (size_t)-1) {
384 slen--;
386 dlen -= 2;
387 retval += 2;
388 if (!lastp)
389 break;
390 } else {
391 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
392 goto general_case;
393 #else
394 size_t ret = convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv);
395 if (ret == (size_t)-1) {
396 return ret;
398 return retval + ret;
399 #endif
402 if (!dlen) {
403 /* Even if we fast path we should note if we ran out of room. */
404 if (((slen != (size_t)-1) && slen) ||
405 ((slen == (size_t)-1) && lastp)) {
406 errno = E2BIG;
409 return retval;
412 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
413 general_case:
414 #endif
415 return convert_string_internal(from, to, src, srclen, dest, destlen, allow_bad_conv);
419 * Convert between character sets, allocating a new buffer using talloc for the result.
421 * @param srclen length of source buffer.
422 * @param dest always set at least to NULL
423 * @parm converted_size set to the number of bytes occupied by the string in
424 * the destination on success.
425 * @note -1 is not accepted for srclen.
427 * @return true if new buffer was correctly allocated, and string was
428 * converted.
430 * Ensure the srclen contains the terminating zero.
432 * I hate the goto's in this function. It's embarressing.....
433 * There has to be a cleaner way to do this. JRA.
435 bool convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to,
436 void const *src, size_t srclen, void *dst,
437 size_t *converted_size, bool allow_bad_conv)
440 size_t i_len, o_len, destlen = (srclen * 3) / 2;
441 size_t retval;
442 const char *inbuf = (const char *)src;
443 char *outbuf = NULL, *ob = NULL;
444 smb_iconv_t descriptor;
445 void **dest = (void **)dst;
446 struct smb_iconv_convenience *ic;
448 *dest = NULL;
450 if (!converted_size) {
451 errno = EINVAL;
452 return false;
455 if (src == NULL || srclen == (size_t)-1) {
456 errno = EINVAL;
457 return false;
460 if (srclen == 0) {
461 /* We really should treat this as an error, but
462 there are too many callers that need this to
463 return a NULL terminated string in the correct
464 character set. */
465 if (to == CH_UTF16LE|| to == CH_UTF16BE || to == CH_UTF16MUNGED) {
466 destlen = 2;
467 } else {
468 destlen = 1;
470 ob = talloc_zero_array(ctx, char, destlen);
471 if (ob == NULL) {
472 errno = ENOMEM;
473 return false;
475 *converted_size = destlen;
476 *dest = ob;
477 return true;
480 lazy_initialize_conv();
481 ic = get_iconv_convenience();
482 descriptor = get_conv_handle(ic, from, to);
484 if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
485 if (!conv_silent)
486 DEBUG(0,("convert_string_talloc: Conversion not supported.\n"));
487 errno = EOPNOTSUPP;
488 return false;
491 convert:
493 /* +2 is for ucs2 null termination. */
494 if ((destlen*2)+2 < destlen) {
495 /* wrapped ! abort. */
496 if (!conv_silent)
497 DEBUG(0, ("convert_string_talloc: destlen wrapped !\n"));
498 TALLOC_FREE(outbuf);
499 errno = EOPNOTSUPP;
500 return false;
501 } else {
502 destlen = destlen * 2;
505 /* +2 is for ucs2 null termination. */
506 ob = (char *)TALLOC_REALLOC(ctx, ob, destlen + 2);
508 if (!ob) {
509 DEBUG(0, ("convert_string_talloc: realloc failed!\n"));
510 errno = ENOMEM;
511 return false;
513 outbuf = ob;
514 i_len = srclen;
515 o_len = destlen;
517 again:
519 retval = smb_iconv(descriptor,
520 &inbuf, &i_len,
521 &outbuf, &o_len);
522 if(retval == (size_t)-1) {
523 const char *reason="unknown error";
524 switch(errno) {
525 case EINVAL:
526 reason="Incomplete multibyte sequence";
527 if (!conv_silent)
528 DEBUG(3,("convert_string_talloc: Conversion error: %s(%s)\n",reason,inbuf));
529 if (allow_bad_conv)
530 goto use_as_is;
531 break;
532 case E2BIG:
533 goto convert;
534 case EILSEQ:
535 reason="Illegal multibyte sequence";
536 if (!conv_silent)
537 DEBUG(3,("convert_string_talloc: Conversion error: %s(%s)\n",reason,inbuf));
538 if (allow_bad_conv)
539 goto use_as_is;
540 break;
542 if (!conv_silent)
543 DEBUG(0,("Conversion error: %s(%s)\n",reason,inbuf));
544 /* smb_panic(reason); */
545 TALLOC_FREE(ob);
546 return false;
549 out:
551 destlen = destlen - o_len;
552 /* Don't shrink unless we're reclaiming a lot of
553 * space. This is in the hot codepath and these
554 * reallocs *cost*. JRA.
556 if (o_len > 1024) {
557 /* We're shrinking here so we know the +2 is safe from wrap. */
558 ob = (char *)TALLOC_REALLOC(ctx,ob,destlen + 2);
561 if (destlen && !ob) {
562 DEBUG(0, ("convert_string_talloc: out of memory!\n"));
563 errno = ENOMEM;
564 return false;
567 *dest = ob;
569 /* Must ucs2 null terminate in the extra space we allocated. */
570 ob[destlen] = '\0';
571 ob[destlen+1] = '\0';
573 /* Ensure we can never return a *converted_size of zero. */
574 if (destlen == 0) {
575 /* This can happen from a bad iconv "use_as_is:" call. */
576 if (to == CH_UTF16LE|| to == CH_UTF16BE || to == CH_UTF16MUNGED) {
577 destlen = 2;
578 } else {
579 destlen = 1;
583 *converted_size = destlen;
584 return true;
586 use_as_is:
589 * Conversion not supported. This is actually an error, but there are so
590 * many misconfigured iconv systems and smb.conf's out there we can't just
591 * fail. Do a very bad conversion instead.... JRA.
595 if (o_len == 0 || i_len == 0)
596 goto out;
598 if (((from == CH_UTF16LE)||(from == CH_UTF16BE)) &&
599 ((to != CH_UTF16LE)||(to != CH_UTF16BE))) {
600 /* Can't convert from utf16 any endian to multibyte.
601 Replace with the default fail char.
604 if (i_len < 2)
605 goto out;
607 if (i_len >= 2) {
608 *outbuf = lp_failed_convert_char();
610 outbuf++;
611 o_len--;
613 inbuf += 2;
614 i_len -= 2;
617 if (o_len == 0 || i_len == 0)
618 goto out;
620 /* Keep trying with the next char... */
621 goto again;
623 } else if (from != CH_UTF16LE && from != CH_UTF16BE && to == CH_UTF16LE) {
624 /* Can't convert to UTF16LE - just widen by adding the
625 default fail char then zero.
627 if (o_len < 2)
628 goto out;
630 outbuf[0] = lp_failed_convert_char();
631 outbuf[1] = '\0';
633 inbuf++;
634 i_len--;
636 outbuf += 2;
637 o_len -= 2;
639 if (o_len == 0 || i_len == 0)
640 goto out;
642 /* Keep trying with the next char... */
643 goto again;
645 } else if (from != CH_UTF16LE && from != CH_UTF16BE &&
646 to != CH_UTF16LE && to != CH_UTF16BE) {
647 /* Failed multibyte to multibyte. Just copy the default fail char and
648 try again. */
649 outbuf[0] = lp_failed_convert_char();
651 inbuf++;
652 i_len--;
654 outbuf++;
655 o_len--;
657 if (o_len == 0 || i_len == 0)
658 goto out;
660 /* Keep trying with the next char... */
661 goto again;
663 } else {
664 /* Keep compiler happy.... */
665 goto out;
670 size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
672 size_t size;
673 smb_ucs2_t *buffer;
675 if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &size)) {
676 return (size_t)-1;
679 if (!strupper_w(buffer) && (dest == src)) {
680 TALLOC_FREE(buffer);
681 return srclen;
684 size = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen, True);
685 TALLOC_FREE(buffer);
686 return size;
690 talloc_strdup() a unix string to upper case.
693 char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *s)
695 char *out_buffer = talloc_strdup(ctx,s);
696 const unsigned char *p = (const unsigned char *)s;
697 unsigned char *q = (unsigned char *)out_buffer;
699 if (!q) {
700 return NULL;
703 /* this is quite a common operation, so we want it to be
704 fast. We optimise for the ascii case, knowing that all our
705 supported multi-byte character sets are ascii-compatible
706 (ie. they match for the first 128 chars) */
708 while (*p) {
709 if (*p & 0x80)
710 break;
711 *q++ = toupper_ascii_fast(*p);
712 p++;
715 if (*p) {
716 /* MB case. */
717 size_t converted_size, converted_size2;
718 smb_ucs2_t *ubuf = NULL;
720 /* We're not using the ascii buffer above. */
721 TALLOC_FREE(out_buffer);
723 if (!convert_string_talloc(ctx, CH_UNIX, CH_UTF16LE, s,
724 strlen(s)+1, (void *)&ubuf,
725 &converted_size, True))
727 return NULL;
730 strupper_w(ubuf);
732 if (!convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, ubuf,
733 converted_size, (void *)&out_buffer,
734 &converted_size2, True))
736 TALLOC_FREE(ubuf);
737 return NULL;
740 /* Don't need the intermediate buffer
741 * anymore.
743 TALLOC_FREE(ubuf);
746 return out_buffer;
749 char *strupper_talloc(TALLOC_CTX *ctx, const char *s) {
750 return talloc_strdup_upper(ctx, s);
754 size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
756 size_t size;
757 smb_ucs2_t *buffer = NULL;
759 if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_UTF16LE, src, srclen,
760 (void **)(void *)&buffer, &size,
761 True))
763 smb_panic("failed to create UCS2 buffer");
765 if (!strlower_w(buffer) && (dest == src)) {
766 TALLOC_FREE(buffer);
767 return srclen;
769 size = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen, True);
770 TALLOC_FREE(buffer);
771 return size;
775 char *talloc_strdup_lower(TALLOC_CTX *ctx, const char *s)
777 size_t converted_size;
778 smb_ucs2_t *buffer = NULL;
779 char *out_buffer;
781 if (!push_ucs2_talloc(ctx, &buffer, s, &converted_size)) {
782 return NULL;
785 strlower_w(buffer);
787 if (!pull_ucs2_talloc(ctx, &out_buffer, buffer, &converted_size)) {
788 TALLOC_FREE(buffer);
789 return NULL;
792 TALLOC_FREE(buffer);
794 return out_buffer;
797 char *strlower_talloc(TALLOC_CTX *ctx, const char *s) {
798 return talloc_strdup_lower(ctx, s);
801 size_t ucs2_align(const void *base_ptr, const void *p, int flags)
803 if (flags & (STR_NOALIGN|STR_ASCII))
804 return 0;
805 return PTR_DIFF(p, base_ptr) & 1;
810 * Copy a string from a char* unix src to a dos codepage string destination.
812 * @return the number of bytes occupied by the string in the destination.
814 * @param flags can include
815 * <dl>
816 * <dt>STR_TERMINATE</dt> <dd>means include the null termination</dd>
817 * <dt>STR_UPPER</dt> <dd>means uppercase in the destination</dd>
818 * </dl>
820 * @param dest_len the maximum length in bytes allowed in the
821 * destination.
823 size_t push_ascii(void *dest, const char *src, size_t dest_len, int flags)
825 size_t src_len = strlen(src);
826 char *tmpbuf = NULL;
827 size_t ret;
829 /* No longer allow a length of -1. */
830 if (dest_len == (size_t)-1) {
831 smb_panic("push_ascii - dest_len == -1");
834 if (flags & STR_UPPER) {
835 tmpbuf = SMB_STRDUP(src);
836 if (!tmpbuf) {
837 smb_panic("malloc fail");
839 strupper_m(tmpbuf);
840 src = tmpbuf;
843 if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII)) {
844 src_len++;
847 ret = convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len, True);
848 if (ret == (size_t)-1 &&
849 (flags & (STR_TERMINATE | STR_TERMINATE_ASCII))
850 && dest_len > 0) {
851 ((char *)dest)[0] = '\0';
853 SAFE_FREE(tmpbuf);
854 return ret;
857 size_t push_ascii_fstring(void *dest, const char *src)
859 return push_ascii(dest, src, sizeof(fstring), STR_TERMINATE);
862 /********************************************************************
863 Push an nstring - ensure null terminated. Written by
864 moriyama@miraclelinux.com (MORIYAMA Masayuki).
865 ********************************************************************/
867 size_t push_ascii_nstring(void *dest, const char *src)
869 size_t i, buffer_len, dest_len;
870 smb_ucs2_t *buffer;
872 conv_silent = True;
873 if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &buffer_len)) {
874 smb_panic("failed to create UCS2 buffer");
877 /* We're using buffer_len below to count ucs2 characters, not bytes. */
878 buffer_len /= sizeof(smb_ucs2_t);
880 dest_len = 0;
881 for (i = 0; buffer[i] != 0 && (i < buffer_len); i++) {
882 unsigned char mb[10];
883 /* Convert one smb_ucs2_t character at a time. */
884 size_t mb_len = convert_string(CH_UTF16LE, CH_DOS, buffer+i, sizeof(smb_ucs2_t), mb, sizeof(mb), False);
885 if ((mb_len != (size_t)-1) && (dest_len + mb_len <= MAX_NETBIOSNAME_LEN - 1)) {
886 memcpy((char *)dest + dest_len, mb, mb_len);
887 dest_len += mb_len;
888 } else {
889 errno = E2BIG;
890 break;
893 ((char *)dest)[dest_len] = '\0';
895 conv_silent = False;
896 TALLOC_FREE(buffer);
897 return dest_len;
900 /********************************************************************
901 Push and malloc an ascii string. src and dest null terminated.
902 ********************************************************************/
904 bool push_ascii_talloc(TALLOC_CTX *mem_ctx, char **dest, const char *src, size_t *converted_size)
906 size_t src_len = strlen(src)+1;
908 *dest = NULL;
909 return convert_string_talloc(mem_ctx, CH_UNIX, CH_DOS, src, src_len,
910 (void **)dest, converted_size, True);
914 * Copy a string from a dos codepage source to a unix char* destination.
916 * The resulting string in "dest" is always null terminated.
918 * @param flags can have:
919 * <dl>
920 * <dt>STR_TERMINATE</dt>
921 * <dd>STR_TERMINATE means the string in @p src
922 * is null terminated, and src_len is ignored.</dd>
923 * </dl>
925 * @param src_len is the length of the source area in bytes.
926 * @returns the number of bytes occupied by the string in @p src.
928 size_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
930 size_t ret;
932 if (dest_len == (size_t)-1) {
933 /* No longer allow dest_len of -1. */
934 smb_panic("pull_ascii - invalid dest_len of -1");
937 if (flags & STR_TERMINATE) {
938 if (src_len == (size_t)-1) {
939 src_len = strlen((const char *)src) + 1;
940 } else {
941 size_t len = strnlen((const char *)src, src_len);
942 if (len < src_len)
943 len++;
944 src_len = len;
948 ret = convert_string(CH_DOS, CH_UNIX, src, src_len, dest, dest_len, True);
949 if (ret == (size_t)-1) {
950 ret = 0;
951 dest_len = 0;
954 if (dest_len && ret) {
955 /* Did we already process the terminating zero ? */
956 if (dest[MIN(ret-1, dest_len-1)] != 0) {
957 dest[MIN(ret, dest_len-1)] = 0;
959 } else {
960 dest[0] = 0;
963 return src_len;
967 * Copy a string from a dos codepage source to a unix char* destination.
968 * Talloc version.
970 * The resulting string in "dest" is always null terminated.
972 * @param flags can have:
973 * <dl>
974 * <dt>STR_TERMINATE</dt>
975 * <dd>STR_TERMINATE means the string in @p src
976 * is null terminated, and src_len is ignored.</dd>
977 * </dl>
979 * @param src_len is the length of the source area in bytes.
980 * @returns the number of bytes occupied by the string in @p src.
983 static size_t pull_ascii_base_talloc(TALLOC_CTX *ctx,
984 char **ppdest,
985 const void *src,
986 size_t src_len,
987 int flags)
989 char *dest = NULL;
990 size_t dest_len;
992 *ppdest = NULL;
994 if (!src_len) {
995 return 0;
998 if (flags & STR_TERMINATE) {
999 if (src_len == (size_t)-1) {
1000 src_len = strlen((const char *)src) + 1;
1001 } else {
1002 size_t len = strnlen((const char *)src, src_len);
1003 if (len < src_len)
1004 len++;
1005 src_len = len;
1007 /* Ensure we don't use an insane length from the client. */
1008 if (src_len >= 1024*1024) {
1009 char *msg = talloc_asprintf(ctx,
1010 "Bad src length (%u) in "
1011 "pull_ascii_base_talloc",
1012 (unsigned int)src_len);
1013 smb_panic(msg);
1015 } else {
1016 /* Can't have an unlimited length
1017 * non STR_TERMINATE'd.
1019 if (src_len == (size_t)-1) {
1020 errno = EINVAL;
1021 return 0;
1025 /* src_len != -1 here. */
1027 if (!convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len, &dest,
1028 &dest_len, True)) {
1029 dest_len = 0;
1032 if (dest_len && dest) {
1033 /* Did we already process the terminating zero ? */
1034 if (dest[dest_len-1] != 0) {
1035 size_t size = talloc_get_size(dest);
1036 /* Have we got space to append the '\0' ? */
1037 if (size <= dest_len) {
1038 /* No, realloc. */
1039 dest = TALLOC_REALLOC_ARRAY(ctx, dest, char,
1040 dest_len+1);
1041 if (!dest) {
1042 /* talloc fail. */
1043 dest_len = (size_t)-1;
1044 return 0;
1047 /* Yay - space ! */
1048 dest[dest_len] = '\0';
1049 dest_len++;
1051 } else if (dest) {
1052 dest[0] = 0;
1055 *ppdest = dest;
1056 return src_len;
1059 size_t pull_ascii_fstring(char *dest, const void *src)
1061 return pull_ascii(dest, src, sizeof(fstring), -1, STR_TERMINATE);
1064 /* When pulling an nstring it can expand into a larger size (dos cp -> utf8). Cope with this. */
1066 size_t pull_ascii_nstring(char *dest, size_t dest_len, const void *src)
1068 return pull_ascii(dest, src, dest_len, sizeof(nstring)-1, STR_TERMINATE);
1072 * Copy a string from a char* src to a unicode destination.
1074 * @returns the number of bytes occupied by the string in the destination.
1076 * @param flags can have:
1078 * <dl>
1079 * <dt>STR_TERMINATE <dd>means include the null termination.
1080 * <dt>STR_UPPER <dd>means uppercase in the destination.
1081 * <dt>STR_NOALIGN <dd>means don't do alignment.
1082 * </dl>
1084 * @param dest_len is the maximum length allowed in the
1085 * destination.
1088 size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags)
1090 size_t len=0;
1091 size_t src_len;
1092 size_t ret;
1094 if (dest_len == (size_t)-1) {
1095 /* No longer allow dest_len of -1. */
1096 smb_panic("push_ucs2 - invalid dest_len of -1");
1099 if (flags & STR_TERMINATE)
1100 src_len = (size_t)-1;
1101 else
1102 src_len = strlen(src);
1104 if (ucs2_align(base_ptr, dest, flags)) {
1105 *(char *)dest = 0;
1106 dest = (void *)((char *)dest + 1);
1107 if (dest_len)
1108 dest_len--;
1109 len++;
1112 /* ucs2 is always a multiple of 2 bytes */
1113 dest_len &= ~1;
1115 ret = convert_string(CH_UNIX, CH_UTF16LE, src, src_len, dest, dest_len, True);
1116 if (ret == (size_t)-1) {
1117 if ((flags & STR_TERMINATE) &&
1118 dest &&
1119 dest_len) {
1120 *(char *)dest = 0;
1122 return len;
1125 len += ret;
1127 if (flags & STR_UPPER) {
1128 smb_ucs2_t *dest_ucs2 = (smb_ucs2_t *)dest;
1129 size_t i;
1131 /* We check for i < (ret / 2) below as the dest string isn't null
1132 terminated if STR_TERMINATE isn't set. */
1134 for (i = 0; i < (ret / 2) && i < (dest_len / 2) && dest_ucs2[i]; i++) {
1135 smb_ucs2_t v = toupper_m(dest_ucs2[i]);
1136 if (v != dest_ucs2[i]) {
1137 dest_ucs2[i] = v;
1142 return len;
1147 * Copy a string from a unix char* src to a UCS2 destination,
1148 * allocating a buffer using talloc().
1150 * @param dest always set at least to NULL
1151 * @parm converted_size set to the number of bytes occupied by the string in
1152 * the destination on success.
1154 * @return true if new buffer was correctly allocated, and string was
1155 * converted.
1157 bool push_ucs2_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src,
1158 size_t *converted_size)
1160 size_t src_len = strlen(src)+1;
1162 *dest = NULL;
1163 return convert_string_talloc(ctx, CH_UNIX, CH_UTF16LE, src, src_len,
1164 (void **)dest, converted_size, True);
1169 Copy a string from a char* src to a UTF-8 destination.
1170 Return the number of bytes occupied by the string in the destination
1171 Flags can have:
1172 STR_TERMINATE means include the null termination
1173 STR_UPPER means uppercase in the destination
1174 dest_len is the maximum length allowed in the destination. If dest_len
1175 is -1 then no maxiumum is used.
1178 static size_t push_utf8(void *dest, const char *src, size_t dest_len, int flags)
1180 size_t src_len = 0;
1181 size_t ret;
1182 char *tmpbuf = NULL;
1184 if (dest_len == (size_t)-1) {
1185 /* No longer allow dest_len of -1. */
1186 smb_panic("push_utf8 - invalid dest_len of -1");
1189 if (flags & STR_UPPER) {
1190 tmpbuf = strupper_talloc(talloc_tos(), src);
1191 if (!tmpbuf) {
1192 return (size_t)-1;
1194 src = tmpbuf;
1195 src_len = strlen(src);
1198 src_len = strlen(src);
1199 if (flags & STR_TERMINATE) {
1200 src_len++;
1203 ret = convert_string(CH_UNIX, CH_UTF8, src, src_len, dest, dest_len, True);
1204 TALLOC_FREE(tmpbuf);
1205 return ret;
1208 size_t push_utf8_fstring(void *dest, const char *src)
1210 return push_utf8(dest, src, sizeof(fstring), STR_TERMINATE);
1214 * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer using talloc
1216 * @param dest always set at least to NULL
1217 * @parm converted_size set to the number of bytes occupied by the string in
1218 * the destination on success.
1220 * @return true if new buffer was correctly allocated, and string was
1221 * converted.
1224 bool push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
1225 size_t *converted_size)
1227 size_t src_len = strlen(src)+1;
1229 *dest = NULL;
1230 return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len,
1231 (void**)dest, converted_size, True);
1235 Copy a string from a ucs2 source to a unix char* destination.
1236 Flags can have:
1237 STR_TERMINATE means the string in src is null terminated.
1238 STR_NOALIGN means don't try to align.
1239 if STR_TERMINATE is set then src_len is ignored if it is -1.
1240 src_len is the length of the source area in bytes
1241 Return the number of bytes occupied by the string in src.
1242 The resulting string in "dest" is always null terminated.
1245 size_t pull_ucs2(const void *base_ptr, char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
1247 size_t ret;
1248 size_t ucs2_align_len = 0;
1250 if (dest_len == (size_t)-1) {
1251 /* No longer allow dest_len of -1. */
1252 smb_panic("pull_ucs2 - invalid dest_len of -1");
1255 if (!src_len) {
1256 if (dest && dest_len > 0) {
1257 dest[0] = '\0';
1259 return 0;
1262 if (ucs2_align(base_ptr, src, flags)) {
1263 src = (const void *)((const char *)src + 1);
1264 if (src_len != (size_t)-1)
1265 src_len--;
1266 ucs2_align_len = 1;
1269 if (flags & STR_TERMINATE) {
1270 /* src_len -1 is the default for null terminated strings. */
1271 if (src_len != (size_t)-1) {
1272 size_t len = strnlen_w((const smb_ucs2_t *)src,
1273 src_len/2);
1274 if (len < src_len/2)
1275 len++;
1276 src_len = len*2;
1280 /* ucs2 is always a multiple of 2 bytes */
1281 if (src_len != (size_t)-1)
1282 src_len &= ~1;
1284 ret = convert_string(CH_UTF16LE, CH_UNIX, src, src_len, dest, dest_len, True);
1285 if (ret == (size_t)-1) {
1286 ret = 0;
1287 dest_len = 0;
1290 if (src_len == (size_t)-1)
1291 src_len = ret*2;
1293 if (dest_len && ret) {
1294 /* Did we already process the terminating zero ? */
1295 if (dest[MIN(ret-1, dest_len-1)] != 0) {
1296 dest[MIN(ret, dest_len-1)] = 0;
1298 } else {
1299 dest[0] = 0;
1302 return src_len + ucs2_align_len;
1306 Copy a string from a ucs2 source to a unix char* destination.
1307 Talloc version with a base pointer.
1308 Uses malloc if TALLOC_CTX is NULL (this is a bad interface and
1309 needs fixing. JRA).
1310 Flags can have:
1311 STR_TERMINATE means the string in src is null terminated.
1312 STR_NOALIGN means don't try to align.
1313 if STR_TERMINATE is set then src_len is ignored if it is -1.
1314 src_len is the length of the source area in bytes
1315 Return the number of bytes occupied by the string in src.
1316 The resulting string in "dest" is always null terminated.
1319 size_t pull_ucs2_base_talloc(TALLOC_CTX *ctx,
1320 const void *base_ptr,
1321 char **ppdest,
1322 const void *src,
1323 size_t src_len,
1324 int flags)
1326 char *dest;
1327 size_t dest_len;
1328 size_t ucs2_align_len = 0;
1330 *ppdest = NULL;
1332 #ifdef DEVELOPER
1333 /* Ensure we never use the braindead "malloc" varient. */
1334 if (ctx == NULL) {
1335 smb_panic("NULL talloc CTX in pull_ucs2_base_talloc\n");
1337 #endif
1339 if (!src_len) {
1340 return 0;
1343 if (ucs2_align(base_ptr, src, flags)) {
1344 src = (const void *)((const char *)src + 1);
1345 if (src_len != (size_t)-1)
1346 src_len--;
1347 ucs2_align_len = 1;
1350 if (flags & STR_TERMINATE) {
1351 /* src_len -1 is the default for null terminated strings. */
1352 if (src_len != (size_t)-1) {
1353 size_t len = strnlen_w((const smb_ucs2_t *)src,
1354 src_len/2);
1355 if (len < src_len/2)
1356 len++;
1357 src_len = len*2;
1358 } else {
1360 * src_len == -1 - alloc interface won't take this
1361 * so we must calculate.
1363 src_len = (strlen_w((const smb_ucs2_t *)src)+1)*sizeof(smb_ucs2_t);
1365 /* Ensure we don't use an insane length from the client. */
1366 if (src_len >= 1024*1024) {
1367 smb_panic("Bad src length in pull_ucs2_base_talloc\n");
1369 } else {
1370 /* Can't have an unlimited length
1371 * non STR_TERMINATE'd.
1373 if (src_len == (size_t)-1) {
1374 errno = EINVAL;
1375 return 0;
1379 /* src_len != -1 here. */
1381 /* ucs2 is always a multiple of 2 bytes */
1382 src_len &= ~1;
1384 if (!convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, src, src_len,
1385 (void *)&dest, &dest_len, True)) {
1386 dest_len = 0;
1389 if (dest_len) {
1390 /* Did we already process the terminating zero ? */
1391 if (dest[dest_len-1] != 0) {
1392 size_t size = talloc_get_size(dest);
1393 /* Have we got space to append the '\0' ? */
1394 if (size <= dest_len) {
1395 /* No, realloc. */
1396 dest = TALLOC_REALLOC_ARRAY(ctx, dest, char,
1397 dest_len+1);
1398 if (!dest) {
1399 /* talloc fail. */
1400 dest_len = (size_t)-1;
1401 return 0;
1404 /* Yay - space ! */
1405 dest[dest_len] = '\0';
1406 dest_len++;
1408 } else if (dest) {
1409 dest[0] = 0;
1412 *ppdest = dest;
1413 return src_len + ucs2_align_len;
1416 size_t pull_ucs2_fstring(char *dest, const void *src)
1418 return pull_ucs2(NULL, dest, src, sizeof(fstring), -1, STR_TERMINATE);
1422 * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer using talloc
1424 * @param dest always set at least to NULL
1425 * @parm converted_size set to the number of bytes occupied by the string in
1426 * the destination on success.
1428 * @return true if new buffer was correctly allocated, and string was
1429 * converted.
1432 bool pull_ucs2_talloc(TALLOC_CTX *ctx, char **dest, const smb_ucs2_t *src,
1433 size_t *converted_size)
1435 size_t src_len = (strlen_w(src)+1) * sizeof(smb_ucs2_t);
1437 *dest = NULL;
1438 return convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, src, src_len,
1439 (void **)dest, converted_size, True);
1443 * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc
1445 * @param dest always set at least to NULL
1446 * @parm converted_size set to the number of bytes occupied by the string in
1447 * the destination on success.
1449 * @return true if new buffer was correctly allocated, and string was
1450 * converted.
1453 bool pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
1454 size_t *converted_size)
1456 size_t src_len = strlen(src)+1;
1458 *dest = NULL;
1459 return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len,
1460 (void **)dest, converted_size, True);
1465 * Copy a string from a DOS src to a unix char * destination, allocating a buffer using talloc
1467 * @param dest always set at least to NULL
1468 * @parm converted_size set to the number of bytes occupied by the string in
1469 * the destination on success.
1471 * @return true if new buffer was correctly allocated, and string was
1472 * converted.
1475 bool pull_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
1476 size_t *converted_size)
1478 size_t src_len = strlen(src)+1;
1480 *dest = NULL;
1481 return convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len,
1482 (void **)dest, converted_size, True);
1486 Copy a string from a char* src to a unicode or ascii
1487 dos codepage destination choosing unicode or ascii based on the
1488 flags supplied
1489 Return the number of bytes occupied by the string in the destination.
1490 flags can have:
1491 STR_TERMINATE means include the null termination.
1492 STR_UPPER means uppercase in the destination.
1493 STR_ASCII use ascii even with unicode packet.
1494 STR_NOALIGN means don't do alignment.
1495 dest_len is the maximum length allowed in the destination. If dest_len
1496 is -1 then no maxiumum is used.
1499 size_t push_string_check_fn(const char *function, unsigned int line,
1500 void *dest, const char *src,
1501 size_t dest_len, int flags)
1503 #ifdef DEVELOPER
1504 /* We really need to zero fill here, not clobber
1505 * region, as we want to ensure that valgrind thinks
1506 * all of the outgoing buffer has been written to
1507 * so a send() or write() won't trap an error.
1508 * JRA.
1510 #if 0
1511 clobber_region(function, line, dest, dest_len);
1512 #else
1513 memset(dest, '\0', dest_len);
1514 #endif
1515 #endif
1517 if (!(flags & STR_ASCII) && (flags & STR_UNICODE)) {
1518 return push_ucs2(NULL, dest, src, dest_len, flags);
1520 return push_ascii(dest, src, dest_len, flags);
1525 Copy a string from a char* src to a unicode or ascii
1526 dos codepage destination choosing unicode or ascii based on the
1527 flags in the SMB buffer starting at base_ptr.
1528 Return the number of bytes occupied by the string in the destination.
1529 flags can have:
1530 STR_TERMINATE means include the null termination.
1531 STR_UPPER means uppercase in the destination.
1532 STR_ASCII use ascii even with unicode packet.
1533 STR_NOALIGN means don't do alignment.
1534 dest_len is the maximum length allowed in the destination. If dest_len
1535 is -1 then no maxiumum is used.
1538 size_t push_string_base(const char *function, unsigned int line,
1539 const char *base, uint16 flags2,
1540 void *dest, const char *src,
1541 size_t dest_len, int flags)
1543 #ifdef DEVELOPER
1544 /* We really need to zero fill here, not clobber
1545 * region, as we want to ensure that valgrind thinks
1546 * all of the outgoing buffer has been written to
1547 * so a send() or write() won't trap an error.
1548 * JRA.
1550 #if 0
1551 clobber_region(function, line, dest, dest_len);
1552 #else
1553 memset(dest, '\0', dest_len);
1554 #endif
1555 #endif
1557 if (!(flags & STR_ASCII) && \
1558 ((flags & STR_UNICODE || \
1559 (flags2 & FLAGS2_UNICODE_STRINGS)))) {
1560 return push_ucs2(base, dest, src, dest_len, flags);
1562 return push_ascii(dest, src, dest_len, flags);
1566 Copy a string from a char* src to a unicode or ascii
1567 dos codepage destination choosing unicode or ascii based on the
1568 flags supplied
1569 Return the number of bytes occupied by the string in the destination.
1570 flags can have:
1571 STR_TERMINATE means include the null termination.
1572 STR_UPPER means uppercase in the destination.
1573 STR_ASCII use ascii even with unicode packet.
1574 STR_NOALIGN means don't do alignment.
1575 dest_len is the maximum length allowed in the destination. If dest_len
1576 is -1 then no maxiumum is used.
1579 ssize_t push_string(void *dest, const char *src, size_t dest_len, int flags)
1581 size_t ret;
1582 #ifdef DEVELOPER
1583 /* We really need to zero fill here, not clobber
1584 * region, as we want to ensure that valgrind thinks
1585 * all of the outgoing buffer has been written to
1586 * so a send() or write() won't trap an error.
1587 * JRA.
1589 memset(dest, '\0', dest_len);
1590 #endif
1592 if (!(flags & STR_ASCII) && \
1593 (flags & STR_UNICODE)) {
1594 ret = push_ucs2(NULL, dest, src, dest_len, flags);
1595 } else {
1596 ret = push_ascii(dest, src, dest_len, flags);
1598 if (ret == (size_t)-1) {
1599 return -1;
1601 return ret;
1605 Copy a string from a unicode or ascii source (depending on
1606 the packet flags) to a char* destination.
1607 Flags can have:
1608 STR_TERMINATE means the string in src is null terminated.
1609 STR_UNICODE means to force as unicode.
1610 STR_ASCII use ascii even with unicode packet.
1611 STR_NOALIGN means don't do alignment.
1612 if STR_TERMINATE is set then src_len is ignored is it is -1
1613 src_len is the length of the source area in bytes.
1614 Return the number of bytes occupied by the string in src.
1615 The resulting string in "dest" is always null terminated.
1618 size_t pull_string_fn(const char *function,
1619 unsigned int line,
1620 const void *base_ptr,
1621 uint16 smb_flags2,
1622 char *dest,
1623 const void *src,
1624 size_t dest_len,
1625 size_t src_len,
1626 int flags)
1628 #ifdef DEVELOPER
1629 clobber_region(function, line, dest, dest_len);
1630 #endif
1632 if ((base_ptr == NULL) && ((flags & (STR_ASCII|STR_UNICODE)) == 0)) {
1633 smb_panic("No base ptr to get flg2 and neither ASCII nor "
1634 "UNICODE defined");
1637 if (!(flags & STR_ASCII) && \
1638 ((flags & STR_UNICODE || \
1639 (smb_flags2 & FLAGS2_UNICODE_STRINGS)))) {
1640 return pull_ucs2(base_ptr, dest, src, dest_len, src_len, flags);
1642 return pull_ascii(dest, src, dest_len, src_len, flags);
1646 Copy a string from a unicode or ascii source (depending on
1647 the packet flags) to a char* destination.
1648 Variant that uses talloc.
1649 Flags can have:
1650 STR_TERMINATE means the string in src is null terminated.
1651 STR_UNICODE means to force as unicode.
1652 STR_ASCII use ascii even with unicode packet.
1653 STR_NOALIGN means don't do alignment.
1654 if STR_TERMINATE is set then src_len is ignored is it is -1
1655 src_len is the length of the source area in bytes.
1656 Return the number of bytes occupied by the string in src.
1657 The resulting string in "dest" is always null terminated.
1660 size_t pull_string_talloc_fn(const char *function,
1661 unsigned int line,
1662 TALLOC_CTX *ctx,
1663 const void *base_ptr,
1664 uint16 smb_flags2,
1665 char **ppdest,
1666 const void *src,
1667 size_t src_len,
1668 int flags)
1670 if ((base_ptr == NULL) && ((flags & (STR_ASCII|STR_UNICODE)) == 0)) {
1671 smb_panic("No base ptr to get flg2 and neither ASCII nor "
1672 "UNICODE defined");
1675 if (!(flags & STR_ASCII) && \
1676 ((flags & STR_UNICODE || \
1677 (smb_flags2 & FLAGS2_UNICODE_STRINGS)))) {
1678 return pull_ucs2_base_talloc(ctx,
1679 base_ptr,
1680 ppdest,
1681 src,
1682 src_len,
1683 flags);
1685 return pull_ascii_base_talloc(ctx,
1686 ppdest,
1687 src,
1688 src_len,
1689 flags);
1693 size_t align_string(const void *base_ptr, const char *p, int flags)
1695 if (!(flags & STR_ASCII) && \
1696 ((flags & STR_UNICODE || \
1697 (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) {
1698 return ucs2_align(base_ptr, p, flags);
1700 return 0;