r13915: Fixed a very interesting class of realloc() bugs found by Coverity.
[samba.git] / source / lib / charcnv.c
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
8    
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.
13    
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.
18    
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.
22
23 */
24 #include "includes.h"
25
26 /* We can parameterize this if someone complains.... JRA. */
27
28 char lp_failed_convert_char(void)
29 {
30         return '_';
31 }
32
33 /**
34  * @file
35  *
36  * @brief Character-set conversion routines built on our iconv.
37  * 
38  * @note Samba's internal character set (at least in the 3.0 series)
39  * is always the same as the one for the Unix filesystem.  It is
40  * <b>not</b> necessarily UTF-8 and may be different on machines that
41  * need i18n filenames to be compatible with Unix software.  It does
42  * have to be a superset of ASCII.  All multibyte sequences must start
43  * with a byte with the high bit set.
44  *
45  * @sa lib/iconv.c
46  */
47
48
49 static smb_iconv_t conv_handles[NUM_CHARSETS][NUM_CHARSETS];
50 static BOOL conv_silent; /* Should we do a debug if the conversion fails ? */
51
52 /**
53  * Return the name of a charset to give to iconv().
54  **/
55 static const char *charset_name(charset_t ch)
56 {
57         const char *ret = NULL;
58
59         if (ch == CH_UCS2) ret = "UTF-16LE";
60         else if (ch == CH_UNIX) ret = lp_unix_charset();
61         else if (ch == CH_DOS) ret = lp_dos_charset();
62         else if (ch == CH_DISPLAY) ret = lp_display_charset();
63         else if (ch == CH_UTF8) ret = "UTF8";
64
65 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
66         if (ret && !strcmp(ret, "LOCALE")) {
67                 const char *ln = NULL;
68
69 #ifdef HAVE_SETLOCALE
70                 setlocale(LC_ALL, "");
71 #endif
72                 ln = nl_langinfo(CODESET);
73                 if (ln) {
74                         /* Check whether the charset name is supported
75                            by iconv */
76                         smb_iconv_t handle = smb_iconv_open(ln,"UCS-2LE");
77                         if (handle == (smb_iconv_t) -1) {
78                                 DEBUG(5,("Locale charset '%s' unsupported, using ASCII instead\n", ln));
79                                 ln = NULL;
80                         } else {
81                                 DEBUG(5,("Substituting charset '%s' for LOCALE\n", ln));
82                                 smb_iconv_close(handle);
83                         }
84                 }
85                 ret = ln;
86         }
87 #endif
88
89         if (!ret || !*ret) ret = "ASCII";
90         return ret;
91 }
92
93 void lazy_initialize_conv(void)
94 {
95         static int initialized = False;
96
97         if (!initialized) {
98                 initialized = True;
99                 load_case_tables();
100                 init_iconv();
101         }
102 }
103
104 /**
105  * Initialize iconv conversion descriptors.
106  *
107  * This is called the first time it is needed, and also called again
108  * every time the configuration is reloaded, because the charset or
109  * codepage might have changed.
110  **/
111 void init_iconv(void)
112 {
113         int c1, c2;
114         BOOL did_reload = False;
115
116         /* so that charset_name() works we need to get the UNIX<->UCS2 going
117            first */
118         if (!conv_handles[CH_UNIX][CH_UCS2])
119                 conv_handles[CH_UNIX][CH_UCS2] = smb_iconv_open(charset_name(CH_UCS2), "ASCII");
120
121         if (!conv_handles[CH_UCS2][CH_UNIX])
122                 conv_handles[CH_UCS2][CH_UNIX] = smb_iconv_open("ASCII", charset_name(CH_UCS2));
123
124         for (c1=0;c1<NUM_CHARSETS;c1++) {
125                 for (c2=0;c2<NUM_CHARSETS;c2++) {
126                         const char *n1 = charset_name((charset_t)c1);
127                         const char *n2 = charset_name((charset_t)c2);
128                         if (conv_handles[c1][c2] &&
129                             strcmp(n1, conv_handles[c1][c2]->from_name) == 0 &&
130                             strcmp(n2, conv_handles[c1][c2]->to_name) == 0)
131                                 continue;
132
133                         did_reload = True;
134
135                         if (conv_handles[c1][c2])
136                                 smb_iconv_close(conv_handles[c1][c2]);
137
138                         conv_handles[c1][c2] = smb_iconv_open(n2,n1);
139                         if (conv_handles[c1][c2] == (smb_iconv_t)-1) {
140                                 DEBUG(0,("init_iconv: Conversion from %s to %s not supported\n",
141                                          charset_name((charset_t)c1), charset_name((charset_t)c2)));
142                                 if (c1 != CH_UCS2) {
143                                         n1 = "ASCII";
144                                 }
145                                 if (c2 != CH_UCS2) {
146                                         n2 = "ASCII";
147                                 }
148                                 DEBUG(0,("init_iconv: Attempting to replace with conversion from %s to %s\n",
149                                         n1, n2 ));
150                                 conv_handles[c1][c2] = smb_iconv_open(n2,n1);
151                                 if (!conv_handles[c1][c2]) {
152                                         DEBUG(0,("init_iconv: Conversion from %s to %s failed", n1, n2));
153                                         smb_panic("init_iconv: conv_handle initialization failed.");
154                                 }
155                         }
156                 }
157         }
158
159         if (did_reload) {
160                 /* XXX: Does this really get called every time the dos
161                  * codepage changes? */
162                 /* XXX: Is the did_reload test too strict? */
163                 conv_silent = True;
164                 init_doschar_table();
165                 init_valid_table();
166                 conv_silent = False;
167         }
168 }
169
170 /**
171  * Convert string from one encoding to another, making error checking etc
172  * Slow path version - uses (slow) iconv.
173  *
174  * @param src pointer to source string (multibyte or singlebyte)
175  * @param srclen length of the source string in bytes
176  * @param dest pointer to destination string (multibyte or singlebyte)
177  * @param destlen maximal length allowed for string
178  * @param allow_bad_conv determines if a "best effort" conversion is acceptable (never returns errors)
179  * @returns the number of bytes occupied in the destination
180  *
181  * Ensure the srclen contains the terminating zero.
182  *
183  **/
184
185 static size_t convert_string_internal(charset_t from, charset_t to,
186                       void const *src, size_t srclen, 
187                       void *dest, size_t destlen, BOOL allow_bad_conv)
188 {
189         size_t i_len, o_len;
190         size_t retval;
191         const char* inbuf = (const char*)src;
192         char* outbuf = (char*)dest;
193         smb_iconv_t descriptor;
194
195         lazy_initialize_conv();
196
197         descriptor = conv_handles[from][to];
198
199         if (srclen == (size_t)-1) {
200                 if (from == CH_UCS2) {
201                         srclen = (strlen_w((const smb_ucs2_t *)src)+1) * 2;
202                 } else {
203                         srclen = strlen((const char *)src)+1;
204                 }
205         }
206
207
208         if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
209                 if (!conv_silent)
210                         DEBUG(0,("convert_string_internal: Conversion not supported.\n"));
211                 return (size_t)-1;
212         }
213
214         i_len=srclen;
215         o_len=destlen;
216
217  again:
218
219         retval = smb_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len);
220         if(retval==(size_t)-1) {
221                 const char *reason="unknown error";
222                 switch(errno) {
223                         case EINVAL:
224                                 reason="Incomplete multibyte sequence";
225                                 if (!conv_silent)
226                                         DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
227                                 if (allow_bad_conv)
228                                         goto use_as_is;
229                                 break;
230                         case E2BIG:
231                                 reason="No more room"; 
232                                 if (!conv_silent) {
233                                         if (from == CH_UNIX) {
234                                                 DEBUG(3,("E2BIG: convert_string(%s,%s): srclen=%u destlen=%u - '%s'\n",
235                                                         charset_name(from), charset_name(to),
236                                                         (unsigned int)srclen, (unsigned int)destlen, (const char *)src));
237                                         } else {
238                                                 DEBUG(3,("E2BIG: convert_string(%s,%s): srclen=%u destlen=%u\n",
239                                                         charset_name(from), charset_name(to),
240                                                         (unsigned int)srclen, (unsigned int)destlen));
241                                         }
242                                 }
243                                 break;
244                         case EILSEQ:
245                                 reason="Illegal multibyte sequence";
246                                 if (!conv_silent)
247                                         DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
248                                 if (allow_bad_conv)
249                                         goto use_as_is;
250                                 break;
251                         default:
252                                 if (!conv_silent)
253                                         DEBUG(0,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
254                                 break;
255                 }
256                 /* smb_panic(reason); */
257         }
258         return destlen-o_len;
259
260  use_as_is:
261
262         /* 
263          * Conversion not supported. This is actually an error, but there are so
264          * many misconfigured iconv systems and smb.conf's out there we can't just
265          * fail. Do a very bad conversion instead.... JRA.
266          */
267
268         {
269                 if (o_len == 0 || i_len == 0)
270                         return destlen - o_len;
271
272                 if (from == CH_UCS2 && to != CH_UCS2) {
273                         /* Can't convert from ucs2 to multibyte. Replace with the default fail char. */
274                         if (i_len < 2)
275                                 return destlen - o_len;
276                         if (i_len >= 2) {
277                                 *outbuf = lp_failed_convert_char();
278
279                                 outbuf++;
280                                 o_len--;
281
282                                 inbuf += 2;
283                                 i_len -= 2;
284                         }
285
286                         if (o_len == 0 || i_len == 0)
287                                 return destlen - o_len;
288
289                         /* Keep trying with the next char... */
290                         goto again;
291
292                 } else if (from != CH_UCS2 && to == CH_UCS2) {
293                         /* Can't convert to ucs2 - just widen by adding the default fail char then zero. */
294                         if (o_len < 2)
295                                 return destlen - o_len;
296
297                         outbuf[0] = lp_failed_convert_char();
298                         outbuf[1] = '\0';
299
300                         inbuf++;
301                         i_len--;
302
303                         outbuf += 2;
304                         o_len -= 2;
305
306                         if (o_len == 0 || i_len == 0)
307                                 return destlen - o_len;
308
309                         /* Keep trying with the next char... */
310                         goto again;
311
312                 } else if (from != CH_UCS2 && to != CH_UCS2) {
313                         /* Failed multibyte to multibyte. Just copy the default fail char and
314                                 try again. */
315                         outbuf[0] = lp_failed_convert_char();
316
317                         inbuf++;
318                         i_len--;
319
320                         outbuf++;
321                         o_len--;
322
323                         if (o_len == 0 || i_len == 0)
324                                 return destlen - o_len;
325
326                         /* Keep trying with the next char... */
327                         goto again;
328
329                 } else {
330                         /* Keep compiler happy.... */
331                         return destlen - o_len;
332                 }
333         }
334 }
335
336 /**
337  * Convert string from one encoding to another, making error checking etc
338  * Fast path version - handles ASCII first.
339  *
340  * @param src pointer to source string (multibyte or singlebyte)
341  * @param srclen length of the source string in bytes, or -1 for nul terminated.
342  * @param dest pointer to destination string (multibyte or singlebyte)
343  * @param destlen maximal length allowed for string - *NEVER* -1.
344  * @param allow_bad_conv determines if a "best effort" conversion is acceptable (never returns errors)
345  * @returns the number of bytes occupied in the destination
346  *
347  * Ensure the srclen contains the terminating zero.
348  *
349  * This function has been hand-tuned to provide a fast path.
350  * Don't change unless you really know what you are doing. JRA.
351  **/
352
353 size_t convert_string(charset_t from, charset_t to,
354                       void const *src, size_t srclen, 
355                       void *dest, size_t destlen, BOOL allow_bad_conv)
356 {
357         /*
358          * NB. We deliberately don't do a strlen here if srclen == -1.
359          * This is very expensive over millions of calls and is taken
360          * care of in the slow path in convert_string_internal. JRA.
361          */
362
363 #ifdef DEVELOPER
364         SMB_ASSERT(destlen != (size_t)-1);
365 #endif
366
367         if (srclen == 0)
368                 return 0;
369
370         if (from != CH_UCS2 && to != CH_UCS2) {
371                 const unsigned char *p = (const unsigned char *)src;
372                 unsigned char *q = (unsigned char *)dest;
373                 size_t slen = srclen;
374                 size_t dlen = destlen;
375                 unsigned char lastp = '\0';
376                 size_t retval = 0;
377
378                 /* If all characters are ascii, fast path here. */
379                 while (slen && dlen) {
380                         if ((lastp = *p) <= 0x7f) {
381                                 *q++ = *p++;
382                                 if (slen != (size_t)-1) {
383                                         slen--;
384                                 }
385                                 dlen--;
386                                 retval++;
387                                 if (!lastp)
388                                         break;
389                         } else {
390 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
391                                 goto general_case;
392 #else
393                                 return retval + convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv);
394 #endif
395                         }
396                 }
397                 if (!dlen) {
398                         /* Even if we fast path we should note if we ran out of room. */
399                         if (((slen != (size_t)-1) && slen) ||
400                                         ((slen == (size_t)-1) && lastp)) {
401                                 errno = E2BIG;
402                         }
403                 }
404                 return retval;
405         } else if (from == CH_UCS2 && to != CH_UCS2) {
406                 const unsigned char *p = (const unsigned char *)src;
407                 unsigned char *q = (unsigned char *)dest;
408                 size_t retval = 0;
409                 size_t slen = srclen;
410                 size_t dlen = destlen;
411                 unsigned char lastp = '\0';
412
413                 /* If all characters are ascii, fast path here. */
414                 while (((slen == (size_t)-1) || (slen >= 2)) && dlen) {
415                         if (((lastp = *p) <= 0x7f) && (p[1] == 0)) {
416                                 *q++ = *p;
417                                 if (slen != (size_t)-1) {
418                                         slen -= 2;
419                                 }
420                                 p += 2;
421                                 dlen--;
422                                 retval++;
423                                 if (!lastp)
424                                         break;
425                         } else {
426 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
427                                 goto general_case;
428 #else
429                                 return retval + convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv);
430 #endif
431                         }
432                 }
433                 if (!dlen) {
434                         /* Even if we fast path we should note if we ran out of room. */
435                         if (((slen != (size_t)-1) && slen) ||
436                                         ((slen == (size_t)-1) && lastp)) {
437                                 errno = E2BIG;
438                         }
439                 }
440                 return retval;
441         } else if (from != CH_UCS2 && to == CH_UCS2) {
442                 const unsigned char *p = (const unsigned char *)src;
443                 unsigned char *q = (unsigned char *)dest;
444                 size_t retval = 0;
445                 size_t slen = srclen;
446                 size_t dlen = destlen;
447                 unsigned char lastp = '\0';
448
449                 /* If all characters are ascii, fast path here. */
450                 while (slen && (dlen >= 2)) {
451                         if ((lastp = *p) <= 0x7F) {
452                                 *q++ = *p++;
453                                 *q++ = '\0';
454                                 if (slen != (size_t)-1) {
455                                         slen--;
456                                 }
457                                 dlen -= 2;
458                                 retval += 2;
459                                 if (!lastp)
460                                         break;
461                         } else {
462 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
463                                 goto general_case;
464 #else
465                                 return retval + convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv);
466 #endif
467                         }
468                 }
469                 if (!dlen) {
470                         /* Even if we fast path we should note if we ran out of room. */
471                         if (((slen != (size_t)-1) && slen) ||
472                                         ((slen == (size_t)-1) && lastp)) {
473                                 errno = E2BIG;
474                         }
475                 }
476                 return retval;
477         }
478
479 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
480   general_case:
481 #endif
482         return convert_string_internal(from, to, src, srclen, dest, destlen, allow_bad_conv);
483 }
484
485 /**
486  * Convert between character sets, allocating a new buffer for the result.
487  *
488  * @param ctx TALLOC_CTX to use to allocate with. If NULL use malloc.
489  * @param srclen length of source buffer.
490  * @param dest always set at least to NULL
491  * @note -1 is not accepted for srclen.
492  *
493  * @returns Size in bytes of the converted string; or -1 in case of error.
494  *
495  * Ensure the srclen contains the terminating zero.
496  * 
497  * I hate the goto's in this function. It's embarressing.....
498  * There has to be a cleaner way to do this. JRA.
499  **/
500
501 size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
502                                void const *src, size_t srclen, void **dest, BOOL allow_bad_conv)
503 {
504         size_t i_len, o_len, destlen = MAX(srclen, 512);
505         size_t retval;
506         const char *inbuf = (const char *)src;
507         char *outbuf = NULL, *ob = NULL;
508         smb_iconv_t descriptor;
509
510         *dest = NULL;
511
512         if (src == NULL || srclen == (size_t)-1)
513                 return (size_t)-1;
514         if (srclen == 0)
515                 return 0;
516
517         lazy_initialize_conv();
518
519         descriptor = conv_handles[from][to];
520
521         if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
522                 if (!conv_silent)
523                         DEBUG(0,("convert_string_allocate: Conversion not supported.\n"));
524                 return (size_t)-1;
525         }
526
527   convert:
528
529         if ((destlen*2) < destlen) {
530                 /* wrapped ! abort. */
531                 if (!conv_silent)
532                         DEBUG(0, ("convert_string_allocate: destlen wrapped !\n"));
533                 if (!ctx)
534                         SAFE_FREE(outbuf);
535                 return (size_t)-1;
536         } else {
537                 destlen = destlen * 2;
538         }
539
540         if (ctx) {
541                 ob = (char *)TALLOC_REALLOC(ctx, ob, destlen);
542         } else {
543                 ob = (char *)SMB_REALLOC(ob, destlen);
544         }
545
546         if (!ob) {
547                 DEBUG(0, ("convert_string_allocate: realloc failed!\n"));
548                 return (size_t)-1;
549         }
550         outbuf = ob;
551         i_len = srclen;
552         o_len = destlen;
553
554  again:
555
556         retval = smb_iconv(descriptor,
557                            &inbuf, &i_len,
558                            &outbuf, &o_len);
559         if(retval == (size_t)-1)                {
560                 const char *reason="unknown error";
561                 switch(errno) {
562                         case EINVAL:
563                                 reason="Incomplete multibyte sequence";
564                                 if (!conv_silent)
565                                         DEBUG(3,("convert_string_allocate: Conversion error: %s(%s)\n",reason,inbuf));
566                                 if (allow_bad_conv)
567                                         goto use_as_is;
568                                 break;
569                         case E2BIG:
570                                 goto convert;           
571                         case EILSEQ:
572                                 reason="Illegal multibyte sequence";
573                                 if (!conv_silent)
574                                         DEBUG(3,("convert_string_allocate: Conversion error: %s(%s)\n",reason,inbuf));
575                                 if (allow_bad_conv)
576                                         goto use_as_is;
577                                 break;
578                 }
579                 if (!conv_silent)
580                         DEBUG(0,("Conversion error: %s(%s)\n",reason,inbuf));
581                 /* smb_panic(reason); */
582                 return (size_t)-1;
583         }
584
585   out:
586
587         destlen = destlen - o_len;
588         if (ctx) {
589                 ob = (char *)TALLOC_REALLOC(ctx,ob,destlen);
590         } else {
591                 ob = (char *)SMB_REALLOC(ob,destlen);
592         }
593
594         if (destlen && !ob) {
595                 DEBUG(0, ("convert_string_allocate: out of memory!\n"));
596                 return (size_t)-1;
597         }
598
599         *dest = ob;
600         return destlen;
601
602  use_as_is:
603
604         /* 
605          * Conversion not supported. This is actually an error, but there are so
606          * many misconfigured iconv systems and smb.conf's out there we can't just
607          * fail. Do a very bad conversion instead.... JRA.
608          */
609
610         {
611                 if (o_len == 0 || i_len == 0)
612                         goto out;
613
614                 if (from == CH_UCS2 && to != CH_UCS2) {
615                         /* Can't convert from ucs2 to multibyte. Just use the default fail char. */
616                         if (i_len < 2)
617                                 goto out;
618
619                         if (i_len >= 2) {
620                                 *outbuf = lp_failed_convert_char();
621
622                                 outbuf++;
623                                 o_len--;
624
625                                 inbuf += 2;
626                                 i_len -= 2;
627                         }
628
629                         if (o_len == 0 || i_len == 0)
630                                 goto out;
631
632                         /* Keep trying with the next char... */
633                         goto again;
634
635                 } else if (from != CH_UCS2 && to == CH_UCS2) {
636                         /* Can't convert to ucs2 - just widen by adding the default fail char then zero. */
637                         if (o_len < 2)
638                                 goto out;
639
640                         outbuf[0] = lp_failed_convert_char();
641                         outbuf[1] = '\0';
642
643                         inbuf++;
644                         i_len--;
645
646                         outbuf += 2;
647                         o_len -= 2;
648
649                         if (o_len == 0 || i_len == 0)
650                                 goto out;
651
652                         /* Keep trying with the next char... */
653                         goto again;
654
655                 } else if (from != CH_UCS2 && to != CH_UCS2) {
656                         /* Failed multibyte to multibyte. Just copy the default fail char and
657                                 try again. */
658                         outbuf[0] = lp_failed_convert_char();
659
660                         inbuf++;
661                         i_len--;
662
663                         outbuf++;
664                         o_len--;
665
666                         if (o_len == 0 || i_len == 0)
667                                 goto out;
668
669                         /* Keep trying with the next char... */
670                         goto again;
671
672                 } else {
673                         /* Keep compiler happy.... */
674                         goto out;
675                 }
676         }
677 }
678
679 /**
680  * Convert between character sets, allocating a new buffer using talloc for the result.
681  *
682  * @param srclen length of source buffer.
683  * @param dest always set at least to NULL 
684  * @note -1 is not accepted for srclen.
685  *
686  * @returns Size in bytes of the converted string; or -1 in case of error.
687  **/
688 static size_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to,
689                                 void const *src, size_t srclen, void **dest, BOOL allow_bad_conv)
690 {
691         size_t dest_len;
692
693         *dest = NULL;
694         dest_len=convert_string_allocate(ctx, from, to, src, srclen, dest, allow_bad_conv);
695         if (dest_len == (size_t)-1)
696                 return (size_t)-1;
697         if (*dest == NULL)
698                 return (size_t)-1;
699         return dest_len;
700 }
701
702 size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
703 {
704         size_t size;
705         smb_ucs2_t *buffer;
706         
707         size = push_ucs2_allocate(&buffer, src);
708         if (size == (size_t)-1) {
709                 smb_panic("failed to create UCS2 buffer");
710         }
711         if (!strupper_w(buffer) && (dest == src)) {
712                 free(buffer);
713                 return srclen;
714         }
715         
716         size = convert_string(CH_UCS2, CH_UNIX, buffer, size, dest, destlen, True);
717         free(buffer);
718         return size;
719 }
720
721 /**
722  strdup() a unix string to upper case.
723  Max size is pstring.
724 **/
725
726 char *strdup_upper(const char *s)
727 {
728         pstring out_buffer;
729         const unsigned char *p = (const unsigned char *)s;
730         unsigned char *q = (unsigned char *)out_buffer;
731
732         /* this is quite a common operation, so we want it to be
733            fast. We optimise for the ascii case, knowing that all our
734            supported multi-byte character sets are ascii-compatible
735            (ie. they match for the first 128 chars) */
736
737         while (1) {
738                 if (*p & 0x80)
739                         break;
740                 *q++ = toupper_ascii(*p);
741                 if (!*p)
742                         break;
743                 p++;
744                 if (p - ( const unsigned char *)s >= sizeof(pstring))
745                         break;
746         }
747
748         if (*p) {
749                 /* MB case. */
750                 size_t size;
751                 wpstring buffer;
752                 size = convert_string(CH_UNIX, CH_UCS2, s, -1, buffer, sizeof(buffer), True);
753                 if (size == (size_t)-1) {
754                         return NULL;
755                 }
756
757                 strupper_w(buffer);
758         
759                 size = convert_string(CH_UCS2, CH_UNIX, buffer, -1, out_buffer, sizeof(out_buffer), True);
760                 if (size == (size_t)-1) {
761                         return NULL;
762                 }
763         }
764
765         return SMB_STRDUP(out_buffer);
766 }
767
768 size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
769 {
770         size_t size;
771         smb_ucs2_t *buffer = NULL;
772         
773         size = convert_string_allocate(NULL, CH_UNIX, CH_UCS2, src, srclen,
774                                        (void **)(void *)&buffer, True);
775         if (size == (size_t)-1 || !buffer) {
776                 smb_panic("failed to create UCS2 buffer");
777         }
778         if (!strlower_w(buffer) && (dest == src)) {
779                 SAFE_FREE(buffer);
780                 return srclen;
781         }
782         size = convert_string(CH_UCS2, CH_UNIX, buffer, size, dest, destlen, True);
783         SAFE_FREE(buffer);
784         return size;
785 }
786
787 /**
788  strdup() a unix string to lower case.
789 **/
790
791 char *strdup_lower(const char *s)
792 {
793         size_t size;
794         smb_ucs2_t *buffer = NULL;
795         char *out_buffer;
796         
797         size = push_ucs2_allocate(&buffer, s);
798         if (size == -1 || !buffer) {
799                 return NULL;
800         }
801
802         strlower_w(buffer);
803         
804         size = pull_ucs2_allocate(&out_buffer, buffer);
805         SAFE_FREE(buffer);
806
807         if (size == (size_t)-1) {
808                 return NULL;
809         }
810         
811         return out_buffer;
812 }
813
814 static size_t ucs2_align(const void *base_ptr, const void *p, int flags)
815 {
816         if (flags & (STR_NOALIGN|STR_ASCII))
817                 return 0;
818         return PTR_DIFF(p, base_ptr) & 1;
819 }
820
821
822 /**
823  * Copy a string from a char* unix src to a dos codepage string destination.
824  *
825  * @return the number of bytes occupied by the string in the destination.
826  *
827  * @param flags can include
828  * <dl>
829  * <dt>STR_TERMINATE</dt> <dd>means include the null termination</dd>
830  * <dt>STR_UPPER</dt> <dd>means uppercase in the destination</dd>
831  * </dl>
832  *
833  * @param dest_len the maximum length in bytes allowed in the
834  * destination.  If @p dest_len is -1 then no maximum is used.
835  **/
836 size_t push_ascii(void *dest, const char *src, size_t dest_len, int flags)
837 {
838         size_t src_len = strlen(src);
839         pstring tmpbuf;
840
841         /* treat a pstring as "unlimited" length */
842         if (dest_len == (size_t)-1)
843                 dest_len = sizeof(pstring);
844
845         if (flags & STR_UPPER) {
846                 pstrcpy(tmpbuf, src);
847                 strupper_m(tmpbuf);
848                 src = tmpbuf;
849         }
850
851         if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII))
852                 src_len++;
853
854         return convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len, True);
855 }
856
857 size_t push_ascii_fstring(void *dest, const char *src)
858 {
859         return push_ascii(dest, src, sizeof(fstring), STR_TERMINATE);
860 }
861
862 size_t push_ascii_pstring(void *dest, const char *src)
863 {
864         return push_ascii(dest, src, sizeof(pstring), STR_TERMINATE);
865 }
866
867 /********************************************************************
868  Push an nstring - ensure null terminated. Written by
869  moriyama@miraclelinux.com (MORIYAMA Masayuki).
870 ********************************************************************/
871
872 size_t push_ascii_nstring(void *dest, const char *src)
873 {
874         size_t i, buffer_len, dest_len;
875         smb_ucs2_t *buffer;
876
877         conv_silent = True;
878         buffer_len = push_ucs2_allocate(&buffer, src);
879         if (buffer_len == (size_t)-1) {
880                 smb_panic("failed to create UCS2 buffer");
881         }
882
883         /* We're using buffer_len below to count ucs2 characters, not bytes. */
884         buffer_len /= sizeof(smb_ucs2_t);
885
886         dest_len = 0;
887         for (i = 0; buffer[i] != 0 && (i < buffer_len); i++) {
888                 unsigned char mb[10];
889                 /* Convert one smb_ucs2_t character at a time. */
890                 size_t mb_len = convert_string(CH_UCS2, CH_DOS, buffer+i, sizeof(smb_ucs2_t), mb, sizeof(mb), False);
891                 if ((mb_len != (size_t)-1) && (dest_len + mb_len <= MAX_NETBIOSNAME_LEN - 1)) {
892                         memcpy((char *)dest + dest_len, mb, mb_len);
893                         dest_len += mb_len;
894                 } else {
895                         errno = E2BIG;
896                         break;
897                 }
898         }
899         ((char *)dest)[dest_len] = '\0';
900
901         SAFE_FREE(buffer);
902         conv_silent = False;
903         return dest_len;
904 }
905
906 /**
907  * Copy a string from a dos codepage source to a unix char* destination.
908  *
909  * The resulting string in "dest" is always null terminated.
910  *
911  * @param flags can have:
912  * <dl>
913  * <dt>STR_TERMINATE</dt>
914  * <dd>STR_TERMINATE means the string in @p src
915  * is null terminated, and src_len is ignored.</dd>
916  * </dl>
917  *
918  * @param src_len is the length of the source area in bytes.
919  * @returns the number of bytes occupied by the string in @p src.
920  **/
921 size_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
922 {
923         size_t ret;
924
925         if (dest_len == (size_t)-1)
926                 dest_len = sizeof(pstring);
927
928         if (flags & STR_TERMINATE) {
929                 if (src_len == (size_t)-1) {
930                         src_len = strlen(src) + 1;
931                 } else {
932                         size_t len = strnlen(src, src_len);
933                         if (len < src_len)
934                                 len++;
935                         src_len = len;
936                 }
937         }
938
939         ret = convert_string(CH_DOS, CH_UNIX, src, src_len, dest, dest_len, True);
940         if (ret == (size_t)-1) {
941                 dest_len = 0;
942         }
943
944         if (dest_len)
945                 dest[MIN(ret, dest_len-1)] = 0;
946         else 
947                 dest[0] = 0;
948
949         return src_len;
950 }
951
952 size_t pull_ascii_pstring(char *dest, const void *src)
953 {
954         return pull_ascii(dest, src, sizeof(pstring), -1, STR_TERMINATE);
955 }
956
957 size_t pull_ascii_fstring(char *dest, const void *src)
958 {
959         return pull_ascii(dest, src, sizeof(fstring), -1, STR_TERMINATE);
960 }
961
962 /* When pulling an nstring it can expand into a larger size (dos cp -> utf8). Cope with this. */
963
964 size_t pull_ascii_nstring(char *dest, size_t dest_len, const void *src)
965 {
966         return pull_ascii(dest, src, dest_len, sizeof(nstring)-1, STR_TERMINATE);
967 }
968
969 /**
970  * Copy a string from a char* src to a unicode destination.
971  *
972  * @returns the number of bytes occupied by the string in the destination.
973  *
974  * @param flags can have:
975  *
976  * <dl>
977  * <dt>STR_TERMINATE <dd>means include the null termination.
978  * <dt>STR_UPPER     <dd>means uppercase in the destination.
979  * <dt>STR_NOALIGN   <dd>means don't do alignment.
980  * </dl>
981  *
982  * @param dest_len is the maximum length allowed in the
983  * destination. If dest_len is -1 then no maxiumum is used.
984  **/
985
986 size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags)
987 {
988         size_t len=0;
989         size_t src_len;
990         size_t ret;
991
992         /* treat a pstring as "unlimited" length */
993         if (dest_len == (size_t)-1)
994                 dest_len = sizeof(pstring);
995
996         if (flags & STR_TERMINATE)
997                 src_len = (size_t)-1;
998         else
999                 src_len = strlen(src);
1000
1001         if (ucs2_align(base_ptr, dest, flags)) {
1002                 *(char *)dest = 0;
1003                 dest = (void *)((char *)dest + 1);
1004                 if (dest_len)
1005                         dest_len--;
1006                 len++;
1007         }
1008
1009         /* ucs2 is always a multiple of 2 bytes */
1010         dest_len &= ~1;
1011
1012         ret =  convert_string(CH_UNIX, CH_UCS2, src, src_len, dest, dest_len, True);
1013         if (ret == (size_t)-1) {
1014                 return 0;
1015         }
1016
1017         len += ret;
1018
1019         if (flags & STR_UPPER) {
1020                 smb_ucs2_t *dest_ucs2 = dest;
1021                 size_t i;
1022                 for (i = 0; i < (dest_len / 2) && dest_ucs2[i]; i++) {
1023                         smb_ucs2_t v = toupper_w(dest_ucs2[i]);
1024                         if (v != dest_ucs2[i]) {
1025                                 dest_ucs2[i] = v;
1026                         }
1027                 }
1028         }
1029
1030         return len;
1031 }
1032
1033
1034 /**
1035  * Copy a string from a unix char* src to a UCS2 destination,
1036  * allocating a buffer using talloc().
1037  *
1038  * @param dest always set at least to NULL 
1039  *
1040  * @returns The number of bytes occupied by the string in the destination
1041  *         or -1 in case of error.
1042  **/
1043 size_t push_ucs2_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src)
1044 {
1045         size_t src_len = strlen(src)+1;
1046
1047         *dest = NULL;
1048         return convert_string_talloc(ctx, CH_UNIX, CH_UCS2, src, src_len, (void **)dest, True);
1049 }
1050
1051
1052 /**
1053  * Copy a string from a unix char* src to a UCS2 destination, allocating a buffer
1054  *
1055  * @param dest always set at least to NULL 
1056  *
1057  * @returns The number of bytes occupied by the string in the destination
1058  *         or -1 in case of error.
1059  **/
1060
1061 size_t push_ucs2_allocate(smb_ucs2_t **dest, const char *src)
1062 {
1063         size_t src_len = strlen(src)+1;
1064
1065         *dest = NULL;
1066         return convert_string_allocate(NULL, CH_UNIX, CH_UCS2, src, src_len, (void **)dest, True);
1067 }
1068
1069 /**
1070  Copy a string from a char* src to a UTF-8 destination.
1071  Return the number of bytes occupied by the string in the destination
1072  Flags can have:
1073   STR_TERMINATE means include the null termination
1074   STR_UPPER     means uppercase in the destination
1075  dest_len is the maximum length allowed in the destination. If dest_len
1076  is -1 then no maxiumum is used.
1077 **/
1078
1079 static size_t push_utf8(void *dest, const char *src, size_t dest_len, int flags)
1080 {
1081         size_t src_len = strlen(src);
1082         pstring tmpbuf;
1083
1084         /* treat a pstring as "unlimited" length */
1085         if (dest_len == (size_t)-1)
1086                 dest_len = sizeof(pstring);
1087
1088         if (flags & STR_UPPER) {
1089                 pstrcpy(tmpbuf, src);
1090                 strupper_m(tmpbuf);
1091                 src = tmpbuf;
1092         }
1093
1094         if (flags & STR_TERMINATE)
1095                 src_len++;
1096
1097         return convert_string(CH_UNIX, CH_UTF8, src, src_len, dest, dest_len, True);
1098 }
1099
1100 size_t push_utf8_fstring(void *dest, const char *src)
1101 {
1102         return push_utf8(dest, src, sizeof(fstring), STR_TERMINATE);
1103 }
1104
1105 /**
1106  * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer using talloc
1107  *
1108  * @param dest always set at least to NULL 
1109  *
1110  * @returns The number of bytes occupied by the string in the destination
1111  **/
1112
1113 size_t push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
1114 {
1115         size_t src_len = strlen(src)+1;
1116
1117         *dest = NULL;
1118         return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len, (void**)dest, True);
1119 }
1120
1121 /**
1122  * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer
1123  *
1124  * @param dest always set at least to NULL 
1125  *
1126  * @returns The number of bytes occupied by the string in the destination
1127  **/
1128
1129 size_t push_utf8_allocate(char **dest, const char *src)
1130 {
1131         size_t src_len = strlen(src)+1;
1132
1133         *dest = NULL;
1134         return convert_string_allocate(NULL, CH_UNIX, CH_UTF8, src, src_len, (void **)dest, True);      
1135 }
1136
1137 /**
1138  Copy a string from a ucs2 source to a unix char* destination.
1139  Flags can have:
1140   STR_TERMINATE means the string in src is null terminated.
1141   STR_NOALIGN   means don't try to align.
1142  if STR_TERMINATE is set then src_len is ignored if it is -1.
1143  src_len is the length of the source area in bytes
1144  Return the number of bytes occupied by the string in src.
1145  The resulting string in "dest" is always null terminated.
1146 **/
1147
1148 size_t pull_ucs2(const void *base_ptr, char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
1149 {
1150         size_t ret;
1151
1152         if (dest_len == (size_t)-1)
1153                 dest_len = sizeof(pstring);
1154
1155         if (ucs2_align(base_ptr, src, flags)) {
1156                 src = (const void *)((const char *)src + 1);
1157                 if (src_len != (size_t)-1)
1158                         src_len--;
1159         }
1160
1161         if (flags & STR_TERMINATE) {
1162                 /* src_len -1 is the default for null terminated strings. */
1163                 if (src_len != (size_t)-1) {
1164                         size_t len = strnlen_w(src, src_len/2);
1165                         if (len < src_len/2)
1166                                 len++;
1167                         src_len = len*2;
1168                 }
1169         }
1170
1171         /* ucs2 is always a multiple of 2 bytes */
1172         if (src_len != (size_t)-1)
1173                 src_len &= ~1;
1174         
1175         ret = convert_string(CH_UCS2, CH_UNIX, src, src_len, dest, dest_len, True);
1176         if (ret == (size_t)-1) {
1177                 return 0;
1178         }
1179
1180         if (src_len == (size_t)-1)
1181                 src_len = ret*2;
1182                 
1183         if (dest_len)
1184                 dest[MIN(ret, dest_len-1)] = 0;
1185         else 
1186                 dest[0] = 0;
1187
1188         return src_len;
1189 }
1190
1191 size_t pull_ucs2_pstring(char *dest, const void *src)
1192 {
1193         return pull_ucs2(NULL, dest, src, sizeof(pstring), -1, STR_TERMINATE);
1194 }
1195
1196 size_t pull_ucs2_fstring(char *dest, const void *src)
1197 {
1198         return pull_ucs2(NULL, dest, src, sizeof(fstring), -1, STR_TERMINATE);
1199 }
1200
1201 /**
1202  * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer using talloc
1203  *
1204  * @param dest always set at least to NULL 
1205  *
1206  * @returns The number of bytes occupied by the string in the destination
1207  **/
1208
1209 size_t pull_ucs2_talloc(TALLOC_CTX *ctx, char **dest, const smb_ucs2_t *src)
1210 {
1211         size_t src_len = (strlen_w(src)+1) * sizeof(smb_ucs2_t);
1212         *dest = NULL;
1213         return convert_string_talloc(ctx, CH_UCS2, CH_UNIX, src, src_len, (void **)dest, True);
1214 }
1215
1216 /**
1217  * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer
1218  *
1219  * @param dest always set at least to NULL 
1220  *
1221  * @returns The number of bytes occupied by the string in the destination
1222  **/
1223
1224 size_t pull_ucs2_allocate(char **dest, const smb_ucs2_t *src)
1225 {
1226         size_t src_len = (strlen_w(src)+1) * sizeof(smb_ucs2_t);
1227         *dest = NULL;
1228         return convert_string_allocate(NULL, CH_UCS2, CH_UNIX, src, src_len, (void **)dest, True);
1229 }
1230
1231 /**
1232  * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc
1233  *
1234  * @param dest always set at least to NULL 
1235  *
1236  * @returns The number of bytes occupied by the string in the destination
1237  **/
1238
1239 size_t pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
1240 {
1241         size_t src_len = strlen(src)+1;
1242         *dest = NULL;
1243         return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len, (void **)dest, True);
1244 }
1245
1246 /**
1247  * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer
1248  *
1249  * @param dest always set at least to NULL 
1250  *
1251  * @returns The number of bytes occupied by the string in the destination
1252  **/
1253
1254 size_t pull_utf8_allocate(char **dest, const char *src)
1255 {
1256         size_t src_len = strlen(src)+1;
1257         *dest = NULL;
1258         return convert_string_allocate(NULL, CH_UTF8, CH_UNIX, src, src_len, (void **)dest, True);
1259 }
1260  
1261 /**
1262  * Copy a string from a DOS src to a unix char * destination, allocating a buffer using talloc
1263  *
1264  * @param dest always set at least to NULL 
1265  *
1266  * @returns The number of bytes occupied by the string in the destination
1267  **/
1268
1269 size_t pull_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
1270 {
1271         size_t src_len = strlen(src)+1;
1272         *dest = NULL;
1273         return convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len, (void **)dest, True);
1274 }
1275
1276 /**
1277  Copy a string from a char* src to a unicode or ascii
1278  dos codepage destination choosing unicode or ascii based on the 
1279  flags in the SMB buffer starting at base_ptr.
1280  Return the number of bytes occupied by the string in the destination.
1281  flags can have:
1282   STR_TERMINATE means include the null termination.
1283   STR_UPPER     means uppercase in the destination.
1284   STR_ASCII     use ascii even with unicode packet.
1285   STR_NOALIGN   means don't do alignment.
1286  dest_len is the maximum length allowed in the destination. If dest_len
1287  is -1 then no maxiumum is used.
1288 **/
1289
1290 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)
1291 {
1292 #ifdef DEVELOPER
1293         /* We really need to zero fill here, not clobber
1294          * region, as we want to ensure that valgrind thinks
1295          * all of the outgoing buffer has been written to
1296          * so a send() or write() won't trap an error.
1297          * JRA.
1298          */
1299 #if 0
1300         if (dest_len != (size_t)-1)
1301                 clobber_region(function, line, dest, dest_len);
1302 #else
1303         if (dest_len != (size_t)-1)
1304                 memset(dest, '\0', dest_len);
1305 #endif
1306 #endif
1307
1308         if (!(flags & STR_ASCII) && \
1309             ((flags & STR_UNICODE || \
1310               (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) {
1311                 return push_ucs2(base_ptr, dest, src, dest_len, flags);
1312         }
1313         return push_ascii(dest, src, dest_len, flags);
1314 }
1315
1316
1317 /**
1318  Copy a string from a unicode or ascii source (depending on
1319  the packet flags) to a char* destination.
1320  Flags can have:
1321   STR_TERMINATE means the string in src is null terminated.
1322   STR_UNICODE   means to force as unicode.
1323   STR_ASCII     use ascii even with unicode packet.
1324   STR_NOALIGN   means don't do alignment.
1325  if STR_TERMINATE is set then src_len is ignored is it is -1
1326  src_len is the length of the source area in bytes.
1327  Return the number of bytes occupied by the string in src.
1328  The resulting string in "dest" is always null terminated.
1329 **/
1330
1331 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)
1332 {
1333 #ifdef DEVELOPER
1334         if (dest_len != (size_t)-1)
1335                 clobber_region(function, line, dest, dest_len);
1336 #endif
1337
1338         if (!(flags & STR_ASCII) && \
1339             ((flags & STR_UNICODE || \
1340               (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) {
1341                 return pull_ucs2(base_ptr, dest, src, dest_len, src_len, flags);
1342         }
1343         return pull_ascii(dest, src, dest_len, src_len, flags);
1344 }
1345
1346 size_t align_string(const void *base_ptr, const char *p, int flags)
1347 {
1348         if (!(flags & STR_ASCII) && \
1349             ((flags & STR_UNICODE || \
1350               (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) {
1351                 return ucs2_align(base_ptr, p, flags);
1352         }
1353         return 0;
1354 }
1355
1356 /****************************************************************
1357  Calculate the size (in bytes) of the next multibyte character in
1358  our internal character set. Note that p must be pointing to a
1359  valid mb char, not within one.
1360 ****************************************************************/
1361
1362 size_t next_mb_char_size(const char *s)
1363 {
1364         size_t i;
1365
1366         if (!(*s & 0x80))
1367                 return 1; /* ascii. */
1368
1369         conv_silent = True;
1370         for ( i = 1; i <=4; i++ ) {
1371                 smb_ucs2_t uc;
1372                 if (convert_string(CH_UNIX, CH_UCS2, s, i, &uc, 2, False) == 2) {
1373 #if 0 /* JRATEST */
1374                         DEBUG(10,("next_mb_char_size: size %u at string %s\n",
1375                                 (unsigned int)i, s));
1376 #endif
1377                         conv_silent = False;
1378                         return i;
1379                 }
1380         }
1381         /* We're hosed - we don't know how big this is... */
1382         DEBUG(10,("next_mb_char_size: unknown size at string %s\n", s));
1383         conv_silent = False;
1384         return 1;
1385 }