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;
30 /*******************************************************************
31 Write a string in (little-endian) unicode format. src is in
32 the current DOS codepage. len is the length in bytes of the
33 string pointed to by dst.
35 if null_terminate is True then null terminate the packet (adds 2 bytes)
37 the return value is the length in bytes consumed by the string, including the
38 null termination if applied
39 ********************************************************************/
41 size_t dos_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminate)
43 return push_ucs2(NULL, dst, src, len,
44 STR_UNICODE|STR_NOALIGN | (null_terminate?STR_TERMINATE:0));
48 /*******************************************************************
49 Skip past a unicode string, but not more than len. Always move
50 past a terminating zero if found.
51 ********************************************************************/
53 char *skip_unibuf(char *src, size_t len)
55 char *srcend = src + len;
57 while (src < srcend && SVAL(src,0))
66 /* Copy a string from little-endian or big-endian unicode source (depending
67 * on flags) to internal samba format destination
69 int rpcstr_pull(char* dest, void *src, int dest_len, int src_len, int flags)
71 if(dest_len==-1) dest_len=MAXUNI-3;
72 return pull_ucs2(NULL, dest, src, dest_len, src_len, flags|STR_UNICODE|STR_NOALIGN);
75 /* Copy a string from a unistr2 source to internal samba format
76 destination. Use this instead of direct calls to rpcstr_pull() to avoid
77 having to determine whether the source string is null terminated. */
79 int rpcstr_pull_unistr2_fstring(char *dest, UNISTR2 *src)
81 return pull_ucs2(NULL, dest, src->buffer, sizeof(fstring),
82 src->uni_str_len * 2, 0);
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(const 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*2, 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)
163 if (v < TABLE1_BOUNDARY) return map_table1[v].flags;
164 if (v >= TABLE2_BOUNDARY) return map_table2[v - TABLE2_BOUNDARY].flags;
168 static smb_ucs2_t map_table_lower(smb_ucs2_t v)
171 if (v < TABLE1_BOUNDARY) return map_table1[v].lower;
172 if (v >= TABLE2_BOUNDARY) return map_table2[v - TABLE2_BOUNDARY].lower;
176 static smb_ucs2_t map_table_upper(smb_ucs2_t v)
179 if (v < TABLE1_BOUNDARY) return map_table1[v].upper;
180 if (v >= TABLE2_BOUNDARY) return map_table2[v - TABLE2_BOUNDARY].upper;
184 /*******************************************************************
185 Is an upper case wchar.
186 ********************************************************************/
188 int isupper_w( smb_ucs2_t val)
190 return (map_table_flags(val) & UNI_UPPER);
193 /*******************************************************************
194 Is a lower case wchar.
195 ********************************************************************/
197 int islower_w( smb_ucs2_t val)
199 return (map_table_flags(val) & UNI_LOWER);
202 /*******************************************************************
203 Convert a wchar to upper case.
204 ********************************************************************/
206 smb_ucs2_t toupper_w( smb_ucs2_t val )
208 val = map_table_upper(val);
213 /*******************************************************************
214 Convert a wchar to lower case.
215 ********************************************************************/
217 smb_ucs2_t tolower_w( smb_ucs2_t val )
219 val = map_table_lower(val);
224 /*******************************************************************
225 Count the number of characters in a smb_ucs2_t string.
226 ********************************************************************/
227 size_t strlen_w(const smb_ucs2_t *src)
231 for(len = 0; *src++; len++) ;
236 /*******************************************************************
238 ********************************************************************/
239 smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
242 if (c == *s) return (smb_ucs2_t *)s;
249 /*******************************************************************
250 Convert a string to lower case.
251 return True if any char is converted
252 ********************************************************************/
253 BOOL strlower_w(smb_ucs2_t *s)
266 /*******************************************************************
267 Convert a string to upper case.
268 return True if any char is converted
269 ********************************************************************/
270 BOOL strupper_w(smb_ucs2_t *s)
283 /*******************************************************************
284 case insensitive string comparison
285 ********************************************************************/
286 int strcasecmp_w(const smb_ucs2_t *a, const smb_ucs2_t *b)
288 while (*b && tolower_w(*a) == tolower_w(*b)) { a++; b++; }
289 return (tolower_w(*a) - tolower_w(*b));
293 /*******************************************************************
295 ********************************************************************/
296 smb_ucs2_t *strdup_w(const smb_ucs2_t *src)
302 dest = (smb_ucs2_t *)malloc((len+1)*sizeof(smb_ucs2_t));
304 DEBUG(0,("strdup_w: out of memory!\n"));
308 memcpy(dest, src, (len+1)*sizeof(smb_ucs2_t));
313 /*******************************************************************
314 copy a string with max len
315 ********************************************************************/
317 smb_ucs2_t *strncpy_w(smb_ucs2_t *dest, const smb_ucs2_t *src, const size_t max)
321 if (!dest || !src) return NULL;
323 for (len = 0; (src[len] != 0) && (len < max); len++)
324 dest[len] = src[len];
332 /*******************************************************************
333 append a string of len bytes and add a terminator
334 ********************************************************************/
336 smb_ucs2_t *strncat_w(smb_ucs2_t *dest, const smb_ucs2_t *src, const size_t max)
341 if (!dest || !src) return NULL;
343 start = strlen_w(dest);
345 if (len > max) len = max;
347 memcpy(&dest[start], src, len);
348 dest[start+len+1] = 0;
355 The *_wa() functions take a combination of 7 bit ascii
356 and wide characters They are used so that you can use string
357 functions combining C string constants with ucs2 strings
359 The char* arguments must NOT be multibyte - to be completely sure
360 of this only pass string constants */
363 void pstrcpy_wa(smb_ucs2_t *dest, const char *src)
366 for (i=0;i<PSTRING_LEN;i++) {
367 dest[i] = UCS2_CHAR(src[i]);
368 if (src[i] == 0) return;
372 int strcmp_wa(const smb_ucs2_t *a, const char *b)
374 while (*b && *a == UCS2_CHAR(*b)) { a++; b++; }
375 return (*a - UCS2_CHAR(*b));
380 smb_ucs2_t *strchr_wa(const smb_ucs2_t *s, char c)
383 if (UCS2_CHAR(c) == *s) return (smb_ucs2_t *)s;
389 smb_ucs2_t *strrchr_wa(const smb_ucs2_t *s, char c)
391 const smb_ucs2_t *p = s;
392 int len = strlen_w(s);
393 if (len == 0) return NULL;
396 if (UCS2_CHAR(c) == *p) return (smb_ucs2_t *)p;
401 smb_ucs2_t *strpbrk_wa(const smb_ucs2_t *s, const char *p)
405 for (i=0; p[i] && *s != UCS2_CHAR(p[i]); i++)
407 if (p[i]) return (smb_ucs2_t *)s;
414 /*******************************************************************
415 copy a string with max len
416 ********************************************************************/
418 smb_ucs2_t *strncpy_wa(smb_ucs2_t *dest, const char *src, const size_t max)
420 smb_ucs2_t *ucs2_src;
422 if (!dest || !src) return NULL;
423 ucs2_src = (smb_ucs2_t *)malloc((strlen(src)+1)*sizeof(smb_ucs2_t));
425 DEBUG(0,("strncpy_wa: out of memory!\n"));
428 push_ucs2(NULL, ucs2_src, src, -1, STR_TERMINATE|STR_NOALIGN);
430 strncpy_w(dest, ucs2_src, max);
436 /*******************************************************************
437 append a string of len bytes and add a terminator
438 ********************************************************************/
440 smb_ucs2_t *strncat_wa(smb_ucs2_t *dest, const char *src, const size_t max)
442 smb_ucs2_t *ucs2_src;
444 if (!dest || !src) return NULL;
445 ucs2_src = (smb_ucs2_t *)malloc((strlen(src)+1)*sizeof(smb_ucs2_t));
447 DEBUG(0,("strncat_wa: out of memory!\n"));
450 push_ucs2(NULL, ucs2_src, src, -1, STR_TERMINATE|STR_NOALIGN);
452 strncat_w(dest, ucs2_src, max);