tevent: Add lib/tevent as include directory.
[Samba.git] / source3 / lib / charcnv.c
blob6f1ced69d03630b8665ba99e9b6074e6df925c3c
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;
459 if (srclen == 0) {
460 ob = talloc_strdup(ctx, "");
461 if (ob == NULL) {
462 errno = ENOMEM;
463 return false;
465 *dest = ob;
466 *converted_size = 0;
467 return true;
470 lazy_initialize_conv();
471 ic = get_iconv_convenience();
472 descriptor = get_conv_handle(ic, from, to);
474 if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
475 if (!conv_silent)
476 DEBUG(0,("convert_string_talloc: Conversion not supported.\n"));
477 errno = EOPNOTSUPP;
478 return false;
481 convert:
483 /* +2 is for ucs2 null termination. */
484 if ((destlen*2)+2 < destlen) {
485 /* wrapped ! abort. */
486 if (!conv_silent)
487 DEBUG(0, ("convert_string_talloc: destlen wrapped !\n"));
488 TALLOC_FREE(outbuf);
489 errno = EOPNOTSUPP;
490 return false;
491 } else {
492 destlen = destlen * 2;
495 /* +2 is for ucs2 null termination. */
496 ob = (char *)TALLOC_REALLOC(ctx, ob, destlen + 2);
498 if (!ob) {
499 DEBUG(0, ("convert_string_talloc: realloc failed!\n"));
500 errno = ENOMEM;
501 return false;
503 outbuf = ob;
504 i_len = srclen;
505 o_len = destlen;
507 again:
509 retval = smb_iconv(descriptor,
510 &inbuf, &i_len,
511 &outbuf, &o_len);
512 if(retval == (size_t)-1) {
513 const char *reason="unknown error";
514 switch(errno) {
515 case EINVAL:
516 reason="Incomplete multibyte sequence";
517 if (!conv_silent)
518 DEBUG(3,("convert_string_talloc: Conversion error: %s(%s)\n",reason,inbuf));
519 if (allow_bad_conv)
520 goto use_as_is;
521 break;
522 case E2BIG:
523 goto convert;
524 case EILSEQ:
525 reason="Illegal multibyte sequence";
526 if (!conv_silent)
527 DEBUG(3,("convert_string_talloc: Conversion error: %s(%s)\n",reason,inbuf));
528 if (allow_bad_conv)
529 goto use_as_is;
530 break;
532 if (!conv_silent)
533 DEBUG(0,("Conversion error: %s(%s)\n",reason,inbuf));
534 /* smb_panic(reason); */
535 TALLOC_FREE(ob);
536 return false;
539 out:
541 destlen = destlen - o_len;
542 /* Don't shrink unless we're reclaiming a lot of
543 * space. This is in the hot codepath and these
544 * reallocs *cost*. JRA.
546 if (o_len > 1024) {
547 /* We're shrinking here so we know the +2 is safe from wrap. */
548 ob = (char *)TALLOC_REALLOC(ctx,ob,destlen + 2);
551 if (destlen && !ob) {
552 DEBUG(0, ("convert_string_talloc: out of memory!\n"));
553 errno = ENOMEM;
554 return false;
557 *dest = ob;
559 /* Must ucs2 null terminate in the extra space we allocated. */
560 ob[destlen] = '\0';
561 ob[destlen+1] = '\0';
563 *converted_size = destlen;
564 return true;
566 use_as_is:
569 * Conversion not supported. This is actually an error, but there are so
570 * many misconfigured iconv systems and smb.conf's out there we can't just
571 * fail. Do a very bad conversion instead.... JRA.
575 if (o_len == 0 || i_len == 0)
576 goto out;
578 if (((from == CH_UTF16LE)||(from == CH_UTF16BE)) &&
579 ((to != CH_UTF16LE)||(to != CH_UTF16BE))) {
580 /* Can't convert from utf16 any endian to multibyte.
581 Replace with the default fail char.
584 if (i_len < 2)
585 goto out;
587 if (i_len >= 2) {
588 *outbuf = lp_failed_convert_char();
590 outbuf++;
591 o_len--;
593 inbuf += 2;
594 i_len -= 2;
597 if (o_len == 0 || i_len == 0)
598 goto out;
600 /* Keep trying with the next char... */
601 goto again;
603 } else if (from != CH_UTF16LE && from != CH_UTF16BE && to == CH_UTF16LE) {
604 /* Can't convert to UTF16LE - just widen by adding the
605 default fail char then zero.
607 if (o_len < 2)
608 goto out;
610 outbuf[0] = lp_failed_convert_char();
611 outbuf[1] = '\0';
613 inbuf++;
614 i_len--;
616 outbuf += 2;
617 o_len -= 2;
619 if (o_len == 0 || i_len == 0)
620 goto out;
622 /* Keep trying with the next char... */
623 goto again;
625 } else if (from != CH_UTF16LE && from != CH_UTF16BE &&
626 to != CH_UTF16LE && to != CH_UTF16BE) {
627 /* Failed multibyte to multibyte. Just copy the default fail char and
628 try again. */
629 outbuf[0] = lp_failed_convert_char();
631 inbuf++;
632 i_len--;
634 outbuf++;
635 o_len--;
637 if (o_len == 0 || i_len == 0)
638 goto out;
640 /* Keep trying with the next char... */
641 goto again;
643 } else {
644 /* Keep compiler happy.... */
645 goto out;
650 size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
652 size_t size;
653 smb_ucs2_t *buffer;
655 if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &size)) {
656 return (size_t)-1;
659 if (!strupper_w(buffer) && (dest == src)) {
660 TALLOC_FREE(buffer);
661 return srclen;
664 size = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen, True);
665 TALLOC_FREE(buffer);
666 return size;
670 talloc_strdup() a unix string to upper case.
673 char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *s)
675 char *out_buffer = talloc_strdup(ctx,s);
676 const unsigned char *p = (const unsigned char *)s;
677 unsigned char *q = (unsigned char *)out_buffer;
679 if (!q) {
680 return NULL;
683 /* this is quite a common operation, so we want it to be
684 fast. We optimise for the ascii case, knowing that all our
685 supported multi-byte character sets are ascii-compatible
686 (ie. they match for the first 128 chars) */
688 while (*p) {
689 if (*p & 0x80)
690 break;
691 *q++ = toupper_ascii_fast(*p);
692 p++;
695 if (*p) {
696 /* MB case. */
697 size_t converted_size, converted_size2;
698 smb_ucs2_t *ubuf = NULL;
700 /* We're not using the ascii buffer above. */
701 TALLOC_FREE(out_buffer);
703 if (!convert_string_talloc(ctx, CH_UNIX, CH_UTF16LE, s,
704 strlen(s)+1, (void *)&ubuf,
705 &converted_size, True))
707 return NULL;
710 strupper_w(ubuf);
712 if (!convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, ubuf,
713 converted_size, (void *)&out_buffer,
714 &converted_size2, True))
716 TALLOC_FREE(ubuf);
717 return NULL;
720 /* Don't need the intermediate buffer
721 * anymore.
723 TALLOC_FREE(ubuf);
726 return out_buffer;
729 char *strupper_talloc(TALLOC_CTX *ctx, const char *s) {
730 return talloc_strdup_upper(ctx, s);
734 size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
736 size_t size;
737 smb_ucs2_t *buffer = NULL;
739 if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_UTF16LE, src, srclen,
740 (void **)(void *)&buffer, &size,
741 True))
743 smb_panic("failed to create UCS2 buffer");
745 if (!strlower_w(buffer) && (dest == src)) {
746 TALLOC_FREE(buffer);
747 return srclen;
749 size = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen, True);
750 TALLOC_FREE(buffer);
751 return size;
755 char *talloc_strdup_lower(TALLOC_CTX *ctx, const char *s)
757 size_t converted_size;
758 smb_ucs2_t *buffer = NULL;
759 char *out_buffer;
761 if (!push_ucs2_talloc(ctx, &buffer, s, &converted_size)) {
762 return NULL;
765 strlower_w(buffer);
767 if (!pull_ucs2_talloc(ctx, &out_buffer, buffer, &converted_size)) {
768 TALLOC_FREE(buffer);
769 return NULL;
772 TALLOC_FREE(buffer);
774 return out_buffer;
777 char *strlower_talloc(TALLOC_CTX *ctx, const char *s) {
778 return talloc_strdup_lower(ctx, s);
781 size_t ucs2_align(const void *base_ptr, const void *p, int flags)
783 if (flags & (STR_NOALIGN|STR_ASCII))
784 return 0;
785 return PTR_DIFF(p, base_ptr) & 1;
790 * Copy a string from a char* unix src to a dos codepage string destination.
792 * @return the number of bytes occupied by the string in the destination.
794 * @param flags can include
795 * <dl>
796 * <dt>STR_TERMINATE</dt> <dd>means include the null termination</dd>
797 * <dt>STR_UPPER</dt> <dd>means uppercase in the destination</dd>
798 * </dl>
800 * @param dest_len the maximum length in bytes allowed in the
801 * destination.
803 size_t push_ascii(void *dest, const char *src, size_t dest_len, int flags)
805 size_t src_len = strlen(src);
806 char *tmpbuf = NULL;
807 size_t ret;
809 /* No longer allow a length of -1. */
810 if (dest_len == (size_t)-1) {
811 smb_panic("push_ascii - dest_len == -1");
814 if (flags & STR_UPPER) {
815 tmpbuf = SMB_STRDUP(src);
816 if (!tmpbuf) {
817 smb_panic("malloc fail");
819 strupper_m(tmpbuf);
820 src = tmpbuf;
823 if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII)) {
824 src_len++;
827 ret = convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len, True);
828 if (ret == (size_t)-1 &&
829 (flags & (STR_TERMINATE | STR_TERMINATE_ASCII))
830 && dest_len > 0) {
831 ((char *)dest)[0] = '\0';
833 SAFE_FREE(tmpbuf);
834 return ret;
837 size_t push_ascii_fstring(void *dest, const char *src)
839 return push_ascii(dest, src, sizeof(fstring), STR_TERMINATE);
842 /********************************************************************
843 Push an nstring - ensure null terminated. Written by
844 moriyama@miraclelinux.com (MORIYAMA Masayuki).
845 ********************************************************************/
847 size_t push_ascii_nstring(void *dest, const char *src)
849 size_t i, buffer_len, dest_len;
850 smb_ucs2_t *buffer;
852 conv_silent = True;
853 if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &buffer_len)) {
854 smb_panic("failed to create UCS2 buffer");
857 /* We're using buffer_len below to count ucs2 characters, not bytes. */
858 buffer_len /= sizeof(smb_ucs2_t);
860 dest_len = 0;
861 for (i = 0; buffer[i] != 0 && (i < buffer_len); i++) {
862 unsigned char mb[10];
863 /* Convert one smb_ucs2_t character at a time. */
864 size_t mb_len = convert_string(CH_UTF16LE, CH_DOS, buffer+i, sizeof(smb_ucs2_t), mb, sizeof(mb), False);
865 if ((mb_len != (size_t)-1) && (dest_len + mb_len <= MAX_NETBIOSNAME_LEN - 1)) {
866 memcpy((char *)dest + dest_len, mb, mb_len);
867 dest_len += mb_len;
868 } else {
869 errno = E2BIG;
870 break;
873 ((char *)dest)[dest_len] = '\0';
875 conv_silent = False;
876 TALLOC_FREE(buffer);
877 return dest_len;
880 /********************************************************************
881 Push and malloc an ascii string. src and dest null terminated.
882 ********************************************************************/
884 bool push_ascii_talloc(TALLOC_CTX *mem_ctx, char **dest, const char *src, size_t *converted_size)
886 size_t src_len = strlen(src)+1;
888 *dest = NULL;
889 return convert_string_talloc(mem_ctx, CH_UNIX, CH_DOS, src, src_len,
890 (void **)dest, converted_size, True);
894 * Copy a string from a dos codepage source to a unix char* destination.
896 * The resulting string in "dest" is always null terminated.
898 * @param flags can have:
899 * <dl>
900 * <dt>STR_TERMINATE</dt>
901 * <dd>STR_TERMINATE means the string in @p src
902 * is null terminated, and src_len is ignored.</dd>
903 * </dl>
905 * @param src_len is the length of the source area in bytes.
906 * @returns the number of bytes occupied by the string in @p src.
908 size_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
910 size_t ret;
912 if (dest_len == (size_t)-1) {
913 /* No longer allow dest_len of -1. */
914 smb_panic("pull_ascii - invalid dest_len of -1");
917 if (flags & STR_TERMINATE) {
918 if (src_len == (size_t)-1) {
919 src_len = strlen((const char *)src) + 1;
920 } else {
921 size_t len = strnlen((const char *)src, src_len);
922 if (len < src_len)
923 len++;
924 src_len = len;
928 ret = convert_string(CH_DOS, CH_UNIX, src, src_len, dest, dest_len, True);
929 if (ret == (size_t)-1) {
930 ret = 0;
931 dest_len = 0;
934 if (dest_len && ret) {
935 /* Did we already process the terminating zero ? */
936 if (dest[MIN(ret-1, dest_len-1)] != 0) {
937 dest[MIN(ret, dest_len-1)] = 0;
939 } else {
940 dest[0] = 0;
943 return src_len;
947 * Copy a string from a dos codepage source to a unix char* destination.
948 * Talloc version.
950 * The resulting string in "dest" is always null terminated.
952 * @param flags can have:
953 * <dl>
954 * <dt>STR_TERMINATE</dt>
955 * <dd>STR_TERMINATE means the string in @p src
956 * is null terminated, and src_len is ignored.</dd>
957 * </dl>
959 * @param src_len is the length of the source area in bytes.
960 * @returns the number of bytes occupied by the string in @p src.
963 static size_t pull_ascii_base_talloc(TALLOC_CTX *ctx,
964 char **ppdest,
965 const void *src,
966 size_t src_len,
967 int flags)
969 char *dest = NULL;
970 size_t dest_len;
972 *ppdest = NULL;
974 if (!src_len) {
975 return 0;
978 if (flags & STR_TERMINATE) {
979 if (src_len == (size_t)-1) {
980 src_len = strlen((const char *)src) + 1;
981 } else {
982 size_t len = strnlen((const char *)src, src_len);
983 if (len < src_len)
984 len++;
985 src_len = len;
987 /* Ensure we don't use an insane length from the client. */
988 if (src_len >= 1024*1024) {
989 char *msg = talloc_asprintf(ctx,
990 "Bad src length (%u) in "
991 "pull_ascii_base_talloc",
992 (unsigned int)src_len);
993 smb_panic(msg);
995 } else {
996 /* Can't have an unlimited length
997 * non STR_TERMINATE'd.
999 if (src_len == (size_t)-1) {
1000 errno = EINVAL;
1001 return 0;
1005 /* src_len != -1 here. */
1007 if (!convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len, &dest,
1008 &dest_len, True)) {
1009 dest_len = 0;
1012 if (dest_len && dest) {
1013 /* Did we already process the terminating zero ? */
1014 if (dest[dest_len-1] != 0) {
1015 size_t size = talloc_get_size(dest);
1016 /* Have we got space to append the '\0' ? */
1017 if (size <= dest_len) {
1018 /* No, realloc. */
1019 dest = TALLOC_REALLOC_ARRAY(ctx, dest, char,
1020 dest_len+1);
1021 if (!dest) {
1022 /* talloc fail. */
1023 dest_len = (size_t)-1;
1024 return 0;
1027 /* Yay - space ! */
1028 dest[dest_len] = '\0';
1029 dest_len++;
1031 } else if (dest) {
1032 dest[0] = 0;
1035 *ppdest = dest;
1036 return src_len;
1039 size_t pull_ascii_fstring(char *dest, const void *src)
1041 return pull_ascii(dest, src, sizeof(fstring), -1, STR_TERMINATE);
1044 /* When pulling an nstring it can expand into a larger size (dos cp -> utf8). Cope with this. */
1046 size_t pull_ascii_nstring(char *dest, size_t dest_len, const void *src)
1048 return pull_ascii(dest, src, dest_len, sizeof(nstring)-1, STR_TERMINATE);
1052 * Copy a string from a char* src to a unicode destination.
1054 * @returns the number of bytes occupied by the string in the destination.
1056 * @param flags can have:
1058 * <dl>
1059 * <dt>STR_TERMINATE <dd>means include the null termination.
1060 * <dt>STR_UPPER <dd>means uppercase in the destination.
1061 * <dt>STR_NOALIGN <dd>means don't do alignment.
1062 * </dl>
1064 * @param dest_len is the maximum length allowed in the
1065 * destination.
1068 size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags)
1070 size_t len=0;
1071 size_t src_len;
1072 size_t ret;
1074 if (dest_len == (size_t)-1) {
1075 /* No longer allow dest_len of -1. */
1076 smb_panic("push_ucs2 - invalid dest_len of -1");
1079 if (flags & STR_TERMINATE)
1080 src_len = (size_t)-1;
1081 else
1082 src_len = strlen(src);
1084 if (ucs2_align(base_ptr, dest, flags)) {
1085 *(char *)dest = 0;
1086 dest = (void *)((char *)dest + 1);
1087 if (dest_len)
1088 dest_len--;
1089 len++;
1092 /* ucs2 is always a multiple of 2 bytes */
1093 dest_len &= ~1;
1095 ret = convert_string(CH_UNIX, CH_UTF16LE, src, src_len, dest, dest_len, True);
1096 if (ret == (size_t)-1) {
1097 if ((flags & STR_TERMINATE) &&
1098 dest &&
1099 dest_len) {
1100 *(char *)dest = 0;
1102 return len;
1105 len += ret;
1107 if (flags & STR_UPPER) {
1108 smb_ucs2_t *dest_ucs2 = (smb_ucs2_t *)dest;
1109 size_t i;
1111 /* We check for i < (ret / 2) below as the dest string isn't null
1112 terminated if STR_TERMINATE isn't set. */
1114 for (i = 0; i < (ret / 2) && i < (dest_len / 2) && dest_ucs2[i]; i++) {
1115 smb_ucs2_t v = toupper_m(dest_ucs2[i]);
1116 if (v != dest_ucs2[i]) {
1117 dest_ucs2[i] = v;
1122 return len;
1127 * Copy a string from a unix char* src to a UCS2 destination,
1128 * allocating a buffer using talloc().
1130 * @param dest always set at least to NULL
1131 * @parm converted_size set to the number of bytes occupied by the string in
1132 * the destination on success.
1134 * @return true if new buffer was correctly allocated, and string was
1135 * converted.
1137 bool push_ucs2_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src,
1138 size_t *converted_size)
1140 size_t src_len = strlen(src)+1;
1142 *dest = NULL;
1143 return convert_string_talloc(ctx, CH_UNIX, CH_UTF16LE, src, src_len,
1144 (void **)dest, converted_size, True);
1149 Copy a string from a char* src to a UTF-8 destination.
1150 Return the number of bytes occupied by the string in the destination
1151 Flags can have:
1152 STR_TERMINATE means include the null termination
1153 STR_UPPER means uppercase in the destination
1154 dest_len is the maximum length allowed in the destination. If dest_len
1155 is -1 then no maxiumum is used.
1158 static size_t push_utf8(void *dest, const char *src, size_t dest_len, int flags)
1160 size_t src_len = 0;
1161 size_t ret;
1162 char *tmpbuf = NULL;
1164 if (dest_len == (size_t)-1) {
1165 /* No longer allow dest_len of -1. */
1166 smb_panic("push_utf8 - invalid dest_len of -1");
1169 if (flags & STR_UPPER) {
1170 tmpbuf = strupper_talloc(talloc_tos(), src);
1171 if (!tmpbuf) {
1172 return (size_t)-1;
1174 src = tmpbuf;
1175 src_len = strlen(src);
1178 src_len = strlen(src);
1179 if (flags & STR_TERMINATE) {
1180 src_len++;
1183 ret = convert_string(CH_UNIX, CH_UTF8, src, src_len, dest, dest_len, True);
1184 TALLOC_FREE(tmpbuf);
1185 return ret;
1188 size_t push_utf8_fstring(void *dest, const char *src)
1190 return push_utf8(dest, src, sizeof(fstring), STR_TERMINATE);
1194 * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer using talloc
1196 * @param dest always set at least to NULL
1197 * @parm converted_size set to the number of bytes occupied by the string in
1198 * the destination on success.
1200 * @return true if new buffer was correctly allocated, and string was
1201 * converted.
1204 bool push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
1205 size_t *converted_size)
1207 size_t src_len = strlen(src)+1;
1209 *dest = NULL;
1210 return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len,
1211 (void**)dest, converted_size, True);
1215 Copy a string from a ucs2 source to a unix char* destination.
1216 Flags can have:
1217 STR_TERMINATE means the string in src is null terminated.
1218 STR_NOALIGN means don't try to align.
1219 if STR_TERMINATE is set then src_len is ignored if it is -1.
1220 src_len is the length of the source area in bytes
1221 Return the number of bytes occupied by the string in src.
1222 The resulting string in "dest" is always null terminated.
1225 size_t pull_ucs2(const void *base_ptr, char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
1227 size_t ret;
1229 if (dest_len == (size_t)-1) {
1230 /* No longer allow dest_len of -1. */
1231 smb_panic("pull_ucs2 - invalid dest_len of -1");
1234 if (!src_len) {
1235 if (dest && dest_len > 0) {
1236 dest[0] = '\0';
1238 return 0;
1241 if (ucs2_align(base_ptr, src, flags)) {
1242 src = (const void *)((const char *)src + 1);
1243 if (src_len != (size_t)-1)
1244 src_len--;
1247 if (flags & STR_TERMINATE) {
1248 /* src_len -1 is the default for null terminated strings. */
1249 if (src_len != (size_t)-1) {
1250 size_t len = strnlen_w((const smb_ucs2_t *)src,
1251 src_len/2);
1252 if (len < src_len/2)
1253 len++;
1254 src_len = len*2;
1258 /* ucs2 is always a multiple of 2 bytes */
1259 if (src_len != (size_t)-1)
1260 src_len &= ~1;
1262 ret = convert_string(CH_UTF16LE, CH_UNIX, src, src_len, dest, dest_len, True);
1263 if (ret == (size_t)-1) {
1264 ret = 0;
1265 dest_len = 0;
1268 if (src_len == (size_t)-1)
1269 src_len = ret*2;
1271 if (dest_len && ret) {
1272 /* Did we already process the terminating zero ? */
1273 if (dest[MIN(ret-1, dest_len-1)] != 0) {
1274 dest[MIN(ret, dest_len-1)] = 0;
1276 } else {
1277 dest[0] = 0;
1280 return src_len;
1284 Copy a string from a ucs2 source to a unix char* destination.
1285 Talloc version with a base pointer.
1286 Uses malloc if TALLOC_CTX is NULL (this is a bad interface and
1287 needs fixing. JRA).
1288 Flags can have:
1289 STR_TERMINATE means the string in src is null terminated.
1290 STR_NOALIGN means don't try to align.
1291 if STR_TERMINATE is set then src_len is ignored if it is -1.
1292 src_len is the length of the source area in bytes
1293 Return the number of bytes occupied by the string in src.
1294 The resulting string in "dest" is always null terminated.
1297 size_t pull_ucs2_base_talloc(TALLOC_CTX *ctx,
1298 const void *base_ptr,
1299 char **ppdest,
1300 const void *src,
1301 size_t src_len,
1302 int flags)
1304 char *dest;
1305 size_t dest_len;
1307 *ppdest = NULL;
1309 #ifdef DEVELOPER
1310 /* Ensure we never use the braindead "malloc" varient. */
1311 if (ctx == NULL) {
1312 smb_panic("NULL talloc CTX in pull_ucs2_base_talloc\n");
1314 #endif
1316 if (!src_len) {
1317 return 0;
1320 if (ucs2_align(base_ptr, src, flags)) {
1321 src = (const void *)((const char *)src + 1);
1322 if (src_len != (size_t)-1)
1323 src_len--;
1326 if (flags & STR_TERMINATE) {
1327 /* src_len -1 is the default for null terminated strings. */
1328 if (src_len != (size_t)-1) {
1329 size_t len = strnlen_w((const smb_ucs2_t *)src,
1330 src_len/2);
1331 if (len < src_len/2)
1332 len++;
1333 src_len = len*2;
1334 } else {
1336 * src_len == -1 - alloc interface won't take this
1337 * so we must calculate.
1339 src_len = (strlen_w((const smb_ucs2_t *)src)+1)*sizeof(smb_ucs2_t);
1341 /* Ensure we don't use an insane length from the client. */
1342 if (src_len >= 1024*1024) {
1343 smb_panic("Bad src length in pull_ucs2_base_talloc\n");
1345 } else {
1346 /* Can't have an unlimited length
1347 * non STR_TERMINATE'd.
1349 if (src_len == (size_t)-1) {
1350 errno = EINVAL;
1351 return 0;
1355 /* src_len != -1 here. */
1357 /* ucs2 is always a multiple of 2 bytes */
1358 src_len &= ~1;
1360 if (!convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, src, src_len,
1361 (void *)&dest, &dest_len, True)) {
1362 dest_len = 0;
1365 if (dest_len) {
1366 /* Did we already process the terminating zero ? */
1367 if (dest[dest_len-1] != 0) {
1368 size_t size = talloc_get_size(dest);
1369 /* Have we got space to append the '\0' ? */
1370 if (size <= dest_len) {
1371 /* No, realloc. */
1372 dest = TALLOC_REALLOC_ARRAY(ctx, dest, char,
1373 dest_len+1);
1374 if (!dest) {
1375 /* talloc fail. */
1376 dest_len = (size_t)-1;
1377 return 0;
1380 /* Yay - space ! */
1381 dest[dest_len] = '\0';
1382 dest_len++;
1384 } else if (dest) {
1385 dest[0] = 0;
1388 *ppdest = dest;
1389 return src_len;
1392 size_t pull_ucs2_fstring(char *dest, const void *src)
1394 return pull_ucs2(NULL, dest, src, sizeof(fstring), -1, STR_TERMINATE);
1398 * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer using talloc
1400 * @param dest always set at least to NULL
1401 * @parm converted_size set to the number of bytes occupied by the string in
1402 * the destination on success.
1404 * @return true if new buffer was correctly allocated, and string was
1405 * converted.
1408 bool pull_ucs2_talloc(TALLOC_CTX *ctx, char **dest, const smb_ucs2_t *src,
1409 size_t *converted_size)
1411 size_t src_len = (strlen_w(src)+1) * sizeof(smb_ucs2_t);
1413 *dest = NULL;
1414 return convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, src, src_len,
1415 (void **)dest, converted_size, True);
1419 * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc
1421 * @param dest always set at least to NULL
1422 * @parm converted_size set to the number of bytes occupied by the string in
1423 * the destination on success.
1425 * @return true if new buffer was correctly allocated, and string was
1426 * converted.
1429 bool pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
1430 size_t *converted_size)
1432 size_t src_len = strlen(src)+1;
1434 *dest = NULL;
1435 return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len,
1436 (void **)dest, converted_size, True);
1441 * Copy a string from a DOS src to a unix char * destination, allocating a buffer using talloc
1443 * @param dest always set at least to NULL
1444 * @parm converted_size set to the number of bytes occupied by the string in
1445 * the destination on success.
1447 * @return true if new buffer was correctly allocated, and string was
1448 * converted.
1451 bool pull_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
1452 size_t *converted_size)
1454 size_t src_len = strlen(src)+1;
1456 *dest = NULL;
1457 return convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len,
1458 (void **)dest, converted_size, True);
1462 Copy a string from a char* src to a unicode or ascii
1463 dos codepage destination choosing unicode or ascii based on the
1464 flags supplied
1465 Return the number of bytes occupied by the string in the destination.
1466 flags can have:
1467 STR_TERMINATE means include the null termination.
1468 STR_UPPER means uppercase in the destination.
1469 STR_ASCII use ascii even with unicode packet.
1470 STR_NOALIGN means don't do alignment.
1471 dest_len is the maximum length allowed in the destination. If dest_len
1472 is -1 then no maxiumum is used.
1475 size_t push_string_check_fn(const char *function, unsigned int line,
1476 void *dest, const char *src,
1477 size_t dest_len, int flags)
1479 #ifdef DEVELOPER
1480 /* We really need to zero fill here, not clobber
1481 * region, as we want to ensure that valgrind thinks
1482 * all of the outgoing buffer has been written to
1483 * so a send() or write() won't trap an error.
1484 * JRA.
1486 #if 0
1487 clobber_region(function, line, dest, dest_len);
1488 #else
1489 memset(dest, '\0', dest_len);
1490 #endif
1491 #endif
1493 if (!(flags & STR_ASCII) && (flags & STR_UNICODE)) {
1494 return push_ucs2(NULL, dest, src, dest_len, flags);
1496 return push_ascii(dest, src, dest_len, flags);
1501 Copy a string from a char* src to a unicode or ascii
1502 dos codepage destination choosing unicode or ascii based on the
1503 flags in the SMB buffer starting at base_ptr.
1504 Return the number of bytes occupied by the string in the destination.
1505 flags can have:
1506 STR_TERMINATE means include the null termination.
1507 STR_UPPER means uppercase in the destination.
1508 STR_ASCII use ascii even with unicode packet.
1509 STR_NOALIGN means don't do alignment.
1510 dest_len is the maximum length allowed in the destination. If dest_len
1511 is -1 then no maxiumum is used.
1514 size_t push_string_base(const char *function, unsigned int line,
1515 const char *base, uint16 flags2,
1516 void *dest, const char *src,
1517 size_t dest_len, int flags)
1519 #ifdef DEVELOPER
1520 /* We really need to zero fill here, not clobber
1521 * region, as we want to ensure that valgrind thinks
1522 * all of the outgoing buffer has been written to
1523 * so a send() or write() won't trap an error.
1524 * JRA.
1526 #if 0
1527 clobber_region(function, line, dest, dest_len);
1528 #else
1529 memset(dest, '\0', dest_len);
1530 #endif
1531 #endif
1533 if (!(flags & STR_ASCII) && \
1534 ((flags & STR_UNICODE || \
1535 (flags2 & FLAGS2_UNICODE_STRINGS)))) {
1536 return push_ucs2(base, dest, src, dest_len, flags);
1538 return push_ascii(dest, src, dest_len, flags);
1542 Copy a string from a char* src to a unicode or ascii
1543 dos codepage destination choosing unicode or ascii based on the
1544 flags supplied
1545 Return the number of bytes occupied by the string in the destination.
1546 flags can have:
1547 STR_TERMINATE means include the null termination.
1548 STR_UPPER means uppercase in the destination.
1549 STR_ASCII use ascii even with unicode packet.
1550 STR_NOALIGN means don't do alignment.
1551 dest_len is the maximum length allowed in the destination. If dest_len
1552 is -1 then no maxiumum is used.
1555 ssize_t push_string(void *dest, const char *src, size_t dest_len, int flags)
1557 size_t ret;
1558 #ifdef DEVELOPER
1559 /* We really need to zero fill here, not clobber
1560 * region, as we want to ensure that valgrind thinks
1561 * all of the outgoing buffer has been written to
1562 * so a send() or write() won't trap an error.
1563 * JRA.
1565 memset(dest, '\0', dest_len);
1566 #endif
1568 if (!(flags & STR_ASCII) && \
1569 (flags & STR_UNICODE)) {
1570 ret = push_ucs2(NULL, dest, src, dest_len, flags);
1571 } else {
1572 ret = push_ascii(dest, src, dest_len, flags);
1574 if (ret == (size_t)-1) {
1575 return -1;
1577 return ret;
1581 Copy a string from a unicode or ascii source (depending on
1582 the packet flags) to a char* destination.
1583 Flags can have:
1584 STR_TERMINATE means the string in src is null terminated.
1585 STR_UNICODE means to force as unicode.
1586 STR_ASCII use ascii even with unicode packet.
1587 STR_NOALIGN means don't do alignment.
1588 if STR_TERMINATE is set then src_len is ignored is it is -1
1589 src_len is the length of the source area in bytes.
1590 Return the number of bytes occupied by the string in src.
1591 The resulting string in "dest" is always null terminated.
1594 size_t pull_string_fn(const char *function,
1595 unsigned int line,
1596 const void *base_ptr,
1597 uint16 smb_flags2,
1598 char *dest,
1599 const void *src,
1600 size_t dest_len,
1601 size_t src_len,
1602 int flags)
1604 #ifdef DEVELOPER
1605 clobber_region(function, line, dest, dest_len);
1606 #endif
1608 if ((base_ptr == NULL) && ((flags & (STR_ASCII|STR_UNICODE)) == 0)) {
1609 smb_panic("No base ptr to get flg2 and neither ASCII nor "
1610 "UNICODE defined");
1613 if (!(flags & STR_ASCII) && \
1614 ((flags & STR_UNICODE || \
1615 (smb_flags2 & FLAGS2_UNICODE_STRINGS)))) {
1616 return pull_ucs2(base_ptr, dest, src, dest_len, src_len, flags);
1618 return pull_ascii(dest, src, dest_len, src_len, flags);
1622 Copy a string from a unicode or ascii source (depending on
1623 the packet flags) to a char* destination.
1624 Variant that uses talloc.
1625 Flags can have:
1626 STR_TERMINATE means the string in src is null terminated.
1627 STR_UNICODE means to force as unicode.
1628 STR_ASCII use ascii even with unicode packet.
1629 STR_NOALIGN means don't do alignment.
1630 if STR_TERMINATE is set then src_len is ignored is it is -1
1631 src_len is the length of the source area in bytes.
1632 Return the number of bytes occupied by the string in src.
1633 The resulting string in "dest" is always null terminated.
1636 size_t pull_string_talloc_fn(const char *function,
1637 unsigned int line,
1638 TALLOC_CTX *ctx,
1639 const void *base_ptr,
1640 uint16 smb_flags2,
1641 char **ppdest,
1642 const void *src,
1643 size_t src_len,
1644 int flags)
1646 if ((base_ptr == NULL) && ((flags & (STR_ASCII|STR_UNICODE)) == 0)) {
1647 smb_panic("No base ptr to get flg2 and neither ASCII nor "
1648 "UNICODE defined");
1651 if (!(flags & STR_ASCII) && \
1652 ((flags & STR_UNICODE || \
1653 (smb_flags2 & FLAGS2_UNICODE_STRINGS)))) {
1654 return pull_ucs2_base_talloc(ctx,
1655 base_ptr,
1656 ppdest,
1657 src,
1658 src_len,
1659 flags);
1661 return pull_ascii_base_talloc(ctx,
1662 ppdest,
1663 src,
1664 src_len,
1665 flags);
1669 size_t align_string(const void *base_ptr, const char *p, int flags)
1671 if (!(flags & STR_ASCII) && \
1672 ((flags & STR_UNICODE || \
1673 (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) {
1674 return ucs2_align(base_ptr, p, flags);
1676 return 0;