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 in bytes consumed by the string, including the
52 null termination if applied
53 ********************************************************************/
55 size_t 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 Pull a DOS codepage string out of a UNICODE array. len is in bytes.
88 ********************************************************************/
90 void unistr_to_dos(char *dest, const char *src, size_t len)
92 char *destend = dest + len;
94 while (dest < destend) {
95 uint16 ucs2_val = SVAL(src,0);
96 uint16 cp_val = ucs2_to_doscp[ucs2_val];
104 *dest++ = (char)cp_val;
106 *dest++ = (cp_val >> 8) & 0xff;
107 *dest++ = (cp_val & 0xff);
114 /*******************************************************************
115 Skip past a unicode string, but not more than len. Always move
116 past a terminating zero if found.
117 ********************************************************************/
119 char *skip_unibuf(char *src, size_t len)
121 char *srcend = src + len;
123 while (src < srcend && SVAL(src,0))
132 /*******************************************************************
133 Return a DOS codepage version of a little-endian unicode string.
134 len is the filename length (ignoring any terminating zero) in uin16
135 units. Always null terminates.
136 Hack alert: uses fixed buffer(s).
137 ********************************************************************/
139 char *dos_unistrn2(uint16 *src, int len)
141 static char lbufs[8][MAXUNI];
143 char *lbuf = lbufs[nexti];
148 for (p = lbuf; (len > 0) && (p-lbuf < MAXUNI-3) && *src; len--, src++) {
149 uint16 ucs2_val = SVAL(src,0);
150 uint16 cp_val = ucs2_to_doscp[ucs2_val];
155 *p++ = (cp_val >> 8) & 0xff;
156 *p++ = (cp_val & 0xff);
164 static char lbufs[8][MAXUNI];
167 /*******************************************************************
168 Return a DOS codepage version of a little-endian unicode string.
169 Hack alert: uses fixed buffer(s).
170 ********************************************************************/
172 char *dos_unistr2(uint16 *src)
174 char *lbuf = lbufs[nexti];
179 for (p = lbuf; *src && (p-lbuf < MAXUNI-3); src++) {
180 uint16 ucs2_val = SVAL(src,0);
181 uint16 cp_val = ucs2_to_doscp[ucs2_val];
186 *p++ = (cp_val >> 8) & 0xff;
187 *p++ = (cp_val & 0xff);
195 /*******************************************************************
196 Return a DOS codepage version of a little-endian unicode string
197 ********************************************************************/
199 char *dos_unistr2_to_str(UNISTR2 *str)
201 char *lbuf = lbufs[nexti];
203 uint16 *src = str->buffer;
204 int max_size = MIN(sizeof(str->buffer)-3, str->uni_str_len);
208 for (p = lbuf; *src && p-lbuf < max_size; src++) {
209 uint16 ucs2_val = SVAL(src,0);
210 uint16 cp_val = ucs2_to_doscp[ucs2_val];
215 *p++ = (cp_val >> 8) & 0xff;
216 *p++ = (cp_val & 0xff);
224 /*******************************************************************
225 Convert a UNISTR2 structure to an ASCII string
226 Warning: this version does DOS codepage.
227 ********************************************************************/
229 void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
237 len = MIN(str->uni_str_len, maxlen);
238 destend = dest + len;
240 while (dest < destend)
251 ucs2_val = SVAL(src++,0);
252 cp_val = ucs2_to_doscp[ucs2_val];
255 *(dest++) = (char)cp_val;
257 *dest= (cp_val >> 8) & 0xff;
258 *(dest++) = (cp_val & 0xff);
266 /*******************************************************************
267 Return a number stored in a buffer
268 ********************************************************************/
270 uint32 buffer2_to_uint32(BUFFER2 *str)
272 if (str->buf_len == 4)
273 return IVAL(str->buffer, 0);
278 /*******************************************************************
279 Return a DOS codepage version of a NOTunicode string
280 ********************************************************************/
282 char *dos_buffer2_to_str(BUFFER2 *str)
284 char *lbuf = lbufs[nexti];
286 uint16 *src = str->buffer;
287 int max_size = MIN(sizeof(str->buffer)-3, str->buf_len/2);
291 for (p = lbuf; *src && p-lbuf < max_size; src++) {
292 uint16 ucs2_val = SVAL(src,0);
293 uint16 cp_val = ucs2_to_doscp[ucs2_val];
298 *p++ = (cp_val >> 8) & 0xff;
299 *p++ = (cp_val & 0xff);
307 /*******************************************************************
308 Return a dos codepage version of a NOTunicode string
309 ********************************************************************/
311 char *dos_buffer2_to_multistr(BUFFER2 *str)
313 char *lbuf = lbufs[nexti];
315 uint16 *src = str->buffer;
316 int max_size = MIN(sizeof(str->buffer)-3, str->buf_len/2);
320 for (p = lbuf; p-lbuf < max_size; src++) {
324 uint16 ucs2_val = SVAL(src,0);
325 uint16 cp_val = ucs2_to_doscp[ucs2_val];
330 *p++ = (cp_val >> 8) & 0xff;
331 *p++ = (cp_val & 0xff);
340 /*******************************************************************
341 Create a null-terminated unicode string from a null-terminated DOS
343 Return number of unicode chars copied, excluding the null character.
344 Unicode strings created are in little-endian format.
345 ********************************************************************/
347 size_t dos_struni2(char *dst, const char *src, size_t max_len)
355 for (; *src && len < max_len-2; len++, dst +=2) {
356 size_t skip = get_character_len(*src);
357 smb_ucs2_t val = (*src & 0xff);
360 * If this is a multibyte character (and all DOS/Windows
361 * codepages have at maximum 2 byte multibyte characters)
362 * then work out the index value for the unicode conversion.
366 val = ((val << 8) | (src[1] & 0xff));
368 SSVAL(dst,0,doscp_to_ucs2[val]);
381 /*******************************************************************
382 Return a DOS codepage version of a little-endian unicode string.
383 Hack alert: uses fixed buffer(s).
384 ********************************************************************/
386 char *dos_unistr(char *buf)
388 char *lbuf = lbufs[nexti];
389 uint16 *src = (uint16 *)buf;
394 for (p = lbuf; *src && p-lbuf < MAXUNI-3; src++) {
395 uint16 ucs2_val = SVAL(src,0);
396 uint16 cp_val = ucs2_to_doscp[ucs2_val];
401 *p++ = (cp_val >> 8) & 0xff;
402 *p++ = (cp_val & 0xff);
410 /*******************************************************************
411 Strcpy for unicode strings. returns length (in num of wide chars)
412 ********************************************************************/
414 int unistrcpy(char *dst, char *src)
417 uint16 *wsrc = (uint16 *)src;
418 uint16 *wdst = (uint16 *)dst;
431 /*******************************************************************
432 Free any existing maps.
433 ********************************************************************/
435 static void free_maps(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
437 /* this handles identity mappings where we share the pointer */
438 if (*pp_ucs2_to_cp == *pp_cp_to_ucs2) {
439 *pp_ucs2_to_cp = NULL;
442 if (*pp_cp_to_ucs2) {
443 free(*pp_cp_to_ucs2);
444 *pp_cp_to_ucs2 = NULL;
447 if (*pp_ucs2_to_cp) {
448 free(*pp_ucs2_to_cp);
449 *pp_ucs2_to_cp = NULL;
454 /*******************************************************************
455 Build a default (null) codepage to unicode map.
456 ********************************************************************/
458 void default_unicode_map(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
462 free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
464 if ((*pp_ucs2_to_cp = (uint16 *)malloc(2*65536)) == NULL) {
465 DEBUG(0,("default_unicode_map: malloc fail for ucs2_to_cp size %u.\n", 2*65536));
469 *pp_cp_to_ucs2 = *pp_ucs2_to_cp; /* Default map is an identity. */
470 for (i = 0; i < 65536; i++)
471 (*pp_cp_to_ucs2)[i] = i;
474 /*******************************************************************
475 Load a codepage to unicode and vica-versa map.
476 ********************************************************************/
478 BOOL load_unicode_map(const char *codepage, smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
480 pstring unicode_map_file_name;
483 smb_ucs2_t *cp_to_ucs2 = *pp_cp_to_ucs2;
484 uint16 *ucs2_to_cp = *pp_ucs2_to_cp;
485 size_t cp_to_ucs2_size;
486 size_t ucs2_to_cp_size;
489 char buf[UNICODE_MAP_HEADER_SIZE];
491 DEBUG(5, ("load_unicode_map: loading unicode map for codepage %s.\n", codepage));
493 if (*codepage == '\0')
496 if(strlen(CODEPAGEDIR) + 13 + strlen(codepage) > sizeof(unicode_map_file_name)) {
497 DEBUG(0,("load_unicode_map: filename too long to load\n"));
501 pstrcpy(unicode_map_file_name, CODEPAGEDIR);
502 pstrcat(unicode_map_file_name, "/");
503 pstrcat(unicode_map_file_name, "unicode_map.");
504 pstrcat(unicode_map_file_name, codepage);
506 if(sys_stat(unicode_map_file_name,&st)!=0) {
507 DEBUG(0,("load_unicode_map: filename %s does not exist.\n",
508 unicode_map_file_name));
514 if ((size != UNICODE_MAP_HEADER_SIZE + 4*65536) && (size != UNICODE_MAP_HEADER_SIZE +(2*256 + 2*65536))) {
515 DEBUG(0,("load_unicode_map: file %s is an incorrect size for a \
516 unicode map file (size=%d).\n", unicode_map_file_name, (int)size));
520 if((fp = sys_fopen( unicode_map_file_name, "r")) == NULL) {
521 DEBUG(0,("load_unicode_map: cannot open file %s. Error was %s\n",
522 unicode_map_file_name, strerror(errno)));
526 if(fread( buf, 1, UNICODE_MAP_HEADER_SIZE, fp)!=UNICODE_MAP_HEADER_SIZE) {
527 DEBUG(0,("load_unicode_map: cannot read header from file %s. Error was %s\n",
528 unicode_map_file_name, strerror(errno)));
532 /* Check the version value */
533 if(SVAL(buf,UNICODE_MAP_VERSION_OFFSET) != UNICODE_MAP_FILE_VERSION_ID) {
534 DEBUG(0,("load_unicode_map: filename %s has incorrect version id. \
535 Needed %hu, got %hu.\n",
536 unicode_map_file_name, (uint16)UNICODE_MAP_FILE_VERSION_ID,
537 SVAL(buf,UNICODE_MAP_VERSION_OFFSET)));
541 /* Check the codepage value */
542 if(!strequal(&buf[UNICODE_MAP_CLIENT_CODEPAGE_OFFSET], codepage)) {
543 DEBUG(0,("load_unicode_map: codepage %s in file %s is not the same as that \
544 requested (%s).\n", &buf[UNICODE_MAP_CLIENT_CODEPAGE_OFFSET], unicode_map_file_name, codepage ));
548 ucs2_to_cp_size = 2*65536;
549 if (size == UNICODE_MAP_HEADER_SIZE + 4*65536) {
551 * This is a multibyte code page.
553 cp_to_ucs2_size = 2*65536;
556 * Single byte code page.
558 cp_to_ucs2_size = 2*256;
562 * Free any old translation tables.
565 free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
567 if ((cp_to_ucs2 = (smb_ucs2_t *)malloc(cp_to_ucs2_size)) == NULL) {
568 DEBUG(0,("load_unicode_map: malloc fail for cp_to_ucs2 size %u.\n", cp_to_ucs2_size ));
572 if ((ucs2_to_cp = (uint16 *)malloc(ucs2_to_cp_size)) == NULL) {
573 DEBUG(0,("load_unicode_map: malloc fail for ucs2_to_cp size %u.\n", ucs2_to_cp_size ));
577 if(fread( (char *)cp_to_ucs2, 1, cp_to_ucs2_size, fp)!=cp_to_ucs2_size) {
578 DEBUG(0,("load_unicode_map: cannot read cp_to_ucs2 from file %s. Error was %s\n",
579 unicode_map_file_name, strerror(errno)));
583 if(fread( (char *)ucs2_to_cp, 1, ucs2_to_cp_size, fp)!=ucs2_to_cp_size) {
584 DEBUG(0,("load_unicode_map: cannot read ucs2_to_cp from file %s. Error was %s\n",
585 unicode_map_file_name, strerror(errno)));
590 * Now ensure the 16 bit values are in the correct endianness.
593 for (i = 0; i < cp_to_ucs2_size/2; i++)
594 cp_to_ucs2[i] = SVAL(cp_to_ucs2,i*2);
596 for (i = 0; i < ucs2_to_cp_size/2; i++)
597 ucs2_to_cp[i] = SVAL(ucs2_to_cp,i*2);
601 *pp_cp_to_ucs2 = cp_to_ucs2;
602 *pp_ucs2_to_cp = ucs2_to_cp;
608 /* pseudo destructor :-) */
613 free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
615 default_unicode_map(pp_cp_to_ucs2, pp_ucs2_to_cp);
620 /*******************************************************************
621 Load a dos codepage to unicode and vica-versa map.
622 ********************************************************************/
624 BOOL load_dos_unicode_map(int codepage)
626 fstring codepage_str;
628 slprintf(codepage_str, sizeof(fstring)-1, "%03d", codepage);
629 return load_unicode_map(codepage_str, &doscp_to_ucs2, &ucs2_to_doscp);
632 /*******************************************************************
633 Load a UNIX codepage to unicode and vica-versa map.
634 ********************************************************************/
636 BOOL load_unix_unicode_map(const char *unix_char_set)
638 fstring upper_unix_char_set;
640 fstrcpy(upper_unix_char_set, unix_char_set);
641 strupper(upper_unix_char_set);
642 return load_unicode_map(upper_unix_char_set, &unixcp_to_ucs2, &ucs2_to_unixcp);
645 /*******************************************************************
646 The following functions reproduce many of the non-UNICODE standard
647 string functions in Samba.
648 ********************************************************************/
650 /*******************************************************************
651 Convert a UNICODE string to multibyte format. Note that the 'src' is in
652 native byte order, not little endian. Always zero terminates.
654 ********************************************************************/
656 static char *unicode_to_multibyte(char *dst, const smb_ucs2_t *src,
657 size_t dst_len, const uint16 *ucs2_to_cp)
661 for(dst_pos = 0; *src && (dst_pos < dst_len - 1);) {
662 smb_ucs2_t val = ucs2_to_cp[*src++];
664 dst[dst_pos++] = (char)val;
667 if(dst_pos >= dst_len - 2)
671 * A 2 byte value is always written as
672 * high/low into the buffer stream.
675 dst[dst_pos++] = (char)((val >> 8) & 0xff);
676 dst[dst_pos++] = (char)(val & 0xff);
685 /*******************************************************************
686 Convert a multibyte string to UNICODE format. Note that the 'dst' is in
687 native byte order, not little endian. Always zero terminates.
689 ********************************************************************/
691 smb_ucs2_t *multibyte_to_unicode(smb_ucs2_t *dst, const char *src,
692 size_t dst_len, smb_ucs2_t *cp_to_ucs2)
696 dst_len /= sizeof(smb_ucs2_t); /* Convert to smb_ucs2_t units. */
698 for(i = 0; (i < (dst_len - 1)) && src[i];) {
699 size_t skip = skip_multibyte_char(*src);
700 smb_ucs2_t val = (*src & 0xff);
703 * If this is a multibyte character
704 * then work out the index value for the unicode conversion.
708 val = ((val << 8) | (src[1] & 0xff));
710 dst[i++] = cp_to_ucs2[val];
722 /*******************************************************************
723 Convert a UNICODE string to multibyte format. Note that the 'src' is in
724 native byte order, not little endian. Always zero terminates.
725 This function may be replaced if the MB codepage format is an
726 encoded one (ie. utf8, hex). See the code in lib/kanji.c
727 for details. dst_len is in bytes.
728 ********************************************************************/
730 char *unicode_to_unix(char *dst, const smb_ucs2_t *src, size_t dst_len)
732 return unicode_to_multibyte(dst, src, dst_len, ucs2_to_unixcp);
735 /*******************************************************************
736 Convert a UNIX string to UNICODE format. Note that the 'dst' is in
737 native byte order, not little endian. Always zero terminates.
738 This function may be replaced if the UNIX codepage format is a
739 multi-byte one (ie. JIS, SJIS or utf8). See the code in lib/kanji.c
740 for details. dst_len is in bytes, not ucs2 units.
741 ********************************************************************/
743 smb_ucs2_t *unix_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len)
745 return multibyte_to_unicode(dst, src, dst_len, unixcp_to_ucs2);
748 /*******************************************************************
749 Convert a UNICODE string to DOS format. Note that the 'src' is in
750 native byte order, not little endian. Always zero terminates.
752 ********************************************************************/
754 char *unicode_to_dos(char *dst, const smb_ucs2_t *src, size_t dst_len)
756 return unicode_to_multibyte(dst, src, dst_len, ucs2_to_doscp);
759 /*******************************************************************
760 Convert a single UNICODE character to DOS codepage. Returns the
761 number of bytes in the DOS codepage character.
762 ********************************************************************/
764 size_t unicode_to_dos_char(char *dst, const smb_ucs2_t src)
766 smb_ucs2_t val = ucs2_to_doscp[src];
772 * A 2 byte value is always written as
773 * high/low into the buffer stream.
776 dst[0] = (char)((val >> 8) & 0xff);
777 dst[1] = (char)(val & 0xff);
781 /*******************************************************************
782 Convert a DOS string to UNICODE format. Note that the 'dst' is in
783 native byte order, not little endian. Always zero terminates.
784 This function may be replaced if the DOS codepage format is a
785 multi-byte one (ie. JIS, SJIS or utf8). See the code in lib/kanji.c
786 for details. dst_len is in bytes, not ucs2 units.
787 ********************************************************************/
789 smb_ucs2_t *dos_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len)
791 return multibyte_to_unicode(dst, src, dst_len, doscp_to_ucs2);
794 /*******************************************************************
795 Count the number of characters in a smb_ucs2_t string.
796 ********************************************************************/
798 size_t strlen_w(const smb_ucs2_t *src)
802 for(len = 0; *src; len++)
808 /*******************************************************************
809 Safe wstring copy into a known length string. maxlength includes
810 the terminating zero. maxlength is in ucs2 units.
811 ********************************************************************/
813 smb_ucs2_t *safe_strcpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src, size_t maxlength)
818 DEBUG(0,("ERROR: NULL dest in safe_strcpy_w\n"));
827 maxlength /= sizeof(smb_ucs2_t);
829 ucs2_len = strlen_w(src);
831 if (ucs2_len >= maxlength) {
833 DEBUG(0,("ERROR: string overflow by %u bytes in safe_strcpy_w [%.50s]\n",
834 (unsigned int)((ucs2_len-maxlength)*sizeof(smb_ucs2_t)),
835 unicode_to_unix(out,src,sizeof(out))) );
836 ucs2_len = maxlength - 1;
839 memcpy(dest, src, ucs2_len*sizeof(smb_ucs2_t));
844 /*******************************************************************
845 Safe string cat into a string. maxlength includes the terminating zero.
846 maxlength is in ucs2 units.
847 ********************************************************************/
849 smb_ucs2_t *safe_strcat_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength)
851 size_t ucs2_src_len, ucs2_dest_len;
854 DEBUG(0,("ERROR: NULL dest in safe_strcat_w\n"));
861 ucs2_src_len = strlen_w(src);
862 ucs2_dest_len = strlen_w(dest);
864 if (ucs2_src_len + ucs2_dest_len >= maxlength) {
866 int new_len = maxlength - ucs2_dest_len - 1;
867 DEBUG(0,("ERROR: string overflow by %u characters in safe_strcat_w [%.50s]\n",
868 (unsigned int)(sizeof(smb_ucs2_t)*(ucs2_src_len + ucs2_dest_len - maxlength)),
869 unicode_to_unix(out,src,sizeof(out))) );
870 ucs2_src_len = (size_t)(new_len > 0 ? new_len : 0);
873 memcpy(&dest[ucs2_dest_len], src, ucs2_src_len*sizeof(smb_ucs2_t));
874 dest[ucs2_dest_len + ucs2_src_len] = 0;
878 /*******************************************************************
879 Compare the two strings s1 and s2.
880 ********************************************************************/
882 int strcmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
899 /*******************************************************************
900 Compare the first n characters of s1 to s2. len is in ucs2 units.
901 ********************************************************************/
903 int strncmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2, size_t len)
907 for (; len != 0; --len) {
921 /*******************************************************************
922 Search string s2 from s1.
923 ********************************************************************/
925 smb_ucs2_t *strstr_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
927 size_t len = strlen_w(s2);
930 return (smb_ucs2_t *)s1;
934 if (strncmp_w(s1, s2, len) == 0)
935 return (smb_ucs2_t *)s1;
941 /*******************************************************************
942 Search for ucs2 char c from the beginning of s.
943 ********************************************************************/
945 smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
949 return (smb_ucs2_t *)s;
955 /*******************************************************************
956 Search for ucs2 char c from the end of s.
957 ********************************************************************/
959 smb_ucs2_t *strrchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
961 smb_ucs2_t *retval = 0;
965 retval = (smb_ucs2_t *)s;
971 /*******************************************************************
972 Search token from s1 separated by any ucs2 char of s2.
973 ********************************************************************/
975 smb_ucs2_t *strtok_w(smb_ucs2_t *s1, const smb_ucs2_t *s2)
977 static smb_ucs2_t *s = NULL;
986 for (q = s1; *s1; s1++) {
987 smb_ucs2_t *p = strchr_w(s2, *s1);
1005 /*******************************************************************
1006 Duplicate a ucs2 string.
1007 ********************************************************************/
1009 smb_ucs2_t *strdup_w(const smb_ucs2_t *s)
1011 size_t newlen = (strlen_w(s)+1)*sizeof(smb_ucs2_t);
1012 smb_ucs2_t *newstr = (smb_ucs2_t *)malloc(newlen);
1015 safe_strcpy_w(newstr, s, newlen);
1019 /*******************************************************************
1020 Mapping tables for UNICODE character. Allows toupper/tolower and
1021 isXXX functions to work.
1023 tridge: split into 2 pieces. This saves us 5/6 of the memory
1024 with a small speed penalty
1025 The magic constants are the lower/upper range of the tables two
1027 ********************************************************************/
1032 unsigned char flags;
1033 } smb_unicode_table_t;
1035 #define TABLE1_BOUNDARY 9450
1036 #define TABLE2_BOUNDARY 64256
1038 static smb_unicode_table_t map_table1[] = {
1039 #include "unicode_map_table1.h"
1042 static smb_unicode_table_t map_table2[] = {
1043 #include "unicode_map_table2.h"
1046 static unsigned char map_table_flags(smb_ucs2_t v)
1048 if (v < TABLE1_BOUNDARY) return map_table1[v].flags;
1049 if (v >= TABLE2_BOUNDARY) return map_table2[v - TABLE2_BOUNDARY].flags;
1053 static smb_ucs2_t map_table_lower(smb_ucs2_t v)
1055 if (v < TABLE1_BOUNDARY) return map_table1[v].lower;
1056 if (v >= TABLE2_BOUNDARY) return map_table2[v - TABLE2_BOUNDARY].lower;
1060 static smb_ucs2_t map_table_upper(smb_ucs2_t v)
1062 if (v < TABLE1_BOUNDARY) return map_table1[v].upper;
1063 if (v >= TABLE2_BOUNDARY) return map_table2[v - TABLE2_BOUNDARY].upper;
1067 /*******************************************************************
1068 Is an upper case wchar.
1069 ********************************************************************/
1071 int isupper_w( smb_ucs2_t val)
1073 return (map_table_flags(val) & UNI_UPPER);
1076 /*******************************************************************
1077 Is a lower case wchar.
1078 ********************************************************************/
1080 int islower_w( smb_ucs2_t val)
1082 return (map_table_flags(val) & UNI_LOWER);
1085 /*******************************************************************
1087 ********************************************************************/
1089 int isdigit_w( smb_ucs2_t val)
1091 return (map_table_flags(val) & UNI_DIGIT);
1094 /*******************************************************************
1095 Is a hex digit wchar.
1096 ********************************************************************/
1098 int isxdigit_w( smb_ucs2_t val)
1100 return (map_table_flags(val) & UNI_XDIGIT);
1103 /*******************************************************************
1105 ********************************************************************/
1107 int isspace_w( smb_ucs2_t val)
1109 return (map_table_flags(val) & UNI_SPACE);
1112 /*******************************************************************
1113 Convert a wchar to upper case.
1114 ********************************************************************/
1116 smb_ucs2_t toupper_w( smb_ucs2_t val )
1118 return map_table_upper(val);
1121 /*******************************************************************
1122 Convert a wchar to lower case.
1123 ********************************************************************/
1125 smb_ucs2_t tolower_w( smb_ucs2_t val )
1127 return map_table_lower(val);
1130 static smb_ucs2_t *last_ptr = NULL;
1132 void set_first_token_w(smb_ucs2_t *ptr)
1137 /****************************************************************************
1138 Get the next token from a string, return False if none found
1139 handles double-quotes.
1140 Based on a routine by GJC@VILLAGE.COM.
1141 Extensively modified by Andrew.Tridgell@anu.edu.au
1142 bufsize is in bytes.
1143 ****************************************************************************/
1145 static smb_ucs2_t sep_list[] = { (smb_ucs2_t)' ', (smb_ucs2_t)'\t', (smb_ucs2_t)'\n', (smb_ucs2_t)'\r', 0};
1146 static smb_ucs2_t quotechar = (smb_ucs2_t)'\"';
1148 BOOL next_token_w(smb_ucs2_t **ptr, smb_ucs2_t *buff, smb_ucs2_t *sep, size_t bufsize)
1155 * Convert bufsize to smb_ucs2_t units.
1158 bufsize /= sizeof(smb_ucs2_t);
1168 * Default to simple separators.
1175 * Find the first non sep char.
1178 while(*s && strchr_w(sep,*s))
1189 * Copy over the token.
1192 for (quoted = False; len < bufsize && *s && (quoted || !strchr_w(sep,*s)); s++) {
1193 if (*s == quotechar) {
1201 *ptr = (*s) ? s+1 : s;
1208 /****************************************************************************
1209 Convert list of tokens to array; dependent on above routine.
1210 Uses last_ptr from above - bit of a hack.
1211 ****************************************************************************/
1213 smb_ucs2_t **toktocliplist_w(int *ctok, smb_ucs2_t *sep)
1215 smb_ucs2_t *s=last_ptr;
1217 smb_ucs2_t **ret, **iret;
1222 while(*s && strchr_w(sep,*s))
1234 while(*s && (!strchr_w(sep,*s)))
1236 while(*s && strchr_w(sep,*s))
1243 if (!(ret=iret=malloc(ictok*sizeof(smb_ucs2_t *))))
1257 /*******************************************************************
1258 Case insensitive string compararison.
1259 ********************************************************************/
1261 int StrCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t)
1264 * Compare until we run out of string, either t or s, or find a difference.
1267 while (*s && *t && toupper_w(*s) == toupper_w(*t)) {
1272 return(toupper_w(*s) - toupper_w(*t));
1275 /*******************************************************************
1276 Case insensitive string compararison, length limited.
1278 ********************************************************************/
1280 int StrnCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t, size_t n)
1283 * Compare until we run out of string, either t or s, or chars.
1286 while (n && *s && *t && toupper_w(*s) == toupper_w(*t)) {
1293 * Not run out of chars - strings are different lengths.
1297 return(toupper_w(*s) - toupper_w(*t));
1300 * Identical up to where we run out of chars,
1301 * and strings are same length.
1307 /*******************************************************************
1309 ********************************************************************/
1311 BOOL strequal_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
1318 return(StrCaseCmp_w(s1,s2)==0);
1321 /*******************************************************************
1322 Compare 2 strings up to and including the nth char. n is in ucs2
1324 ******************************************************************/
1326 BOOL strnequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2,size_t n)
1330 if (!s1 || !s2 || !n)
1333 return(StrnCaseCmp_w(s1,s2,n)==0);
1336 /*******************************************************************
1337 Compare 2 strings (case sensitive).
1338 ********************************************************************/
1340 BOOL strcsequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2)
1347 return(strcmp_w(s1,s2)==0);
1350 /*******************************************************************
1351 Convert a string to lower case.
1352 ********************************************************************/
1354 void strlower_w(smb_ucs2_t *s)
1363 /*******************************************************************
1364 Convert a string to upper case.
1365 ********************************************************************/
1367 void strupper_w(smb_ucs2_t *s)
1376 /*******************************************************************
1377 Convert a string to "normal" form.
1378 ********************************************************************/
1380 void strnorm_w(smb_ucs2_t *s)
1382 extern int case_default;
1383 if (case_default == CASE_UPPER)
1389 /*******************************************************************
1390 Check if a string is in "normal" case.
1391 ********************************************************************/
1393 BOOL strisnormal_w(smb_ucs2_t *s)
1395 extern int case_default;
1396 if (case_default == CASE_UPPER)
1397 return(!strhaslower_w(s));
1399 return(!strhasupper_w(s));
1402 /****************************************************************************
1404 ****************************************************************************/
1406 void string_replace_w(smb_ucs2_t *s, smb_ucs2_t oldc, smb_ucs2_t newc)
1415 /*******************************************************************
1416 Skip past some strings in a buffer. n is in bytes.
1417 ********************************************************************/
1419 smb_ucs2_t *skip_string_w(smb_ucs2_t *buf,size_t n)
1422 buf += (strlen_w(buf)*sizeof(smb_ucs2_t)) + 1;
1426 /*******************************************************************
1427 Count the number of characters in a string. Same as strlen_w in
1428 smb_ucs2_t string units.
1429 ********************************************************************/
1431 size_t str_charnum_w(const smb_ucs2_t *s)
1436 /*******************************************************************
1437 Trim the specified elements off the front and back of a string.
1438 ********************************************************************/
1440 BOOL trim_string_w(smb_ucs2_t *s,const smb_ucs2_t *front,const smb_ucs2_t *back)
1443 size_t front_len = (front && *front) ? strlen_w(front) : 0;
1444 size_t back_len = (back && *back) ? strlen_w(back) : 0;
1447 while (front_len && strncmp_w(s, front, front_len) == 0) {
1452 if (!(*p = p[front_len]))
1459 s_len = strlen_w(s);
1460 while ((s_len >= back_len) &&
1461 (strncmp_w(s + s_len - back_len, back, back_len)==0)) {
1463 s[s_len - back_len] = 0;
1464 s_len = strlen_w(s);
1471 /****************************************************************************
1472 Does a string have any uppercase chars in it ?
1473 ****************************************************************************/
1475 BOOL strhasupper_w(const smb_ucs2_t *s)
1485 /****************************************************************************
1486 Does a string have any lowercase chars in it ?
1487 ****************************************************************************/
1489 BOOL strhaslower_w(const smb_ucs2_t *s)
1499 /****************************************************************************
1500 Find the number of 'c' chars in a string.
1501 ****************************************************************************/
1503 size_t count_chars_w(const smb_ucs2_t *s,smb_ucs2_t c)
1515 /*******************************************************************
1516 Return True if a string consists only of one particular character.
1517 ********************************************************************/
1519 BOOL str_is_all_w(const smb_ucs2_t *s,smb_ucs2_t c)
1534 /*******************************************************************
1535 Paranoid strcpy into a buffer of given length (includes terminating
1536 zero. Strips out all but 'a-Z0-9' and replaces with '_'. Deliberately
1537 does *NOT* check for multibyte characters. Don't change it !
1538 maxlength is in ucs2 units.
1539 ********************************************************************/
1541 smb_ucs2_t *alpha_strcpy_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength)
1546 DEBUG(0,("ERROR: NULL dest in alpha_strcpy_w\n"));
1555 len = strlen_w(src);
1556 if (len >= maxlength)
1557 len = maxlength - 1;
1559 for(i = 0; i < len; i++) {
1560 smb_ucs2_t val = src[i];
1561 if(isupper_w(val) ||islower_w(val) || isdigit_w(val))
1564 dest[i] = (smb_ucs2_t)'_';
1572 /****************************************************************************
1573 Like strncpy but always null terminates. Make sure there is room !
1574 The variable n should always be one less than the available size and is in
1576 ****************************************************************************/
1578 smb_ucs2_t *StrnCpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src,size_t n)
1580 smb_ucs2_t *d = dest;
1588 while (n-- && (*d++ = *src++))
1594 /****************************************************************************
1595 Like strncpy but copies up to the character marker. Always null terminates.
1596 returns a pointer to the character marker in the source string (src).
1598 ****************************************************************************/
1600 smb_ucs2_t *strncpyn_w(smb_ucs2_t *dest, const smb_ucs2_t *src,size_t n, smb_ucs2_t c)
1605 p = strchr_w(src, c);
1608 smb_ucs2_t mbcval[2];
1611 DEBUG(5, ("strncpyn_w: separator character (%s) not found\n",
1612 unicode_to_unix(cval,mbcval,sizeof(cval)) ));
1616 str_len = PTR_DIFF(p, src) + 1;
1617 safe_strcpy_w(dest, src, MIN(n, str_len));
1622 /*************************************************************
1623 Routine to get hex characters and turn them into a 16 byte array.
1624 The array can be variable length, and any non-hex-numeric
1625 characters are skipped. "0xnn" or "0Xnn" is specially catered
1626 for. len is in bytes.
1627 Valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
1628 **************************************************************/
1630 static smb_ucs2_t hexprefix[] = { (smb_ucs2_t)'0', (smb_ucs2_t)'x', 0 };
1631 static smb_ucs2_t hexchars[] = { (smb_ucs2_t)'0', (smb_ucs2_t)'1', (smb_ucs2_t)'2', (smb_ucs2_t)'3',
1632 (smb_ucs2_t)'4', (smb_ucs2_t)'5', (smb_ucs2_t)'6', (smb_ucs2_t)'7',
1633 (smb_ucs2_t)'8', (smb_ucs2_t)'9', (smb_ucs2_t)'A', (smb_ucs2_t)'B',
1634 (smb_ucs2_t)'C', (smb_ucs2_t)'D', (smb_ucs2_t)'E', (smb_ucs2_t)'F', 0 };
1636 size_t strhex_to_str_w(char *p, size_t len, const smb_ucs2_t *strhex)
1639 size_t num_chars = 0;
1640 unsigned char lonybble, hinybble;
1641 smb_ucs2_t *p1 = NULL, *p2 = NULL;
1644 * Convert to smb_ucs2_t units.
1647 len /= sizeof(smb_ucs2_t);
1649 for (i = 0; i < len && strhex[i] != 0; i++) {
1650 if (strnequal_w(hexchars, hexprefix, 2)) {
1651 i++; /* skip two chars */
1655 if (!(p1 = strchr_w(hexchars, toupper_w(strhex[i]))))
1658 i++; /* next hex digit */
1660 if (!(p2 = strchr_w(hexchars, toupper_w(strhex[i]))))
1663 /* get the two nybbles */
1664 hinybble = (PTR_DIFF(p1, hexchars)/sizeof(smb_ucs2_t));
1665 lonybble = (PTR_DIFF(p2, hexchars)/sizeof(smb_ucs2_t));
1667 p[num_chars] = (hinybble << 4) | lonybble;
1676 /****************************************************************************
1677 Check if a string is part of a list.
1678 ****************************************************************************/
1680 BOOL in_list_w(smb_ucs2_t *s,smb_ucs2_t *list,BOOL casesensitive)
1688 while (next_token_w(&p,tok,LIST_SEP_W,sizeof(tok))) {
1689 if (casesensitive) {
1690 if (strcmp_w(tok,s) == 0)
1693 if (StrCaseCmp_w(tok,s) == 0)
1700 /* This is used to prevent lots of mallocs of size 2 */
1701 static smb_ucs2_t *null_string = NULL;
1703 /****************************************************************************
1704 Set a string value, allocing the space for the string.
1705 ****************************************************************************/
1707 BOOL string_init_w(smb_ucs2_t **dest,const smb_ucs2_t *src)
1712 if((null_string = (smb_ucs2_t *)malloc(sizeof(smb_ucs2_t))) == NULL) {
1713 DEBUG(0,("string_init_w: malloc fail for null_string.\n"));
1725 *dest = null_string;
1727 (*dest) = (smb_ucs2_t *)malloc(sizeof(smb_ucs2_t)*(l+1));
1728 if ((*dest) == NULL) {
1729 DEBUG(0,("Out of memory in string_init_w\n"));
1733 wpstrcpy(*dest,src);
1738 /****************************************************************************
1739 Free a string value.
1740 ****************************************************************************/
1742 void string_free_w(smb_ucs2_t **s)
1746 if (*s == null_string)
1753 /****************************************************************************
1754 Set a string value, allocing the space for the string, and deallocating any
1756 ****************************************************************************/
1758 BOOL string_set_w(smb_ucs2_t **dest,const smb_ucs2_t *src)
1760 string_free_w(dest);
1762 return(string_init_w(dest,src));
1765 /****************************************************************************
1766 Substitute a string for a pattern in another string. Make sure there is
1769 This routine looks for pattern in s and replaces it with
1770 insert. It may do multiple replacements.
1772 Any of " ; ' $ or ` in the insert string are replaced with _
1773 if len==0 then no length check is performed
1774 len is in ucs2 units.
1775 ****************************************************************************/
1777 void string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len)
1780 ssize_t ls,lp,li, i;
1782 if (!insert || !pattern || !s)
1785 ls = (ssize_t)strlen_w(s);
1786 lp = (ssize_t)strlen_w(pattern);
1787 li = (ssize_t)strlen_w(insert);
1792 while (lp <= ls && (p = strstr_w(s,pattern))) {
1793 if (len && (ls + (li-lp) >= len)) {
1795 DEBUG(0,("ERROR: string overflow by %d in string_sub_w(%.50s, %d)\n",
1796 (int)(sizeof(smb_ucs2_t)*(ls + (li-lp) - len)),
1797 unicode_to_unix(out,pattern,sizeof(out)), (int)len*sizeof(smb_ucs2_t)));
1801 memmove(p+li,p+lp,sizeof(smb_ucs2_t)*(strlen_w(p+lp)+1));
1803 for (i=0;i<li;i++) {
1804 switch (insert[i]) {
1805 case (smb_ucs2_t)'`':
1806 case (smb_ucs2_t)'"':
1807 case (smb_ucs2_t)'\'':
1808 case (smb_ucs2_t)';':
1809 case (smb_ucs2_t)'$':
1810 case (smb_ucs2_t)'%':
1811 case (smb_ucs2_t)'\r':
1812 case (smb_ucs2_t)'\n':
1813 p[i] = (smb_ucs2_t)'_';
1824 void fstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert)
1826 string_sub_w(s, pattern, insert, sizeof(wfstring));
1829 void pstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,smb_ucs2_t *insert)
1831 string_sub_w(s, pattern, insert, sizeof(wpstring));
1834 /****************************************************************************
1835 Similar to string_sub() but allows for any character to be substituted.
1837 if len==0 then no length check is performed.
1838 ****************************************************************************/
1840 void all_string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len)
1845 if (!insert || !pattern || !s)
1848 ls = (ssize_t)strlen_w(s);
1849 lp = (ssize_t)strlen_w(pattern);
1850 li = (ssize_t)strlen_w(insert);
1855 while (lp <= ls && (p = strstr_w(s,pattern))) {
1856 if (len && (ls + (li-lp) >= len)) {
1858 DEBUG(0,("ERROR: string overflow by %d in all_string_sub_w(%.50s, %d)\n",
1859 (int)(sizeof(smb_ucs2_t)*(ls + (li-lp) - len)),
1860 unicode_to_unix(out,pattern,sizeof(out)), (int)len*sizeof(smb_ucs2_t)));
1864 memmove(p+li,p+lp,sizeof(smb_ucs2_t)*(strlen_w(p+lp)+1));
1866 memcpy(p, insert, li*sizeof(smb_ucs2_t));
1872 /****************************************************************************
1873 Splits out the front and back at a separator.
1874 ****************************************************************************/
1876 void split_at_last_component_w(smb_ucs2_t *path, smb_ucs2_t *front, smb_ucs2_t sep, smb_ucs2_t *back)
1878 smb_ucs2_t *p = strrchr_w(path, sep);
1884 wpstrcpy(front, path);
1888 wpstrcpy(back, p+1);
1889 *p = (smb_ucs2_t)'\\';
1897 /****************************************************************************
1898 Write an octal as a string.
1899 ****************************************************************************/
1901 smb_ucs2_t *octal_string_w(int i)
1903 static smb_ucs2_t wret[64];
1907 slprintf(ret, sizeof(ret), "-1");
1909 slprintf(ret, sizeof(ret), "0%o", i);
1910 return unix_to_unicode(wret, ret, sizeof(wret));
1914 /****************************************************************************
1915 Truncate a string at a specified length.
1916 length is in ucs2 units.
1917 ****************************************************************************/
1919 smb_ucs2_t *string_truncate_w(smb_ucs2_t *s, size_t length)
1921 if (s && strlen_w(s) > length)