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
;
40 /*******************************************************************
41 Write a string in (little-endian) unicode format. src is in
42 the current DOS codepage. len is the length in bytes of the
43 string pointed to by dst.
45 if null_terminate is True then null terminate the packet (adds 2 bytes)
47 the return value is the length consumed by the string, including the
48 null termination if applied
49 ********************************************************************/
51 int dos_PutUniCode(char *dst
,const char *src
, ssize_t len
, BOOL null_terminate
)
54 while (*src
&& (len
> 2)) {
55 size_t skip
= get_character_len(*src
);
56 smb_ucs2_t val
= (*src
& 0xff);
59 * If this is a multibyte character (and all DOS/Windows
60 * codepages have at maximum 2 byte multibyte characters)
61 * then work out the index value for the unicode conversion.
65 val
= ((val
<< 8) | (src
[1] & 0xff));
67 SSVAL(dst
,ret
,doscp_to_ucs2
[val
]);
86 /*******************************************************************
87 Return a DOS codepage version of a little-endian unicode string.
88 len is the filename length (ignoring any terminating zero) in uin16
89 units. Always null terminates.
90 Hack alert: uses fixed buffer(s).
91 ********************************************************************/
93 char *dos_unistrn2(uint16
*src
, int len
)
95 static char lbufs
[8][MAXUNI
];
97 char *lbuf
= lbufs
[nexti
];
102 for (p
= lbuf
; (len
> 0) && (p
-lbuf
< MAXUNI
-3) && *src
; len
--, src
++) {
103 uint16 ucs2_val
= SVAL(src
,0);
104 uint16 cp_val
= ucs2_to_doscp
[ucs2_val
];
109 *p
++ = (cp_val
>> 8) & 0xff;
110 *p
++ = (cp_val
& 0xff);
118 static char lbufs
[8][MAXUNI
];
121 /*******************************************************************
122 Return a DOS codepage version of a little-endian unicode string.
123 Hack alert: uses fixed buffer(s).
124 ********************************************************************/
126 char *dos_unistr2(uint16
*src
)
128 char *lbuf
= lbufs
[nexti
];
133 for (p
= lbuf
; *src
&& (p
-lbuf
< MAXUNI
-3); src
++) {
134 uint16 ucs2_val
= SVAL(src
,0);
135 uint16 cp_val
= ucs2_to_doscp
[ucs2_val
];
140 *p
++ = (cp_val
>> 8) & 0xff;
141 *p
++ = (cp_val
& 0xff);
149 /*******************************************************************
150 Return a DOS codepage version of a little-endian unicode string
151 ********************************************************************/
153 char *dos_unistr2_to_str(UNISTR2
*str
)
155 char *lbuf
= lbufs
[nexti
];
157 uint16
*src
= str
->buffer
;
158 int max_size
= MIN(sizeof(str
->buffer
)-3, str
->uni_str_len
);
162 for (p
= lbuf
; *src
&& p
-lbuf
< max_size
; src
++) {
163 uint16 ucs2_val
= SVAL(src
,0);
164 uint16 cp_val
= ucs2_to_doscp
[ucs2_val
];
169 *p
++ = (cp_val
>> 8) & 0xff;
170 *p
++ = (cp_val
& 0xff);
178 /*******************************************************************
179 Convert a UNISTR2 structure to an ASCII string
180 Warning: this version does DOS codepage.
181 ********************************************************************/
183 void unistr2_to_ascii(char *dest
, const UNISTR2
*str
, size_t maxlen
)
191 len
= MIN(str
->uni_str_len
, maxlen
);
192 destend
= dest
+ len
;
194 while (dest
< destend
)
205 ucs2_val
= SVAL(src
++,0);
206 cp_val
= ucs2_to_doscp
[ucs2_val
];
209 *(dest
++) = (char)cp_val
;
211 *dest
= (cp_val
>> 8) & 0xff;
212 *(dest
++) = (cp_val
& 0xff);
219 /*******************************************************************
220 Return a DOS codepage version of a NOTunicode string
221 ********************************************************************/
223 char *dos_buffer2_to_str(BUFFER2
*str
)
225 char *lbuf
= lbufs
[nexti
];
227 uint16
*src
= str
->buffer
;
228 int max_size
= MIN(sizeof(str
->buffer
)-3, str
->buf_len
/2);
232 for (p
= lbuf
; *src
&& p
-lbuf
< max_size
; src
++) {
233 uint16 ucs2_val
= SVAL(src
,0);
234 uint16 cp_val
= ucs2_to_doscp
[ucs2_val
];
239 *p
++ = (cp_val
>> 8) & 0xff;
240 *p
++ = (cp_val
& 0xff);
248 /*******************************************************************
249 Return a dos codepage version of a NOTunicode string
250 ********************************************************************/
252 char *dos_buffer2_to_multistr(BUFFER2
*str
)
254 char *lbuf
= lbufs
[nexti
];
256 uint16
*src
= str
->buffer
;
257 int max_size
= MIN(sizeof(str
->buffer
)-3, str
->buf_len
/2);
261 for (p
= lbuf
; p
-lbuf
< max_size
; src
++) {
265 uint16 ucs2_val
= SVAL(src
,0);
266 uint16 cp_val
= ucs2_to_doscp
[ucs2_val
];
271 *p
++ = (cp_val
>> 8) & 0xff;
272 *p
++ = (cp_val
& 0xff);
281 /*******************************************************************
282 Create a null-terminated unicode string from a null-terminated DOS
284 Return number of unicode chars copied, excluding the null character.
285 Unicode strings created are in little-endian format.
286 ********************************************************************/
288 size_t dos_struni2(char *dst
, const char *src
, size_t max_len
)
296 for (; *src
&& len
< max_len
-2; len
++, dst
+=2) {
297 size_t skip
= get_character_len(*src
);
298 smb_ucs2_t val
= (*src
& 0xff);
301 * If this is a multibyte character (and all DOS/Windows
302 * codepages have at maximum 2 byte multibyte characters)
303 * then work out the index value for the unicode conversion.
307 val
= ((val
<< 8) | (src
[1] & 0xff));
309 SSVAL(dst
,0,doscp_to_ucs2
[val
]);
322 /*******************************************************************
323 Return a DOS codepage version of a little-endian unicode string.
324 Hack alert: uses fixed buffer(s).
325 ********************************************************************/
327 char *dos_unistr(char *buf
)
329 char *lbuf
= lbufs
[nexti
];
330 uint16
*src
= (uint16
*)buf
;
335 for (p
= lbuf
; *src
&& p
-lbuf
< MAXUNI
-3; src
++) {
336 uint16 ucs2_val
= SVAL(src
,0);
337 uint16 cp_val
= ucs2_to_doscp
[ucs2_val
];
342 *p
++ = (cp_val
>> 8) & 0xff;
343 *p
++ = (cp_val
& 0xff);
351 /*******************************************************************
352 Free any existing maps.
353 ********************************************************************/
355 static void free_maps(smb_ucs2_t
**pp_cp_to_ucs2
, uint16
**pp_ucs2_to_cp
)
357 /* this handles identity mappings where we share the pointer */
358 if (*pp_ucs2_to_cp
== *pp_cp_to_ucs2
) {
359 *pp_ucs2_to_cp
= NULL
;
362 if (*pp_cp_to_ucs2
) {
363 free(*pp_cp_to_ucs2
);
364 *pp_cp_to_ucs2
= NULL
;
367 if (*pp_ucs2_to_cp
) {
368 free(*pp_ucs2_to_cp
);
369 *pp_ucs2_to_cp
= NULL
;
374 /*******************************************************************
375 Build a default (null) codepage to unicode map.
376 ********************************************************************/
378 void default_unicode_map(smb_ucs2_t
**pp_cp_to_ucs2
, uint16
**pp_ucs2_to_cp
)
382 free_maps(pp_cp_to_ucs2
, pp_ucs2_to_cp
);
384 if ((*pp_ucs2_to_cp
= (uint16
*)malloc(2*65536)) == NULL
) {
385 DEBUG(0,("default_unicode_map: malloc fail for ucs2_to_cp size %u.\n", 2*65536));
389 *pp_cp_to_ucs2
= *pp_ucs2_to_cp
; /* Default map is an identity. */
390 for (i
= 0; i
< 65536; i
++)
391 (*pp_cp_to_ucs2
)[i
] = i
;
394 /*******************************************************************
395 Load a codepage to unicode and vica-versa map.
396 ********************************************************************/
398 BOOL
load_unicode_map(const char *codepage
, smb_ucs2_t
**pp_cp_to_ucs2
, uint16
**pp_ucs2_to_cp
)
400 pstring unicode_map_file_name
;
403 smb_ucs2_t
*cp_to_ucs2
= *pp_cp_to_ucs2
;
404 uint16
*ucs2_to_cp
= *pp_ucs2_to_cp
;
405 size_t cp_to_ucs2_size
;
406 size_t ucs2_to_cp_size
;
409 char buf
[UNICODE_MAP_HEADER_SIZE
];
411 DEBUG(5, ("load_unicode_map: loading unicode map for codepage %s.\n", codepage
));
413 if (*codepage
== '\0')
416 if(strlen(CODEPAGEDIR
) + 13 + strlen(codepage
) > sizeof(unicode_map_file_name
)) {
417 DEBUG(0,("load_unicode_map: filename too long to load\n"));
421 pstrcpy(unicode_map_file_name
, CODEPAGEDIR
);
422 pstrcat(unicode_map_file_name
, "/");
423 pstrcat(unicode_map_file_name
, "unicode_map.");
424 pstrcat(unicode_map_file_name
, codepage
);
426 if(sys_stat(unicode_map_file_name
,&st
)!=0) {
427 DEBUG(0,("load_unicode_map: filename %s does not exist.\n",
428 unicode_map_file_name
));
434 if ((size
!= UNICODE_MAP_HEADER_SIZE
+ 4*65536) && (size
!= UNICODE_MAP_HEADER_SIZE
+(2*256 + 2*65536))) {
435 DEBUG(0,("load_unicode_map: file %s is an incorrect size for a \
436 unicode map file (size=%d).\n", unicode_map_file_name
, (int)size
));
440 if((fp
= sys_fopen( unicode_map_file_name
, "r")) == NULL
) {
441 DEBUG(0,("load_unicode_map: cannot open file %s. Error was %s\n",
442 unicode_map_file_name
, strerror(errno
)));
446 if(fread( buf
, 1, UNICODE_MAP_HEADER_SIZE
, fp
)!=UNICODE_MAP_HEADER_SIZE
) {
447 DEBUG(0,("load_unicode_map: cannot read header from file %s. Error was %s\n",
448 unicode_map_file_name
, strerror(errno
)));
452 /* Check the version value */
453 if(SVAL(buf
,UNICODE_MAP_VERSION_OFFSET
) != UNICODE_MAP_FILE_VERSION_ID
) {
454 DEBUG(0,("load_unicode_map: filename %s has incorrect version id. \
455 Needed %hu, got %hu.\n",
456 unicode_map_file_name
, (uint16
)UNICODE_MAP_FILE_VERSION_ID
,
457 SVAL(buf
,UNICODE_MAP_VERSION_OFFSET
)));
461 /* Check the codepage value */
462 if(!strequal(&buf
[UNICODE_MAP_CLIENT_CODEPAGE_OFFSET
], codepage
)) {
463 DEBUG(0,("load_unicode_map: codepage %s in file %s is not the same as that \
464 requested (%s).\n", &buf
[UNICODE_MAP_CLIENT_CODEPAGE_OFFSET
], unicode_map_file_name
, codepage
));
468 ucs2_to_cp_size
= 2*65536;
469 if (size
== UNICODE_MAP_HEADER_SIZE
+ 4*65536) {
471 * This is a multibyte code page.
473 cp_to_ucs2_size
= 2*65536;
476 * Single byte code page.
478 cp_to_ucs2_size
= 2*256;
482 * Free any old translation tables.
485 free_maps(pp_cp_to_ucs2
, pp_ucs2_to_cp
);
487 if ((cp_to_ucs2
= (smb_ucs2_t
*)malloc(cp_to_ucs2_size
)) == NULL
) {
488 DEBUG(0,("load_unicode_map: malloc fail for cp_to_ucs2 size %u.\n", cp_to_ucs2_size
));
492 if ((ucs2_to_cp
= (uint16
*)malloc(ucs2_to_cp_size
)) == NULL
) {
493 DEBUG(0,("load_unicode_map: malloc fail for ucs2_to_cp size %u.\n", ucs2_to_cp_size
));
497 if(fread( (char *)cp_to_ucs2
, 1, cp_to_ucs2_size
, fp
)!=cp_to_ucs2_size
) {
498 DEBUG(0,("load_unicode_map: cannot read cp_to_ucs2 from file %s. Error was %s\n",
499 unicode_map_file_name
, strerror(errno
)));
503 if(fread( (char *)ucs2_to_cp
, 1, ucs2_to_cp_size
, fp
)!=ucs2_to_cp_size
) {
504 DEBUG(0,("load_unicode_map: cannot read ucs2_to_cp from file %s. Error was %s\n",
505 unicode_map_file_name
, strerror(errno
)));
510 * Now ensure the 16 bit values are in the correct endianness.
513 for (i
= 0; i
< cp_to_ucs2_size
/2; i
++)
514 cp_to_ucs2
[i
] = SVAL(cp_to_ucs2
,i
*2);
516 for (i
= 0; i
< ucs2_to_cp_size
/2; i
++)
517 ucs2_to_cp
[i
] = SVAL(ucs2_to_cp
,i
*2);
521 *pp_cp_to_ucs2
= cp_to_ucs2
;
522 *pp_ucs2_to_cp
= ucs2_to_cp
;
528 /* pseudo destructor :-) */
533 free_maps(pp_cp_to_ucs2
, pp_ucs2_to_cp
);
535 default_unicode_map(pp_cp_to_ucs2
, pp_ucs2_to_cp
);
540 /*******************************************************************
541 Load a dos codepage to unicode and vica-versa map.
542 ********************************************************************/
544 BOOL
load_dos_unicode_map(int codepage
)
546 fstring codepage_str
;
548 slprintf(codepage_str
, sizeof(fstring
)-1, "%03d", codepage
);
549 return load_unicode_map(codepage_str
, &doscp_to_ucs2
, &ucs2_to_doscp
);
552 /*******************************************************************
553 Load a UNIX codepage to unicode and vica-versa map.
554 ********************************************************************/
556 BOOL
load_unix_unicode_map(const char *unix_char_set
)
558 fstring upper_unix_char_set
;
560 fstrcpy(upper_unix_char_set
, unix_char_set
);
561 strupper(upper_unix_char_set
);
562 return load_unicode_map(upper_unix_char_set
, &unixcp_to_ucs2
, &ucs2_to_unixcp
);
565 /*******************************************************************
566 The following functions reproduce many of the non-UNICODE standard
567 string functions in Samba.
568 ********************************************************************/
570 /*******************************************************************
571 Convert a UNICODE string to multibyte format. Note that the 'src' is in
572 native byte order, not little endian. Always zero terminates.
574 ********************************************************************/
576 static char *unicode_to_multibyte(char *dst
, const smb_ucs2_t
*src
,
577 size_t dst_len
, const uint16
*ucs2_to_cp
)
581 for(dst_pos
= 0; *src
&& (dst_pos
< dst_len
- 1);) {
582 smb_ucs2_t val
= ucs2_to_cp
[*src
++];
584 dst
[dst_pos
++] = (char)val
;
587 if(dst_pos
>= dst_len
- 2)
591 * A 2 byte value is always written as
592 * high/low into the buffer stream.
595 dst
[dst_pos
++] = (char)((val
>> 8) & 0xff);
596 dst
[dst_pos
++] = (char)(val
& 0xff);
605 /*******************************************************************
606 Convert a multibyte string to UNICODE format. Note that the 'dst' is in
607 native byte order, not little endian. Always zero terminates.
609 ********************************************************************/
611 smb_ucs2_t
*multibyte_to_unicode(smb_ucs2_t
*dst
, const char *src
,
612 size_t dst_len
, smb_ucs2_t
*cp_to_ucs2
)
616 dst_len
/= sizeof(smb_ucs2_t
); /* Convert to smb_ucs2_t units. */
618 for(i
= 0; (i
< (dst_len
- 1)) && src
[i
];) {
619 size_t skip
= skip_multibyte_char(*src
);
620 smb_ucs2_t val
= (*src
& 0xff);
623 * If this is a multibyte character
624 * then work out the index value for the unicode conversion.
628 val
= ((val
<< 8) | (src
[1] & 0xff));
630 dst
[i
++] = cp_to_ucs2
[val
];
642 /*******************************************************************
643 Convert a UNICODE string to multibyte format. Note that the 'src' is in
644 native byte order, not little endian. Always zero terminates.
645 This function may be replaced if the MB codepage format is an
646 encoded one (ie. utf8, hex). See the code in lib/kanji.c
647 for details. dst_len is in bytes.
648 ********************************************************************/
650 char *unicode_to_unix(char *dst
, const smb_ucs2_t
*src
, size_t dst_len
)
652 return unicode_to_multibyte(dst
, src
, dst_len
, ucs2_to_unixcp
);
655 /*******************************************************************
656 Convert a UNIX string to UNICODE format. Note that the 'dst' is in
657 native byte order, not little endian. Always zero terminates.
658 This function may be replaced if the UNIX codepage format is a
659 multi-byte one (ie. JIS, SJIS or utf8). See the code in lib/kanji.c
660 for details. dst_len is in bytes, not ucs2 units.
661 ********************************************************************/
663 smb_ucs2_t
*unix_to_unicode(smb_ucs2_t
*dst
, const char *src
, size_t dst_len
)
665 return multibyte_to_unicode(dst
, src
, dst_len
, unixcp_to_ucs2
);
668 /*******************************************************************
669 Convert a UNICODE string to DOS format. Note that the 'src' is in
670 native byte order, not little endian. Always zero terminates.
672 ********************************************************************/
674 char *unicode_to_dos(char *dst
, const smb_ucs2_t
*src
, size_t dst_len
)
676 return unicode_to_multibyte(dst
, src
, dst_len
, ucs2_to_doscp
);
679 /*******************************************************************
680 Convert a DOS string to UNICODE format. Note that the 'dst' is in
681 native byte order, not little endian. Always zero terminates.
682 This function may be replaced if the DOS codepage format is a
683 multi-byte one (ie. JIS, SJIS or utf8). See the code in lib/kanji.c
684 for details. dst_len is in bytes, not ucs2 units.
685 ********************************************************************/
687 smb_ucs2_t
*dos_to_unicode(smb_ucs2_t
*dst
, const char *src
, size_t dst_len
)
689 return multibyte_to_unicode(dst
, src
, dst_len
, doscp_to_ucs2
);
692 /*******************************************************************
693 Count the number of characters in a smb_ucs2_t string.
694 ********************************************************************/
696 size_t strlen_w(const smb_ucs2_t
*src
)
700 for(len
= 0; *src
; len
++)
706 /*******************************************************************
707 Safe wstring copy into a known length string. maxlength includes
708 the terminating zero. maxlength is in ucs2 units.
709 ********************************************************************/
711 smb_ucs2_t
*safe_strcpy_w(smb_ucs2_t
*dest
,const smb_ucs2_t
*src
, size_t maxlength
)
716 DEBUG(0,("ERROR: NULL dest in safe_strcpy_w\n"));
725 maxlength
/= sizeof(smb_ucs2_t
);
727 ucs2_len
= strlen_w(src
);
729 if (ucs2_len
>= maxlength
) {
731 DEBUG(0,("ERROR: string overflow by %u bytes in safe_strcpy_w [%.50s]\n",
732 (unsigned int)((ucs2_len
-maxlength
)*sizeof(smb_ucs2_t
)),
733 unicode_to_unix(out
,src
,sizeof(out
))) );
734 ucs2_len
= maxlength
- 1;
737 memcpy(dest
, src
, ucs2_len
*sizeof(smb_ucs2_t
));
742 /*******************************************************************
743 Safe string cat into a string. maxlength includes the terminating zero.
744 maxlength is in ucs2 units.
745 ********************************************************************/
747 smb_ucs2_t
*safe_strcat_w(smb_ucs2_t
*dest
, const smb_ucs2_t
*src
, size_t maxlength
)
749 size_t ucs2_src_len
, ucs2_dest_len
;
752 DEBUG(0,("ERROR: NULL dest in safe_strcat_w\n"));
759 ucs2_src_len
= strlen_w(src
);
760 ucs2_dest_len
= strlen_w(dest
);
762 if (ucs2_src_len
+ ucs2_dest_len
>= maxlength
) {
764 int new_len
= maxlength
- ucs2_dest_len
- 1;
765 DEBUG(0,("ERROR: string overflow by %u characters in safe_strcat_w [%.50s]\n",
766 (unsigned int)(sizeof(smb_ucs2_t
)*(ucs2_src_len
+ ucs2_dest_len
- maxlength
)),
767 unicode_to_unix(out
,src
,sizeof(out
))) );
768 ucs2_src_len
= (size_t)(new_len
> 0 ? new_len
: 0);
771 memcpy(&dest
[ucs2_dest_len
], src
, ucs2_src_len
*sizeof(smb_ucs2_t
));
772 dest
[ucs2_dest_len
+ ucs2_src_len
] = 0;
776 /*******************************************************************
777 Compare the two strings s1 and s2.
778 ********************************************************************/
780 int strcmp_w(const smb_ucs2_t
*s1
, const smb_ucs2_t
*s2
)
797 /*******************************************************************
798 Compare the first n characters of s1 to s2. len is in ucs2 units.
799 ********************************************************************/
801 int strncmp_w(const smb_ucs2_t
*s1
, const smb_ucs2_t
*s2
, size_t len
)
805 for (; len
!= 0; --len
) {
819 /*******************************************************************
820 Search string s2 from s1.
821 ********************************************************************/
823 smb_ucs2_t
*strstr_w(const smb_ucs2_t
*s1
, const smb_ucs2_t
*s2
)
825 size_t len
= strlen_w(s2
);
828 return (smb_ucs2_t
*)s1
;
832 if (strncmp_w(s1
, s2
, len
) == 0)
833 return (smb_ucs2_t
*)s1
;
839 /*******************************************************************
840 Search for ucs2 char c from the beginning of s.
841 ********************************************************************/
843 smb_ucs2_t
*strchr_w(const smb_ucs2_t
*s
, smb_ucs2_t c
)
847 return (smb_ucs2_t
*)s
;
853 /*******************************************************************
854 Search for ucs2 char c from the end of s.
855 ********************************************************************/
857 smb_ucs2_t
*strrchr_w(const smb_ucs2_t
*s
, smb_ucs2_t c
)
859 smb_ucs2_t
*retval
= 0;
863 retval
= (smb_ucs2_t
*)s
;
869 /*******************************************************************
870 Search token from s1 separated by any ucs2 char of s2.
871 ********************************************************************/
873 smb_ucs2_t
*strtok_w(smb_ucs2_t
*s1
, const smb_ucs2_t
*s2
)
875 static smb_ucs2_t
*s
= NULL
;
884 for (q
= s1
; *s1
; s1
++) {
885 smb_ucs2_t
*p
= strchr_w(s2
, *s1
);
903 /*******************************************************************
904 Duplicate a ucs2 string.
905 ********************************************************************/
907 smb_ucs2_t
*strdup_w(const smb_ucs2_t
*s
)
909 size_t newlen
= (strlen_w(s
)+1)*sizeof(smb_ucs2_t
);
910 smb_ucs2_t
*newstr
= (smb_ucs2_t
*)malloc(newlen
);
913 safe_strcpy_w(newstr
, s
, newlen
);
917 /*******************************************************************
918 Mapping tables for UNICODE character. Allows toupper/tolower and
919 isXXX functions to work.
920 ********************************************************************/
926 } smb_unicode_table_t
;
928 static smb_unicode_table_t map_table
[] = {
929 #include "unicode_map_table.h"
932 /*******************************************************************
933 Is an upper case wchar.
934 ********************************************************************/
936 int isupper_w( smb_ucs2_t val
)
938 return (map_table
[val
].flags
& UNI_UPPER
);
941 /*******************************************************************
942 Is a lower case wchar.
943 ********************************************************************/
945 int islower_w( smb_ucs2_t val
)
947 return (map_table
[val
].flags
& UNI_LOWER
);
950 /*******************************************************************
952 ********************************************************************/
954 int isdigit_w( smb_ucs2_t val
)
956 return (map_table
[val
].flags
& UNI_DIGIT
);
959 /*******************************************************************
960 Is a hex digit wchar.
961 ********************************************************************/
963 int isxdigit_w( smb_ucs2_t val
)
965 return (map_table
[val
].flags
& UNI_XDIGIT
);
968 /*******************************************************************
970 ********************************************************************/
972 int isspace_w( smb_ucs2_t val
)
974 return (map_table
[val
].flags
& UNI_SPACE
);
977 /*******************************************************************
978 Convert a wchar to upper case.
979 ********************************************************************/
981 smb_ucs2_t
toupper_w( smb_ucs2_t val
)
983 return map_table
[val
].upper
;
986 /*******************************************************************
987 Convert a wchar to lower case.
988 ********************************************************************/
990 smb_ucs2_t
tolower_w( smb_ucs2_t val
)
992 return map_table
[val
].lower
;
995 static smb_ucs2_t
*last_ptr
= NULL
;
997 void set_first_token_w(smb_ucs2_t
*ptr
)
1002 /****************************************************************************
1003 Get the next token from a string, return False if none found
1004 handles double-quotes.
1005 Based on a routine by GJC@VILLAGE.COM.
1006 Extensively modified by Andrew.Tridgell@anu.edu.au
1007 bufsize is in bytes.
1008 ****************************************************************************/
1010 static smb_ucs2_t sep_list
[] = { (smb_ucs2_t
)' ', (smb_ucs2_t
)'\t', (smb_ucs2_t
)'\n', (smb_ucs2_t
)'\r', 0};
1011 static smb_ucs2_t quotechar
= (smb_ucs2_t
)'\"';
1013 BOOL
next_token_w(smb_ucs2_t
**ptr
, smb_ucs2_t
*buff
, smb_ucs2_t
*sep
, size_t bufsize
)
1020 * Convert bufsize to smb_ucs2_t units.
1023 bufsize
/= sizeof(smb_ucs2_t
);
1033 * Default to simple separators.
1040 * Find the first non sep char.
1043 while(*s
&& strchr_w(sep
,*s
))
1054 * Copy over the token.
1057 for (quoted
= False
; len
< bufsize
&& *s
&& (quoted
|| !strchr_w(sep
,*s
)); s
++) {
1058 if (*s
== quotechar
) {
1066 *ptr
= (*s
) ? s
+1 : s
;
1073 /****************************************************************************
1074 Convert list of tokens to array; dependent on above routine.
1075 Uses last_ptr from above - bit of a hack.
1076 ****************************************************************************/
1078 smb_ucs2_t
**toktocliplist_w(int *ctok
, smb_ucs2_t
*sep
)
1080 smb_ucs2_t
*s
=last_ptr
;
1082 smb_ucs2_t
**ret
, **iret
;
1087 while(*s
&& strchr_w(sep
,*s
))
1099 while(*s
&& (!strchr_w(sep
,*s
)))
1101 while(*s
&& strchr_w(sep
,*s
))
1108 if (!(ret
=iret
=malloc(ictok
*sizeof(smb_ucs2_t
*))))
1122 /*******************************************************************
1123 Case insensitive string compararison.
1124 ********************************************************************/
1126 int StrCaseCmp_w(const smb_ucs2_t
*s
, const smb_ucs2_t
*t
)
1129 * Compare until we run out of string, either t or s, or find a difference.
1132 while (*s
&& *t
&& toupper_w(*s
) == toupper_w(*t
)) {
1137 return(toupper_w(*s
) - toupper_w(*t
));
1140 /*******************************************************************
1141 Case insensitive string compararison, length limited.
1143 ********************************************************************/
1145 int StrnCaseCmp_w(const smb_ucs2_t
*s
, const smb_ucs2_t
*t
, size_t n
)
1148 * Compare until we run out of string, either t or s, or chars.
1151 while (n
&& *s
&& *t
&& toupper_w(*s
) == toupper_w(*t
)) {
1158 * Not run out of chars - strings are different lengths.
1162 return(toupper_w(*s
) - toupper_w(*t
));
1165 * Identical up to where we run out of chars,
1166 * and strings are same length.
1172 /*******************************************************************
1174 ********************************************************************/
1176 BOOL
strequal_w(const smb_ucs2_t
*s1
, const smb_ucs2_t
*s2
)
1183 return(StrCaseCmp_w(s1
,s2
)==0);
1186 /*******************************************************************
1187 Compare 2 strings up to and including the nth char. n is in ucs2
1189 ******************************************************************/
1191 BOOL
strnequal_w(const smb_ucs2_t
*s1
,const smb_ucs2_t
*s2
,size_t n
)
1195 if (!s1
|| !s2
|| !n
)
1198 return(StrnCaseCmp_w(s1
,s2
,n
)==0);
1201 /*******************************************************************
1202 Compare 2 strings (case sensitive).
1203 ********************************************************************/
1205 BOOL
strcsequal_w(const smb_ucs2_t
*s1
,const smb_ucs2_t
*s2
)
1212 return(strcmp_w(s1
,s2
)==0);
1215 /*******************************************************************
1216 Convert a string to lower case.
1217 ********************************************************************/
1219 void strlower_w(smb_ucs2_t
*s
)
1228 /*******************************************************************
1229 Convert a string to upper case.
1230 ********************************************************************/
1232 void strupper_w(smb_ucs2_t
*s
)
1241 /*******************************************************************
1242 Convert a string to "normal" form.
1243 ********************************************************************/
1245 void strnorm_w(smb_ucs2_t
*s
)
1247 extern int case_default
;
1248 if (case_default
== CASE_UPPER
)
1254 /*******************************************************************
1255 Check if a string is in "normal" case.
1256 ********************************************************************/
1258 BOOL
strisnormal_w(smb_ucs2_t
*s
)
1260 extern int case_default
;
1261 if (case_default
== CASE_UPPER
)
1262 return(!strhaslower_w(s
));
1264 return(!strhasupper_w(s
));
1267 /****************************************************************************
1269 ****************************************************************************/
1271 void string_replace_w(smb_ucs2_t
*s
, smb_ucs2_t oldc
, smb_ucs2_t newc
)
1280 /*******************************************************************
1281 Skip past some strings in a buffer. n is in bytes.
1282 ********************************************************************/
1284 smb_ucs2_t
*skip_string_w(smb_ucs2_t
*buf
,size_t n
)
1287 buf
+= (strlen_w(buf
)*sizeof(smb_ucs2_t
)) + 1;
1291 /*******************************************************************
1292 Count the number of characters in a string. Same as strlen_w in
1293 smb_ucs2_t string units.
1294 ********************************************************************/
1296 size_t str_charnum_w(const smb_ucs2_t
*s
)
1301 /*******************************************************************
1302 Trim the specified elements off the front and back of a string.
1303 ********************************************************************/
1305 BOOL
trim_string_w(smb_ucs2_t
*s
,const smb_ucs2_t
*front
,const smb_ucs2_t
*back
)
1308 size_t front_len
= (front
&& *front
) ? strlen_w(front
) : 0;
1309 size_t back_len
= (back
&& *back
) ? strlen_w(back
) : 0;
1312 while (front_len
&& strncmp_w(s
, front
, front_len
) == 0) {
1317 if (!(*p
= p
[front_len
]))
1324 s_len
= strlen_w(s
);
1325 while ((s_len
>= back_len
) &&
1326 (strncmp_w(s
+ s_len
- back_len
, back
, back_len
)==0)) {
1328 s
[s_len
- back_len
] = 0;
1329 s_len
= strlen_w(s
);
1336 /****************************************************************************
1337 Does a string have any uppercase chars in it ?
1338 ****************************************************************************/
1340 BOOL
strhasupper_w(const smb_ucs2_t
*s
)
1350 /****************************************************************************
1351 Does a string have any lowercase chars in it ?
1352 ****************************************************************************/
1354 BOOL
strhaslower_w(const smb_ucs2_t
*s
)
1364 /****************************************************************************
1365 Find the number of 'c' chars in a string.
1366 ****************************************************************************/
1368 size_t count_chars_w(const smb_ucs2_t
*s
,smb_ucs2_t c
)
1380 /*******************************************************************
1381 Return True if a string consists only of one particular character.
1382 ********************************************************************/
1384 BOOL
str_is_all_w(const smb_ucs2_t
*s
,smb_ucs2_t c
)
1399 /*******************************************************************
1400 Paranoid strcpy into a buffer of given length (includes terminating
1401 zero. Strips out all but 'a-Z0-9' and replaces with '_'. Deliberately
1402 does *NOT* check for multibyte characters. Don't change it !
1403 maxlength is in ucs2 units.
1404 ********************************************************************/
1406 smb_ucs2_t
*alpha_strcpy_w(smb_ucs2_t
*dest
, const smb_ucs2_t
*src
, size_t maxlength
)
1411 DEBUG(0,("ERROR: NULL dest in alpha_strcpy_w\n"));
1420 len
= strlen_w(src
);
1421 if (len
>= maxlength
)
1422 len
= maxlength
- 1;
1424 for(i
= 0; i
< len
; i
++) {
1425 smb_ucs2_t val
= src
[i
];
1426 if(isupper_w(val
) ||islower_w(val
) || isdigit_w(val
))
1429 dest
[i
] = (smb_ucs2_t
)'_';
1437 /****************************************************************************
1438 Like strncpy but always null terminates. Make sure there is room !
1439 The variable n should always be one less than the available size and is in
1441 ****************************************************************************/
1443 smb_ucs2_t
*StrnCpy_w(smb_ucs2_t
*dest
,const smb_ucs2_t
*src
,size_t n
)
1445 smb_ucs2_t
*d
= dest
;
1453 while (n
-- && (*d
++ = *src
++))
1459 /****************************************************************************
1460 Like strncpy but copies up to the character marker. Always null terminates.
1461 returns a pointer to the character marker in the source string (src).
1463 ****************************************************************************/
1465 smb_ucs2_t
*strncpyn_w(smb_ucs2_t
*dest
, const smb_ucs2_t
*src
,size_t n
, smb_ucs2_t c
)
1470 p
= strchr_w(src
, c
);
1473 smb_ucs2_t mbcval
[2];
1476 DEBUG(5, ("strncpyn_w: separator character (%s) not found\n",
1477 unicode_to_unix(cval
,mbcval
,sizeof(cval
)) ));
1481 str_len
= PTR_DIFF(p
, src
) + 1;
1482 safe_strcpy_w(dest
, src
, MIN(n
, str_len
));
1487 /*************************************************************
1488 Routine to get hex characters and turn them into a 16 byte array.
1489 The array can be variable length, and any non-hex-numeric
1490 characters are skipped. "0xnn" or "0Xnn" is specially catered
1491 for. len is in bytes.
1492 Valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
1493 **************************************************************/
1495 static smb_ucs2_t hexprefix
[] = { (smb_ucs2_t
)'0', (smb_ucs2_t
)'x', 0 };
1496 static smb_ucs2_t hexchars
[] = { (smb_ucs2_t
)'0', (smb_ucs2_t
)'1', (smb_ucs2_t
)'2', (smb_ucs2_t
)'3',
1497 (smb_ucs2_t
)'4', (smb_ucs2_t
)'5', (smb_ucs2_t
)'6', (smb_ucs2_t
)'7',
1498 (smb_ucs2_t
)'8', (smb_ucs2_t
)'9', (smb_ucs2_t
)'A', (smb_ucs2_t
)'B',
1499 (smb_ucs2_t
)'C', (smb_ucs2_t
)'D', (smb_ucs2_t
)'E', (smb_ucs2_t
)'F', 0 };
1501 size_t strhex_to_str_w(char *p
, size_t len
, const smb_ucs2_t
*strhex
)
1504 size_t num_chars
= 0;
1505 unsigned char lonybble
, hinybble
;
1506 smb_ucs2_t
*p1
= NULL
, *p2
= NULL
;
1509 * Convert to smb_ucs2_t units.
1512 len
/= sizeof(smb_ucs2_t
);
1514 for (i
= 0; i
< len
&& strhex
[i
] != 0; i
++) {
1515 if (strnequal_w(hexchars
, hexprefix
, 2)) {
1516 i
++; /* skip two chars */
1520 if (!(p1
= strchr_w(hexchars
, toupper_w(strhex
[i
]))))
1523 i
++; /* next hex digit */
1525 if (!(p2
= strchr_w(hexchars
, toupper_w(strhex
[i
]))))
1528 /* get the two nybbles */
1529 hinybble
= (PTR_DIFF(p1
, hexchars
)/sizeof(smb_ucs2_t
));
1530 lonybble
= (PTR_DIFF(p2
, hexchars
)/sizeof(smb_ucs2_t
));
1532 p
[num_chars
] = (hinybble
<< 4) | lonybble
;
1541 /****************************************************************************
1542 Check if a string is part of a list.
1543 ****************************************************************************/
1545 BOOL
in_list_w(smb_ucs2_t
*s
,smb_ucs2_t
*list
,BOOL casesensitive
)
1553 while (next_token_w(&p
,tok
,LIST_SEP_W
,sizeof(tok
))) {
1554 if (casesensitive
) {
1555 if (strcmp_w(tok
,s
) == 0)
1558 if (StrCaseCmp_w(tok
,s
) == 0)
1565 /* This is used to prevent lots of mallocs of size 2 */
1566 static smb_ucs2_t
*null_string
= NULL
;
1568 /****************************************************************************
1569 Set a string value, allocing the space for the string.
1570 ****************************************************************************/
1572 BOOL
string_init_w(smb_ucs2_t
**dest
,const smb_ucs2_t
*src
)
1577 if((null_string
= (smb_ucs2_t
*)malloc(sizeof(smb_ucs2_t
))) == NULL
) {
1578 DEBUG(0,("string_init_w: malloc fail for null_string.\n"));
1590 *dest
= null_string
;
1592 (*dest
) = (smb_ucs2_t
*)malloc(sizeof(smb_ucs2_t
)*(l
+1));
1593 if ((*dest
) == NULL
) {
1594 DEBUG(0,("Out of memory in string_init_w\n"));
1598 wpstrcpy(*dest
,src
);
1603 /****************************************************************************
1604 Free a string value.
1605 ****************************************************************************/
1607 void string_free_w(smb_ucs2_t
**s
)
1611 if (*s
== null_string
)
1618 /****************************************************************************
1619 Set a string value, allocing the space for the string, and deallocating any
1621 ****************************************************************************/
1623 BOOL
string_set_w(smb_ucs2_t
**dest
,const smb_ucs2_t
*src
)
1625 string_free_w(dest
);
1627 return(string_init_w(dest
,src
));
1630 /****************************************************************************
1631 Substitute a string for a pattern in another string. Make sure there is
1634 This routine looks for pattern in s and replaces it with
1635 insert. It may do multiple replacements.
1637 Any of " ; ' $ or ` in the insert string are replaced with _
1638 if len==0 then no length check is performed
1639 len is in ucs2 units.
1640 ****************************************************************************/
1642 void string_sub_w(smb_ucs2_t
*s
,const smb_ucs2_t
*pattern
,const smb_ucs2_t
*insert
, size_t len
)
1645 ssize_t ls
,lp
,li
, i
;
1647 if (!insert
|| !pattern
|| !s
)
1650 ls
= (ssize_t
)strlen_w(s
);
1651 lp
= (ssize_t
)strlen_w(pattern
);
1652 li
= (ssize_t
)strlen_w(insert
);
1657 while (lp
<= ls
&& (p
= strstr_w(s
,pattern
))) {
1658 if (len
&& (ls
+ (li
-lp
) >= len
)) {
1660 DEBUG(0,("ERROR: string overflow by %d in string_sub_w(%.50s, %d)\n",
1661 (int)(sizeof(smb_ucs2_t
)*(ls
+ (li
-lp
) - len
)),
1662 unicode_to_unix(out
,pattern
,sizeof(out
)), (int)len
*sizeof(smb_ucs2_t
)));
1666 memmove(p
+li
,p
+lp
,sizeof(smb_ucs2_t
)*(strlen_w(p
+lp
)+1));
1668 for (i
=0;i
<li
;i
++) {
1669 switch (insert
[i
]) {
1670 case (smb_ucs2_t
)'`':
1671 case (smb_ucs2_t
)'"':
1672 case (smb_ucs2_t
)'\'':
1673 case (smb_ucs2_t
)';':
1674 case (smb_ucs2_t
)'$':
1675 case (smb_ucs2_t
)'%':
1676 case (smb_ucs2_t
)'\r':
1677 case (smb_ucs2_t
)'\n':
1678 p
[i
] = (smb_ucs2_t
)'_';
1689 void fstring_sub_w(smb_ucs2_t
*s
,const smb_ucs2_t
*pattern
,const smb_ucs2_t
*insert
)
1691 string_sub_w(s
, pattern
, insert
, sizeof(wfstring
));
1694 void pstring_sub_w(smb_ucs2_t
*s
,const smb_ucs2_t
*pattern
,smb_ucs2_t
*insert
)
1696 string_sub_w(s
, pattern
, insert
, sizeof(wpstring
));
1699 /****************************************************************************
1700 Similar to string_sub() but allows for any character to be substituted.
1702 if len==0 then no length check is performed.
1703 ****************************************************************************/
1705 void all_string_sub_w(smb_ucs2_t
*s
,const smb_ucs2_t
*pattern
,const smb_ucs2_t
*insert
, size_t len
)
1710 if (!insert
|| !pattern
|| !s
)
1713 ls
= (ssize_t
)strlen_w(s
);
1714 lp
= (ssize_t
)strlen_w(pattern
);
1715 li
= (ssize_t
)strlen_w(insert
);
1720 while (lp
<= ls
&& (p
= strstr_w(s
,pattern
))) {
1721 if (len
&& (ls
+ (li
-lp
) >= len
)) {
1723 DEBUG(0,("ERROR: string overflow by %d in all_string_sub_w(%.50s, %d)\n",
1724 (int)(sizeof(smb_ucs2_t
)*(ls
+ (li
-lp
) - len
)),
1725 unicode_to_unix(out
,pattern
,sizeof(out
)), (int)len
*sizeof(smb_ucs2_t
)));
1729 memmove(p
+li
,p
+lp
,sizeof(smb_ucs2_t
)*(strlen_w(p
+lp
)+1));
1731 memcpy(p
, insert
, li
*sizeof(smb_ucs2_t
));
1737 /****************************************************************************
1738 Splits out the front and back at a separator.
1739 ****************************************************************************/
1741 void split_at_last_component_w(smb_ucs2_t
*path
, smb_ucs2_t
*front
, smb_ucs2_t sep
, smb_ucs2_t
*back
)
1743 smb_ucs2_t
*p
= strrchr_w(path
, sep
);
1749 wpstrcpy(front
, path
);
1753 wpstrcpy(back
, p
+1);
1754 *p
= (smb_ucs2_t
)'\\';
1762 /****************************************************************************
1763 Write an octal as a string.
1764 ****************************************************************************/
1766 smb_ucs2_t
*octal_string_w(int i
)
1768 static smb_ucs2_t wret
[64];
1772 slprintf(ret
, sizeof(ret
), "-1");
1774 slprintf(ret
, sizeof(ret
), "0%o", i
);
1775 return unix_to_unicode(wret
, ret
, sizeof(wret
));
1779 /****************************************************************************
1780 Truncate a string at a specified length.
1781 length is in ucs2 units.
1782 ****************************************************************************/
1784 smb_ucs2_t
*string_truncate_w(smb_ucs2_t
*s
, size_t length
)
1786 if (s
&& strlen_w(s
) > length
)