2 Unix SMB/Netbios implementation.
4 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-1998
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.
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.
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.
24 extern int DEBUGLEVEL;
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 };
30 * The following are the codepage to ucs2 and vica versa maps.
31 * These are dynamically loaded from a unicode translation file.
34 static smb_ucs2_t *doscp_to_ucs2;
35 static uint16 *ucs2_to_doscp;
37 static smb_ucs2_t *unixcp_to_ucs2;
38 static uint16 *ucs2_to_unixcp;
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.
49 if null_terminate is True then null terminate the packet (adds 2 bytes)
51 the return value is the length consumed by the string, including the
52 null termination if applied
53 ********************************************************************/
55 int dos_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminate)
58 while (*src && (len > 2)) {
59 size_t skip = get_character_len(*src);
60 smb_ucs2_t val = (*src & 0xff);
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.
69 val = ((val << 8) | (src[1] & 0xff));
71 SSVAL(dst,ret,doscp_to_ucs2[val]);
86 /*******************************************************************
87 Put an ASCII string into a UNICODE array (uint16's).
89 Warning: doesn't do any codepage !!! BAD !!!
91 Help ! Fix Me ! Fix Me !
92 ********************************************************************/
94 void ascii_to_unistr(uint16 *dest, const char *src, int maxlen)
96 uint16 *destend = dest + maxlen;
99 while (dest < destend)
107 *(dest++) = (uint16)c;
113 /*******************************************************************
114 Pull an ASCII string out of a UNICODE array (uint16's).
116 Warning: doesn't do any codepage !!! BAD !!!
118 Help ! Fix Me ! Fix Me !
119 ********************************************************************/
121 void unistr_to_ascii(char *dest, const uint16 *src, int len)
123 char *destend = dest + len;
126 while (dest < destend)
141 /*******************************************************************
142 Skip past some unicode strings in a buffer.
143 ********************************************************************/
145 char *skip_unicode_string(char *buf,int n)
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 ********************************************************************/
162 char *dos_unistrn2(uint16 *src, int len)
164 static char lbufs[8][MAXUNI];
166 char *lbuf = lbufs[nexti];
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];
178 *p++ = (cp_val >> 8) & 0xff;
179 *p++ = (cp_val & 0xff);
187 static char lbufs[8][MAXUNI];
190 /*******************************************************************
191 Return a DOS codepage version of a little-endian unicode string.
192 Hack alert: uses fixed buffer(s).
193 ********************************************************************/
195 char *dos_unistr2(uint16 *src)
197 char *lbuf = lbufs[nexti];
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];
209 *p++ = (cp_val >> 8) & 0xff;
210 *p++ = (cp_val & 0xff);
218 /*******************************************************************
219 Return a DOS codepage version of a little-endian unicode string
220 ********************************************************************/
222 char *dos_unistr2_to_str(UNISTR2 *str)
224 char *lbuf = lbufs[nexti];
226 uint16 *src = str->buffer;
227 int max_size = MIN(sizeof(str->buffer)-3, str->uni_str_len);
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];
238 *p++ = (cp_val >> 8) & 0xff;
239 *p++ = (cp_val & 0xff);
247 /*******************************************************************
248 Convert a UNISTR2 structure to an ASCII string
249 Warning: this version does DOS codepage.
250 ********************************************************************/
252 void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
260 len = MIN(str->uni_str_len, maxlen);
261 destend = dest + len;
263 while (dest < destend)
274 ucs2_val = SVAL(src++,0);
275 cp_val = ucs2_to_doscp[ucs2_val];
278 *(dest++) = (char)cp_val;
280 *dest= (cp_val >> 8) & 0xff;
281 *(dest++) = (cp_val & 0xff);
289 /*******************************************************************
290 Return a number stored in a buffer
291 ********************************************************************/
293 uint32 buffer2_to_uint32(BUFFER2 *str)
295 if (str->buf_len == 4)
296 return IVAL(str->buffer, 0);
301 /*******************************************************************
302 Return a DOS codepage version of a NOTunicode string
303 ********************************************************************/
305 char *dos_buffer2_to_str(BUFFER2 *str)
307 char *lbuf = lbufs[nexti];
309 uint16 *src = str->buffer;
310 int max_size = MIN(sizeof(str->buffer)-3, str->buf_len/2);
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];
321 *p++ = (cp_val >> 8) & 0xff;
322 *p++ = (cp_val & 0xff);
330 /*******************************************************************
331 Return a dos codepage version of a NOTunicode string
332 ********************************************************************/
334 char *dos_buffer2_to_multistr(BUFFER2 *str)
336 char *lbuf = lbufs[nexti];
338 uint16 *src = str->buffer;
339 int max_size = MIN(sizeof(str->buffer)-3, str->buf_len/2);
343 for (p = lbuf; p-lbuf < max_size; src++) {
347 uint16 ucs2_val = SVAL(src,0);
348 uint16 cp_val = ucs2_to_doscp[ucs2_val];
353 *p++ = (cp_val >> 8) & 0xff;
354 *p++ = (cp_val & 0xff);
363 /*******************************************************************
364 Create a null-terminated unicode string from a null-terminated DOS
366 Return number of unicode chars copied, excluding the null character.
367 Unicode strings created are in little-endian format.
368 ********************************************************************/
370 size_t dos_struni2(char *dst, const char *src, size_t max_len)
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);
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.
389 val = ((val << 8) | (src[1] & 0xff));
391 SSVAL(dst,0,doscp_to_ucs2[val]);
404 /*******************************************************************
405 Return a DOS codepage version of a little-endian unicode string.
406 Hack alert: uses fixed buffer(s).
407 ********************************************************************/
409 char *dos_unistr(char *buf)
411 char *lbuf = lbufs[nexti];
412 uint16 *src = (uint16 *)buf;
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];
424 *p++ = (cp_val >> 8) & 0xff;
425 *p++ = (cp_val & 0xff);
433 /*******************************************************************
434 Strcpy for unicode strings. returns length (in num of wide chars)
435 ********************************************************************/
437 int unistrcpy(char *dst, char *src)
440 uint16 *wsrc = (uint16 *)src;
441 uint16 *wdst = (uint16 *)dst;
454 /*******************************************************************
455 Free any existing maps.
456 ********************************************************************/
458 static void free_maps(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
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;
465 if (*pp_cp_to_ucs2) {
466 free(*pp_cp_to_ucs2);
467 *pp_cp_to_ucs2 = NULL;
470 if (*pp_ucs2_to_cp) {
471 free(*pp_ucs2_to_cp);
472 *pp_ucs2_to_cp = NULL;
477 /*******************************************************************
478 Build a default (null) codepage to unicode map.
479 ********************************************************************/
481 void default_unicode_map(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
485 free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
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));
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;
497 /*******************************************************************
498 Load a codepage to unicode and vica-versa map.
499 ********************************************************************/
501 BOOL load_unicode_map(const char *codepage, smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
503 pstring unicode_map_file_name;
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;
512 char buf[UNICODE_MAP_HEADER_SIZE];
514 DEBUG(5, ("load_unicode_map: loading unicode map for codepage %s.\n", codepage));
516 if (*codepage == '\0')
519 if(strlen(CODEPAGEDIR) + 13 + strlen(codepage) > sizeof(unicode_map_file_name)) {
520 DEBUG(0,("load_unicode_map: filename too long to load\n"));
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);
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));
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));
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)));
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)));
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)));
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 ));
571 ucs2_to_cp_size = 2*65536;
572 if (size == UNICODE_MAP_HEADER_SIZE + 4*65536) {
574 * This is a multibyte code page.
576 cp_to_ucs2_size = 2*65536;
579 * Single byte code page.
581 cp_to_ucs2_size = 2*256;
585 * Free any old translation tables.
588 free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
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 ));
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 ));
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)));
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)));
613 * Now ensure the 16 bit values are in the correct endianness.
616 for (i = 0; i < cp_to_ucs2_size/2; i++)
617 cp_to_ucs2[i] = SVAL(cp_to_ucs2,i*2);
619 for (i = 0; i < ucs2_to_cp_size/2; i++)
620 ucs2_to_cp[i] = SVAL(ucs2_to_cp,i*2);
624 *pp_cp_to_ucs2 = cp_to_ucs2;
625 *pp_ucs2_to_cp = ucs2_to_cp;
631 /* pseudo destructor :-) */
636 free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
638 default_unicode_map(pp_cp_to_ucs2, pp_ucs2_to_cp);
643 /*******************************************************************
644 Load a dos codepage to unicode and vica-versa map.
645 ********************************************************************/
647 BOOL load_dos_unicode_map(int codepage)
649 fstring codepage_str;
651 slprintf(codepage_str, sizeof(fstring)-1, "%03d", codepage);
652 return load_unicode_map(codepage_str, &doscp_to_ucs2, &ucs2_to_doscp);
655 /*******************************************************************
656 Load a UNIX codepage to unicode and vica-versa map.
657 ********************************************************************/
659 BOOL load_unix_unicode_map(const char *unix_char_set)
661 fstring upper_unix_char_set;
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);
668 /*******************************************************************
669 The following functions reproduce many of the non-UNICODE standard
670 string functions in Samba.
671 ********************************************************************/
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.
677 ********************************************************************/
679 static char *unicode_to_multibyte(char *dst, const smb_ucs2_t *src,
680 size_t dst_len, const uint16 *ucs2_to_cp)
684 for(dst_pos = 0; *src && (dst_pos < dst_len - 1);) {
685 smb_ucs2_t val = ucs2_to_cp[*src++];
687 dst[dst_pos++] = (char)val;
690 if(dst_pos >= dst_len - 2)
694 * A 2 byte value is always written as
695 * high/low into the buffer stream.
698 dst[dst_pos++] = (char)((val >> 8) & 0xff);
699 dst[dst_pos++] = (char)(val & 0xff);
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.
712 ********************************************************************/
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)
719 dst_len /= sizeof(smb_ucs2_t); /* Convert to smb_ucs2_t units. */
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);
726 * If this is a multibyte character
727 * then work out the index value for the unicode conversion.
731 val = ((val << 8) | (src[1] & 0xff));
733 dst[i++] = cp_to_ucs2[val];
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 ********************************************************************/
753 char *unicode_to_unix(char *dst, const smb_ucs2_t *src, size_t dst_len)
755 return unicode_to_multibyte(dst, src, dst_len, ucs2_to_unixcp);
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 ********************************************************************/
766 smb_ucs2_t *unix_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len)
768 return multibyte_to_unicode(dst, src, dst_len, unixcp_to_ucs2);
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.
775 ********************************************************************/
777 char *unicode_to_dos(char *dst, const smb_ucs2_t *src, size_t dst_len)
779 return unicode_to_multibyte(dst, src, dst_len, ucs2_to_doscp);
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 ********************************************************************/
790 smb_ucs2_t *dos_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len)
792 return multibyte_to_unicode(dst, src, dst_len, doscp_to_ucs2);
795 /*******************************************************************
796 Count the number of characters in a smb_ucs2_t string.
797 ********************************************************************/
799 size_t strlen_w(const smb_ucs2_t *src)
803 for(len = 0; *src; len++)
809 /*******************************************************************
810 Safe wstring copy into a known length string. maxlength includes
811 the terminating zero. maxlength is in ucs2 units.
812 ********************************************************************/
814 smb_ucs2_t *safe_strcpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src, size_t maxlength)
819 DEBUG(0,("ERROR: NULL dest in safe_strcpy_w\n"));
828 maxlength /= sizeof(smb_ucs2_t);
830 ucs2_len = strlen_w(src);
832 if (ucs2_len >= maxlength) {
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;
840 memcpy(dest, src, ucs2_len*sizeof(smb_ucs2_t));
845 /*******************************************************************
846 Safe string cat into a string. maxlength includes the terminating zero.
847 maxlength is in ucs2 units.
848 ********************************************************************/
850 smb_ucs2_t *safe_strcat_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength)
852 size_t ucs2_src_len, ucs2_dest_len;
855 DEBUG(0,("ERROR: NULL dest in safe_strcat_w\n"));
862 ucs2_src_len = strlen_w(src);
863 ucs2_dest_len = strlen_w(dest);
865 if (ucs2_src_len + ucs2_dest_len >= maxlength) {
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);
874 memcpy(&dest[ucs2_dest_len], src, ucs2_src_len*sizeof(smb_ucs2_t));
875 dest[ucs2_dest_len + ucs2_src_len] = 0;
879 /*******************************************************************
880 Compare the two strings s1 and s2.
881 ********************************************************************/
883 int strcmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
900 /*******************************************************************
901 Compare the first n characters of s1 to s2. len is in ucs2 units.
902 ********************************************************************/
904 int strncmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2, size_t len)
908 for (; len != 0; --len) {
922 /*******************************************************************
923 Search string s2 from s1.
924 ********************************************************************/
926 smb_ucs2_t *strstr_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
928 size_t len = strlen_w(s2);
931 return (smb_ucs2_t *)s1;
935 if (strncmp_w(s1, s2, len) == 0)
936 return (smb_ucs2_t *)s1;
942 /*******************************************************************
943 Search for ucs2 char c from the beginning of s.
944 ********************************************************************/
946 smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
950 return (smb_ucs2_t *)s;
956 /*******************************************************************
957 Search for ucs2 char c from the end of s.
958 ********************************************************************/
960 smb_ucs2_t *strrchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
962 smb_ucs2_t *retval = 0;
966 retval = (smb_ucs2_t *)s;
972 /*******************************************************************
973 Search token from s1 separated by any ucs2 char of s2.
974 ********************************************************************/
976 smb_ucs2_t *strtok_w(smb_ucs2_t *s1, const smb_ucs2_t *s2)
978 static smb_ucs2_t *s = NULL;
987 for (q = s1; *s1; s1++) {
988 smb_ucs2_t *p = strchr_w(s2, *s1);
1006 /*******************************************************************
1007 Duplicate a ucs2 string.
1008 ********************************************************************/
1010 smb_ucs2_t *strdup_w(const smb_ucs2_t *s)
1012 size_t newlen = (strlen_w(s)+1)*sizeof(smb_ucs2_t);
1013 smb_ucs2_t *newstr = (smb_ucs2_t *)malloc(newlen);
1016 safe_strcpy_w(newstr, s, newlen);
1020 /*******************************************************************
1021 Mapping tables for UNICODE character. Allows toupper/tolower and
1022 isXXX functions to work.
1023 ********************************************************************/
1028 unsigned char flags;
1029 } smb_unicode_table_t;
1031 static smb_unicode_table_t map_table[] = {
1032 #include "unicode_map_table.h"
1035 /*******************************************************************
1036 Is an upper case wchar.
1037 ********************************************************************/
1039 int isupper_w( smb_ucs2_t val)
1041 return (map_table[val].flags & UNI_UPPER);
1044 /*******************************************************************
1045 Is a lower case wchar.
1046 ********************************************************************/
1048 int islower_w( smb_ucs2_t val)
1050 return (map_table[val].flags & UNI_LOWER);
1053 /*******************************************************************
1055 ********************************************************************/
1057 int isdigit_w( smb_ucs2_t val)
1059 return (map_table[val].flags & UNI_DIGIT);
1062 /*******************************************************************
1063 Is a hex digit wchar.
1064 ********************************************************************/
1066 int isxdigit_w( smb_ucs2_t val)
1068 return (map_table[val].flags & UNI_XDIGIT);
1071 /*******************************************************************
1073 ********************************************************************/
1075 int isspace_w( smb_ucs2_t val)
1077 return (map_table[val].flags & UNI_SPACE);
1080 /*******************************************************************
1081 Convert a wchar to upper case.
1082 ********************************************************************/
1084 smb_ucs2_t toupper_w( smb_ucs2_t val )
1086 return map_table[val].upper;
1089 /*******************************************************************
1090 Convert a wchar to lower case.
1091 ********************************************************************/
1093 smb_ucs2_t tolower_w( smb_ucs2_t val )
1095 return map_table[val].lower;
1098 static smb_ucs2_t *last_ptr = NULL;
1100 void set_first_token_w(smb_ucs2_t *ptr)
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 ****************************************************************************/
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)'\"';
1116 BOOL next_token_w(smb_ucs2_t **ptr, smb_ucs2_t *buff, smb_ucs2_t *sep, size_t bufsize)
1123 * Convert bufsize to smb_ucs2_t units.
1126 bufsize /= sizeof(smb_ucs2_t);
1136 * Default to simple separators.
1143 * Find the first non sep char.
1146 while(*s && strchr_w(sep,*s))
1157 * Copy over the token.
1160 for (quoted = False; len < bufsize && *s && (quoted || !strchr_w(sep,*s)); s++) {
1161 if (*s == quotechar) {
1169 *ptr = (*s) ? s+1 : s;
1176 /****************************************************************************
1177 Convert list of tokens to array; dependent on above routine.
1178 Uses last_ptr from above - bit of a hack.
1179 ****************************************************************************/
1181 smb_ucs2_t **toktocliplist_w(int *ctok, smb_ucs2_t *sep)
1183 smb_ucs2_t *s=last_ptr;
1185 smb_ucs2_t **ret, **iret;
1190 while(*s && strchr_w(sep,*s))
1202 while(*s && (!strchr_w(sep,*s)))
1204 while(*s && strchr_w(sep,*s))
1211 if (!(ret=iret=malloc(ictok*sizeof(smb_ucs2_t *))))
1225 /*******************************************************************
1226 Case insensitive string compararison.
1227 ********************************************************************/
1229 int StrCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t)
1232 * Compare until we run out of string, either t or s, or find a difference.
1235 while (*s && *t && toupper_w(*s) == toupper_w(*t)) {
1240 return(toupper_w(*s) - toupper_w(*t));
1243 /*******************************************************************
1244 Case insensitive string compararison, length limited.
1246 ********************************************************************/
1248 int StrnCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t, size_t n)
1251 * Compare until we run out of string, either t or s, or chars.
1254 while (n && *s && *t && toupper_w(*s) == toupper_w(*t)) {
1261 * Not run out of chars - strings are different lengths.
1265 return(toupper_w(*s) - toupper_w(*t));
1268 * Identical up to where we run out of chars,
1269 * and strings are same length.
1275 /*******************************************************************
1277 ********************************************************************/
1279 BOOL strequal_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
1286 return(StrCaseCmp_w(s1,s2)==0);
1289 /*******************************************************************
1290 Compare 2 strings up to and including the nth char. n is in ucs2
1292 ******************************************************************/
1294 BOOL strnequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2,size_t n)
1298 if (!s1 || !s2 || !n)
1301 return(StrnCaseCmp_w(s1,s2,n)==0);
1304 /*******************************************************************
1305 Compare 2 strings (case sensitive).
1306 ********************************************************************/
1308 BOOL strcsequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2)
1315 return(strcmp_w(s1,s2)==0);
1318 /*******************************************************************
1319 Convert a string to lower case.
1320 ********************************************************************/
1322 void strlower_w(smb_ucs2_t *s)
1331 /*******************************************************************
1332 Convert a string to upper case.
1333 ********************************************************************/
1335 void strupper_w(smb_ucs2_t *s)
1344 /*******************************************************************
1345 Convert a string to "normal" form.
1346 ********************************************************************/
1348 void strnorm_w(smb_ucs2_t *s)
1350 extern int case_default;
1351 if (case_default == CASE_UPPER)
1357 /*******************************************************************
1358 Check if a string is in "normal" case.
1359 ********************************************************************/
1361 BOOL strisnormal_w(smb_ucs2_t *s)
1363 extern int case_default;
1364 if (case_default == CASE_UPPER)
1365 return(!strhaslower_w(s));
1367 return(!strhasupper_w(s));
1370 /****************************************************************************
1372 ****************************************************************************/
1374 void string_replace_w(smb_ucs2_t *s, smb_ucs2_t oldc, smb_ucs2_t newc)
1383 /*******************************************************************
1384 Skip past some strings in a buffer. n is in bytes.
1385 ********************************************************************/
1387 smb_ucs2_t *skip_string_w(smb_ucs2_t *buf,size_t n)
1390 buf += (strlen_w(buf)*sizeof(smb_ucs2_t)) + 1;
1394 /*******************************************************************
1395 Count the number of characters in a string. Same as strlen_w in
1396 smb_ucs2_t string units.
1397 ********************************************************************/
1399 size_t str_charnum_w(const smb_ucs2_t *s)
1404 /*******************************************************************
1405 Trim the specified elements off the front and back of a string.
1406 ********************************************************************/
1408 BOOL trim_string_w(smb_ucs2_t *s,const smb_ucs2_t *front,const smb_ucs2_t *back)
1411 size_t front_len = (front && *front) ? strlen_w(front) : 0;
1412 size_t back_len = (back && *back) ? strlen_w(back) : 0;
1415 while (front_len && strncmp_w(s, front, front_len) == 0) {
1420 if (!(*p = p[front_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)) {
1431 s[s_len - back_len] = 0;
1432 s_len = strlen_w(s);
1439 /****************************************************************************
1440 Does a string have any uppercase chars in it ?
1441 ****************************************************************************/
1443 BOOL strhasupper_w(const smb_ucs2_t *s)
1453 /****************************************************************************
1454 Does a string have any lowercase chars in it ?
1455 ****************************************************************************/
1457 BOOL strhaslower_w(const smb_ucs2_t *s)
1467 /****************************************************************************
1468 Find the number of 'c' chars in a string.
1469 ****************************************************************************/
1471 size_t count_chars_w(const smb_ucs2_t *s,smb_ucs2_t c)
1483 /*******************************************************************
1484 Return True if a string consists only of one particular character.
1485 ********************************************************************/
1487 BOOL str_is_all_w(const smb_ucs2_t *s,smb_ucs2_t c)
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 ********************************************************************/
1509 smb_ucs2_t *alpha_strcpy_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength)
1514 DEBUG(0,("ERROR: NULL dest in alpha_strcpy_w\n"));
1523 len = strlen_w(src);
1524 if (len >= maxlength)
1525 len = maxlength - 1;
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))
1532 dest[i] = (smb_ucs2_t)'_';
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
1544 ****************************************************************************/
1546 smb_ucs2_t *StrnCpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src,size_t n)
1548 smb_ucs2_t *d = dest;
1556 while (n-- && (*d++ = *src++))
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).
1566 ****************************************************************************/
1568 smb_ucs2_t *strncpyn_w(smb_ucs2_t *dest, const smb_ucs2_t *src,size_t n, smb_ucs2_t c)
1573 p = strchr_w(src, c);
1576 smb_ucs2_t mbcval[2];
1579 DEBUG(5, ("strncpyn_w: separator character (%s) not found\n",
1580 unicode_to_unix(cval,mbcval,sizeof(cval)) ));
1584 str_len = PTR_DIFF(p, src) + 1;
1585 safe_strcpy_w(dest, src, MIN(n, str_len));
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 **************************************************************/
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 };
1604 size_t strhex_to_str_w(char *p, size_t len, const smb_ucs2_t *strhex)
1607 size_t num_chars = 0;
1608 unsigned char lonybble, hinybble;
1609 smb_ucs2_t *p1 = NULL, *p2 = NULL;
1612 * Convert to smb_ucs2_t units.
1615 len /= sizeof(smb_ucs2_t);
1617 for (i = 0; i < len && strhex[i] != 0; i++) {
1618 if (strnequal_w(hexchars, hexprefix, 2)) {
1619 i++; /* skip two chars */
1623 if (!(p1 = strchr_w(hexchars, toupper_w(strhex[i]))))
1626 i++; /* next hex digit */
1628 if (!(p2 = strchr_w(hexchars, toupper_w(strhex[i]))))
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));
1635 p[num_chars] = (hinybble << 4) | lonybble;
1644 /****************************************************************************
1645 Check if a string is part of a list.
1646 ****************************************************************************/
1648 BOOL in_list_w(smb_ucs2_t *s,smb_ucs2_t *list,BOOL casesensitive)
1656 while (next_token_w(&p,tok,LIST_SEP_W,sizeof(tok))) {
1657 if (casesensitive) {
1658 if (strcmp_w(tok,s) == 0)
1661 if (StrCaseCmp_w(tok,s) == 0)
1668 /* This is used to prevent lots of mallocs of size 2 */
1669 static smb_ucs2_t *null_string = NULL;
1671 /****************************************************************************
1672 Set a string value, allocing the space for the string.
1673 ****************************************************************************/
1675 BOOL string_init_w(smb_ucs2_t **dest,const smb_ucs2_t *src)
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"));
1693 *dest = null_string;
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"));
1701 wpstrcpy(*dest,src);
1706 /****************************************************************************
1707 Free a string value.
1708 ****************************************************************************/
1710 void string_free_w(smb_ucs2_t **s)
1714 if (*s == null_string)
1721 /****************************************************************************
1722 Set a string value, allocing the space for the string, and deallocating any
1724 ****************************************************************************/
1726 BOOL string_set_w(smb_ucs2_t **dest,const smb_ucs2_t *src)
1728 string_free_w(dest);
1730 return(string_init_w(dest,src));
1733 /****************************************************************************
1734 Substitute a string for a pattern in another string. Make sure there is
1737 This routine looks for pattern in s and replaces it with
1738 insert. It may do multiple replacements.
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 ****************************************************************************/
1745 void string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len)
1748 ssize_t ls,lp,li, i;
1750 if (!insert || !pattern || !s)
1753 ls = (ssize_t)strlen_w(s);
1754 lp = (ssize_t)strlen_w(pattern);
1755 li = (ssize_t)strlen_w(insert);
1760 while (lp <= ls && (p = strstr_w(s,pattern))) {
1761 if (len && (ls + (li-lp) >= len)) {
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)));
1769 memmove(p+li,p+lp,sizeof(smb_ucs2_t)*(strlen_w(p+lp)+1));
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)'_';
1792 void fstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert)
1794 string_sub_w(s, pattern, insert, sizeof(wfstring));
1797 void pstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,smb_ucs2_t *insert)
1799 string_sub_w(s, pattern, insert, sizeof(wpstring));
1802 /****************************************************************************
1803 Similar to string_sub() but allows for any character to be substituted.
1805 if len==0 then no length check is performed.
1806 ****************************************************************************/
1808 void all_string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len)
1813 if (!insert || !pattern || !s)
1816 ls = (ssize_t)strlen_w(s);
1817 lp = (ssize_t)strlen_w(pattern);
1818 li = (ssize_t)strlen_w(insert);
1823 while (lp <= ls && (p = strstr_w(s,pattern))) {
1824 if (len && (ls + (li-lp) >= len)) {
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)));
1832 memmove(p+li,p+lp,sizeof(smb_ucs2_t)*(strlen_w(p+lp)+1));
1834 memcpy(p, insert, li*sizeof(smb_ucs2_t));
1840 /****************************************************************************
1841 Splits out the front and back at a separator.
1842 ****************************************************************************/
1844 void split_at_last_component_w(smb_ucs2_t *path, smb_ucs2_t *front, smb_ucs2_t sep, smb_ucs2_t *back)
1846 smb_ucs2_t *p = strrchr_w(path, sep);
1852 wpstrcpy(front, path);
1856 wpstrcpy(back, p+1);
1857 *p = (smb_ucs2_t)'\\';
1865 /****************************************************************************
1866 Write an octal as a string.
1867 ****************************************************************************/
1869 smb_ucs2_t *octal_string_w(int i)
1871 static smb_ucs2_t wret[64];
1875 slprintf(ret, sizeof(ret), "-1");
1877 slprintf(ret, sizeof(ret), "0%o", i);
1878 return unix_to_unicode(wret, ret, sizeof(wret));
1882 /****************************************************************************
1883 Truncate a string at a specified length.
1884 length is in ucs2 units.
1885 ****************************************************************************/
1887 smb_ucs2_t *string_truncate_w(smb_ucs2_t *s, size_t length)
1889 if (s && strlen_w(s) > length)