fixed word-order issue in password set and password change.
[Samba.git] / source / lib / util_unistr.c
blobb739d638f5ae4f742be2cff7e3eac88c64a56318
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-2000
6 Copyright (C) Luke Kenneth Casson Leighton 1996-2000
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "includes.h"
25 extern int DEBUGLEVEL;
27 /*******************************************************************
28 Put an ASCII string into a UNICODE buffer (little endian).
29 ********************************************************************/
31 char *ascii_to_unibuf(char *dest, const char *src, int maxlen)
33 char *destend = dest + maxlen;
34 register char c;
36 while (dest < destend)
38 c = *(src++);
39 if (c == 0)
41 break;
44 *(dest++) = c;
45 *(dest++) = 0;
48 *dest++ = 0;
49 *dest++ = 0;
50 return dest;
54 /*******************************************************************
55 Pull an ASCII string out of a UNICODE buffer (little endian).
56 ********************************************************************/
58 const char* unibuf_to_ascii(char *dest, const char *src, int maxlen)
60 char *destend = dest + maxlen;
61 register char c;
63 while (dest < destend)
65 c = *(src++);
66 if ((c == 0) && (*src == 0))
68 break;
71 *dest++ = c;
72 src++;
75 *dest = 0;
77 return src;
81 /*******************************************************************
82 Put an ASCII string into a UNICODE array (uint16's).
83 ********************************************************************/
84 void ascii_to_unistr(uint16 *dest, const char *src, int maxlen)
86 uint16 *destend = dest + maxlen;
87 register char c;
89 while (dest < destend)
91 c = *(src++);
92 if (c == 0)
94 break;
97 *(dest++) = (uint16)c;
100 *dest = 0;
104 /*******************************************************************
105 Pull an ASCII string out of a UNICODE array (uint16's).
106 ********************************************************************/
108 void unistr_to_ascii(char *dest, const uint16 *src, int len)
110 char *destend = dest + len;
111 register uint16 c;
113 while (dest < destend)
115 c = *(src++);
116 if (c == 0)
118 break;
121 *(dest++) = (char)c;
124 *dest = 0;
128 /*******************************************************************
129 Convert a UNISTR2 structure to an ASCII string
130 ********************************************************************/
132 char *unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
134 char *destend;
135 const uint16 *src;
136 size_t len;
137 register uint16 c;
139 src = str->buffer;
141 if (dest == NULL)
143 if (maxlen == 0)
145 maxlen = str->uni_str_len;
147 dest = g_new(char, maxlen + 1);
148 if (dest == NULL)
150 DEBUG(2, ("malloc(%d) problem in unistr2_to_ascii\n",
151 maxlen + 1));
152 return NULL;
156 len = MIN(str->uni_str_len, maxlen);
157 destend = dest + len;
159 while (dest < destend)
161 c = *(src++);
162 if (c == 0)
164 break;
167 *(dest++) = (char)c;
170 *dest = 0;
172 return dest;
176 /*******************************************************************
177 Skip a UNICODE string in a little endian buffer.
178 ********************************************************************/
180 char *skip_unibuf(char *srcbuf, int len)
182 uint16 *src = (uint16 *)srcbuf;
183 uint16 *srcend = src + len/2;
185 while ((src < srcend) && (*(src++) != 0))
189 return (char *)src;
193 /*******************************************************************
194 UNICODE strcpy between buffers.
195 ********************************************************************/
197 char *uni_strncpy(char *destbuf, const char *srcbuf, int len)
199 const uint16 *src = (const uint16 *)srcbuf;
200 uint16 *dest = (uint16 *)destbuf;
201 uint16 *destend = dest + len/2;
202 register uint16 c;
204 while (dest < destend)
206 c = *(src++);
207 if (c == 0)
209 break;
212 *(dest++) = c;
215 *dest++ = 0;
216 return (char *)dest;
220 /*******************************************************************
221 Return a number stored in a buffer
222 ********************************************************************/
224 uint32 buffer2_to_uint32(const BUFFER2 *str)
226 if (str->buf_len == 4)
228 const uchar *src = str->buffer;
229 return IVAL(src, 0);
231 else
233 return 0;
238 /*******************************************************************
239 Convert a 'multi-string' buffer to space-separated ASCII.
240 ********************************************************************/
241 void buffer2_to_multistr(char *dest, const BUFFER2 *str, size_t maxlen)
243 char *destend;
244 const uchar *src;
245 size_t len;
246 register uint16 c;
248 src = str->buffer;
249 len = MIN(str->buf_len/2, maxlen);
250 destend = dest + len;
252 while (dest < destend)
254 c = *(src++);
255 *(dest++) = (c == 0) ? ' ' : (char)c;
256 src++;
259 *dest = 0;
262 /*******************************************************************
263 Convert a buffer4 to space-separated ASCII.
264 ********************************************************************/
265 void buffer4_to_str(char *dest, const BUFFER4 *str, size_t maxlen)
267 char *destend;
268 const uchar *src;
269 size_t len;
270 register uint16 c;
272 src = str->buffer;
273 len = MIN(str->buf_len, maxlen);
274 destend = dest + len;
276 while (dest < destend)
278 c = *(src++);
279 *(dest++) = (char)c;
282 *dest = 0;
286 /*******************************************************************
287 creates a new UNISTR2.
288 ********************************************************************/
289 UNISTR2 *unistr2_new(const char *init)
291 UNISTR2 *str;
292 str = g_new(UNISTR2, 1);
293 if (str == NULL)
295 DEBUG(1, ("malloc problem in unistr2_new\n"));
296 return NULL;
299 str->uni_max_len = 0;
300 str->undoc = 0;
301 str->uni_str_len = 0;
303 if (init != NULL)
305 unistr2_assign_ascii_str(str, init);
308 return str;
311 UNISTR2 *unistr2_assign(UNISTR2 *str, const uint16 *src, size_t len)
313 if (str == NULL)
315 DEBUG(1, ("NULL unistr2\n"));
316 return NULL;
319 if (src == NULL)
321 len = 0;
324 if (len >= MAX_UNISTRLEN)
326 len = MAX_UNISTRLEN - 1;
329 unistr2_grow(str, len + 1);
331 /* set up string lengths. */
332 str->uni_max_len = len;
333 str->undoc = 0;
334 str->uni_str_len = len;
336 if (len != 0)
338 memcpy(str->buffer, src, len * sizeof(uint16));
340 str->buffer[len] = 0;
342 return str;
345 UNISTR2 *unistr2_assign_ascii(UNISTR2 *str, const char *buf, int len)
347 if (str == NULL)
349 DEBUG(1, ("NULL unistr2\n"));
350 return NULL;
353 if (buf == NULL)
355 len = 0;
358 if (len >= MAX_UNISTRLEN)
360 len = MAX_UNISTRLEN - 1;
363 unistr2_grow(str, len + 1);
365 /* set up string lengths. */
366 str->uni_max_len = len;
367 str->undoc = 0;
368 str->uni_str_len = len;
370 /* store the string (wide chars) */
371 ascii_to_unistr(str->buffer, buf, len);
373 return str;
376 UNISTR2 *unistr2_assign_ascii_str(UNISTR2 *str, const char *buf)
378 return unistr2_assign_ascii(str, buf, (buf ? strlen(buf) : 0));
381 /*******************************************************************
382 grows the buffer of a UNISTR2.
383 doesn't shrink
384 doesn't modify lengh
385 ********************************************************************/
386 UNISTR2 *unistr2_grow(UNISTR2 *str, size_t new_size)
388 if (str == NULL)
390 DEBUG(1, ("NULL unistr2\n"));
391 return NULL;
393 /* It's currently a fake, yes */
394 if (new_size > MAX_UNISTRLEN)
396 DEBUG(3, ("Growing buffer beyond its current static size\n"));
398 return str;
402 /*******************************************************************
403 copies a UNISTR2 structure.
404 ********************************************************************/
405 BOOL unistr2upper(UNISTR2 *str, const UNISTR2 *from)
407 if (from != NULL)
409 int i;
411 ZERO_STRUCTP(str);
413 /* copy up string lengths*/
414 str->uni_max_len = from->uni_max_len;
415 str->undoc = from->undoc;
416 str->uni_str_len = from->uni_str_len;
418 /* copy the string */
419 for (i = 0; i < from->uni_str_len; i++)
421 str->buffer[i] = toupper(from->buffer[i]);
424 else
426 str->uni_max_len = 1;
427 str->undoc = 0;
428 str->uni_str_len = 1;
429 str->buffer[0] = 0;
432 return True;
435 /*******************************************************************
436 copies a UNISTR2 structure.
437 ********************************************************************/
438 BOOL copy_unistr2(UNISTR2 *str, const UNISTR2 *from)
440 if (str == NULL)
442 return False;
444 if (from != NULL)
446 ZERO_STRUCTP(str);
448 /* set up string lengths. add one if string is not null-terminated */
449 str->uni_max_len = from->uni_max_len;
450 str->undoc = from->undoc;
451 str->uni_str_len = from->uni_str_len;
453 /* copy the string */
454 memcpy(str->buffer, from->buffer, str->uni_str_len * 2);
455 DEBUG(10,("copy_unistr2: string len %d\n", str->uni_str_len));
457 else
459 str->uni_max_len = 1;
460 str->undoc = 0;
461 str->uni_str_len = 1;
462 str->buffer[0] = 0;
465 return True;
468 /*******************************************************************
469 duplicates a UNISTR2 structure.
470 ********************************************************************/
471 UNISTR2 *unistr2_dup(const UNISTR2 *name)
473 UNISTR2 *copy = (UNISTR2*)malloc(sizeof(*copy));
474 copy_unistr2(copy, name);
475 return copy;
478 /*******************************************************************
479 frees a UNISTR2 structure.
480 ********************************************************************/
481 void unistr2_free(UNISTR2 *name)
483 safe_free(name);
486 /*******************************************************************
487 case insensitive string compararison
488 ********************************************************************/
489 int StrCaseCmpW(const UNISTR2 *ws, const UNISTR2 *wt)
491 int len = MIN(ws->uni_str_len, wt->uni_str_len);
492 uint16 *s = ws->buffer;
493 uint16 *t = wt->buffer;
494 uint16 sc;
495 uint16 tc;
497 while (len > 0 && *s && *t && toupper(*s) == toupper(*t))
499 s++;
500 t++;
501 len--;
504 if (len == 0 && ws->uni_str_len == wt->uni_str_len)
506 return 0;
509 sc = toupper(*s);
510 tc = toupper(*t);
512 if (wt->uni_str_len > ws->uni_str_len)
514 /* wt is longer, therefore last ws char must be 0 */
515 sc = 0;
518 if (ws->uni_str_len > wt->uni_str_len)
520 /* ws is longer, therefore last wt char must be 0 */
521 tc = 0;
524 return sc - tc;
527 /*******************************************************************
528 compare 2 UNISTR2 strings . first implementation, unicode string
529 comparison isn't simple, you don't necessarily have a NULL-termination
530 character but it's the same string...
531 ********************************************************************/
532 BOOL unistr2equal(const UNISTR2 *s1, const UNISTR2 *s2)
534 #if 0
535 DEBUG(20,("unistr2equal:\n"));
536 dump_data(20, s1, sizeof(*s1));
537 dump_data(20, s2, sizeof(*s2));
538 #endif
540 if (s1 == s2) return(True);
541 if (!s1 || !s2) return(False);
543 return(StrCaseCmpW(s1,s2)==0);