changed the definition of dos_PutUniCode
[jra/samba/.git] / source3 / lib / util_unistr.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Samba utility functions
5    Copyright (C) Andrew Tridgell 1992-1998
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24 extern int DEBUGLEVEL;
25
26  smb_ucs2_t wchar_list_sep[] = { (smb_ucs2_t)' ', (smb_ucs2_t)'\t', (smb_ucs2_t)',',
27                                                                 (smb_ucs2_t)';', (smb_ucs2_t)':', (smb_ucs2_t)'\n',
28                                                                 (smb_ucs2_t)'\r', 0 };
29 /*
30  * The following are the codepage to ucs2 and vica versa maps.
31  * These are dynamically loaded from a unicode translation file.
32  */
33
34 static smb_ucs2_t *doscp_to_ucs2;
35 static uint16 *ucs2_to_doscp;
36
37 static smb_ucs2_t *unixcp_to_ucs2;
38 static uint16 *ucs2_to_unixcp;
39
40 #ifndef MAXUNI
41 #define MAXUNI 1024
42 #endif
43
44 /*******************************************************************
45  Write a string in (little-endian) unicode format. src is in
46  the current DOS codepage. len is the length in bytes of the
47  string pointed to by dst.
48
49  if null_terminate is True then null terminate the packet (adds 2 bytes)
50
51  the return value is the length consumed by the string, including the
52  null termination if applied
53 ********************************************************************/
54
55 int dos_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminate)
56 {
57         int ret = 0;
58         while (*src && (len > 2)) {
59                 size_t skip = get_character_len(*src);
60                 smb_ucs2_t val = (*src & 0xff);
61
62                 /*
63                  * If this is a multibyte character (and all DOS/Windows
64                  * codepages have at maximum 2 byte multibyte characters)
65                  * then work out the index value for the unicode conversion.
66                  */
67
68                 if (skip == 2)
69                         val = ((val << 8) | (src[1] & 0xff));
70
71                 SSVAL(dst,ret,doscp_to_ucs2[val]);
72                 ret += 2;
73                 len -= 2;
74                 if (skip)
75                         src += skip;
76                 else
77                         src++;
78         }
79         if (null_terminate) {
80                 SSVAL(dst,ret,0);
81                 ret += 2;
82         }
83         return(ret);
84 }
85
86 /*******************************************************************
87  Put an ASCII string into a UNICODE array (uint16's).
88
89  Warning: doesn't do any codepage !!! BAD !!!
90  
91  Help ! Fix Me ! Fix Me !
92 ********************************************************************/
93
94 void ascii_to_unistr(uint16 *dest, const char *src, int maxlen)
95 {
96         uint16 *destend = dest + maxlen;
97         register char c;
98
99         while (dest < destend)
100         {
101                 c = *(src++);
102                 if (c == 0)
103                 {
104                         break;
105                 }
106
107                 *(dest++) = (uint16)c;
108         }
109
110         *dest = 0;
111 }
112
113 /*******************************************************************
114  Pull an ASCII string out of a UNICODE array (uint16's).
115
116  Warning: doesn't do any codepage !!! BAD !!!
117  
118  Help ! Fix Me ! Fix Me !
119 ********************************************************************/
120
121 void unistr_to_ascii(char *dest, const uint16 *src, int len)
122 {
123         char *destend = dest + len;
124         register uint16 c;
125
126         while (dest < destend)
127         {
128                 c = *(src++);
129                 if (c == 0)
130                 {
131                         break;
132                 }
133
134                 *(dest++) = (char)c;
135         }
136
137         *dest = 0;
138 }
139
140
141 /*******************************************************************
142  Skip past some unicode strings in a buffer.
143 ********************************************************************/
144
145 char *skip_unicode_string(char *buf,int n)
146 {
147         while (n--) {
148                 while (*buf)
149                         buf += 2;
150                 buf += 2;
151         }
152         return(buf);
153 }
154
155 /*******************************************************************
156  Return a DOS codepage version of a little-endian unicode string.
157  len is the filename length (ignoring any terminating zero) in uin16
158  units. Always null terminates.
159  Hack alert: uses fixed buffer(s).
160 ********************************************************************/
161
162 char *dos_unistrn2(uint16 *src, int len)
163 {
164         static char lbufs[8][MAXUNI];
165         static int nexti;
166         char *lbuf = lbufs[nexti];
167         char *p;
168
169         nexti = (nexti+1)%8;
170
171         for (p = lbuf; (len > 0) && (p-lbuf < MAXUNI-3) && *src; len--, src++) {
172                 uint16 ucs2_val = SVAL(src,0);
173                 uint16 cp_val = ucs2_to_doscp[ucs2_val];
174
175                 if (cp_val < 256)
176                         *p++ = (char)cp_val;
177                 else {
178                         *p++ = (cp_val >> 8) & 0xff;
179                         *p++ = (cp_val & 0xff);
180                 }
181         }
182
183         *p = 0;
184         return lbuf;
185 }
186
187 static char lbufs[8][MAXUNI];
188 static int nexti;
189
190 /*******************************************************************
191  Return a DOS codepage version of a little-endian unicode string.
192  Hack alert: uses fixed buffer(s).
193 ********************************************************************/
194
195 char *dos_unistr2(uint16 *src)
196 {
197         char *lbuf = lbufs[nexti];
198         char *p;
199
200         nexti = (nexti+1)%8;
201
202         for (p = lbuf; *src && (p-lbuf < MAXUNI-3); src++) {
203                 uint16 ucs2_val = SVAL(src,0);
204                 uint16 cp_val = ucs2_to_doscp[ucs2_val];
205
206                 if (cp_val < 256)
207                         *p++ = (char)cp_val;
208                 else {
209                         *p++ = (cp_val >> 8) & 0xff;
210                         *p++ = (cp_val & 0xff);
211                 }
212         }
213
214         *p = 0;
215         return lbuf;
216 }
217
218 /*******************************************************************
219 Return a DOS codepage version of a little-endian unicode string
220 ********************************************************************/
221
222 char *dos_unistr2_to_str(UNISTR2 *str)
223 {
224         char *lbuf = lbufs[nexti];
225         char *p;
226         uint16 *src = str->buffer;
227         int max_size = MIN(sizeof(str->buffer)-3, str->uni_str_len);
228
229         nexti = (nexti+1)%8;
230
231         for (p = lbuf; *src && p-lbuf < max_size; src++) {
232                 uint16 ucs2_val = SVAL(src,0);
233                 uint16 cp_val = ucs2_to_doscp[ucs2_val];
234
235                 if (cp_val < 256)
236                         *p++ = (char)cp_val;
237                 else {
238                         *p++ = (cp_val >> 8) & 0xff;
239                         *p++ = (cp_val & 0xff);
240                 }
241         }
242
243         *p = 0;
244         return lbuf;
245 }
246
247 /*******************************************************************
248  Convert a UNISTR2 structure to an ASCII string
249  Warning: this version does DOS codepage.
250 ********************************************************************/
251
252 void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
253 {
254         char *destend;
255         const uint16 *src;
256         size_t len;
257         register uint16 c;
258
259         src = str->buffer;
260         len = MIN(str->uni_str_len, maxlen);
261         destend = dest + len;
262
263         while (dest < destend)
264         {
265                 uint16 ucs2_val;
266                 uint16 cp_val;
267
268                 c = *src;
269                 if (c == 0)
270                 {
271                         break;
272                 }
273                 
274                 ucs2_val = SVAL(src++,0);
275                 cp_val = ucs2_to_doscp[ucs2_val];
276                                 
277                 if (cp_val < 256)
278                         *(dest++) = (char)cp_val;
279                 else {
280                         *dest= (cp_val >> 8) & 0xff;
281                         *(dest++) = (cp_val & 0xff);
282                 }
283         }
284
285         *dest = 0;
286 }
287
288
289 /*******************************************************************
290 Return a number stored in a buffer
291 ********************************************************************/
292
293 uint32 buffer2_to_uint32(BUFFER2 *str)
294 {
295         if (str->buf_len == 4)
296                 return IVAL(str->buffer, 0);
297         else
298                 return 0;
299 }
300
301 /*******************************************************************
302 Return a DOS codepage version of a NOTunicode string
303 ********************************************************************/
304
305 char *dos_buffer2_to_str(BUFFER2 *str)
306 {
307         char *lbuf = lbufs[nexti];
308         char *p;
309         uint16 *src = str->buffer;
310         int max_size = MIN(sizeof(str->buffer)-3, str->buf_len/2);
311
312         nexti = (nexti+1)%8;
313
314         for (p = lbuf; *src && p-lbuf < max_size; src++) {
315                 uint16 ucs2_val = SVAL(src,0);
316                 uint16 cp_val = ucs2_to_doscp[ucs2_val];
317
318                 if (cp_val < 256)
319                         *p++ = (char)cp_val;
320                 else {
321                         *p++ = (cp_val >> 8) & 0xff;
322                         *p++ = (cp_val & 0xff);
323                 }
324         }
325
326         *p = 0;
327         return lbuf;
328 }
329
330 /*******************************************************************
331  Return a dos codepage version of a NOTunicode string
332 ********************************************************************/
333
334 char *dos_buffer2_to_multistr(BUFFER2 *str)
335 {
336         char *lbuf = lbufs[nexti];
337         char *p;
338         uint16 *src = str->buffer;
339         int max_size = MIN(sizeof(str->buffer)-3, str->buf_len/2);
340
341         nexti = (nexti+1)%8;
342
343         for (p = lbuf; p-lbuf < max_size; src++) {
344                 if (*src == 0) {
345                         *p++ = ' ';
346                 } else {
347                         uint16 ucs2_val = SVAL(src,0);
348                         uint16 cp_val = ucs2_to_doscp[ucs2_val];
349
350                         if (cp_val < 256)
351                                 *p++ = (char)cp_val;
352                         else {
353                                 *p++ = (cp_val >> 8) & 0xff;
354                                 *p++ = (cp_val & 0xff);
355                         }
356                 }
357         }
358
359         *p = 0;
360         return lbuf;
361 }
362
363 /*******************************************************************
364  Create a null-terminated unicode string from a null-terminated DOS
365  codepage string.
366  Return number of unicode chars copied, excluding the null character.
367  Unicode strings created are in little-endian format.
368 ********************************************************************/
369
370 size_t dos_struni2(char *dst, const char *src, size_t max_len)
371 {
372         size_t len = 0;
373
374         if (dst == NULL)
375                 return 0;
376
377         if (src != NULL) {
378                 for (; *src && len < max_len-2; len++, dst +=2) {
379                         size_t skip = get_character_len(*src);
380                         smb_ucs2_t val = (*src & 0xff);
381
382                         /*
383                          * If this is a multibyte character (and all DOS/Windows
384                          * codepages have at maximum 2 byte multibyte characters)
385                          * then work out the index value for the unicode conversion.
386                          */
387
388                         if (skip == 2)
389                                 val = ((val << 8) | (src[1] & 0xff));
390
391                         SSVAL(dst,0,doscp_to_ucs2[val]);
392                         if (skip)
393                                 src += skip;
394                         else
395                                 src++;
396                 }
397         }
398
399         SSVAL(dst,0,0);
400
401         return len;
402 }
403
404 /*******************************************************************
405  Return a DOS codepage version of a little-endian unicode string.
406  Hack alert: uses fixed buffer(s).
407 ********************************************************************/
408
409 char *dos_unistr(char *buf)
410 {
411         char *lbuf = lbufs[nexti];
412         uint16 *src = (uint16 *)buf;
413         char *p;
414
415         nexti = (nexti+1)%8;
416
417         for (p = lbuf; *src && p-lbuf < MAXUNI-3; src++) {
418                 uint16 ucs2_val = SVAL(src,0);
419                 uint16 cp_val = ucs2_to_doscp[ucs2_val];
420
421                 if (cp_val < 256)
422                         *p++ = (char)cp_val;
423                 else {
424                         *p++ = (cp_val >> 8) & 0xff;
425                         *p++ = (cp_val & 0xff);
426                 }
427         }
428
429         *p = 0;
430         return lbuf;
431 }
432
433 /*******************************************************************
434  Strcpy for unicode strings.  returns length (in num of wide chars)
435 ********************************************************************/
436
437 int unistrcpy(char *dst, char *src)
438 {
439         int num_wchars = 0;
440         uint16 *wsrc = (uint16 *)src;
441         uint16 *wdst = (uint16 *)dst;
442
443         while (*wsrc) {
444                 *wdst++ = *wsrc++;
445                 num_wchars++;
446         }
447         *wdst = 0;
448
449         return num_wchars;
450 }
451
452
453
454 /*******************************************************************
455  Free any existing maps.
456 ********************************************************************/
457
458 static void free_maps(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
459 {
460         /* this handles identity mappings where we share the pointer */
461         if (*pp_ucs2_to_cp == *pp_cp_to_ucs2) {
462                 *pp_ucs2_to_cp = NULL;
463         }
464
465         if (*pp_cp_to_ucs2) {
466                 free(*pp_cp_to_ucs2);
467                 *pp_cp_to_ucs2 = NULL;
468         }
469
470         if (*pp_ucs2_to_cp) {
471                 free(*pp_ucs2_to_cp);
472                 *pp_ucs2_to_cp = NULL;
473         }
474 }
475
476
477 /*******************************************************************
478  Build a default (null) codepage to unicode map.
479 ********************************************************************/
480
481 void default_unicode_map(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
482 {
483   int i;
484
485   free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
486
487   if ((*pp_ucs2_to_cp = (uint16 *)malloc(2*65536)) == NULL) {
488     DEBUG(0,("default_unicode_map: malloc fail for ucs2_to_cp size %u.\n", 2*65536));
489     abort();
490   }
491
492   *pp_cp_to_ucs2 = *pp_ucs2_to_cp; /* Default map is an identity. */
493   for (i = 0; i < 65536; i++)
494     (*pp_cp_to_ucs2)[i] = i;
495 }
496
497 /*******************************************************************
498  Load a codepage to unicode and vica-versa map.
499 ********************************************************************/
500
501 BOOL load_unicode_map(const char *codepage, smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
502 {
503   pstring unicode_map_file_name;
504   FILE *fp = NULL;
505   SMB_STRUCT_STAT st;
506   smb_ucs2_t *cp_to_ucs2 = *pp_cp_to_ucs2;
507   uint16 *ucs2_to_cp = *pp_ucs2_to_cp;
508   size_t cp_to_ucs2_size;
509   size_t ucs2_to_cp_size;
510   size_t i;
511   size_t size;
512   char buf[UNICODE_MAP_HEADER_SIZE];
513
514   DEBUG(5, ("load_unicode_map: loading unicode map for codepage %s.\n", codepage));
515
516   if (*codepage == '\0')
517     goto clean_and_exit;
518
519   if(strlen(CODEPAGEDIR) + 13 + strlen(codepage) > sizeof(unicode_map_file_name)) {
520     DEBUG(0,("load_unicode_map: filename too long to load\n"));
521     goto clean_and_exit;
522   }
523
524   pstrcpy(unicode_map_file_name, CODEPAGEDIR);
525   pstrcat(unicode_map_file_name, "/");
526   pstrcat(unicode_map_file_name, "unicode_map.");
527   pstrcat(unicode_map_file_name, codepage);
528
529   if(sys_stat(unicode_map_file_name,&st)!=0) {
530     DEBUG(0,("load_unicode_map: filename %s does not exist.\n",
531               unicode_map_file_name));
532     goto clean_and_exit;
533   }
534
535   size = st.st_size;
536
537   if ((size != UNICODE_MAP_HEADER_SIZE + 4*65536) && (size != UNICODE_MAP_HEADER_SIZE +(2*256 + 2*65536))) {
538     DEBUG(0,("load_unicode_map: file %s is an incorrect size for a \
539 unicode map file (size=%d).\n", unicode_map_file_name, (int)size));
540     goto clean_and_exit;
541   }
542
543   if((fp = sys_fopen( unicode_map_file_name, "r")) == NULL) {
544     DEBUG(0,("load_unicode_map: cannot open file %s. Error was %s\n",
545               unicode_map_file_name, strerror(errno)));
546     goto clean_and_exit;
547   }
548
549   if(fread( buf, 1, UNICODE_MAP_HEADER_SIZE, fp)!=UNICODE_MAP_HEADER_SIZE) {
550     DEBUG(0,("load_unicode_map: cannot read header from file %s. Error was %s\n",
551               unicode_map_file_name, strerror(errno)));
552     goto clean_and_exit;
553   }
554
555   /* Check the version value */
556   if(SVAL(buf,UNICODE_MAP_VERSION_OFFSET) != UNICODE_MAP_FILE_VERSION_ID) {
557     DEBUG(0,("load_unicode_map: filename %s has incorrect version id. \
558 Needed %hu, got %hu.\n",
559           unicode_map_file_name, (uint16)UNICODE_MAP_FILE_VERSION_ID,
560           SVAL(buf,UNICODE_MAP_VERSION_OFFSET)));
561     goto clean_and_exit;
562   }
563
564   /* Check the codepage value */
565   if(!strequal(&buf[UNICODE_MAP_CLIENT_CODEPAGE_OFFSET], codepage)) {
566     DEBUG(0,("load_unicode_map: codepage %s in file %s is not the same as that \
567 requested (%s).\n", &buf[UNICODE_MAP_CLIENT_CODEPAGE_OFFSET], unicode_map_file_name, codepage ));
568     goto clean_and_exit;
569   }
570
571   ucs2_to_cp_size = 2*65536;
572   if (size == UNICODE_MAP_HEADER_SIZE + 4*65536) {
573     /* 
574      * This is a multibyte code page.
575      */
576     cp_to_ucs2_size = 2*65536;
577   } else {
578     /*
579      * Single byte code page.
580      */
581     cp_to_ucs2_size = 2*256;
582   }
583
584   /* 
585    * Free any old translation tables.
586    */
587
588   free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
589
590   if ((cp_to_ucs2 = (smb_ucs2_t *)malloc(cp_to_ucs2_size)) == NULL) {
591     DEBUG(0,("load_unicode_map: malloc fail for cp_to_ucs2 size %u.\n", cp_to_ucs2_size ));
592     goto clean_and_exit;
593   }
594
595   if ((ucs2_to_cp = (uint16 *)malloc(ucs2_to_cp_size)) == NULL) {
596     DEBUG(0,("load_unicode_map: malloc fail for ucs2_to_cp size %u.\n", ucs2_to_cp_size ));
597     goto clean_and_exit;
598   }
599
600   if(fread( (char *)cp_to_ucs2, 1, cp_to_ucs2_size, fp)!=cp_to_ucs2_size) {
601     DEBUG(0,("load_unicode_map: cannot read cp_to_ucs2 from file %s. Error was %s\n",
602               unicode_map_file_name, strerror(errno)));
603     goto clean_and_exit;
604   }
605
606   if(fread( (char *)ucs2_to_cp, 1, ucs2_to_cp_size, fp)!=ucs2_to_cp_size) {
607     DEBUG(0,("load_unicode_map: cannot read ucs2_to_cp from file %s. Error was %s\n",
608               unicode_map_file_name, strerror(errno)));
609     goto clean_and_exit;
610   }
611
612   /*
613    * Now ensure the 16 bit values are in the correct endianness.
614    */
615
616   for (i = 0; i < cp_to_ucs2_size/2; i++)
617     cp_to_ucs2[i] = SVAL(cp_to_ucs2,i*2);
618
619   for (i = 0; i < ucs2_to_cp_size/2; i++)
620     ucs2_to_cp[i] = SVAL(ucs2_to_cp,i*2);
621
622   fclose(fp);
623
624   *pp_cp_to_ucs2 = cp_to_ucs2;
625   *pp_ucs2_to_cp = ucs2_to_cp;
626
627   return True;
628
629 clean_and_exit:
630
631   /* pseudo destructor :-) */
632
633   if(fp != NULL)
634     fclose(fp);
635
636   free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
637
638   default_unicode_map(pp_cp_to_ucs2, pp_ucs2_to_cp);
639
640   return False;
641 }
642
643 /*******************************************************************
644  Load a dos codepage to unicode and vica-versa map.
645 ********************************************************************/
646
647 BOOL load_dos_unicode_map(int codepage)
648 {
649   fstring codepage_str;
650
651   slprintf(codepage_str, sizeof(fstring)-1, "%03d", codepage);
652   return load_unicode_map(codepage_str, &doscp_to_ucs2, &ucs2_to_doscp);
653 }
654
655 /*******************************************************************
656  Load a UNIX codepage to unicode and vica-versa map.
657 ********************************************************************/
658
659 BOOL load_unix_unicode_map(const char *unix_char_set)
660 {
661   fstring upper_unix_char_set;
662
663   fstrcpy(upper_unix_char_set, unix_char_set);
664   strupper(upper_unix_char_set);
665   return load_unicode_map(upper_unix_char_set, &unixcp_to_ucs2, &ucs2_to_unixcp);
666 }
667
668 /*******************************************************************
669  The following functions reproduce many of the non-UNICODE standard
670  string functions in Samba.
671 ********************************************************************/
672
673 /*******************************************************************
674  Convert a UNICODE string to multibyte format. Note that the 'src' is in
675  native byte order, not little endian. Always zero terminates.
676  dst_len is in bytes.
677 ********************************************************************/
678
679 static char *unicode_to_multibyte(char *dst, const smb_ucs2_t *src,
680                                   size_t dst_len, const uint16 *ucs2_to_cp)
681 {
682         size_t dst_pos;
683
684         for(dst_pos = 0; *src && (dst_pos < dst_len - 1);) {
685                 smb_ucs2_t val = ucs2_to_cp[*src++];
686                 if(val < 256) {
687                         dst[dst_pos++] = (char)val;
688                 } else {
689
690                         if(dst_pos >= dst_len - 2)
691                                 break;
692
693                         /*
694                          * A 2 byte value is always written as
695                          * high/low into the buffer stream.
696                          */
697
698                         dst[dst_pos++] = (char)((val >> 8) & 0xff);
699                         dst[dst_pos++] = (char)(val & 0xff);
700                 }
701         }       
702
703         dst[dst_pos] = '\0';
704
705         return dst;
706 }
707
708 /*******************************************************************
709  Convert a multibyte string to UNICODE format. Note that the 'dst' is in
710  native byte order, not little endian. Always zero terminates.
711  dst_len is in bytes.
712 ********************************************************************/
713
714 smb_ucs2_t *multibyte_to_unicode(smb_ucs2_t *dst, const char *src,
715                                  size_t dst_len, smb_ucs2_t *cp_to_ucs2)
716 {
717         size_t i;
718
719         dst_len /= sizeof(smb_ucs2_t); /* Convert to smb_ucs2_t units. */
720
721         for(i = 0; (i < (dst_len  - 1)) && src[i];) {
722                 size_t skip = skip_multibyte_char(*src);
723                 smb_ucs2_t val = (*src & 0xff);
724
725                 /*
726                  * If this is a multibyte character
727                  * then work out the index value for the unicode conversion.
728                  */
729
730                 if (skip == 2)
731                         val = ((val << 8) | (src[1] & 0xff));
732
733                 dst[i++] = cp_to_ucs2[val];
734                 if (skip)
735                         src += skip;
736                 else
737                         src++;
738         }
739
740         dst[i] = 0;
741
742         return dst;
743 }
744
745 /*******************************************************************
746  Convert a UNICODE string to multibyte format. Note that the 'src' is in
747  native byte order, not little endian. Always zero terminates.
748  This function may be replaced if the MB  codepage format is an
749  encoded one (ie. utf8, hex). See the code in lib/kanji.c
750  for details. dst_len is in bytes.
751 ********************************************************************/
752
753 char *unicode_to_unix(char *dst, const smb_ucs2_t *src, size_t dst_len)
754 {
755         return unicode_to_multibyte(dst, src, dst_len, ucs2_to_unixcp);
756 }
757
758 /*******************************************************************
759  Convert a UNIX string to UNICODE format. Note that the 'dst' is in
760  native byte order, not little endian. Always zero terminates.
761  This function may be replaced if the UNIX codepage format is a
762  multi-byte one (ie. JIS, SJIS or utf8). See the code in lib/kanji.c
763  for details. dst_len is in bytes, not ucs2 units.
764 ********************************************************************/
765
766 smb_ucs2_t *unix_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len)
767 {
768         return multibyte_to_unicode(dst, src, dst_len, unixcp_to_ucs2);
769 }
770
771 /*******************************************************************
772  Convert a UNICODE string to DOS format. Note that the 'src' is in
773  native byte order, not little endian. Always zero terminates. 
774  dst_len is in bytes.
775 ********************************************************************/ 
776
777 char *unicode_to_dos(char *dst, const smb_ucs2_t *src, size_t dst_len)
778 {
779         return unicode_to_multibyte(dst, src, dst_len, ucs2_to_doscp);
780 }
781
782 /*******************************************************************
783  Convert a DOS string to UNICODE format. Note that the 'dst' is in
784  native byte order, not little endian. Always zero terminates.
785  This function may be replaced if the DOS codepage format is a
786  multi-byte one (ie. JIS, SJIS or utf8). See the code in lib/kanji.c
787  for details. dst_len is in bytes, not ucs2 units.
788 ********************************************************************/
789
790 smb_ucs2_t *dos_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len)
791 {
792         return multibyte_to_unicode(dst, src, dst_len, doscp_to_ucs2);
793 }
794
795 /*******************************************************************
796  Count the number of characters in a smb_ucs2_t string.
797 ********************************************************************/
798
799 size_t strlen_w(const smb_ucs2_t *src)
800 {
801   size_t len;
802
803   for(len = 0; *src; len++)
804     ;
805
806   return len;
807 }
808
809 /*******************************************************************
810  Safe wstring copy into a known length string. maxlength includes
811  the terminating zero. maxlength is in ucs2 units.
812 ********************************************************************/
813
814 smb_ucs2_t *safe_strcpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src, size_t maxlength)
815 {
816     size_t ucs2_len;
817
818     if (!dest) {
819         DEBUG(0,("ERROR: NULL dest in safe_strcpy_w\n"));
820         return NULL;
821     }
822
823     if (!src) {
824         *dest = 0;
825         return dest;
826     }
827
828         maxlength /= sizeof(smb_ucs2_t);
829
830         ucs2_len = strlen_w(src);
831
832     if (ucs2_len >= maxlength) {
833                 fstring out;
834         DEBUG(0,("ERROR: string overflow by %u bytes in safe_strcpy_w [%.50s]\n",
835                         (unsigned int)((ucs2_len-maxlength)*sizeof(smb_ucs2_t)),
836                         unicode_to_unix(out,src,sizeof(out))) );
837                 ucs2_len = maxlength - 1;
838     }
839
840     memcpy(dest, src, ucs2_len*sizeof(smb_ucs2_t));
841     dest[ucs2_len] = 0;
842     return dest;
843 }
844
845 /*******************************************************************
846  Safe string cat into a string. maxlength includes the terminating zero.
847  maxlength is in ucs2 units.
848 ********************************************************************/
849
850 smb_ucs2_t *safe_strcat_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength)
851 {
852     size_t ucs2_src_len, ucs2_dest_len;
853
854     if (!dest) {
855         DEBUG(0,("ERROR: NULL dest in safe_strcat_w\n"));
856         return NULL;
857     }
858
859     if (!src)
860         return dest;
861
862     ucs2_src_len = strlen_w(src);
863     ucs2_dest_len = strlen_w(dest);
864
865     if (ucs2_src_len + ucs2_dest_len >= maxlength) {
866                 fstring out;
867                 int new_len = maxlength - ucs2_dest_len - 1;
868         DEBUG(0,("ERROR: string overflow by %u characters in safe_strcat_w [%.50s]\n",
869                         (unsigned int)(sizeof(smb_ucs2_t)*(ucs2_src_len + ucs2_dest_len - maxlength)),
870                         unicode_to_unix(out,src,sizeof(out))) );
871         ucs2_src_len = (size_t)(new_len > 0 ? new_len : 0);
872     }
873
874     memcpy(&dest[ucs2_dest_len], src, ucs2_src_len*sizeof(smb_ucs2_t));
875     dest[ucs2_dest_len + ucs2_src_len] = 0;
876     return dest;
877 }
878
879 /*******************************************************************
880  Compare the two strings s1 and s2.
881 ********************************************************************/
882
883 int strcmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
884 {
885         smb_ucs2_t c1, c2;
886
887         for (;;) {
888                 c1 = *s1++;
889                 c2 = *s2++;
890
891                 if (c1 != c2)
892                         return c1 - c2;
893
894                 if (c1 == 0)
895             return 0;
896     }
897         return 0;
898 }
899
900 /*******************************************************************
901  Compare the first n characters of s1 to s2. len is in ucs2 units.
902 ********************************************************************/
903
904 int strncmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2, size_t len)
905 {
906         smb_ucs2_t c1, c2;
907
908         for (; len != 0; --len) {
909                 c1 = *s1++;
910                 c2 = *s2++;
911
912                 if (c1 != c2)
913                         return c1 - c2;
914
915                 if (c1 == 0)
916                         return 0;
917
918     }
919         return 0;
920 }
921
922 /*******************************************************************
923  Search string s2 from s1.
924 ********************************************************************/
925
926 smb_ucs2_t *strstr_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
927 {
928         size_t len = strlen_w(s2);
929
930         if (!*s2)
931                 return (smb_ucs2_t *)s1;
932
933         for(;*s1; s1++) {
934                 if (*s1 == *s2) {
935                         if (strncmp_w(s1, s2, len) == 0)
936                                 return (smb_ucs2_t *)s1;
937                 }
938         }
939         return NULL; 
940 }
941
942 /*******************************************************************
943  Search for ucs2 char c from the beginning of s.
944 ********************************************************************/ 
945
946 smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
947 {
948         do {
949                 if (*s == c)
950                         return (smb_ucs2_t *)s;
951         } while (*s++);
952
953         return NULL;
954 }
955
956 /*******************************************************************
957  Search for ucs2 char c from the end of s.
958 ********************************************************************/ 
959
960 smb_ucs2_t *strrchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
961 {
962         smb_ucs2_t *retval = 0;
963
964         do {
965                 if (*s == c)
966                         retval = (smb_ucs2_t *)s;
967         } while (*s++);
968
969         return retval;
970 }
971
972 /*******************************************************************
973  Search token from s1 separated by any ucs2 char of s2.
974 ********************************************************************/
975
976 smb_ucs2_t *strtok_w(smb_ucs2_t *s1, const smb_ucs2_t *s2)
977 {
978         static smb_ucs2_t *s = NULL;
979         smb_ucs2_t *q;
980
981         if (!s1) {
982                 if (!s)
983                         return NULL;
984                 s1 = s;
985         }
986
987         for (q = s1; *s1; s1++) {
988                 smb_ucs2_t *p = strchr_w(s2, *s1);
989                 if (p) {
990                         if (s1 != q) {
991                                 s = s1 + 1;
992                                 *s1 = '\0';
993                                 return q;
994                         }
995                         q = s1 + 1;
996                 }
997         }
998
999         s = NULL;
1000         if (*q)
1001                 return q;
1002
1003         return NULL;
1004 }
1005
1006 /*******************************************************************
1007  Duplicate a ucs2 string.
1008 ********************************************************************/
1009
1010 smb_ucs2_t *strdup_w(const smb_ucs2_t *s)
1011 {
1012         size_t newlen = (strlen_w(s)+1)*sizeof(smb_ucs2_t);
1013         smb_ucs2_t *newstr = (smb_ucs2_t *)malloc(newlen);
1014     if (newstr == NULL)
1015         return NULL;
1016     safe_strcpy_w(newstr, s, newlen);
1017     return newstr;
1018 }
1019
1020 /*******************************************************************
1021  Mapping tables for UNICODE character. Allows toupper/tolower and
1022  isXXX functions to work.
1023 ********************************************************************/
1024
1025 typedef struct {
1026         smb_ucs2_t lower;
1027         smb_ucs2_t upper;
1028         unsigned char flags;
1029 } smb_unicode_table_t;
1030
1031 static smb_unicode_table_t map_table[] = {
1032 #include "unicode_map_table.h"
1033 };
1034
1035 /*******************************************************************
1036  Is an upper case wchar.
1037 ********************************************************************/
1038
1039 int isupper_w( smb_ucs2_t val)
1040 {
1041         return (map_table[val].flags & UNI_UPPER);
1042 }
1043
1044 /*******************************************************************
1045  Is a lower case wchar.
1046 ********************************************************************/
1047
1048 int islower_w( smb_ucs2_t val)
1049 {
1050         return (map_table[val].flags & UNI_LOWER);
1051 }
1052
1053 /*******************************************************************
1054  Is a digit wchar.
1055 ********************************************************************/
1056
1057 int isdigit_w( smb_ucs2_t val)
1058 {
1059         return (map_table[val].flags & UNI_DIGIT);
1060 }
1061
1062 /*******************************************************************
1063  Is a hex digit wchar.
1064 ********************************************************************/
1065
1066 int isxdigit_w( smb_ucs2_t val)
1067 {
1068         return (map_table[val].flags & UNI_XDIGIT);
1069 }
1070
1071 /*******************************************************************
1072  Is a space wchar.
1073 ********************************************************************/
1074
1075 int isspace_w( smb_ucs2_t val)
1076 {
1077         return (map_table[val].flags & UNI_SPACE);
1078 }
1079
1080 /*******************************************************************
1081  Convert a wchar to upper case.
1082 ********************************************************************/
1083
1084 smb_ucs2_t toupper_w( smb_ucs2_t val )
1085 {
1086         return map_table[val].upper;
1087 }
1088
1089 /*******************************************************************
1090  Convert a wchar to lower case.
1091 ********************************************************************/
1092
1093 smb_ucs2_t tolower_w( smb_ucs2_t val )
1094 {
1095         return map_table[val].lower;
1096 }
1097
1098 static smb_ucs2_t *last_ptr = NULL;
1099
1100 void set_first_token_w(smb_ucs2_t *ptr)
1101 {
1102         last_ptr = ptr;
1103 }
1104
1105 /****************************************************************************
1106  Get the next token from a string, return False if none found
1107  handles double-quotes. 
1108  Based on a routine by GJC@VILLAGE.COM. 
1109  Extensively modified by Andrew.Tridgell@anu.edu.au
1110  bufsize is in bytes.
1111 ****************************************************************************/
1112
1113 static smb_ucs2_t sep_list[] = { (smb_ucs2_t)' ', (smb_ucs2_t)'\t',  (smb_ucs2_t)'\n',  (smb_ucs2_t)'\r', 0};
1114 static smb_ucs2_t quotechar = (smb_ucs2_t)'\"';
1115
1116 BOOL next_token_w(smb_ucs2_t **ptr, smb_ucs2_t *buff, smb_ucs2_t *sep, size_t bufsize)
1117 {
1118         smb_ucs2_t *s;
1119         BOOL quoted;
1120         size_t len=1;
1121
1122         /*
1123          * Convert bufsize to smb_ucs2_t units.
1124          */
1125
1126         bufsize /= sizeof(smb_ucs2_t);
1127
1128         if (!ptr)
1129                 ptr = &last_ptr;
1130         if (!ptr)
1131                 return(False);
1132
1133         s = *ptr;
1134
1135         /*
1136          * Default to simple separators.
1137          */
1138
1139         if (!sep)
1140                 sep = sep_list;
1141
1142         /*
1143          * Find the first non sep char.
1144          */
1145
1146         while(*s && strchr_w(sep,*s))
1147                 s++;
1148
1149         /*
1150          * Nothing left ?
1151          */
1152
1153         if (!*s)
1154                 return(False);
1155
1156         /*
1157          * Copy over the token.
1158          */
1159
1160         for (quoted = False; len < bufsize && *s && (quoted || !strchr_w(sep,*s)); s++) {
1161                 if (*s == quotechar) {
1162                         quoted = !quoted;
1163                 } else {
1164                         len++;
1165                         *buff++ = *s;
1166                 }
1167         }
1168
1169         *ptr = (*s) ? s+1 : s;  
1170         *buff = 0;
1171         last_ptr = *ptr;
1172
1173         return(True);
1174 }
1175
1176 /****************************************************************************
1177  Convert list of tokens to array; dependent on above routine.
1178  Uses last_ptr from above - bit of a hack.
1179 ****************************************************************************/
1180
1181 smb_ucs2_t **toktocliplist_w(int *ctok, smb_ucs2_t *sep)
1182 {
1183         smb_ucs2_t *s=last_ptr;
1184         int ictok=0;
1185         smb_ucs2_t **ret, **iret;
1186
1187         if (!sep)
1188                 sep = sep_list;
1189
1190         while(*s && strchr_w(sep,*s))
1191                 s++;
1192
1193         /*
1194          * Nothing left ?
1195          */
1196
1197         if (!*s)
1198                 return(NULL);
1199
1200         do {
1201                 ictok++;
1202                 while(*s && (!strchr_w(sep,*s)))
1203                         s++;
1204                 while(*s && strchr_w(sep,*s))
1205                         *s++=0;
1206         } while(*s);
1207
1208         *ctok = ictok;
1209         s = last_ptr;
1210
1211         if (!(ret=iret=malloc(ictok*sizeof(smb_ucs2_t *))))
1212                 return NULL;
1213   
1214         while(ictok--) {
1215                 *iret++=s;
1216                 while(*s++)
1217                         ;
1218                 while(!*s)
1219                         s++;
1220         }
1221
1222         return ret;
1223 }
1224
1225 /*******************************************************************
1226  Case insensitive string compararison.
1227 ********************************************************************/
1228
1229 int StrCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t)
1230 {
1231         /* 
1232          * Compare until we run out of string, either t or s, or find a difference.
1233          */
1234
1235         while (*s && *t && toupper_w(*s) == toupper_w(*t)) {
1236                 s++;
1237                 t++;
1238         }
1239
1240         return(toupper_w(*s) - toupper_w(*t));
1241 }
1242
1243 /*******************************************************************
1244  Case insensitive string compararison, length limited.
1245  n is in ucs2 units.
1246 ********************************************************************/
1247
1248 int StrnCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t, size_t n)
1249 {
1250         /*
1251          * Compare until we run out of string, either t or s, or chars.
1252          */
1253
1254         while (n && *s && *t && toupper_w(*s) == toupper_w(*t)) {
1255                 s++;
1256                 t++;
1257                 n--;
1258         }
1259
1260     /*
1261          * Not run out of chars - strings are different lengths.
1262          */
1263
1264     if (n) 
1265       return(toupper_w(*s) - toupper_w(*t));
1266
1267     /*
1268          * Identical up to where we run out of chars, 
1269          * and strings are same length.
1270          */
1271
1272         return(0);
1273 }
1274
1275 /*******************************************************************
1276  Compare 2 strings.
1277 ********************************************************************/
1278
1279 BOOL strequal_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
1280 {
1281         if (s1 == s2)
1282                 return(True);
1283         if (!s1 || !s2)
1284                 return(False);
1285   
1286         return(StrCaseCmp_w(s1,s2)==0);
1287 }
1288
1289 /*******************************************************************
1290  Compare 2 strings up to and including the nth char. n is in ucs2
1291  units.
1292 ******************************************************************/
1293
1294 BOOL strnequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2,size_t n)
1295 {
1296         if (s1 == s2)
1297                 return(True);
1298         if (!s1 || !s2 || !n)
1299                 return(False);
1300   
1301         return(StrnCaseCmp_w(s1,s2,n)==0);
1302 }
1303
1304 /*******************************************************************
1305  Compare 2 strings (case sensitive).
1306 ********************************************************************/
1307
1308 BOOL strcsequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2)
1309 {
1310         if (s1 == s2)
1311                 return(True);
1312         if (!s1 || !s2)
1313                 return(False);
1314   
1315         return(strcmp_w(s1,s2)==0);
1316 }
1317
1318 /*******************************************************************
1319  Convert a string to lower case.
1320 ********************************************************************/
1321
1322 void strlower_w(smb_ucs2_t *s)
1323 {
1324         while (*s) {
1325                 if (isupper_w(*s))
1326                         *s = tolower_w(*s);
1327                 s++;
1328         }
1329 }
1330
1331 /*******************************************************************
1332  Convert a string to upper case.
1333 ********************************************************************/
1334
1335 void strupper_w(smb_ucs2_t *s)
1336 {
1337         while (*s) {
1338                 if (islower_w(*s))
1339                         *s = toupper_w(*s);
1340                 s++;
1341         }
1342 }
1343
1344 /*******************************************************************
1345  Convert a string to "normal" form.
1346 ********************************************************************/
1347
1348 void strnorm_w(smb_ucs2_t *s)
1349 {
1350         extern int case_default;
1351         if (case_default == CASE_UPPER)
1352                 strupper_w(s);
1353         else
1354                 strlower_w(s);
1355 }
1356
1357 /*******************************************************************
1358  Check if a string is in "normal" case.
1359 ********************************************************************/
1360
1361 BOOL strisnormal_w(smb_ucs2_t *s)
1362 {
1363         extern int case_default;
1364         if (case_default == CASE_UPPER)
1365                 return(!strhaslower_w(s));
1366
1367         return(!strhasupper_w(s));
1368 }
1369
1370 /****************************************************************************
1371  String replace.
1372 ****************************************************************************/
1373
1374 void string_replace_w(smb_ucs2_t *s, smb_ucs2_t oldc, smb_ucs2_t newc)
1375 {
1376         while (*s) {
1377                 if (oldc == *s)
1378                         *s = newc;
1379                 s++;
1380         }
1381 }
1382
1383 /*******************************************************************
1384  Skip past some strings in a buffer. n is in bytes.
1385 ********************************************************************/
1386
1387 smb_ucs2_t *skip_string_w(smb_ucs2_t *buf,size_t n)
1388 {
1389         while (n--)
1390                 buf += (strlen_w(buf)*sizeof(smb_ucs2_t)) + 1;
1391         return(buf);
1392 }
1393
1394 /*******************************************************************
1395  Count the number of characters in a string. Same as strlen_w in
1396  smb_ucs2_t string units.
1397 ********************************************************************/
1398
1399 size_t str_charnum_w(const smb_ucs2_t *s)
1400 {
1401         return strlen_w(s);
1402 }
1403
1404 /*******************************************************************
1405  Trim the specified elements off the front and back of a string.
1406 ********************************************************************/
1407
1408 BOOL trim_string_w(smb_ucs2_t *s,const smb_ucs2_t *front,const smb_ucs2_t *back)
1409 {
1410         BOOL ret = False;
1411         size_t front_len = (front && *front) ? strlen_w(front) : 0;
1412         size_t back_len = (back && *back) ? strlen_w(back) : 0;
1413         size_t s_len;
1414
1415         while (front_len && strncmp_w(s, front, front_len) == 0) {
1416                 smb_ucs2_t *p = s;
1417                 ret = True;
1418
1419                 while (1) {
1420                         if (!(*p = p[front_len]))
1421                                 break;
1422                         p++;
1423                 }
1424         }
1425
1426         if(back_len) {
1427                 s_len = strlen_w(s);
1428                 while ((s_len >= back_len) && 
1429                         (strncmp_w(s + s_len - back_len, back, back_len)==0)) {
1430                         ret = True;
1431                         s[s_len - back_len] = 0;
1432                         s_len = strlen_w(s);
1433                 }
1434         }
1435
1436         return(ret);
1437 }
1438
1439 /****************************************************************************
1440  Does a string have any uppercase chars in it ?
1441 ****************************************************************************/
1442
1443 BOOL strhasupper_w(const smb_ucs2_t *s)
1444 {
1445         while (*s) {
1446                 if (isupper_w(*s))
1447                         return(True);
1448                 s++;
1449         }
1450         return(False);
1451 }
1452
1453 /****************************************************************************
1454  Does a string have any lowercase chars in it ?
1455 ****************************************************************************/
1456
1457 BOOL strhaslower_w(const smb_ucs2_t *s)
1458 {
1459         while (*s) {
1460                 if (islower(*s))
1461                         return(True);
1462                 s++;
1463         }
1464         return(False);
1465 }
1466
1467 /****************************************************************************
1468  Find the number of 'c' chars in a string.
1469 ****************************************************************************/
1470
1471 size_t count_chars_w(const smb_ucs2_t *s,smb_ucs2_t c)
1472 {
1473         size_t count=0;
1474
1475         while (*s) {
1476                 if (*s == c)
1477                         count++;
1478                 s++;
1479         }
1480         return(count);
1481 }
1482
1483 /*******************************************************************
1484  Return True if a string consists only of one particular character.
1485 ********************************************************************/
1486
1487 BOOL str_is_all_w(const smb_ucs2_t *s,smb_ucs2_t c)
1488 {
1489         if(s == NULL)
1490                 return False;
1491         if(!*s)
1492                 return False;
1493
1494         while (*s) {
1495                 if (*s != c)
1496                         return False;
1497                 s++;
1498         }
1499         return True;
1500 }
1501
1502 /*******************************************************************
1503  Paranoid strcpy into a buffer of given length (includes terminating
1504  zero. Strips out all but 'a-Z0-9' and replaces with '_'. Deliberately
1505  does *NOT* check for multibyte characters. Don't change it !
1506  maxlength is in ucs2 units.
1507 ********************************************************************/
1508
1509 smb_ucs2_t *alpha_strcpy_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength)
1510 {
1511         size_t len, i;
1512
1513         if (!dest) {
1514                 DEBUG(0,("ERROR: NULL dest in alpha_strcpy_w\n"));
1515                 return NULL;
1516         }
1517
1518         if (!src) {
1519                 *dest = 0;
1520                 return dest;
1521         }  
1522
1523         len = strlen_w(src);
1524         if (len >= maxlength)
1525                 len = maxlength - 1;
1526
1527         for(i = 0; i < len; i++) {
1528                 smb_ucs2_t val = src[i];
1529                 if(isupper_w(val) ||islower_w(val) || isdigit_w(val))
1530                         dest[i] = src[i];
1531                 else
1532                         dest[i] = (smb_ucs2_t)'_';
1533         }
1534
1535         dest[i] = 0;
1536
1537         return dest;
1538 }
1539
1540 /****************************************************************************
1541  Like strncpy but always null terminates. Make sure there is room !
1542  The variable n should always be one less than the available size and is in
1543  ucs2 units.
1544 ****************************************************************************/
1545
1546 smb_ucs2_t *StrnCpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src,size_t n)
1547 {
1548         smb_ucs2_t *d = dest;
1549         if (!dest)
1550                 return(NULL);
1551         if (!src) {
1552                 *dest = 0;
1553                 return(dest);
1554         }
1555
1556         while (n-- && (*d++ = *src++))
1557                 ;
1558         *d = 0;
1559         return(dest);
1560 }
1561
1562 /****************************************************************************
1563  Like strncpy but copies up to the character marker. Always null terminates.
1564  returns a pointer to the character marker in the source string (src).
1565  n is in ucs2 units.
1566 ****************************************************************************/
1567
1568 smb_ucs2_t *strncpyn_w(smb_ucs2_t *dest, const smb_ucs2_t *src,size_t n, smb_ucs2_t c)
1569 {
1570         smb_ucs2_t *p;
1571         size_t str_len;
1572
1573         p = strchr_w(src, c);
1574         if (p == NULL) {
1575                 fstring cval;
1576                 smb_ucs2_t mbcval[2];
1577                 mbcval[0] = c;
1578                 mbcval[1] = 0;
1579                 DEBUG(5, ("strncpyn_w: separator character (%s) not found\n",
1580                         unicode_to_unix(cval,mbcval,sizeof(cval)) ));
1581                 return NULL;
1582         }
1583
1584         str_len = PTR_DIFF(p, src) + 1;
1585         safe_strcpy_w(dest, src, MIN(n, str_len));
1586
1587         return p;
1588 }
1589
1590 /*************************************************************
1591  Routine to get hex characters and turn them into a 16 byte array.
1592  The array can be variable length, and any non-hex-numeric
1593  characters are skipped.  "0xnn" or "0Xnn" is specially catered
1594  for. len is in bytes.
1595  Valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
1596 **************************************************************/
1597
1598 static smb_ucs2_t hexprefix[] = { (smb_ucs2_t)'0', (smb_ucs2_t)'x', 0 };
1599 static smb_ucs2_t hexchars[] = { (smb_ucs2_t)'0', (smb_ucs2_t)'1', (smb_ucs2_t)'2', (smb_ucs2_t)'3',
1600                                                                 (smb_ucs2_t)'4', (smb_ucs2_t)'5', (smb_ucs2_t)'6', (smb_ucs2_t)'7',
1601                                                                 (smb_ucs2_t)'8', (smb_ucs2_t)'9', (smb_ucs2_t)'A', (smb_ucs2_t)'B',
1602                                                                 (smb_ucs2_t)'C', (smb_ucs2_t)'D', (smb_ucs2_t)'E', (smb_ucs2_t)'F', 0 };
1603
1604 size_t strhex_to_str_w(char *p, size_t len, const smb_ucs2_t *strhex)
1605 {
1606         size_t i;
1607         size_t num_chars = 0;
1608         unsigned char   lonybble, hinybble;
1609         smb_ucs2_t *p1 = NULL, *p2 = NULL;
1610
1611         /*
1612          * Convert to smb_ucs2_t units.
1613          */
1614
1615         len /= sizeof(smb_ucs2_t);
1616
1617         for (i = 0; i < len && strhex[i] != 0; i++) {
1618                 if (strnequal_w(hexchars, hexprefix, 2)) {
1619                         i++; /* skip two chars */
1620                         continue;
1621                 }
1622
1623                 if (!(p1 = strchr_w(hexchars, toupper_w(strhex[i]))))
1624                         break;
1625
1626                 i++; /* next hex digit */
1627
1628                 if (!(p2 = strchr_w(hexchars, toupper_w(strhex[i]))))
1629                         break;
1630
1631                 /* get the two nybbles */
1632                 hinybble = (PTR_DIFF(p1, hexchars)/sizeof(smb_ucs2_t));
1633                 lonybble = (PTR_DIFF(p2, hexchars)/sizeof(smb_ucs2_t));
1634
1635                 p[num_chars] = (hinybble << 4) | lonybble;
1636                 num_chars++;
1637
1638                 p1 = NULL;
1639                 p2 = NULL;
1640         }
1641         return num_chars;
1642 }
1643
1644 /****************************************************************************
1645  Check if a string is part of a list.
1646 ****************************************************************************/
1647
1648 BOOL in_list_w(smb_ucs2_t *s,smb_ucs2_t *list,BOOL casesensitive)
1649 {
1650         wpstring tok;
1651         smb_ucs2_t *p=list;
1652
1653         if (!list)
1654                 return(False);
1655
1656         while (next_token_w(&p,tok,LIST_SEP_W,sizeof(tok))) {
1657                 if (casesensitive) {
1658                         if (strcmp_w(tok,s) == 0)
1659                                 return(True);
1660                 } else {
1661                         if (StrCaseCmp_w(tok,s) == 0)
1662                                 return(True);
1663                 }
1664         }
1665         return(False);
1666 }
1667
1668 /* This is used to prevent lots of mallocs of size 2 */
1669 static smb_ucs2_t *null_string = NULL;
1670
1671 /****************************************************************************
1672  Set a string value, allocing the space for the string.
1673 ****************************************************************************/
1674
1675 BOOL string_init_w(smb_ucs2_t **dest,const smb_ucs2_t *src)
1676 {
1677         size_t l;
1678
1679         if (!null_string) {
1680                 if((null_string = (smb_ucs2_t *)malloc(sizeof(smb_ucs2_t))) == NULL) {
1681                         DEBUG(0,("string_init_w: malloc fail for null_string.\n"));
1682                 return False;
1683                 }
1684                 *null_string = 0;
1685         }
1686
1687         if (!src)     
1688                 src = null_string;
1689
1690         l = strlen_w(src);
1691
1692         if (l == 0)
1693                 *dest = null_string;
1694         else {
1695                 (*dest) = (smb_ucs2_t *)malloc(sizeof(smb_ucs2_t)*(l+1));
1696                 if ((*dest) == NULL) {
1697                         DEBUG(0,("Out of memory in string_init_w\n"));
1698                         return False;
1699                 }
1700
1701                 wpstrcpy(*dest,src);
1702         }
1703         return(True);
1704 }
1705
1706 /****************************************************************************
1707  Free a string value.
1708 ****************************************************************************/
1709
1710 void string_free_w(smb_ucs2_t **s)
1711 {
1712         if (!s || !(*s))
1713                 return;
1714         if (*s == null_string)
1715                 *s = NULL;
1716         if (*s)
1717                 free((char *)*s);
1718         *s = NULL;
1719 }
1720
1721 /****************************************************************************
1722  Set a string value, allocing the space for the string, and deallocating any 
1723  existing space.
1724 ****************************************************************************/
1725
1726 BOOL string_set_w(smb_ucs2_t **dest,const smb_ucs2_t *src)
1727 {
1728         string_free_w(dest);
1729
1730         return(string_init_w(dest,src));
1731 }
1732
1733 /****************************************************************************
1734  Substitute a string for a pattern in another string. Make sure there is 
1735  enough room !
1736
1737  This routine looks for pattern in s and replaces it with 
1738  insert. It may do multiple replacements.
1739
1740  Any of " ; ' $ or ` in the insert string are replaced with _
1741  if len==0 then no length check is performed
1742  len is in ucs2 units.
1743 ****************************************************************************/
1744
1745 void string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len)
1746 {
1747         smb_ucs2_t *p;
1748         ssize_t ls,lp,li, i;
1749
1750         if (!insert || !pattern || !s)
1751                 return;
1752
1753         ls = (ssize_t)strlen_w(s);
1754         lp = (ssize_t)strlen_w(pattern);
1755         li = (ssize_t)strlen_w(insert);
1756
1757         if (!*pattern)
1758                 return;
1759         
1760         while (lp <= ls && (p = strstr_w(s,pattern))) {
1761                 if (len && (ls + (li-lp) >= len)) {
1762                         fstring out;
1763                         DEBUG(0,("ERROR: string overflow by %d in string_sub_w(%.50s, %d)\n", 
1764                                  (int)(sizeof(smb_ucs2_t)*(ls + (li-lp) - len)),
1765                                  unicode_to_unix(out,pattern,sizeof(out)), (int)len*sizeof(smb_ucs2_t)));
1766                         break;
1767                 }
1768                 if (li != lp)
1769                         memmove(p+li,p+lp,sizeof(smb_ucs2_t)*(strlen_w(p+lp)+1));
1770
1771                 for (i=0;i<li;i++) {
1772                         switch (insert[i]) {
1773                         case (smb_ucs2_t)'`':
1774                         case (smb_ucs2_t)'"':
1775                         case (smb_ucs2_t)'\'':
1776                         case (smb_ucs2_t)';':
1777                         case (smb_ucs2_t)'$':
1778                         case (smb_ucs2_t)'%':
1779                         case (smb_ucs2_t)'\r':
1780                         case (smb_ucs2_t)'\n':
1781                                 p[i] = (smb_ucs2_t)'_';
1782                                 break;
1783                         default:
1784                                 p[i] = insert[i];
1785                         }
1786                 }
1787                 s = p + li;
1788                 ls += (li-lp);
1789         }
1790 }
1791
1792 void fstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert)
1793 {
1794         string_sub_w(s, pattern, insert, sizeof(wfstring));
1795 }
1796
1797 void pstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,smb_ucs2_t *insert)
1798 {
1799         string_sub_w(s, pattern, insert, sizeof(wpstring));
1800 }
1801
1802 /****************************************************************************
1803  Similar to string_sub() but allows for any character to be substituted. 
1804  Use with caution !
1805  if len==0 then no length check is performed.
1806 ****************************************************************************/
1807
1808 void all_string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len)
1809 {
1810         smb_ucs2_t *p;
1811         ssize_t ls,lp,li;
1812
1813         if (!insert || !pattern || !s)
1814                 return;
1815
1816         ls = (ssize_t)strlen_w(s);
1817         lp = (ssize_t)strlen_w(pattern);
1818         li = (ssize_t)strlen_w(insert);
1819
1820         if (!*pattern)
1821                 return;
1822         
1823         while (lp <= ls && (p = strstr_w(s,pattern))) {
1824                 if (len && (ls + (li-lp) >= len)) {
1825                         fstring out;
1826                         DEBUG(0,("ERROR: string overflow by %d in all_string_sub_w(%.50s, %d)\n", 
1827                                  (int)(sizeof(smb_ucs2_t)*(ls + (li-lp) - len)),
1828                                  unicode_to_unix(out,pattern,sizeof(out)), (int)len*sizeof(smb_ucs2_t)));
1829                         break;
1830                 }
1831                 if (li != lp)
1832                         memmove(p+li,p+lp,sizeof(smb_ucs2_t)*(strlen_w(p+lp)+1));
1833
1834                 memcpy(p, insert, li*sizeof(smb_ucs2_t));
1835                 s = p + li;
1836                 ls += (li-lp);
1837         }
1838 }
1839
1840 /****************************************************************************
1841  Splits out the front and back at a separator.
1842 ****************************************************************************/
1843
1844 void split_at_last_component_w(smb_ucs2_t *path, smb_ucs2_t *front, smb_ucs2_t sep, smb_ucs2_t *back)
1845 {
1846     smb_ucs2_t *p = strrchr_w(path, sep);
1847
1848         if (p != NULL)
1849                 *p = 0;
1850
1851         if (front != NULL)
1852                 wpstrcpy(front, path);
1853
1854         if (p != NULL) {
1855                 if (back != NULL)
1856                         wpstrcpy(back, p+1);
1857                 *p = (smb_ucs2_t)'\\';
1858         } else {
1859                 if (back != NULL)
1860                         back[0] = 0;
1861         }
1862 }
1863
1864
1865 /****************************************************************************
1866  Write an octal as a string.
1867 ****************************************************************************/
1868
1869 smb_ucs2_t *octal_string_w(int i)
1870 {
1871         static smb_ucs2_t wret[64];
1872         char ret[64];
1873
1874         if (i == -1)
1875                 slprintf(ret, sizeof(ret), "-1");
1876         else 
1877                 slprintf(ret, sizeof(ret), "0%o", i);
1878         return unix_to_unicode(wret, ret, sizeof(wret));
1879 }
1880
1881
1882 /****************************************************************************
1883  Truncate a string at a specified length.
1884  length is in ucs2 units.
1885 ****************************************************************************/
1886
1887 smb_ucs2_t *string_truncate_w(smb_ucs2_t *s, size_t length)
1888 {
1889         if (s && strlen_w(s) > length)
1890                 s[length] = 0;
1891
1892         return s;
1893 }