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 the return value is the length of the string *without* the trailing
51 ********************************************************************/
53 int dos_PutUniCode(char *dst,const char *src, ssize_t len)
56 while (*src && (len > 2)) {
57 size_t skip = get_character_len(*src);
58 smb_ucs2_t val = (*src & 0xff);
61 * If this is a multibyte character (and all DOS/Windows
62 * codepages have at maximum 2 byte multibyte characters)
63 * then work out the index value for the unicode conversion.
67 val = ((val << 8) | (src[1] & 0xff));
69 SSVAL(dst,ret,doscp_to_ucs2[val]);
81 /*******************************************************************
82 Put an ASCII string into a UNICODE array (uint16's).
84 Warning: doesn't do any codepage !!! BAD !!!
86 Help ! Fix Me ! Fix Me !
87 ********************************************************************/
89 void ascii_to_unistr(uint16 *dest, const char *src, int maxlen)
91 uint16 *destend = dest + maxlen;
94 while (dest < destend)
102 *(dest++) = (uint16)c;
108 /*******************************************************************
109 Pull an ASCII string out of a UNICODE array (uint16's).
111 Warning: doesn't do any codepage !!! BAD !!!
113 Help ! Fix Me ! Fix Me !
114 ********************************************************************/
116 void unistr_to_ascii(char *dest, const uint16 *src, int len)
118 char *destend = dest + len;
121 while (dest < destend)
136 /*******************************************************************
137 Skip past some unicode strings in a buffer.
138 ********************************************************************/
140 char *skip_unicode_string(char *buf,int n)
150 /*******************************************************************
151 Return a DOS codepage version of a little-endian unicode string.
152 Hack alert: uses fixed buffer(s).
153 ********************************************************************/
155 char *dos_unistrn2(uint16 *src, int len)
157 static char lbufs[8][MAXUNI];
159 char *lbuf = lbufs[nexti];
164 for (p = lbuf; (len > 0) && (p-lbuf < MAXUNI-3) && *src; len--, src++) {
165 uint16 ucs2_val = SVAL(src,0);
166 uint16 cp_val = ucs2_to_doscp[ucs2_val];
171 *p++ = (cp_val >> 8) & 0xff;
172 *p++ = (cp_val & 0xff);
180 static char lbufs[8][MAXUNI];
183 /*******************************************************************
184 Return a DOS codepage version of a little-endian unicode string.
185 Hack alert: uses fixed buffer(s).
186 ********************************************************************/
188 char *dos_unistr2(uint16 *src)
190 char *lbuf = lbufs[nexti];
195 for (p = lbuf; *src && (p-lbuf < MAXUNI-3); src++) {
196 uint16 ucs2_val = SVAL(src,0);
197 uint16 cp_val = ucs2_to_doscp[ucs2_val];
202 *p++ = (cp_val >> 8) & 0xff;
203 *p++ = (cp_val & 0xff);
211 /*******************************************************************
212 Return a DOS codepage version of a little-endian unicode string
213 ********************************************************************/
215 char *dos_unistr2_to_str(UNISTR2 *str)
217 char *lbuf = lbufs[nexti];
219 uint16 *src = str->buffer;
220 int max_size = MIN(sizeof(str->buffer)-3, str->uni_str_len);
224 for (p = lbuf; *src && p-lbuf < max_size; src++) {
225 uint16 ucs2_val = SVAL(src,0);
226 uint16 cp_val = ucs2_to_doscp[ucs2_val];
231 *p++ = (cp_val >> 8) & 0xff;
232 *p++ = (cp_val & 0xff);
240 /*******************************************************************
241 Convert a UNISTR2 structure to an ASCII string
242 Warning: this version does DOS codepage.
243 ********************************************************************/
245 void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
253 len = MIN(str->uni_str_len, maxlen);
254 destend = dest + len;
256 while (dest < destend)
267 ucs2_val = SVAL(src,0);
268 cp_val = ucs2_to_doscp[ucs2_val];
271 *(dest++) = (char)cp_val;
273 *dest= (cp_val >> 8) & 0xff;
274 *(dest++) = (cp_val & 0xff);
282 /*******************************************************************
283 Return a number stored in a buffer
284 ********************************************************************/
286 uint32 buffer2_to_uint32(BUFFER2 *str)
288 if (str->buf_len == 4)
289 return IVAL(str->buffer, 0);
294 /*******************************************************************
295 Return a DOS codepage version of a NOTunicode string
296 ********************************************************************/
298 char *dos_buffer2_to_str(BUFFER2 *str)
300 char *lbuf = lbufs[nexti];
302 uint16 *src = str->buffer;
303 int max_size = MIN(sizeof(str->buffer)-3, str->buf_len/2);
307 for (p = lbuf; *src && p-lbuf < max_size; src++) {
308 uint16 ucs2_val = SVAL(src,0);
309 uint16 cp_val = ucs2_to_doscp[ucs2_val];
314 *p++ = (cp_val >> 8) & 0xff;
315 *p++ = (cp_val & 0xff);
323 /*******************************************************************
324 Return a dos codepage version of a NOTunicode string
325 ********************************************************************/
327 char *dos_buffer2_to_multistr(BUFFER2 *str)
329 char *lbuf = lbufs[nexti];
331 uint16 *src = str->buffer;
332 int max_size = MIN(sizeof(str->buffer)-3, str->buf_len/2);
336 for (p = lbuf; p-lbuf < max_size; src++) {
340 uint16 ucs2_val = SVAL(src,0);
341 uint16 cp_val = ucs2_to_doscp[ucs2_val];
346 *p++ = (cp_val >> 8) & 0xff;
347 *p++ = (cp_val & 0xff);
356 /*******************************************************************
357 Create a null-terminated unicode string from a null-terminated DOS
359 Return number of unicode chars copied, excluding the null character.
360 Unicode strings created are in little-endian format.
361 ********************************************************************/
363 size_t dos_struni2(char *dst, const char *src, size_t max_len)
371 for (; *src && len < max_len-2; len++, dst +=2) {
372 size_t skip = get_character_len(*src);
373 smb_ucs2_t val = (*src & 0xff);
376 * If this is a multibyte character (and all DOS/Windows
377 * codepages have at maximum 2 byte multibyte characters)
378 * then work out the index value for the unicode conversion.
382 val = ((val << 8) | (src[1] & 0xff));
384 SSVAL(dst,0,doscp_to_ucs2[val]);
397 /*******************************************************************
398 Return a DOS codepage version of a little-endian unicode string.
399 Hack alert: uses fixed buffer(s).
400 ********************************************************************/
402 char *dos_unistr(char *buf)
404 char *lbuf = lbufs[nexti];
405 uint16 *src = (uint16 *)buf;
410 for (p = lbuf; *src && p-lbuf < MAXUNI-3; src++) {
411 uint16 ucs2_val = SVAL(src,0);
412 uint16 cp_val = ucs2_to_doscp[ucs2_val];
417 *p++ = (cp_val >> 8) & 0xff;
418 *p++ = (cp_val & 0xff);
426 /*******************************************************************
427 Strcpy for unicode strings. returns length (in num of wide chars)
428 ********************************************************************/
430 int unistrcpy(char *dst, char *src)
433 uint16 *wsrc = (uint16 *)src;
434 uint16 *wdst = (uint16 *)dst;
447 /*******************************************************************
448 Free any existing maps.
449 ********************************************************************/
451 static void free_maps(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
453 /* this handles identity mappings where we share the pointer */
454 if (*pp_ucs2_to_cp == *pp_cp_to_ucs2) {
455 *pp_ucs2_to_cp = NULL;
458 if (*pp_cp_to_ucs2) {
459 free(*pp_cp_to_ucs2);
460 *pp_cp_to_ucs2 = NULL;
463 if (*pp_ucs2_to_cp) {
464 free(*pp_ucs2_to_cp);
465 *pp_ucs2_to_cp = NULL;
470 /*******************************************************************
471 Build a default (null) codepage to unicode map.
472 ********************************************************************/
474 void default_unicode_map(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
478 free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
480 if ((*pp_ucs2_to_cp = (uint16 *)malloc(2*65536)) == NULL) {
481 DEBUG(0,("default_unicode_map: malloc fail for ucs2_to_cp size %u.\n", 2*65536));
485 *pp_cp_to_ucs2 = *pp_ucs2_to_cp; /* Default map is an identity. */
486 for (i = 0; i < 65536; i++)
487 (*pp_cp_to_ucs2)[i] = i;
490 /*******************************************************************
491 Load a codepage to unicode and vica-versa map.
492 ********************************************************************/
494 BOOL load_unicode_map(const char *codepage, smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
496 pstring unicode_map_file_name;
499 smb_ucs2_t *cp_to_ucs2 = *pp_cp_to_ucs2;
500 uint16 *ucs2_to_cp = *pp_ucs2_to_cp;
501 size_t cp_to_ucs2_size;
502 size_t ucs2_to_cp_size;
505 char buf[UNICODE_MAP_HEADER_SIZE];
507 DEBUG(5, ("load_unicode_map: loading unicode map for codepage %s.\n", codepage));
509 if (*codepage == '\0')
512 if(strlen(CODEPAGEDIR) + 13 + strlen(codepage) > sizeof(unicode_map_file_name)) {
513 DEBUG(0,("load_unicode_map: filename too long to load\n"));
517 pstrcpy(unicode_map_file_name, CODEPAGEDIR);
518 pstrcat(unicode_map_file_name, "/");
519 pstrcat(unicode_map_file_name, "unicode_map.");
520 pstrcat(unicode_map_file_name, codepage);
522 if(sys_stat(unicode_map_file_name,&st)!=0) {
523 DEBUG(0,("load_unicode_map: filename %s does not exist.\n",
524 unicode_map_file_name));
530 if ((size != UNICODE_MAP_HEADER_SIZE + 4*65536) && (size != UNICODE_MAP_HEADER_SIZE +(2*256 + 2*65536))) {
531 DEBUG(0,("load_unicode_map: file %s is an incorrect size for a \
532 unicode map file (size=%d).\n", unicode_map_file_name, (int)size));
536 if((fp = sys_fopen( unicode_map_file_name, "r")) == NULL) {
537 DEBUG(0,("load_unicode_map: cannot open file %s. Error was %s\n",
538 unicode_map_file_name, strerror(errno)));
542 if(fread( buf, 1, UNICODE_MAP_HEADER_SIZE, fp)!=UNICODE_MAP_HEADER_SIZE) {
543 DEBUG(0,("load_unicode_map: cannot read header from file %s. Error was %s\n",
544 unicode_map_file_name, strerror(errno)));
548 /* Check the version value */
549 if(SVAL(buf,UNICODE_MAP_VERSION_OFFSET) != UNICODE_MAP_FILE_VERSION_ID) {
550 DEBUG(0,("load_unicode_map: filename %s has incorrect version id. \
551 Needed %hu, got %hu.\n",
552 unicode_map_file_name, (uint16)UNICODE_MAP_FILE_VERSION_ID,
553 SVAL(buf,UNICODE_MAP_VERSION_OFFSET)));
557 /* Check the codepage value */
558 if(!strequal(&buf[UNICODE_MAP_CLIENT_CODEPAGE_OFFSET], codepage)) {
559 DEBUG(0,("load_unicode_map: codepage %s in file %s is not the same as that \
560 requested (%s).\n", &buf[UNICODE_MAP_CLIENT_CODEPAGE_OFFSET], unicode_map_file_name, codepage ));
564 ucs2_to_cp_size = 2*65536;
565 if (size == UNICODE_MAP_HEADER_SIZE + 4*65536) {
567 * This is a multibyte code page.
569 cp_to_ucs2_size = 2*65536;
572 * Single byte code page.
574 cp_to_ucs2_size = 2*256;
578 * Free any old translation tables.
581 free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
583 if ((cp_to_ucs2 = (smb_ucs2_t *)malloc(cp_to_ucs2_size)) == NULL) {
584 DEBUG(0,("load_unicode_map: malloc fail for cp_to_ucs2 size %u.\n", cp_to_ucs2_size ));
588 if ((ucs2_to_cp = (uint16 *)malloc(ucs2_to_cp_size)) == NULL) {
589 DEBUG(0,("load_unicode_map: malloc fail for ucs2_to_cp size %u.\n", ucs2_to_cp_size ));
593 if(fread( (char *)cp_to_ucs2, 1, cp_to_ucs2_size, fp)!=cp_to_ucs2_size) {
594 DEBUG(0,("load_unicode_map: cannot read cp_to_ucs2 from file %s. Error was %s\n",
595 unicode_map_file_name, strerror(errno)));
599 if(fread( (char *)ucs2_to_cp, 1, ucs2_to_cp_size, fp)!=ucs2_to_cp_size) {
600 DEBUG(0,("load_unicode_map: cannot read ucs2_to_cp from file %s. Error was %s\n",
601 unicode_map_file_name, strerror(errno)));
606 * Now ensure the 16 bit values are in the correct endianness.
609 for (i = 0; i < cp_to_ucs2_size/2; i++)
610 cp_to_ucs2[i] = SVAL(cp_to_ucs2,i*2);
612 for (i = 0; i < ucs2_to_cp_size/2; i++)
613 ucs2_to_cp[i] = SVAL(ucs2_to_cp,i*2);
617 *pp_cp_to_ucs2 = cp_to_ucs2;
618 *pp_ucs2_to_cp = ucs2_to_cp;
624 /* pseudo destructor :-) */
629 free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
631 default_unicode_map(pp_cp_to_ucs2, pp_ucs2_to_cp);
636 /*******************************************************************
637 Load a dos codepage to unicode and vica-versa map.
638 ********************************************************************/
640 BOOL load_dos_unicode_map(int codepage)
642 fstring codepage_str;
644 slprintf(codepage_str, sizeof(fstring)-1, "%03d", codepage);
645 return load_unicode_map(codepage_str, &doscp_to_ucs2, &ucs2_to_doscp);
648 /*******************************************************************
649 Load a UNIX codepage to unicode and vica-versa map.
650 ********************************************************************/
652 BOOL load_unix_unicode_map(const char *unix_char_set)
654 fstring upper_unix_char_set;
656 fstrcpy(upper_unix_char_set, unix_char_set);
657 strupper(upper_unix_char_set);
658 return load_unicode_map(upper_unix_char_set, &unixcp_to_ucs2, &ucs2_to_unixcp);
661 /*******************************************************************
662 The following functions reproduce many of the non-UNICODE standard
663 string functions in Samba.
664 ********************************************************************/
666 /*******************************************************************
667 Convert a UNICODE string to multibyte format. Note that the 'src' is in
668 native byte order, not little endian. Always zero terminates.
670 ********************************************************************/
672 static char *unicode_to_multibyte(char *dst, const smb_ucs2_t *src,
673 size_t dst_len, const uint16 *ucs2_to_cp)
677 for(dst_pos = 0; *src && (dst_pos < dst_len - 1);) {
678 smb_ucs2_t val = ucs2_to_cp[*src++];
680 dst[dst_pos++] = (char)val;
683 if(dst_pos >= dst_len - 2)
687 * A 2 byte value is always written as
688 * high/low into the buffer stream.
691 dst[dst_pos++] = (char)((val >> 8) & 0xff);
692 dst[dst_pos++] = (char)(val & 0xff);
701 /*******************************************************************
702 Convert a multibyte string to UNICODE format. Note that the 'dst' is in
703 native byte order, not little endian. Always zero terminates.
705 ********************************************************************/
707 smb_ucs2_t *multibyte_to_unicode(smb_ucs2_t *dst, const char *src,
708 size_t dst_len, smb_ucs2_t *cp_to_ucs2)
712 dst_len /= sizeof(smb_ucs2_t); /* Convert to smb_ucs2_t units. */
714 for(i = 0; (i < (dst_len - 1)) && src[i];) {
715 size_t skip = get_character_len(*src);
716 smb_ucs2_t val = (*src & 0xff);
719 * If this is a multibyte character
720 * then work out the index value for the unicode conversion.
724 val = ((val << 8) | (src[1] & 0xff));
726 dst[i++] = cp_to_ucs2[val];
738 /*******************************************************************
739 Convert a UNICODE string to multibyte format. Note that the 'src' is in
740 native byte order, not little endian. Always zero terminates.
741 This function may be replaced if the MB codepage format is an
742 encoded one (ie. utf8, hex). See the code in lib/kanji.c
743 for details. dst_len is in bytes.
744 ********************************************************************/
746 char *unicode_to_unix(char *dst, const smb_ucs2_t *src, size_t dst_len)
748 return unicode_to_multibyte(dst, src, dst_len, ucs2_to_unixcp);
751 /*******************************************************************
752 Convert a UNIX string to UNICODE format. Note that the 'dst' is in
753 native byte order, not little endian. Always zero terminates.
754 This function may be replaced if the UNIX codepage format is a
755 multi-byte one (ie. JIS, SJIS or utf8). See the code in lib/kanji.c
756 for details. dst_len is in bytes, not ucs2 units.
757 ********************************************************************/
759 smb_ucs2_t *unix_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len)
761 return multibyte_to_unicode(dst, src, dst_len, unixcp_to_ucs2);
764 /*******************************************************************
765 Convert a UNICODE string to DOS format. Note that the 'src' is in
766 native byte order, not little endian. Always zero terminates.
768 ********************************************************************/
770 char *unicode_to_dos(char *dst, const smb_ucs2_t *src, size_t dst_len)
772 return unicode_to_multibyte(dst, src, dst_len, ucs2_to_doscp);
775 /*******************************************************************
776 Convert a DOS string to UNICODE format. Note that the 'dst' is in
777 native byte order, not little endian. Always zero terminates.
778 This function may be replaced if the DOS codepage format is a
779 multi-byte one (ie. JIS, SJIS or utf8). See the code in lib/kanji.c
780 for details. dst_len is in bytes, not ucs2 units.
781 ********************************************************************/
783 smb_ucs2_t *dos_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len)
785 return multibyte_to_unicode(dst, src, dst_len, doscp_to_ucs2);
788 /*******************************************************************
789 Count the number of characters in a smb_ucs2_t string.
790 ********************************************************************/
792 size_t strlen_w(const smb_ucs2_t *src)
796 for(len = 0; *src; len++)
802 /*******************************************************************
803 Safe wstring copy into a known length string. maxlength includes
804 the terminating zero. maxlength is in bytes.
805 ********************************************************************/
807 smb_ucs2_t *safe_strcpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src, size_t maxlength)
812 DEBUG(0,("ERROR: NULL dest in safe_strcpy_w\n"));
822 * Convert maxlength to smb_ucs2_t units.
825 maxlength /= sizeof(smb_ucs2_t);
827 ucs2_len = strlen_w(src);
829 if (ucs2_len >= maxlength) {
831 DEBUG(0,("ERROR: string overflow by %u bytes in safe_strcpy_w [%.50s]\n",
832 (unsigned int)((ucs2_len-maxlength)*sizeof(smb_ucs2_t)),
833 unicode_to_unix(out,src,sizeof(out))) );
834 ucs2_len = maxlength - 1;
837 memcpy(dest, src, ucs2_len*sizeof(smb_ucs2_t));
842 /*******************************************************************
843 Safe string cat into a string. maxlength includes the terminating zero.
844 maxlength is in bytes.
845 ********************************************************************/
847 smb_ucs2_t *safe_strcat_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength)
849 size_t ucs2_src_len, ucs2_dest_len;
852 DEBUG(0,("ERROR: NULL dest in safe_strcat_w\n"));
860 * Convert maxlength to smb_ucs2_t units.
863 maxlength /= sizeof(smb_ucs2_t);
865 ucs2_src_len = strlen_w(src);
866 ucs2_dest_len = strlen_w(dest);
868 if (ucs2_src_len + ucs2_dest_len >= maxlength) {
870 int new_len = maxlength - ucs2_dest_len - 1;
871 DEBUG(0,("ERROR: string overflow by %u characters in safe_strcat_w [%.50s]\n",
872 (unsigned int)(sizeof(smb_ucs2_t)*(ucs2_src_len + ucs2_dest_len - maxlength)),
873 unicode_to_unix(out,src,sizeof(out))) );
874 ucs2_src_len = (size_t)(new_len > 0 ? new_len : 0);
877 memcpy(&dest[ucs2_dest_len], src, ucs2_src_len*sizeof(smb_ucs2_t));
878 dest[ucs2_dest_len + ucs2_src_len] = 0;
882 /*******************************************************************
883 Compare the two strings s1 and s2. len is in ucs2 units.
884 ********************************************************************/
886 int strcmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
903 /*******************************************************************
904 Compare the first n characters of s1 to s2. len is in ucs2 units.
905 ********************************************************************/
907 int strncmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2, size_t len)
911 for (; len != 0; --len) {
925 /*******************************************************************
926 Search string s2 from s1.
927 ********************************************************************/
929 smb_ucs2_t *strstr_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
931 size_t len = strlen_w(s2);
934 return (smb_ucs2_t *)s1;
938 if (strncmp_w(s1, s2, len) == 0)
939 return (smb_ucs2_t *)s1;
945 /*******************************************************************
946 Search for ucs2 char c from the beginning of s.
947 ********************************************************************/
949 smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
953 return (smb_ucs2_t *)s;
959 /*******************************************************************
960 Search for ucs2 char c from the end of s.
961 ********************************************************************/
963 smb_ucs2_t *strrchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
965 smb_ucs2_t *retval = 0;
969 retval = (smb_ucs2_t *)s;
975 /*******************************************************************
976 Search token from s1 separated by any ucs2 char of s2.
977 ********************************************************************/
979 smb_ucs2_t *strtok_w(smb_ucs2_t *s1, const smb_ucs2_t *s2)
981 static smb_ucs2_t *s = NULL;
990 for (q = s1; *s1; s1++) {
991 smb_ucs2_t *p = strchr_w(s2, *s1);
1009 /*******************************************************************
1010 Duplicate a ucs2 string.
1011 ********************************************************************/
1013 smb_ucs2_t *strdup_w(const smb_ucs2_t *s)
1015 size_t newlen = (strlen_w(s)+1)*sizeof(smb_ucs2_t);
1016 smb_ucs2_t *newstr = (smb_ucs2_t *)malloc(newlen);
1019 safe_strcpy_w(newstr, s, newlen);
1023 /*******************************************************************
1024 Mapping tables for UNICODE character. Allows toupper/tolower and
1025 isXXX functions to work.
1026 ********************************************************************/
1031 unsigned char flags;
1032 } smb_unicode_table_t;
1034 static smb_unicode_table_t map_table[] = {
1035 #include "unicode_map_table.h"
1038 /*******************************************************************
1039 Is an upper case wchar.
1040 ********************************************************************/
1042 int isupper_w( smb_ucs2_t val)
1044 return (map_table[val].flags & UNI_UPPER);
1047 /*******************************************************************
1048 Is a lower case wchar.
1049 ********************************************************************/
1051 int islower_w( smb_ucs2_t val)
1053 return (map_table[val].flags & UNI_LOWER);
1056 /*******************************************************************
1058 ********************************************************************/
1060 int isdigit_w( smb_ucs2_t val)
1062 return (map_table[val].flags & UNI_DIGIT);
1065 /*******************************************************************
1066 Is a hex digit wchar.
1067 ********************************************************************/
1069 int isxdigit_w( smb_ucs2_t val)
1071 return (map_table[val].flags & UNI_XDIGIT);
1074 /*******************************************************************
1076 ********************************************************************/
1078 int isspace_w( smb_ucs2_t val)
1080 return (map_table[val].flags & UNI_SPACE);
1083 /*******************************************************************
1084 Convert a wchar to upper case.
1085 ********************************************************************/
1087 smb_ucs2_t toupper_w( smb_ucs2_t val )
1089 return map_table[val].upper;
1092 /*******************************************************************
1093 Convert a wchar to lower case.
1094 ********************************************************************/
1096 smb_ucs2_t tolower_w( smb_ucs2_t val )
1098 return map_table[val].lower;
1101 static smb_ucs2_t *last_ptr = NULL;
1103 void set_first_token_w(smb_ucs2_t *ptr)
1108 /****************************************************************************
1109 Get the next token from a string, return False if none found
1110 handles double-quotes.
1111 Based on a routine by GJC@VILLAGE.COM.
1112 Extensively modified by Andrew.Tridgell@anu.edu.au
1113 bufsize is in bytes.
1114 ****************************************************************************/
1116 static smb_ucs2_t sep_list[] = { (smb_ucs2_t)' ', (smb_ucs2_t)'\t', (smb_ucs2_t)'\n', (smb_ucs2_t)'\r', 0};
1117 static smb_ucs2_t quotechar = (smb_ucs2_t)'\"';
1119 BOOL next_token_w(smb_ucs2_t **ptr, smb_ucs2_t *buff, smb_ucs2_t *sep, size_t bufsize)
1126 * Convert bufsize to smb_ucs2_t units.
1129 bufsize /= sizeof(smb_ucs2_t);
1139 * Default to simple separators.
1146 * Find the first non sep char.
1149 while(*s && strchr_w(sep,*s))
1160 * Copy over the token.
1163 for (quoted = False; len < bufsize && *s && (quoted || !strchr_w(sep,*s)); s++) {
1164 if (*s == quotechar) {
1172 *ptr = (*s) ? s+1 : s;
1179 /****************************************************************************
1180 Convert list of tokens to array; dependent on above routine.
1181 Uses last_ptr from above - bit of a hack.
1182 ****************************************************************************/
1184 smb_ucs2_t **toktocliplist_w(int *ctok, smb_ucs2_t *sep)
1186 smb_ucs2_t *s=last_ptr;
1188 smb_ucs2_t **ret, **iret;
1193 while(*s && strchr_w(sep,*s))
1205 while(*s && (!strchr_w(sep,*s)))
1207 while(*s && strchr_w(sep,*s))
1214 if (!(ret=iret=malloc(ictok*sizeof(smb_ucs2_t *))))
1228 /*******************************************************************
1229 Case insensitive string compararison.
1230 ********************************************************************/
1232 int StrCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t)
1235 * Compare until we run out of string, either t or s, or find a difference.
1238 while (*s && *t && toupper_w(*s) == toupper_w(*t)) {
1243 return(toupper_w(*s) - toupper_w(*t));
1246 /*******************************************************************
1247 Case insensitive string compararison, length limited.
1248 ********************************************************************/
1250 int StrnCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t, size_t n)
1253 * Compare until we run out of string, either t or s, or chars.
1256 while (n && *s && *t && toupper_w(*s) == toupper_w(*t)) {
1263 * Not run out of chars - strings are different lengths.
1267 return(toupper_w(*s) - toupper_w(*t));
1270 * Identical up to where we run out of chars,
1271 * and strings are same length.
1277 /*******************************************************************
1279 ********************************************************************/
1281 BOOL strequal_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
1288 return(StrCaseCmp_w(s1,s2)==0);
1291 /*******************************************************************
1292 Compare 2 strings up to and including the nth char.
1293 ******************************************************************/
1295 BOOL strnequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2,size_t n)
1299 if (!s1 || !s2 || !n)
1302 return(StrnCaseCmp_w(s1,s2,n)==0);
1305 /*******************************************************************
1306 Compare 2 strings (case sensitive).
1307 ********************************************************************/
1309 BOOL strcsequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2)
1316 return(strcmp_w(s1,s2)==0);
1319 /*******************************************************************
1320 Convert a string to lower case.
1321 ********************************************************************/
1323 void strlower_w(smb_ucs2_t *s)
1332 /*******************************************************************
1333 Convert a string to upper case.
1334 ********************************************************************/
1336 void strupper_w(smb_ucs2_t *s)
1345 /*******************************************************************
1346 Convert a string to "normal" form.
1347 ********************************************************************/
1349 void strnorm_w(smb_ucs2_t *s)
1351 extern int case_default;
1352 if (case_default == CASE_UPPER)
1358 /*******************************************************************
1359 Check if a string is in "normal" case.
1360 ********************************************************************/
1362 BOOL strisnormal_w(smb_ucs2_t *s)
1364 extern int case_default;
1365 if (case_default == CASE_UPPER)
1366 return(!strhaslower_w(s));
1368 return(!strhasupper_w(s));
1371 /****************************************************************************
1373 ****************************************************************************/
1375 void string_replace_w(smb_ucs2_t *s, smb_ucs2_t oldc, smb_ucs2_t newc)
1384 /*******************************************************************
1385 Skip past some strings in a buffer. n is in bytes.
1386 ********************************************************************/
1388 smb_ucs2_t *skip_string_w(smb_ucs2_t *buf,size_t n)
1391 buf += (strlen_w(buf)*sizeof(smb_ucs2_t)) + 1;
1395 /*******************************************************************
1396 Count the number of characters in a string. Same as strlen_w in
1397 smb_ucs2_t string units.
1398 ********************************************************************/
1400 size_t str_charnum_w(const smb_ucs2_t *s)
1405 /*******************************************************************
1406 Trim the specified elements off the front and back of a string.
1407 ********************************************************************/
1409 BOOL trim_string_w(smb_ucs2_t *s,const smb_ucs2_t *front,const smb_ucs2_t *back)
1412 size_t front_len = (front && *front) ? strlen_w(front) : 0;
1413 size_t back_len = (back && *back) ? strlen_w(back) : 0;
1416 while (front_len && strncmp_w(s, front, front_len) == 0) {
1421 if (!(*p = p[front_len]))
1428 s_len = strlen_w(s);
1429 while ((s_len >= back_len) &&
1430 (strncmp_w(s + s_len - back_len, back, back_len)==0)) {
1432 s[s_len - back_len] = 0;
1433 s_len = strlen_w(s);
1440 /****************************************************************************
1441 Does a string have any uppercase chars in it ?
1442 ****************************************************************************/
1444 BOOL strhasupper_w(const smb_ucs2_t *s)
1454 /****************************************************************************
1455 Does a string have any lowercase chars in it ?
1456 ****************************************************************************/
1458 BOOL strhaslower_w(const smb_ucs2_t *s)
1468 /****************************************************************************
1469 Find the number of 'c' chars in a string.
1470 ****************************************************************************/
1472 size_t count_chars_w(const smb_ucs2_t *s,smb_ucs2_t c)
1484 /*******************************************************************
1485 Return True if a string consists only of one particular character.
1486 ********************************************************************/
1488 BOOL str_is_all_w(const smb_ucs2_t *s,smb_ucs2_t c)
1503 /*******************************************************************
1504 Paranoid strcpy into a buffer of given length (includes terminating
1505 zero. Strips out all but 'a-Z0-9' and replaces with '_'. Deliberately
1506 does *NOT* check for multibyte characters. Don't change it !
1507 maxlength is in bytes.
1508 ********************************************************************/
1510 smb_ucs2_t *alpha_strcpy_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength)
1515 * Convert to smb_ucs2_t units.
1518 maxlength /= sizeof(smb_ucs2_t);
1521 DEBUG(0,("ERROR: NULL dest in alpha_strcpy_w\n"));
1530 len = strlen_w(src);
1531 if (len >= maxlength)
1532 len = maxlength - 1;
1534 for(i = 0; i < len; i++) {
1535 smb_ucs2_t val = src[i];
1536 if(isupper_w(val) ||islower_w(val) || isdigit_w(val))
1539 dest[i] = (smb_ucs2_t)'_';
1547 /****************************************************************************
1548 Like strncpy but always null terminates. Make sure there is room !
1549 The variable n should always be one less than the available size and is in bytes.
1550 ****************************************************************************/
1552 smb_ucs2_t *StrnCpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src,size_t n)
1554 smb_ucs2_t *d = dest;
1563 * Convert to smb_ucs2_t units.
1566 n /= sizeof(smb_ucs2_t);
1568 while (n-- && (*d++ = *src++))
1574 /****************************************************************************
1575 Like strncpy but copies up to the character marker. Always null terminates.
1576 returns a pointer to the character marker in the source string (src).
1578 ****************************************************************************/
1580 smb_ucs2_t *strncpyn_w(smb_ucs2_t *dest, const smb_ucs2_t *src,size_t n, smb_ucs2_t c)
1585 p = strchr_w(src, c);
1588 smb_ucs2_t mbcval[2];
1591 DEBUG(5, ("strncpyn_w: separator character (%s) not found\n",
1592 unicode_to_unix(cval,mbcval,sizeof(cval)) ));
1596 str_len = PTR_DIFF(p, src) + sizeof(smb_ucs2_t);
1597 safe_strcpy_w(dest, src, MIN(n, str_len));
1602 /*************************************************************
1603 Routine to get hex characters and turn them into a 16 byte array.
1604 The array can be variable length, and any non-hex-numeric
1605 characters are skipped. "0xnn" or "0Xnn" is specially catered
1606 for. len is in bytes.
1607 Valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
1608 **************************************************************/
1610 static smb_ucs2_t hexprefix[] = { (smb_ucs2_t)'0', (smb_ucs2_t)'x', 0 };
1611 static smb_ucs2_t hexchars[] = { (smb_ucs2_t)'0', (smb_ucs2_t)'1', (smb_ucs2_t)'2', (smb_ucs2_t)'3',
1612 (smb_ucs2_t)'4', (smb_ucs2_t)'5', (smb_ucs2_t)'6', (smb_ucs2_t)'7',
1613 (smb_ucs2_t)'8', (smb_ucs2_t)'9', (smb_ucs2_t)'A', (smb_ucs2_t)'B',
1614 (smb_ucs2_t)'C', (smb_ucs2_t)'D', (smb_ucs2_t)'E', (smb_ucs2_t)'F', 0 };
1616 size_t strhex_to_str_w(char *p, size_t len, const smb_ucs2_t *strhex)
1619 size_t num_chars = 0;
1620 unsigned char lonybble, hinybble;
1621 smb_ucs2_t *p1 = NULL, *p2 = NULL;
1624 * Convert to smb_ucs2_t units.
1627 len /= sizeof(smb_ucs2_t);
1629 for (i = 0; i < len && strhex[i] != 0; i++) {
1630 if (strnequal_w(hexchars, hexprefix, 2)) {
1631 i++; /* skip two chars */
1635 if (!(p1 = strchr_w(hexchars, toupper_w(strhex[i]))))
1638 i++; /* next hex digit */
1640 if (!(p2 = strchr_w(hexchars, toupper_w(strhex[i]))))
1643 /* get the two nybbles */
1644 hinybble = (PTR_DIFF(p1, hexchars)/sizeof(smb_ucs2_t));
1645 lonybble = (PTR_DIFF(p2, hexchars)/sizeof(smb_ucs2_t));
1647 p[num_chars] = (hinybble << 4) | lonybble;
1656 /****************************************************************************
1657 Check if a string is part of a list.
1658 ****************************************************************************/
1660 BOOL in_list_w(smb_ucs2_t *s,smb_ucs2_t *list,BOOL casesensitive)
1668 while (next_token_w(&p,tok,LIST_SEP_W,sizeof(tok))) {
1669 if (casesensitive) {
1670 if (strcmp_w(tok,s) == 0)
1673 if (StrCaseCmp_w(tok,s) == 0)
1680 /* This is used to prevent lots of mallocs of size 2 */
1681 static smb_ucs2_t *null_string = NULL;
1683 /****************************************************************************
1684 Set a string value, allocing the space for the string.
1685 ****************************************************************************/
1687 BOOL string_init_w(smb_ucs2_t **dest,const smb_ucs2_t *src)
1692 if((null_string = (smb_ucs2_t *)malloc(sizeof(smb_ucs2_t))) == NULL) {
1693 DEBUG(0,("string_init_w: malloc fail for null_string.\n"));
1705 *dest = null_string;
1707 (*dest) = (smb_ucs2_t *)malloc(sizeof(smb_ucs2_t)*(l+1));
1708 if ((*dest) == NULL) {
1709 DEBUG(0,("Out of memory in string_init_w\n"));
1713 wpstrcpy(*dest,src);
1718 /****************************************************************************
1719 Free a string value.
1720 ****************************************************************************/
1722 void string_free_w(smb_ucs2_t **s)
1726 if (*s == null_string)
1733 /****************************************************************************
1734 Set a string value, allocing the space for the string, and deallocating any
1736 ****************************************************************************/
1738 BOOL string_set_w(smb_ucs2_t **dest,const smb_ucs2_t *src)
1740 string_free_w(dest);
1742 return(string_init_w(dest,src));
1745 /****************************************************************************
1746 Substitute a string for a pattern in another string. Make sure there is
1749 This routine looks for pattern in s and replaces it with
1750 insert. It may do multiple replacements.
1752 Any of " ; ' $ or ` in the insert string are replaced with _
1753 if len==0 then no length check is performed
1755 ****************************************************************************/
1757 void string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len)
1760 ssize_t ls,lp,li, i;
1763 * Convert to smb_ucs2_t units.
1766 len /= sizeof(smb_ucs2_t);
1768 if (!insert || !pattern || !s)
1771 ls = (ssize_t)strlen_w(s);
1772 lp = (ssize_t)strlen_w(pattern);
1773 li = (ssize_t)strlen_w(insert);
1778 while (lp <= ls && (p = strstr_w(s,pattern))) {
1779 if (len && (ls + (li-lp) >= len)) {
1781 DEBUG(0,("ERROR: string overflow by %d in string_sub_w(%.50s, %d)\n",
1782 (int)(sizeof(smb_ucs2_t)*(ls + (li-lp) - len)),
1783 unicode_to_unix(out,pattern,sizeof(out)), (int)len*sizeof(smb_ucs2_t)));
1787 memmove(p+li,p+lp,sizeof(smb_ucs2_t)*(strlen_w(p+lp)+1));
1789 for (i=0;i<li;i++) {
1790 switch (insert[i]) {
1791 case (smb_ucs2_t)'`':
1792 case (smb_ucs2_t)'"':
1793 case (smb_ucs2_t)'\'':
1794 case (smb_ucs2_t)';':
1795 case (smb_ucs2_t)'$':
1796 case (smb_ucs2_t)'%':
1797 case (smb_ucs2_t)'\r':
1798 case (smb_ucs2_t)'\n':
1799 p[i] = (smb_ucs2_t)'_';
1810 void fstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert)
1812 string_sub_w(s, pattern, insert, sizeof(wfstring));
1815 void pstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,smb_ucs2_t *insert)
1817 string_sub_w(s, pattern, insert, sizeof(wpstring));
1820 /****************************************************************************
1821 Similar to string_sub() but allows for any character to be substituted.
1823 if len==0 then no length check is performed.
1824 ****************************************************************************/
1826 void all_string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len)
1832 * Convert to smb_ucs2_t units.
1835 len /= sizeof(smb_ucs2_t);
1837 if (!insert || !pattern || !s)
1840 ls = (ssize_t)strlen_w(s);
1841 lp = (ssize_t)strlen_w(pattern);
1842 li = (ssize_t)strlen_w(insert);
1847 while (lp <= ls && (p = strstr_w(s,pattern))) {
1848 if (len && (ls + (li-lp) >= len)) {
1850 DEBUG(0,("ERROR: string overflow by %d in all_string_sub_w(%.50s, %d)\n",
1851 (int)(sizeof(smb_ucs2_t)*(ls + (li-lp) - len)),
1852 unicode_to_unix(out,pattern,sizeof(out)), (int)len*sizeof(smb_ucs2_t)));
1856 memmove(p+li,p+lp,sizeof(smb_ucs2_t)*(strlen_w(p+lp)+1));
1858 memcpy(p, insert, li*sizeof(smb_ucs2_t));
1864 /****************************************************************************
1865 Splits out the front and back at a separator.
1866 ****************************************************************************/
1868 void split_at_last_component_w(smb_ucs2_t *path, smb_ucs2_t *front, smb_ucs2_t sep, smb_ucs2_t *back)
1870 smb_ucs2_t *p = strrchr_w(path, sep);
1876 wpstrcpy(front, path);
1880 wpstrcpy(back, p+1);
1881 *p = (smb_ucs2_t)'\\';
1889 /****************************************************************************
1890 Write an octal as a string.
1891 ****************************************************************************/
1893 smb_ucs2_t *octal_string_w(int i)
1895 static smb_ucs2_t wret[64];
1899 slprintf(ret, sizeof(ret), "-1");
1901 slprintf(ret, sizeof(ret), "0%o", i);
1902 return unix_to_unicode(wret, ret, sizeof(wret));
1906 /****************************************************************************
1907 Truncate a string at a specified length.
1909 ****************************************************************************/
1911 smb_ucs2_t *string_truncate_w(smb_ucs2_t *s, size_t length)
1914 * Convert to smb_ucs2_t units.
1917 length /= sizeof(smb_ucs2_t);
1919 if (s && strlen_w(s) > length)