2 Unix SMB/Netbios implementation.
4 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-2001
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 #define CONV_DEBUGLEVEL 83
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 in bytes consumed by the string, including the
48 null termination if applied
49 ********************************************************************/
51 size_t dos_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminate)
53 return push_ucs2(NULL, dst, src, len,
54 STR_UNICODE|STR_NOALIGN | (null_terminate?STR_TERMINATE:0));
58 /*******************************************************************
59 Skip past a unicode string, but not more than len. Always move
60 past a terminating zero if found.
61 ********************************************************************/
63 char *skip_unibuf(char *src, size_t len)
65 char *srcend = src + len;
67 while (src < srcend && SVAL(src,0))
76 /* Copy a string from little-endian or big-endian unicode source (depending
77 * on flags) to internal samba format destination
79 int rpcstr_pull(char* dest, void *src, int dest_len, int src_len, int flags)
81 if(dest_len==-1) dest_len=MAXUNI-3;
82 return pull_ucs2(NULL, dest, src, dest_len, src_len, flags|STR_UNICODE|STR_NOALIGN);
85 /* Converts a string from internal samba format to unicode
87 int rpcstr_push(void* dest, const char *src, int dest_len, int flags)
89 return push_ucs2(NULL, dest, src, dest_len, flags|STR_UNICODE|STR_NOALIGN);
92 /*******************************************************************
93 Return a DOS codepage version of a little-endian unicode string.
94 len is the filename length (ignoring any terminating zero) in uin16
95 units. Always null terminates.
96 Hack alert: uses fixed buffer(s).
97 ********************************************************************/
98 char *dos_unistrn2(uint16 *src, int len)
100 static char lbufs[8][MAXUNI];
102 char *lbuf = lbufs[nexti];
104 pull_ucs2(NULL, lbuf, src, MAXUNI-3, len*2, STR_NOALIGN);
108 /*******************************************************************
109 Convert a (little-endian) UNISTR2 structure to an ASCII string
110 ********************************************************************/
111 void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
117 pull_ucs2(NULL, dest, str->buffer, maxlen, str->uni_str_len, STR_NOALIGN);
121 /*******************************************************************
122 Return a number stored in a buffer
123 ********************************************************************/
125 uint32 buffer2_to_uint32(BUFFER2 *str)
127 if (str->buf_len == 4)
128 return IVAL(str->buffer, 0);
133 /*******************************************************************
134 Mapping tables for UNICODE character. Allows toupper/tolower and
135 isXXX functions to work.
137 tridge: split into 2 pieces. This saves us 5/6 of the memory
138 with a small speed penalty
139 The magic constants are the lower/upper range of the tables two
141 ********************************************************************/
147 } smb_unicode_table_t;
149 #define TABLE1_BOUNDARY 9450
150 #define TABLE2_BOUNDARY 64256
152 static smb_unicode_table_t map_table1[] = {
153 #include "unicode_map_table1.h"
156 static smb_unicode_table_t map_table2[] = {
157 #include "unicode_map_table2.h"
160 static unsigned char map_table_flags(smb_ucs2_t v)
162 if (v < TABLE1_BOUNDARY) return map_table1[v].flags;
163 if (v >= TABLE2_BOUNDARY) return map_table2[v - TABLE2_BOUNDARY].flags;
167 static smb_ucs2_t map_table_lower(smb_ucs2_t v)
169 if (v < TABLE1_BOUNDARY) return map_table1[v].lower;
170 if (v >= TABLE2_BOUNDARY) return map_table2[v - TABLE2_BOUNDARY].lower;
174 static smb_ucs2_t map_table_upper(smb_ucs2_t v)
176 if (v < TABLE1_BOUNDARY) return map_table1[v].upper;
177 if (v >= TABLE2_BOUNDARY) return map_table2[v - TABLE2_BOUNDARY].upper;
181 /*******************************************************************
182 Is an upper case wchar.
183 ********************************************************************/
185 int isupper_w( smb_ucs2_t val)
187 return (map_table_flags(val) & UNI_UPPER);
190 /*******************************************************************
191 Is a lower case wchar.
192 ********************************************************************/
194 int islower_w( smb_ucs2_t val)
196 return (map_table_flags(val) & UNI_LOWER);
199 /*******************************************************************
200 Convert a wchar to upper case.
201 ********************************************************************/
203 smb_ucs2_t toupper_w( smb_ucs2_t val )
205 return map_table_upper(val);
208 /*******************************************************************
209 Convert a wchar to lower case.
210 ********************************************************************/
212 smb_ucs2_t tolower_w( smb_ucs2_t val )
214 return map_table_lower(val);
217 /*******************************************************************
218 Count the number of characters in a smb_ucs2_t string.
219 ********************************************************************/
220 size_t strlen_w(const smb_ucs2_t *src)
224 for(len = 0; *src++; len++) ;
229 /*******************************************************************
231 ********************************************************************/
232 smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
235 if (c == *s) return (smb_ucs2_t *)s;
242 /*******************************************************************
243 Convert a string to lower case.
244 ********************************************************************/
245 void strlower_w(smb_ucs2_t *s)
254 /*******************************************************************
255 Convert a string to upper case.
256 ********************************************************************/
257 void strupper_w(smb_ucs2_t *s)
266 /*******************************************************************
267 case insensitive string comparison
268 ********************************************************************/
269 int strcasecmp_w(const smb_ucs2_t *a, const smb_ucs2_t *b)
271 while (*b && tolower_w(*a) == tolower_w(*b)) { a++; b++; }
272 return (tolower_w(*a) - tolower_w(*b));
277 The *_wa() functions take a combination of 7 bit ascii
278 and wide characters They are used so that you can use string
279 functions combining C string constants with ucs2 strings
281 The char* arguments must NOT be multibyte - to be completely sure
282 of this only pass string constants */
285 void pstrcpy_wa(smb_ucs2_t *dest, const char *src)
288 for (i=0;i<PSTRING_LEN;i++) {
289 dest[i] = UCS2_CHAR(src[i]);
290 if (src[i] == 0) return;
294 int strcmp_wa(const smb_ucs2_t *a, const char *b)
296 while (*b && *a == UCS2_CHAR(*b)) { a++; b++; }
297 return (*a - UCS2_CHAR(*b));
300 smb_ucs2_t *strchr_wa(const smb_ucs2_t *s, char c)
303 if (UCS2_CHAR(c) == *s) return (smb_ucs2_t *)s;
309 smb_ucs2_t *strrchr_wa(const smb_ucs2_t *s, char c)
311 const smb_ucs2_t *p = s;
312 int len = strlen_w(s);
313 if (len == 0) return NULL;
316 if (UCS2_CHAR(c) == *p) return (smb_ucs2_t *)p;
322 smb_ucs2_t *strpbrk_wa(const smb_ucs2_t *s, const char *p)
326 for (i=0; p[i] && *s != UCS2_CHAR(p[i]); i++)
328 if (p[i]) return (smb_ucs2_t *)s;