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 smb_ucs2_t wchar_list_sep
[] = { (smb_ucs2_t
)' ', (smb_ucs2_t
)'\t', (smb_ucs2_t
)',',
25 (smb_ucs2_t
)';', (smb_ucs2_t
)':', (smb_ucs2_t
)'\n',
26 (smb_ucs2_t
)'\r', 0 };
28 * The following are the codepage to ucs2 and vica versa maps.
29 * These are dynamically loaded from a unicode translation file.
32 static smb_ucs2_t
*doscp_to_ucs2
;
33 static uint16
*ucs2_to_doscp
;
35 static smb_ucs2_t
*unixcp_to_ucs2
;
36 static uint16
*ucs2_to_unixcp
;
42 /*******************************************************************
43 Write a string in (little-endian) unicode format. src is in
44 the current UNIX character set. len is the length in bytes of the
45 string pointed to by dst.
47 if null_terminate is True then null terminate the packet (adds 2 bytes)
49 the return value is the length in bytes consumed by the string, including the
50 null termination if applied
51 ********************************************************************/
53 size_t unix_PutUniCode(char *dst
,const char *src
, ssize_t len
, BOOL null_terminate
)
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
,unixcp_to_ucs2
[val
]);
84 /*******************************************************************
85 Write a string in (little-endian) unicode format. src is in
86 the current DOS codepage. len is the length in bytes of the
87 string pointed to by dst.
89 if null_terminate is True then null terminate the packet (adds 2 bytes)
91 the return value is the length in bytes consumed by the string, including the
92 null termination if applied
93 ********************************************************************/
95 size_t dos_PutUniCode(char *dst
,const char *src
, ssize_t len
, BOOL null_terminate
)
98 while (*src
&& (len
>= 2)) {
99 size_t skip
= get_character_len(*src
);
100 smb_ucs2_t val
= (*src
& 0xff);
103 * If this is a multibyte character (and all DOS/Windows
104 * codepages have at maximum 2 byte multibyte characters)
105 * then work out the index value for the unicode conversion.
109 val
= ((val
<< 8) | (src
[1] & 0xff));
111 SSVAL(dst
,ret
,doscp_to_ucs2
[val
]);
119 if (null_terminate
) {
126 /*******************************************************************
127 Pull a DOS codepage string out of a UNICODE array. len is in bytes.
128 ********************************************************************/
130 void unistr_to_dos(char *dest
, const char *src
, size_t len
)
132 char *destend
= dest
+ len
;
134 while (dest
< destend
) {
135 uint16 ucs2_val
= SVAL(src
,0);
136 uint16 cp_val
= ucs2_to_doscp
[ucs2_val
];
144 *dest
++ = (char)cp_val
;
146 *dest
++ = (cp_val
>> 8) & 0xff;
147 *dest
++ = (cp_val
& 0xff);
154 /*******************************************************************
155 Skip past a unicode string, but not more than len. Always move
156 past a terminating zero if found.
157 ********************************************************************/
159 char *skip_unibuf(char *src
, size_t len
)
161 char *srcend
= src
+ len
;
163 while (src
< srcend
&& SVAL(src
,0))
172 /*******************************************************************
173 Return a DOS codepage version of a little-endian unicode string.
174 len is the filename length (ignoring any terminating zero) in uin16
175 units. Always null terminates.
176 Hack alert: uses fixed buffer(s).
177 len is in 2 byte (unicode) units.
178 ********************************************************************/
180 char *dos_unistrn2(uint16
*src
, int len
)
182 static char lbufs
[8][MAXUNI
];
184 char *lbuf
= lbufs
[nexti
];
189 for (p
= lbuf
; (len
> 0) && (p
-lbuf
< MAXUNI
-3) && *src
; len
--, src
++) {
190 uint16 ucs2_val
= SVAL(src
,0);
191 uint16 cp_val
= ucs2_to_doscp
[ucs2_val
];
196 *p
++ = (cp_val
>> 8) & 0xff;
197 *p
++ = (cp_val
& 0xff);
205 static char lbufs
[8][MAXUNI
];
208 /*******************************************************************
209 Return a DOS codepage version of a little-endian unicode string.
210 Hack alert: uses fixed buffer(s).
211 ********************************************************************/
213 char *dos_unistr2(uint16
*src
)
215 char *lbuf
= lbufs
[nexti
];
220 for (p
= lbuf
; (p
-lbuf
< MAXUNI
-3) && *src
; src
++) {
221 uint16 ucs2_val
= SVAL(src
,0);
222 uint16 cp_val
= ucs2_to_doscp
[ucs2_val
];
227 *p
++ = (cp_val
>> 8) & 0xff;
228 *p
++ = (cp_val
& 0xff);
236 /*******************************************************************
237 Return a DOS codepage version of a little-endian unicode string
238 ********************************************************************/
240 char *dos_unistr2_to_str(UNISTR2
*str
)
242 char *lbuf
= lbufs
[nexti
];
244 uint16
*src
= str
->buffer
;
248 for (p
= lbuf
; (p
- lbuf
< MAXUNI
-3) && (src
- str
->buffer
< str
->uni_str_len
) && *src
; src
++) {
249 uint16 ucs2_val
= SVAL(src
,0);
250 uint16 cp_val
= ucs2_to_doscp
[ucs2_val
];
255 *p
++ = (cp_val
>> 8) & 0xff;
256 *p
++ = (cp_val
& 0xff);
264 /*******************************************************************
265 Put an ASCII string into a UNICODE array (uint16's).
266 use little-endian ucs2
267 ********************************************************************/
268 void ascii_to_unistr(uint16
*dest
, const char *src
, int maxlen
)
270 uint16
*destend
= dest
+ maxlen
;
273 while (dest
< destend
) {
285 /*******************************************************************
286 Pull an ASCII string out of a UNICODE array (uint16's).
287 ********************************************************************/
289 void unistr_to_ascii(char *dest
, const uint16
*src
, int len
)
291 char *destend
= dest
+ len
;
299 /* normal code path for a valid 'src' */
300 while (dest
< destend
) {
313 /*******************************************************************
314 Convert a (little-endian) UNISTR2 structure to an ASCII string, either
315 DOS or UNIX codepage.
316 ********************************************************************/
318 static void unistr2_to_mbcp(char *dest
, const UNISTR2
*str
, size_t maxlen
, uint16
*ucs2_to_mbcp
)
331 len
= MIN(str
->uni_str_len
, maxlen
);
337 for (p
= dest
; (p
-dest
< maxlen
-3) && (src
- str
->buffer
< str
->uni_str_len
) && *src
; src
++) {
338 uint16 ucs2_val
= SVAL(src
,0);
339 uint16 cp_val
= ucs2_to_mbcp
[ucs2_val
];
344 *p
++ = (cp_val
>> 8) & 0xff;
345 *p
++ = (cp_val
& 0xff);
352 /*******************************************************************
353 Convert a (little-endian) UNISTR2 structure to an ASCII string
354 Warning: this version does DOS codepage.
355 ********************************************************************/
357 void unistr2_to_dos(char *dest
, const UNISTR2
*str
, size_t maxlen
)
359 unistr2_to_mbcp(dest
, str
, maxlen
, ucs2_to_doscp
);
362 /*******************************************************************
363 Convert a (little-endian) UNISTR2 structure to an ASCII string
364 Warning: this version does UNIX codepage.
365 ********************************************************************/
367 void unistr2_to_unix(char *dest
, const UNISTR2
*str
, size_t maxlen
)
369 unistr2_to_mbcp(dest
, str
, maxlen
, ucs2_to_unixcp
);
372 /*******************************************************************
373 Return a number stored in a buffer
374 ********************************************************************/
376 uint32
buffer2_to_uint32(BUFFER2
*str
)
378 if (str
->buf_len
== 4)
379 return IVAL(str
->buffer
, 0);
384 /*******************************************************************
385 Return a DOS codepage version of a NOTunicode string
386 ********************************************************************/
388 char *dos_buffer2_to_str(BUFFER2
*str
)
390 char *lbuf
= lbufs
[nexti
];
392 uint16
*src
= str
->buffer
;
396 for (p
= lbuf
; (p
- lbuf
< sizeof(str
->buffer
)-3) && (src
- str
->buffer
< str
->buf_len
/2) && *src
; src
++) {
397 uint16 ucs2_val
= SVAL(src
,0);
398 uint16 cp_val
= ucs2_to_doscp
[ucs2_val
];
403 *p
++ = (cp_val
>> 8) & 0xff;
404 *p
++ = (cp_val
& 0xff);
412 /*******************************************************************
413 Return a dos codepage version of a NOTunicode string
414 ********************************************************************/
416 char *dos_buffer2_to_multistr(BUFFER2
*str
)
418 char *lbuf
= lbufs
[nexti
];
420 uint16
*src
= str
->buffer
;
424 for (p
= lbuf
; (p
- lbuf
< sizeof(str
->buffer
)-3) && (src
- str
->buffer
< str
->buf_len
/2); src
++) {
428 uint16 ucs2_val
= SVAL(src
,0);
429 uint16 cp_val
= ucs2_to_doscp
[ucs2_val
];
434 *p
++ = (cp_val
>> 8) & 0xff;
435 *p
++ = (cp_val
& 0xff);
444 /*******************************************************************
445 Create a null-terminated unicode string from a null-terminated DOS
447 Return number of unicode chars copied, excluding the null character.
448 Unicode strings created are in little-endian format.
450 ********************************************************************/
452 size_t dos_struni2(char *dst
, const char *src
, size_t max_len
)
460 for (; ((len
*2) < max_len
-2) && *src
; len
++, dst
+=2) {
461 size_t skip
= get_character_len(*src
);
462 smb_ucs2_t val
= (*src
& 0xff);
465 * If this is a multibyte character (and all DOS/Windows
466 * codepages have at maximum 2 byte multibyte characters)
467 * then work out the index value for the unicode conversion.
471 val
= ((val
<< 8) | (src
[1] & 0xff));
473 SSVAL(dst
,0,doscp_to_ucs2
[val
]);
486 /*******************************************************************
487 Return a DOS codepage version of a little-endian unicode string.
488 Hack alert: uses fixed buffer(s).
489 ********************************************************************/
491 char *dos_unistr(char *buf
)
493 char *lbuf
= lbufs
[nexti
];
494 uint16
*src
= (uint16
*)buf
;
499 for (p
= lbuf
; (p
-lbuf
< MAXUNI
-3) && *src
; src
++) {
500 uint16 ucs2_val
= SVAL(src
,0);
501 uint16 cp_val
= ucs2_to_doscp
[ucs2_val
];
506 *p
++ = (cp_val
>> 8) & 0xff;
507 *p
++ = (cp_val
& 0xff);
515 /*******************************************************************
516 returns the length in number of wide characters
517 ******************************************************************/
518 int unistrlen(uint16
*s
)
525 for (len
=0; *s
; s
++,len
++);
530 /*******************************************************************
531 Strcpy for unicode strings. returns length (in num of wide chars)
532 ********************************************************************/
534 int unistrcpy(uint16
*dst
, uint16
*src
)
547 /*******************************************************************
548 Free any existing maps.
549 ********************************************************************/
551 static void free_maps(smb_ucs2_t
**pp_cp_to_ucs2
, uint16
**pp_ucs2_to_cp
)
553 /* this handles identity mappings where we share the pointer */
554 if (*pp_ucs2_to_cp
== *pp_cp_to_ucs2
) {
555 *pp_ucs2_to_cp
= NULL
;
558 SAFE_FREE(*pp_cp_to_ucs2
);
559 SAFE_FREE(*pp_ucs2_to_cp
);
562 /*******************************************************************
563 Build a default (null) codepage to unicode map.
564 ********************************************************************/
566 void default_unicode_map(smb_ucs2_t
**pp_cp_to_ucs2
, uint16
**pp_ucs2_to_cp
)
570 free_maps(pp_cp_to_ucs2
, pp_ucs2_to_cp
);
572 if ((*pp_ucs2_to_cp
= (uint16
*)malloc(2*65536)) == NULL
) {
573 DEBUG(0,("default_unicode_map: malloc fail for ucs2_to_cp size %u.\n", 2*65536));
577 *pp_cp_to_ucs2
= *pp_ucs2_to_cp
; /* Default map is an identity. */
578 for (i
= 0; i
< 65536; i
++)
579 (*pp_cp_to_ucs2
)[i
] = i
;
582 /*******************************************************************
583 Load a codepage to unicode and vica-versa map.
584 ********************************************************************/
586 BOOL
load_unicode_map(const char *codepage
, smb_ucs2_t
**pp_cp_to_ucs2
, uint16
**pp_ucs2_to_cp
)
588 pstring unicode_map_file_name
;
591 smb_ucs2_t
*cp_to_ucs2
= *pp_cp_to_ucs2
;
592 uint16
*ucs2_to_cp
= *pp_ucs2_to_cp
;
593 size_t cp_to_ucs2_size
;
594 size_t ucs2_to_cp_size
;
597 char buf
[UNICODE_MAP_HEADER_SIZE
];
599 DEBUG(5, ("load_unicode_map: loading unicode map for codepage %s.\n", codepage
));
601 if (*codepage
== '\0')
604 if(strlen(lp_codepagedir()) + 13 + strlen(codepage
) >
605 sizeof(unicode_map_file_name
)) {
606 DEBUG(0,("load_unicode_map: filename too long to load\n"));
610 pstrcpy(unicode_map_file_name
, lp_codepagedir());
611 pstrcat(unicode_map_file_name
, "/");
612 pstrcat(unicode_map_file_name
, "unicode_map.");
613 pstrcat(unicode_map_file_name
, codepage
);
615 if(sys_stat(unicode_map_file_name
,&st
)!=0) {
616 DEBUG(0,("load_unicode_map: filename %s does not exist.\n",
617 unicode_map_file_name
));
623 if ((size
!= UNICODE_MAP_HEADER_SIZE
+ 4*65536) && (size
!= UNICODE_MAP_HEADER_SIZE
+(2*256 + 2*65536))) {
624 DEBUG(0,("load_unicode_map: file %s is an incorrect size for a \
625 unicode map file (size=%d).\n", unicode_map_file_name
, (int)size
));
629 if((fp
= sys_fopen( unicode_map_file_name
, "r")) == NULL
) {
630 DEBUG(0,("load_unicode_map: cannot open file %s. Error was %s\n",
631 unicode_map_file_name
, strerror(errno
)));
635 if(fread( buf
, 1, UNICODE_MAP_HEADER_SIZE
, fp
)!=UNICODE_MAP_HEADER_SIZE
) {
636 DEBUG(0,("load_unicode_map: cannot read header from file %s. Error was %s\n",
637 unicode_map_file_name
, strerror(errno
)));
641 /* Check the version value */
642 if(SVAL(buf
,UNICODE_MAP_VERSION_OFFSET
) != UNICODE_MAP_FILE_VERSION_ID
) {
643 DEBUG(0,("load_unicode_map: filename %s has incorrect version id. \
644 Needed %hu, got %hu.\n",
645 unicode_map_file_name
, (uint16
)UNICODE_MAP_FILE_VERSION_ID
,
646 SVAL(buf
,UNICODE_MAP_VERSION_OFFSET
)));
650 /* Check the codepage value */
651 if(!strequal(&buf
[UNICODE_MAP_CLIENT_CODEPAGE_OFFSET
], codepage
)) {
652 DEBUG(0,("load_unicode_map: codepage %s in file %s is not the same as that \
653 requested (%s).\n", &buf
[UNICODE_MAP_CLIENT_CODEPAGE_OFFSET
], unicode_map_file_name
, codepage
));
657 ucs2_to_cp_size
= 2*65536;
658 if (size
== UNICODE_MAP_HEADER_SIZE
+ 4*65536) {
660 * This is a multibyte code page.
662 cp_to_ucs2_size
= 2*65536;
665 * Single byte code page.
667 cp_to_ucs2_size
= 2*256;
671 * Free any old translation tables.
674 free_maps(pp_cp_to_ucs2
, pp_ucs2_to_cp
);
676 if ((cp_to_ucs2
= (smb_ucs2_t
*)malloc(cp_to_ucs2_size
)) == NULL
) {
677 DEBUG(0,("load_unicode_map: malloc fail for cp_to_ucs2 size %u.\n", cp_to_ucs2_size
));
681 if ((ucs2_to_cp
= (uint16
*)malloc(ucs2_to_cp_size
)) == NULL
) {
682 DEBUG(0,("load_unicode_map: malloc fail for ucs2_to_cp size %u.\n", ucs2_to_cp_size
));
686 if(fread( (char *)cp_to_ucs2
, 1, cp_to_ucs2_size
, fp
)!=cp_to_ucs2_size
) {
687 DEBUG(0,("load_unicode_map: cannot read cp_to_ucs2 from file %s. Error was %s\n",
688 unicode_map_file_name
, strerror(errno
)));
692 if(fread( (char *)ucs2_to_cp
, 1, ucs2_to_cp_size
, fp
)!=ucs2_to_cp_size
) {
693 DEBUG(0,("load_unicode_map: cannot read ucs2_to_cp from file %s. Error was %s\n",
694 unicode_map_file_name
, strerror(errno
)));
699 * Now ensure the 16 bit values are in the correct endianness.
702 for (i
= 0; i
< cp_to_ucs2_size
/2; i
++)
703 cp_to_ucs2
[i
] = SVAL(cp_to_ucs2
,i
*2);
705 for (i
= 0; i
< ucs2_to_cp_size
/2; i
++)
706 ucs2_to_cp
[i
] = SVAL(ucs2_to_cp
,i
*2);
710 *pp_cp_to_ucs2
= cp_to_ucs2
;
711 *pp_ucs2_to_cp
= ucs2_to_cp
;
717 /* pseudo destructor :-) */
722 free_maps(pp_cp_to_ucs2
, pp_ucs2_to_cp
);
724 default_unicode_map(pp_cp_to_ucs2
, pp_ucs2_to_cp
);
729 /*******************************************************************
730 Load a dos codepage to unicode and vica-versa map.
731 ********************************************************************/
733 BOOL
load_dos_unicode_map(int codepage
)
735 fstring codepage_str
;
737 slprintf(codepage_str
, sizeof(fstring
)-1, "%03d", codepage
);
738 DEBUG(10,("load_dos_unicode_map: %s\n", codepage_str
));
739 return load_unicode_map(codepage_str
, &doscp_to_ucs2
, &ucs2_to_doscp
);
742 /*******************************************************************
743 Load a UNIX codepage to unicode and vica-versa map.
744 ********************************************************************/
746 BOOL
load_unix_unicode_map(const char *unix_char_set
, BOOL override
)
748 static BOOL init_done
;
749 fstring upper_unix_char_set
;
751 fstrcpy(upper_unix_char_set
, unix_char_set
);
752 strupper(upper_unix_char_set
);
754 DEBUG(10,("load_unix_unicode_map: %s (init_done=%d, override=%d)\n",
755 upper_unix_char_set
, (int)init_done
, (int)override
));
762 return load_unicode_map(upper_unix_char_set
, &unixcp_to_ucs2
, &ucs2_to_unixcp
);
765 /*******************************************************************
766 The following functions reproduce many of the non-UNICODE standard
767 string functions in Samba.
768 ********************************************************************/
770 /*******************************************************************
771 Convert a UNICODE string to multibyte format. Note that the 'src' is in
772 native byte order, not little endian. Always zero terminates.
774 ********************************************************************/
776 static char *unicode_to_multibyte(char *dst
, const smb_ucs2_t
*src
,
777 size_t dst_len
, const uint16
*ucs2_to_cp
)
781 for(dst_pos
= 0; (dst_pos
< dst_len
- 1) && *src
;) {
782 smb_ucs2_t val
= ucs2_to_cp
[*src
++];
784 dst
[dst_pos
++] = (char)val
;
787 if(dst_pos
>= dst_len
- 2)
791 * A 2 byte value is always written as
792 * high/low into the buffer stream.
795 dst
[dst_pos
++] = (char)((val
>> 8) & 0xff);
796 dst
[dst_pos
++] = (char)(val
& 0xff);
805 /*******************************************************************
806 Convert a multibyte string to UNICODE format. Note that the 'dst' is in
807 native byte order, not little endian. Always zero terminates.
809 ********************************************************************/
811 smb_ucs2_t
*multibyte_to_unicode(smb_ucs2_t
*dst
, const char *src
,
812 size_t dst_len
, smb_ucs2_t
*cp_to_ucs2
)
816 dst_len
/= sizeof(smb_ucs2_t
); /* Convert to smb_ucs2_t units. */
818 for(i
= 0; (i
< (dst_len
- 1)) && *src
;) {
819 size_t skip
= skip_multibyte_char(*src
);
820 smb_ucs2_t val
= (*src
& 0xff);
823 * If this is a multibyte character
824 * then work out the index value for the unicode conversion.
828 val
= ((val
<< 8) | (src
[1] & 0xff));
830 dst
[i
++] = cp_to_ucs2
[val
];
842 /*******************************************************************
843 Convert a UNICODE string to multibyte format. Note that the 'src' is in
844 native byte order, not little endian. Always zero terminates.
845 This function may be replaced if the MB codepage format is an
846 encoded one (ie. utf8, hex). See the code in lib/kanji.c
847 for details. dst_len is in bytes.
848 ********************************************************************/
850 char *unicode_to_unix(char *dst
, const smb_ucs2_t
*src
, size_t dst_len
)
852 return unicode_to_multibyte(dst
, src
, dst_len
, ucs2_to_unixcp
);
855 /*******************************************************************
856 Convert a UNIX string to UNICODE format. Note that the 'dst' is in
857 native byte order, not little endian. Always zero terminates.
858 This function may be replaced if the UNIX codepage format is a
859 multi-byte one (ie. JIS, SJIS or utf8). See the code in lib/kanji.c
860 for details. dst_len is in bytes, not ucs2 units.
861 ********************************************************************/
863 smb_ucs2_t
*unix_to_unicode(smb_ucs2_t
*dst
, const char *src
, size_t dst_len
)
865 return multibyte_to_unicode(dst
, src
, dst_len
, unixcp_to_ucs2
);
868 /*******************************************************************
869 Convert a single UNICODE character to unix character. Returns the
870 number of bytes in the unix character.
871 ********************************************************************/
873 size_t unicode_to_unix_char(char *dst
, const smb_ucs2_t src
)
875 smb_ucs2_t val
= ucs2_to_unixcp
[src
];
881 * A 2 byte value is always written as
882 * high/low into the buffer stream.
885 dst
[0] = (char)((val
>> 8) & 0xff);
886 dst
[1] = (char)(val
& 0xff);
890 /*******************************************************************
891 Convert a UNICODE string to DOS format. Note that the 'src' is in
892 native byte order, not little endian. Always zero terminates.
894 ********************************************************************/
896 char *unicode_to_dos(char *dst
, const smb_ucs2_t
*src
, size_t dst_len
)
898 return unicode_to_multibyte(dst
, src
, dst_len
, ucs2_to_doscp
);
901 /*******************************************************************
902 Convert a single UNICODE character to DOS codepage. Returns the
903 number of bytes in the DOS codepage character.
904 ********************************************************************/
906 size_t unicode_to_dos_char(char *dst
, const smb_ucs2_t src
)
908 smb_ucs2_t val
= ucs2_to_doscp
[src
];
914 * A 2 byte value is always written as
915 * high/low into the buffer stream.
918 dst
[0] = (char)((val
>> 8) & 0xff);
919 dst
[1] = (char)(val
& 0xff);
923 /*******************************************************************
924 Convert a DOS string to UNICODE format. Note that the 'dst' is in
925 native byte order, not little endian. Always zero terminates.
926 This function may be replaced if the DOS codepage format is a
927 multi-byte one (ie. JIS, SJIS or utf8). See the code in lib/kanji.c
928 for details. dst_len is in bytes, not ucs2 units.
929 ********************************************************************/
931 smb_ucs2_t
*dos_to_unicode(smb_ucs2_t
*dst
, const char *src
, size_t dst_len
)
933 return multibyte_to_unicode(dst
, src
, dst_len
, doscp_to_ucs2
);
936 /*******************************************************************
937 Count the number of characters in a smb_ucs2_t string.
938 ********************************************************************/
940 size_t strlen_w(const smb_ucs2_t
*src
)
944 for(len
= 0; *src
++; len
++)
950 /*******************************************************************
951 Safe wstring copy into a known length string. maxlength includes
952 the terminating zero. maxlength is in ucs2 units.
953 ********************************************************************/
955 smb_ucs2_t
*safe_strcpy_w(smb_ucs2_t
*dest
,const smb_ucs2_t
*src
, size_t maxlength
)
960 DEBUG(0,("ERROR: NULL dest in safe_strcpy_w\n"));
969 maxlength
/= sizeof(smb_ucs2_t
);
971 ucs2_len
= strlen_w(src
);
973 if (ucs2_len
>= maxlength
) {
975 DEBUG(0,("ERROR: string overflow by %u bytes in safe_strcpy_w [%.50s]\n",
976 (unsigned int)((ucs2_len
-maxlength
)*sizeof(smb_ucs2_t
)),
977 unicode_to_unix(out
,src
,sizeof(out
))) );
978 ucs2_len
= maxlength
- 1;
981 memcpy(dest
, src
, ucs2_len
*sizeof(smb_ucs2_t
));
986 /*******************************************************************
987 Safe string cat into a string. maxlength includes the terminating zero.
988 maxlength is in ucs2 units.
989 ********************************************************************/
991 smb_ucs2_t
*safe_strcat_w(smb_ucs2_t
*dest
, const smb_ucs2_t
*src
, size_t maxlength
)
993 size_t ucs2_src_len
, ucs2_dest_len
;
996 DEBUG(0,("ERROR: NULL dest in safe_strcat_w\n"));
1003 ucs2_src_len
= strlen_w(src
);
1004 ucs2_dest_len
= strlen_w(dest
);
1006 if (ucs2_src_len
+ ucs2_dest_len
>= maxlength
) {
1008 int new_len
= maxlength
- ucs2_dest_len
- 1;
1009 DEBUG(0,("ERROR: string overflow by %u characters in safe_strcat_w [%.50s]\n",
1010 (unsigned int)(sizeof(smb_ucs2_t
)*(ucs2_src_len
+ ucs2_dest_len
- maxlength
)),
1011 unicode_to_unix(out
,src
,sizeof(out
))) );
1012 ucs2_src_len
= (size_t)(new_len
> 0 ? new_len
: 0);
1015 memcpy(&dest
[ucs2_dest_len
], src
, ucs2_src_len
*sizeof(smb_ucs2_t
));
1016 dest
[ucs2_dest_len
+ ucs2_src_len
] = 0;
1020 /*******************************************************************
1021 Compare the two strings s1 and s2.
1022 ********************************************************************/
1024 int strcmp_w(const smb_ucs2_t
*s1
, const smb_ucs2_t
*s2
)
1041 /*******************************************************************
1042 Compare the first n characters of s1 to s2. len is in ucs2 units.
1043 ********************************************************************/
1045 int strncmp_w(const smb_ucs2_t
*s1
, const smb_ucs2_t
*s2
, size_t len
)
1049 for (; len
!= 0; --len
) {
1063 /*******************************************************************
1064 Search string s2 from s1.
1065 ********************************************************************/
1067 smb_ucs2_t
*strstr_w(const smb_ucs2_t
*s1
, const smb_ucs2_t
*s2
)
1069 size_t len
= strlen_w(s2
);
1072 return (smb_ucs2_t
*)s1
;
1076 if (strncmp_w(s1
, s2
, len
) == 0)
1077 return (smb_ucs2_t
*)s1
;
1083 /*******************************************************************
1084 Search for ucs2 char c from the beginning of s.
1085 ********************************************************************/
1087 smb_ucs2_t
*strchr_w(const smb_ucs2_t
*s
, smb_ucs2_t c
)
1091 return (smb_ucs2_t
*)s
;
1097 /*******************************************************************
1098 Search for ucs2 char c from the end of s.
1099 ********************************************************************/
1101 smb_ucs2_t
*strrchr_w(const smb_ucs2_t
*s
, smb_ucs2_t c
)
1103 smb_ucs2_t
*retval
= 0;
1107 retval
= (smb_ucs2_t
*)s
;
1113 /*******************************************************************
1114 Search token from s1 separated by any ucs2 char of s2.
1115 ********************************************************************/
1117 smb_ucs2_t
*strtok_w(smb_ucs2_t
*s1
, const smb_ucs2_t
*s2
)
1119 static smb_ucs2_t
*s
= NULL
;
1128 for (q
= s1
; *s1
; s1
++) {
1129 smb_ucs2_t
*p
= strchr_w(s2
, *s1
);
1147 /*******************************************************************
1148 Duplicate a ucs2 string.
1149 ********************************************************************/
1151 smb_ucs2_t
*strdup_w(const smb_ucs2_t
*s
)
1153 size_t newlen
= (strlen_w(s
)+1)*sizeof(smb_ucs2_t
);
1154 smb_ucs2_t
*newstr
= (smb_ucs2_t
*)malloc(newlen
);
1157 safe_strcpy_w(newstr
, s
, newlen
);
1161 /*******************************************************************
1162 Mapping tables for UNICODE character. Allows toupper/tolower and
1163 isXXX functions to work.
1165 tridge: split into 2 pieces. This saves us 5/6 of the memory
1166 with a small speed penalty
1167 The magic constants are the lower/upper range of the tables two
1169 ********************************************************************/
1174 unsigned char flags
;
1175 } smb_unicode_table_t
;
1177 #define TABLE1_BOUNDARY 9450
1178 #define TABLE2_BOUNDARY 64256
1180 static smb_unicode_table_t map_table1
[] = {
1181 #include "unicode_map_table1.h"
1184 static smb_unicode_table_t map_table2
[] = {
1185 #include "unicode_map_table2.h"
1188 static unsigned char map_table_flags(smb_ucs2_t v
)
1190 if (v
< TABLE1_BOUNDARY
) return map_table1
[v
].flags
;
1191 if (v
>= TABLE2_BOUNDARY
) return map_table2
[v
- TABLE2_BOUNDARY
].flags
;
1195 static smb_ucs2_t
map_table_lower(smb_ucs2_t v
)
1197 if (v
< TABLE1_BOUNDARY
) return map_table1
[v
].lower
;
1198 if (v
>= TABLE2_BOUNDARY
) return map_table2
[v
- TABLE2_BOUNDARY
].lower
;
1202 static smb_ucs2_t
map_table_upper(smb_ucs2_t v
)
1204 if (v
< TABLE1_BOUNDARY
) return map_table1
[v
].upper
;
1205 if (v
>= TABLE2_BOUNDARY
) return map_table2
[v
- TABLE2_BOUNDARY
].upper
;
1209 /*******************************************************************
1210 Is an upper case wchar.
1211 ********************************************************************/
1213 int isupper_w( smb_ucs2_t val
)
1215 return (map_table_flags(val
) & UNI_UPPER
);
1218 /*******************************************************************
1219 Is a lower case wchar.
1220 ********************************************************************/
1222 int islower_w( smb_ucs2_t val
)
1224 return (map_table_flags(val
) & UNI_LOWER
);
1227 /*******************************************************************
1229 ********************************************************************/
1231 int isdigit_w( smb_ucs2_t val
)
1233 return (map_table_flags(val
) & UNI_DIGIT
);
1236 /*******************************************************************
1237 Is a hex digit wchar.
1238 ********************************************************************/
1240 int isxdigit_w( smb_ucs2_t val
)
1242 return (map_table_flags(val
) & UNI_XDIGIT
);
1245 /*******************************************************************
1247 ********************************************************************/
1249 int isspace_w( smb_ucs2_t val
)
1251 return (map_table_flags(val
) & UNI_SPACE
);
1254 /*******************************************************************
1255 Convert a wchar to upper case.
1256 ********************************************************************/
1258 smb_ucs2_t
toupper_w( smb_ucs2_t val
)
1260 return map_table_upper(val
);
1263 /*******************************************************************
1264 Convert a wchar to lower case.
1265 ********************************************************************/
1267 smb_ucs2_t
tolower_w( smb_ucs2_t val
)
1269 return map_table_lower(val
);
1272 static smb_ucs2_t
*last_ptr
= NULL
;
1274 void set_first_token_w(smb_ucs2_t
*ptr
)
1279 /****************************************************************************
1280 Get the next token from a string, return False if none found
1281 handles double-quotes.
1282 Based on a routine by GJC@VILLAGE.COM.
1283 Extensively modified by Andrew.Tridgell@anu.edu.au
1284 bufsize is in bytes.
1285 ****************************************************************************/
1287 static smb_ucs2_t sep_list
[] = { (smb_ucs2_t
)' ', (smb_ucs2_t
)'\t', (smb_ucs2_t
)'\n', (smb_ucs2_t
)'\r', 0};
1288 static smb_ucs2_t quotechar
= (smb_ucs2_t
)'\"';
1290 BOOL
next_token_w(smb_ucs2_t
**ptr
, smb_ucs2_t
*buff
, smb_ucs2_t
*sep
, size_t bufsize
)
1297 * Convert bufsize to smb_ucs2_t units.
1300 bufsize
/= sizeof(smb_ucs2_t
);
1310 * Default to simple separators.
1317 * Find the first non sep char.
1320 while(*s
&& strchr_w(sep
,*s
))
1331 * Copy over the token.
1334 for (quoted
= False
; len
< bufsize
&& *s
&& (quoted
|| !strchr_w(sep
,*s
)); s
++) {
1335 if (*s
== quotechar
) {
1343 *ptr
= (*s
) ? s
+1 : s
;
1350 /****************************************************************************
1351 Convert list of tokens to array; dependent on above routine.
1352 Uses last_ptr from above - bit of a hack.
1353 ****************************************************************************/
1355 smb_ucs2_t
**toktocliplist_w(int *ctok
, smb_ucs2_t
*sep
)
1357 smb_ucs2_t
*s
=last_ptr
;
1359 smb_ucs2_t
**ret
, **iret
;
1364 while(*s
&& strchr_w(sep
,*s
))
1376 while(*s
&& (!strchr_w(sep
,*s
)))
1378 while(*s
&& strchr_w(sep
,*s
))
1385 if (!(ret
=iret
=malloc(ictok
*sizeof(smb_ucs2_t
*))))
1399 /*******************************************************************
1400 Case insensitive string compararison.
1401 ********************************************************************/
1403 int StrCaseCmp_w(const smb_ucs2_t
*s
, const smb_ucs2_t
*t
)
1406 * Compare until we run out of string, either t or s, or find a difference.
1409 while (*s
&& *t
&& toupper_w(*s
) == toupper_w(*t
)) {
1414 return(toupper_w(*s
) - toupper_w(*t
));
1417 /*******************************************************************
1418 Case insensitive string compararison, length limited.
1420 ********************************************************************/
1422 int StrnCaseCmp_w(const smb_ucs2_t
*s
, const smb_ucs2_t
*t
, size_t n
)
1425 * Compare until we run out of string, either t or s, or chars.
1428 while (n
&& *s
&& *t
&& toupper_w(*s
) == toupper_w(*t
)) {
1435 * Not run out of chars - strings are different lengths.
1439 return(toupper_w(*s
) - toupper_w(*t
));
1442 * Identical up to where we run out of chars,
1443 * and strings are same length.
1449 /*******************************************************************
1451 ********************************************************************/
1453 BOOL
strequal_w(const smb_ucs2_t
*s1
, const smb_ucs2_t
*s2
)
1460 return(StrCaseCmp_w(s1
,s2
)==0);
1463 /*******************************************************************
1464 Compare 2 strings up to and including the nth char. n is in ucs2
1466 ******************************************************************/
1468 BOOL
strnequal_w(const smb_ucs2_t
*s1
,const smb_ucs2_t
*s2
,size_t n
)
1472 if (!s1
|| !s2
|| !n
)
1475 return(StrnCaseCmp_w(s1
,s2
,n
)==0);
1478 /*******************************************************************
1479 Compare 2 strings (case sensitive).
1480 ********************************************************************/
1482 BOOL
strcsequal_w(const smb_ucs2_t
*s1
,const smb_ucs2_t
*s2
)
1489 return(strcmp_w(s1
,s2
)==0);
1492 /*******************************************************************
1493 Convert a string to lower case.
1494 ********************************************************************/
1496 void strlower_w(smb_ucs2_t
*s
)
1505 /*******************************************************************
1506 Convert a string to upper case.
1507 ********************************************************************/
1509 void strupper_w(smb_ucs2_t
*s
)
1518 /*******************************************************************
1519 Convert a string to "normal" form.
1520 ********************************************************************/
1522 void strnorm_w(smb_ucs2_t
*s
)
1524 extern int case_default
;
1525 if (case_default
== CASE_UPPER
)
1531 /*******************************************************************
1532 Check if a string is in "normal" case.
1533 ********************************************************************/
1535 BOOL
strisnormal_w(smb_ucs2_t
*s
)
1537 extern int case_default
;
1538 if (case_default
== CASE_UPPER
)
1539 return(!strhaslower_w(s
));
1541 return(!strhasupper_w(s
));
1544 /****************************************************************************
1546 ****************************************************************************/
1548 void string_replace_w(smb_ucs2_t
*s
, smb_ucs2_t oldc
, smb_ucs2_t newc
)
1557 /*******************************************************************
1558 Skip past some strings in a buffer. n is in bytes.
1559 ********************************************************************/
1561 smb_ucs2_t
*skip_string_w(smb_ucs2_t
*buf
,size_t n
)
1564 buf
+= (strlen_w(buf
)*sizeof(smb_ucs2_t
)) + 1;
1568 /*******************************************************************
1569 Count the number of characters in a string. Same as strlen_w in
1570 smb_ucs2_t string units.
1571 ********************************************************************/
1573 size_t str_charnum_w(const smb_ucs2_t
*s
)
1578 /*******************************************************************
1579 Trim the specified elements off the front and back of a string.
1580 ********************************************************************/
1582 BOOL
trim_string_w(smb_ucs2_t
*s
,const smb_ucs2_t
*front
,const smb_ucs2_t
*back
)
1585 size_t front_len
= (front
&& *front
) ? strlen_w(front
) : 0;
1586 size_t back_len
= (back
&& *back
) ? strlen_w(back
) : 0;
1589 while (front_len
&& strncmp_w(s
, front
, front_len
) == 0) {
1594 if (!(*p
= p
[front_len
]))
1601 s_len
= strlen_w(s
);
1602 while ((s_len
>= back_len
) &&
1603 (strncmp_w(s
+ s_len
- back_len
, back
, back_len
)==0)) {
1605 s
[s_len
- back_len
] = 0;
1606 s_len
= strlen_w(s
);
1613 /****************************************************************************
1614 Does a string have any uppercase chars in it ?
1615 ****************************************************************************/
1617 BOOL
strhasupper_w(const smb_ucs2_t
*s
)
1627 /****************************************************************************
1628 Does a string have any lowercase chars in it ?
1629 ****************************************************************************/
1631 BOOL
strhaslower_w(const smb_ucs2_t
*s
)
1641 /****************************************************************************
1642 Find the number of 'c' chars in a string.
1643 ****************************************************************************/
1645 size_t count_chars_w(const smb_ucs2_t
*s
,smb_ucs2_t c
)
1657 /*******************************************************************
1658 Return True if a string consists only of one particular character.
1659 ********************************************************************/
1661 BOOL
str_is_all_w(const smb_ucs2_t
*s
,smb_ucs2_t c
)
1676 /*******************************************************************
1677 Paranoid strcpy into a buffer of given length (includes terminating
1678 zero. Strips out all but 'a-Z0-9' and replaces with '_'. Deliberately
1679 does *NOT* check for multibyte characters. Don't change it !
1680 maxlength is in ucs2 units.
1681 ********************************************************************/
1683 smb_ucs2_t
*alpha_strcpy_w(smb_ucs2_t
*dest
, const smb_ucs2_t
*src
, const smb_ucs2_t
*other_safe_chars
, size_t maxlength
)
1686 smb_ucs2_t nullstr_w
= (smb_ucs2_t
)0;
1689 DEBUG(0,("ERROR: NULL dest in alpha_strcpy_w\n"));
1698 len
= strlen_w(src
);
1699 if (len
>= maxlength
)
1700 len
= maxlength
- 1;
1702 if (!other_safe_chars
)
1703 other_safe_chars
= &nullstr_w
;
1705 for(i
= 0; i
< len
; i
++) {
1706 smb_ucs2_t val
= src
[i
];
1707 if(isupper_w(val
) ||islower_w(val
) || isdigit_w(val
) || strchr_w(other_safe_chars
, val
))
1710 dest
[i
] = (smb_ucs2_t
)'_';
1718 /****************************************************************************
1719 Like strncpy but always null terminates. Make sure there is room !
1720 The variable n should always be one less than the available size and is in
1722 ****************************************************************************/
1724 smb_ucs2_t
*StrnCpy_w(smb_ucs2_t
*dest
,const smb_ucs2_t
*src
,size_t n
)
1726 smb_ucs2_t
*d
= dest
;
1734 while (n
-- && (*d
++ = *src
++))
1740 /****************************************************************************
1741 Like strncpy but copies up to the character marker. Always null terminates.
1742 returns a pointer to the character marker in the source string (src).
1744 ****************************************************************************/
1746 smb_ucs2_t
*strncpyn_w(smb_ucs2_t
*dest
, const smb_ucs2_t
*src
,size_t n
, smb_ucs2_t c
)
1751 p
= strchr_w(src
, c
);
1754 smb_ucs2_t mbcval
[2];
1757 DEBUG(5, ("strncpyn_w: separator character (%s) not found\n",
1758 unicode_to_unix(cval
,mbcval
,sizeof(cval
)) ));
1762 str_len
= PTR_DIFF(p
, src
) + 1;
1763 safe_strcpy_w(dest
, src
, MIN(n
, str_len
));
1768 /*************************************************************
1769 Routine to get hex characters and turn them into a 16 byte array.
1770 The array can be variable length, and any non-hex-numeric
1771 characters are skipped. "0xnn" or "0Xnn" is specially catered
1772 for. len is in bytes.
1773 Valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
1774 **************************************************************/
1776 static smb_ucs2_t hexprefix
[] = { (smb_ucs2_t
)'0', (smb_ucs2_t
)'x', 0 };
1777 static smb_ucs2_t hexchars
[] = { (smb_ucs2_t
)'0', (smb_ucs2_t
)'1', (smb_ucs2_t
)'2', (smb_ucs2_t
)'3',
1778 (smb_ucs2_t
)'4', (smb_ucs2_t
)'5', (smb_ucs2_t
)'6', (smb_ucs2_t
)'7',
1779 (smb_ucs2_t
)'8', (smb_ucs2_t
)'9', (smb_ucs2_t
)'A', (smb_ucs2_t
)'B',
1780 (smb_ucs2_t
)'C', (smb_ucs2_t
)'D', (smb_ucs2_t
)'E', (smb_ucs2_t
)'F', 0 };
1782 size_t strhex_to_str_w(char *p
, size_t len
, const smb_ucs2_t
*strhex
)
1785 size_t num_chars
= 0;
1786 unsigned char lonybble
, hinybble
;
1787 smb_ucs2_t
*p1
= NULL
, *p2
= NULL
;
1790 * Convert to smb_ucs2_t units.
1793 len
/= sizeof(smb_ucs2_t
);
1795 for (i
= 0; i
< len
&& strhex
[i
] != 0; i
++) {
1796 if (strnequal_w(hexchars
, hexprefix
, 2)) {
1797 i
++; /* skip two chars */
1801 if (!(p1
= strchr_w(hexchars
, toupper_w(strhex
[i
]))))
1804 i
++; /* next hex digit */
1806 if (!(p2
= strchr_w(hexchars
, toupper_w(strhex
[i
]))))
1809 /* get the two nybbles */
1810 hinybble
= (PTR_DIFF(p1
, hexchars
)/sizeof(smb_ucs2_t
));
1811 lonybble
= (PTR_DIFF(p2
, hexchars
)/sizeof(smb_ucs2_t
));
1813 p
[num_chars
] = (hinybble
<< 4) | lonybble
;
1822 /****************************************************************************
1823 Check if a string is part of a list.
1824 ****************************************************************************/
1826 BOOL
in_list_w(smb_ucs2_t
*s
,smb_ucs2_t
*list
,BOOL casesensitive
)
1834 while (next_token_w(&p
,tok
,LIST_SEP_W
,sizeof(tok
))) {
1835 if (casesensitive
) {
1836 if (strcmp_w(tok
,s
) == 0)
1839 if (StrCaseCmp_w(tok
,s
) == 0)
1846 /* This is used to prevent lots of mallocs of size 2 */
1847 static smb_ucs2_t
*null_string
= NULL
;
1849 /****************************************************************************
1850 Set a string value, allocing the space for the string.
1851 ****************************************************************************/
1853 BOOL
string_init_w(smb_ucs2_t
**dest
,const smb_ucs2_t
*src
)
1858 if((null_string
= (smb_ucs2_t
*)malloc(sizeof(smb_ucs2_t
))) == NULL
) {
1859 DEBUG(0,("string_init_w: malloc fail for null_string.\n"));
1871 *dest
= null_string
;
1873 (*dest
) = (smb_ucs2_t
*)malloc(sizeof(smb_ucs2_t
)*(l
+1));
1874 if ((*dest
) == NULL
) {
1875 DEBUG(0,("Out of memory in string_init_w\n"));
1879 wpstrcpy(*dest
,src
);
1884 /****************************************************************************
1885 Free a string value.
1886 ****************************************************************************/
1888 void string_free_w(smb_ucs2_t
**s
)
1892 if (*s
== null_string
)
1897 /****************************************************************************
1898 Set a string value, allocing the space for the string, and deallocating any
1900 ****************************************************************************/
1902 BOOL
string_set_w(smb_ucs2_t
**dest
,const smb_ucs2_t
*src
)
1904 string_free_w(dest
);
1906 return(string_init_w(dest
,src
));
1909 /****************************************************************************
1910 Substitute a string for a pattern in another string. Make sure there is
1913 This routine looks for pattern in s and replaces it with
1914 insert. It may do multiple replacements.
1916 Any of " ; ' $ or ` in the insert string are replaced with _
1917 if len==0 then no length check is performed
1918 len is in ucs2 units.
1919 ****************************************************************************/
1921 void string_sub_w(smb_ucs2_t
*s
,const smb_ucs2_t
*pattern
,const smb_ucs2_t
*insert
, size_t len
)
1924 ssize_t ls
,lp
,li
, i
;
1926 if (!insert
|| !pattern
|| !s
)
1929 ls
= (ssize_t
)strlen_w(s
);
1930 lp
= (ssize_t
)strlen_w(pattern
);
1931 li
= (ssize_t
)strlen_w(insert
);
1936 while (lp
<= ls
&& (p
= strstr_w(s
,pattern
))) {
1937 if (len
&& (ls
+ (li
-lp
) >= len
)) {
1939 DEBUG(0,("ERROR: string overflow by %d in string_sub_w(%.50s, %d)\n",
1940 (int)(sizeof(smb_ucs2_t
)*(ls
+ (li
-lp
) - len
)),
1941 unicode_to_unix(out
,pattern
,sizeof(out
)), (int)len
*sizeof(smb_ucs2_t
)));
1945 memmove(p
+li
,p
+lp
,sizeof(smb_ucs2_t
)*(strlen_w(p
+lp
)+1));
1947 for (i
=0;i
<li
;i
++) {
1948 switch (insert
[i
]) {
1949 case (smb_ucs2_t
)'`':
1950 case (smb_ucs2_t
)'"':
1951 case (smb_ucs2_t
)'\'':
1952 case (smb_ucs2_t
)';':
1953 case (smb_ucs2_t
)'$':
1954 case (smb_ucs2_t
)'%':
1955 case (smb_ucs2_t
)'\r':
1956 case (smb_ucs2_t
)'\n':
1957 p
[i
] = (smb_ucs2_t
)'_';
1968 void fstring_sub_w(smb_ucs2_t
*s
,const smb_ucs2_t
*pattern
,const smb_ucs2_t
*insert
)
1970 string_sub_w(s
, pattern
, insert
, sizeof(wfstring
));
1973 void pstring_sub_w(smb_ucs2_t
*s
,const smb_ucs2_t
*pattern
,smb_ucs2_t
*insert
)
1975 string_sub_w(s
, pattern
, insert
, sizeof(wpstring
));
1978 /****************************************************************************
1979 Similar to string_sub() but allows for any character to be substituted.
1981 if len==0 then no length check is performed.
1982 ****************************************************************************/
1984 void all_string_sub_w(smb_ucs2_t
*s
,const smb_ucs2_t
*pattern
,const smb_ucs2_t
*insert
, size_t len
)
1989 if (!insert
|| !pattern
|| !s
)
1992 ls
= (ssize_t
)strlen_w(s
);
1993 lp
= (ssize_t
)strlen_w(pattern
);
1994 li
= (ssize_t
)strlen_w(insert
);
1999 while (lp
<= ls
&& (p
= strstr_w(s
,pattern
))) {
2000 if (len
&& (ls
+ (li
-lp
) >= len
)) {
2002 DEBUG(0,("ERROR: string overflow by %d in all_string_sub_w(%.50s, %d)\n",
2003 (int)(sizeof(smb_ucs2_t
)*(ls
+ (li
-lp
) - len
)),
2004 unicode_to_unix(out
,pattern
,sizeof(out
)), (int)len
*sizeof(smb_ucs2_t
)));
2008 memmove(p
+li
,p
+lp
,sizeof(smb_ucs2_t
)*(strlen_w(p
+lp
)+1));
2010 memcpy(p
, insert
, li
*sizeof(smb_ucs2_t
));
2016 /****************************************************************************
2017 Splits out the front and back at a separator.
2018 ****************************************************************************/
2020 void split_at_last_component_w(smb_ucs2_t
*path
, smb_ucs2_t
*front
, smb_ucs2_t sep
, smb_ucs2_t
*back
)
2022 smb_ucs2_t
*p
= strrchr_w(path
, sep
);
2028 wpstrcpy(front
, path
);
2032 wpstrcpy(back
, p
+1);
2033 *p
= (smb_ucs2_t
)'\\';
2041 /****************************************************************************
2042 Write an octal as a string.
2043 ****************************************************************************/
2045 smb_ucs2_t
*octal_string_w(int i
)
2047 static smb_ucs2_t wret
[64];
2051 slprintf(ret
, sizeof(ret
)-1, "-1");
2053 slprintf(ret
, sizeof(ret
)-1, "0%o", i
);
2054 return unix_to_unicode(wret
, ret
, sizeof(wret
));
2058 /****************************************************************************
2059 Truncate a string at a specified length.
2060 length is in ucs2 units.
2061 ****************************************************************************/
2063 smb_ucs2_t
*string_truncate_w(smb_ucs2_t
*s
, size_t length
)
2065 if (s
&& strlen_w(s
) > length
)
2071 /******************************************************************
2072 functions for UTF8 support (using in kanji.c)
2073 ******************************************************************/
2074 smb_ucs2_t
doscp2ucs2(int w
)
2076 return ((smb_ucs2_t
)doscp_to_ucs2
[w
]);
2079 int ucs2doscp(smb_ucs2_t w
)
2081 return ((int)ucs2_to_doscp
[w
]);
2084 /* Temporary fix until 3.0... JRA */
2086 int rpcstr_pull(char* dest
, void *src
, int dest_len
, int src_len
, int flags
)
2091 if (flags
& STR_TERMINATE
)
2092 src_len
= strlen_w(src
)*2+2;
2094 dest_len
= MIN((src_len
/2), (dest_len
-1));
2095 unistr_to_ascii(dest
, src
, dest_len
);