source: branches/samba-3.2.x/source/lib/util_str.c

Last change on this file was 204, checked in by Herwig Bauernfeind, 16 years ago

Update 3.2 branch to 3.2.4

File size: 60.6 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 Samba utility functions
4
5 Copyright (C) Andrew Tridgell 1992-2001
6 Copyright (C) Simo Sorce 2001-2002
7 Copyright (C) Martin Pool 2003
8 Copyright (C) James Peach 2006
9 Copyright (C) Jeremy Allison 1992-2007
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
23*/
24
25#include "includes.h"
26
27char toupper_ascii_fast_table[128] = {
28 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
29 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
30 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
31 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
32 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
33 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
34 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
35 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f
36};
37
38/**
39 * @file
40 * @brief String utilities.
41 **/
42
43static bool next_token_internal_talloc(TALLOC_CTX *ctx,
44 const char **ptr,
45 char **pp_buff,
46 const char *sep,
47 bool ltrim)
48{
49 char *s;
50 char *saved_s;
51 char *pbuf;
52 bool quoted;
53 size_t len=1;
54
55 *pp_buff = NULL;
56 if (!ptr) {
57 return(false);
58 }
59
60 s = (char *)*ptr;
61
62 /* default to simple separators */
63 if (!sep) {
64 sep = " \t\n\r";
65 }
66
67 /* find the first non sep char, if left-trimming is requested */
68 if (ltrim) {
69 while (*s && strchr_m(sep,*s)) {
70 s++;
71 }
72 }
73
74 /* nothing left? */
75 if (!*s) {
76 return false;
77 }
78
79 /* When restarting we need to go from here. */
80 saved_s = s;
81
82 /* Work out the length needed. */
83 for (quoted = false; *s &&
84 (quoted || !strchr_m(sep,*s)); s++) {
85 if (*s == '\"') {
86 quoted = !quoted;
87 } else {
88 len++;
89 }
90 }
91
92 /* We started with len = 1 so we have space for the nul. */
93 *pp_buff = TALLOC_ARRAY(ctx, char, len);
94 if (!*pp_buff) {
95 return false;
96 }
97
98 /* copy over the token */
99 pbuf = *pp_buff;
100 s = saved_s;
101 for (quoted = false; *s &&
102 (quoted || !strchr_m(sep,*s)); s++) {
103 if ( *s == '\"' ) {
104 quoted = !quoted;
105 } else {
106 *pbuf++ = *s;
107 }
108 }
109
110 *ptr = (*s) ? s+1 : s;
111 *pbuf = 0;
112
113 return true;
114}
115
116#if 0
117/*
118 * Get the next token from a string, return false if none found. Handles
119 * double-quotes. This version trims leading separator characters before
120 * looking for a token.
121 */
122bool next_token(const char **ptr, char *buff, const char *sep, size_t bufsize)
123{
124 return next_token_internal(ptr, buff, sep, bufsize, true);
125}
126#endif
127
128bool next_token_talloc(TALLOC_CTX *ctx,
129 const char **ptr,
130 char **pp_buff,
131 const char *sep)
132{
133 return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true);
134}
135
136/*
137 * Get the next token from a string, return false if none found. Handles
138 * double-quotes. This version does not trim leading separator characters
139 * before looking for a token.
140 */
141
142bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx,
143 const char **ptr,
144 char **pp_buff,
145 const char *sep)
146{
147 return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false);
148}
149
150/**
151 * Case insensitive string compararison.
152 *
153 * iconv does not directly give us a way to compare strings in
154 * arbitrary unix character sets -- all we can is convert and then
155 * compare. This is expensive.
156 *
157 * As an optimization, we do a first pass that considers only the
158 * prefix of the strings that is entirely 7-bit. Within this, we
159 * check whether they have the same value.
160 *
161 * Hopefully this will often give the answer without needing to copy.
162 * In particular it should speed comparisons to literal ascii strings
163 * or comparisons of strings that are "obviously" different.
164 *
165 * If we find a non-ascii character we fall back to converting via
166 * iconv.
167 *
168 * This should never be slower than convering the whole thing, and
169 * often faster.
170 *
171 * A different optimization would be to compare for bitwise equality
172 * in the binary encoding. (It would be possible thought hairy to do
173 * both simultaneously.) But in that case if they turn out to be
174 * different, we'd need to restart the whole thing.
175 *
176 * Even better is to implement strcasecmp for each encoding and use a
177 * function pointer.
178 **/
179int StrCaseCmp(const char *s, const char *t)
180{
181
182 const char *ps, *pt;
183 size_t size;
184 smb_ucs2_t *buffer_s, *buffer_t;
185 int ret;
186
187 for (ps = s, pt = t; ; ps++, pt++) {
188 char us, ut;
189
190 if (!*ps && !*pt)
191 return 0; /* both ended */
192 else if (!*ps)
193 return -1; /* s is a prefix */
194 else if (!*pt)
195 return +1; /* t is a prefix */
196 else if ((*ps & 0x80) || (*pt & 0x80))
197 /* not ascii anymore, do it the hard way
198 * from here on in */
199 break;
200
201 us = toupper_ascii_fast(*ps);
202 ut = toupper_ascii_fast(*pt);
203 if (us == ut)
204 continue;
205 else if (us < ut)
206 return -1;
207 else if (us > ut)
208 return +1;
209 }
210
211 size = push_ucs2_allocate(&buffer_s, ps);
212 if (size == (size_t)-1) {
213 return strcmp(ps, pt);
214 /* Not quite the right answer, but finding the right one
215 under this failure case is expensive, and it's pretty
216 close */
217 }
218
219 size = push_ucs2_allocate(&buffer_t, pt);
220 if (size == (size_t)-1) {
221 SAFE_FREE(buffer_s);
222 return strcmp(ps, pt);
223 /* Not quite the right answer, but finding the right one
224 under this failure case is expensive, and it's pretty
225 close */
226 }
227
228 ret = strcasecmp_w(buffer_s, buffer_t);
229 SAFE_FREE(buffer_s);
230 SAFE_FREE(buffer_t);
231 return ret;
232}
233
234
235/**
236 Case insensitive string compararison, length limited.
237**/
238int StrnCaseCmp(const char *s, const char *t, size_t len)
239{
240 size_t n = 0;
241 const char *ps, *pt;
242 size_t size;
243 smb_ucs2_t *buffer_s, *buffer_t;
244 int ret;
245
246 for (ps = s, pt = t; n < len ; ps++, pt++, n++) {
247 char us, ut;
248
249 if (!*ps && !*pt)
250 return 0; /* both ended */
251 else if (!*ps)
252 return -1; /* s is a prefix */
253 else if (!*pt)
254 return +1; /* t is a prefix */
255 else if ((*ps & 0x80) || (*pt & 0x80))
256 /* not ascii anymore, do it the
257 * hard way from here on in */
258 break;
259
260 us = toupper_ascii_fast(*ps);
261 ut = toupper_ascii_fast(*pt);
262 if (us == ut)
263 continue;
264 else if (us < ut)
265 return -1;
266 else if (us > ut)
267 return +1;
268 }
269
270 if (n == len) {
271 return 0;
272 }
273
274 size = push_ucs2_allocate(&buffer_s, ps);
275 if (size == (size_t)-1) {
276 return strncmp(ps, pt, len-n);
277 /* Not quite the right answer, but finding the right one
278 under this failure case is expensive,
279 and it's pretty close */
280 }
281
282 size = push_ucs2_allocate(&buffer_t, pt);
283 if (size == (size_t)-1) {
284 SAFE_FREE(buffer_s);
285 return strncmp(ps, pt, len-n);
286 /* Not quite the right answer, but finding the right one
287 under this failure case is expensive,
288 and it's pretty close */
289 }
290
291 ret = strncasecmp_w(buffer_s, buffer_t, len-n);
292 SAFE_FREE(buffer_s);
293 SAFE_FREE(buffer_t);
294 return ret;
295}
296
297/**
298 * Compare 2 strings.
299 *
300 * @note The comparison is case-insensitive.
301 **/
302bool strequal(const char *s1, const char *s2)
303{
304 if (s1 == s2)
305 return(true);
306 if (!s1 || !s2)
307 return(false);
308
309 return(StrCaseCmp(s1,s2)==0);
310}
311
312/**
313 * Compare 2 strings up to and including the nth char.
314 *
315 * @note The comparison is case-insensitive.
316 **/
317bool strnequal(const char *s1,const char *s2,size_t n)
318{
319 if (s1 == s2)
320 return(true);
321 if (!s1 || !s2 || !n)
322 return(false);
323
324 return(StrnCaseCmp(s1,s2,n)==0);
325}
326
327/**
328 Compare 2 strings (case sensitive).
329**/
330
331bool strcsequal(const char *s1,const char *s2)
332{
333 if (s1 == s2)
334 return(true);
335 if (!s1 || !s2)
336 return(false);
337
338 return(strcmp(s1,s2)==0);
339}
340
341/**
342Do a case-insensitive, whitespace-ignoring string compare.
343**/
344
345int strwicmp(const char *psz1, const char *psz2)
346{
347 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
348 /* appropriate value. */
349 if (psz1 == psz2)
350 return (0);
351 else if (psz1 == NULL)
352 return (-1);
353 else if (psz2 == NULL)
354 return (1);
355
356 /* sync the strings on first non-whitespace */
357 while (1) {
358 while (isspace((int)*psz1))
359 psz1++;
360 while (isspace((int)*psz2))
361 psz2++;
362 if (toupper_ascii(*psz1) != toupper_ascii(*psz2) ||
363 *psz1 == '\0' || *psz2 == '\0')
364 break;
365 psz1++;
366 psz2++;
367 }
368 return (*psz1 - *psz2);
369}
370
371/**
372 Convert a string to "normal" form.
373**/
374
375void strnorm(char *s, int case_default)
376{
377 if (case_default == CASE_UPPER)
378 strupper_m(s);
379 else
380 strlower_m(s);
381}
382
383/**
384 Check if a string is in "normal" case.
385**/
386
387bool strisnormal(const char *s, int case_default)
388{
389 if (case_default == CASE_UPPER)
390 return(!strhaslower(s));
391
392 return(!strhasupper(s));
393}
394
395
396/**
397 String replace.
398 NOTE: oldc and newc must be 7 bit characters
399**/
400void string_replace( char *s, char oldc, char newc )
401{
402 char *p;
403
404 /* this is quite a common operation, so we want it to be
405 fast. We optimise for the ascii case, knowing that all our
406 supported multi-byte character sets are ascii-compatible
407 (ie. they match for the first 128 chars) */
408
409 for (p = s; *p; p++) {
410 if (*p & 0x80) /* mb string - slow path. */
411 break;
412 if (*p == oldc) {
413 *p = newc;
414 }
415 }
416
417 if (!*p)
418 return;
419
420 /* Slow (mb) path. */
421#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
422 /* With compose characters we must restart from the beginning. JRA. */
423 p = s;
424#endif
425
426 while (*p) {
427 size_t c_size;
428 next_codepoint(p, &c_size);
429
430 if (c_size == 1) {
431 if (*p == oldc) {
432 *p = newc;
433 }
434 }
435 p += c_size;
436 }
437}
438
439/**
440 * Skip past some strings in a buffer - old version - no checks.
441 * **/
442
443char *push_skip_string(char *buf)
444{
445 buf += strlen(buf) + 1;
446 return(buf);
447}
448
449/**
450 Skip past a string in a buffer. Buffer may not be
451 null terminated. end_ptr points to the first byte after
452 then end of the buffer.
453**/
454
455char *skip_string(const char *base, size_t len, char *buf)
456{
457 const char *end_ptr = base + len;
458
459 if (end_ptr < base || !base || !buf || buf >= end_ptr) {
460 return NULL;
461 }
462
463 /* Skip the string */
464 while (*buf) {
465 buf++;
466 if (buf >= end_ptr) {
467 return NULL;
468 }
469 }
470 /* Skip the '\0' */
471 buf++;
472 return buf;
473}
474
475/**
476 Count the number of characters in a string. Normally this will
477 be the same as the number of bytes in a string for single byte strings,
478 but will be different for multibyte.
479**/
480
481size_t str_charnum(const char *s)
482{
483 size_t ret;
484 smb_ucs2_t *tmpbuf2 = NULL;
485 if (push_ucs2_allocate(&tmpbuf2, s) == (size_t)-1) {
486 return 0;
487 }
488 ret = strlen_w(tmpbuf2);
489 SAFE_FREE(tmpbuf2);
490 return ret;
491}
492
493/**
494 Count the number of characters in a string. Normally this will
495 be the same as the number of bytes in a string for single byte strings,
496 but will be different for multibyte.
497**/
498
499size_t str_ascii_charnum(const char *s)
500{
501 size_t ret;
502 char *tmpbuf2 = NULL;
503 if (push_ascii_allocate(&tmpbuf2, s) == (size_t)-1) {
504 return 0;
505 }
506 ret = strlen(tmpbuf2);
507 SAFE_FREE(tmpbuf2);
508 return ret;
509}
510
511bool trim_char(char *s,char cfront,char cback)
512{
513 bool ret = false;
514 char *ep;
515 char *fp = s;
516
517 /* Ignore null or empty strings. */
518 if (!s || (s[0] == '\0'))
519 return false;
520
521 if (cfront) {
522 while (*fp && *fp == cfront)
523 fp++;
524 if (!*fp) {
525 /* We ate the string. */
526 s[0] = '\0';
527 return true;
528 }
529 if (fp != s)
530 ret = true;
531 }
532
533 ep = fp + strlen(fp) - 1;
534 if (cback) {
535 /* Attempt ascii only. Bail for mb strings. */
536 while ((ep >= fp) && (*ep == cback)) {
537 ret = true;
538 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
539 /* Could be mb... bail back to tim_string. */
540 char fs[2], bs[2];
541 if (cfront) {
542 fs[0] = cfront;
543 fs[1] = '\0';
544 }
545 bs[0] = cback;
546 bs[1] = '\0';
547 return trim_string(s, cfront ? fs : NULL, bs);
548 } else {
549 ep--;
550 }
551 }
552 if (ep < fp) {
553 /* We ate the string. */
554 s[0] = '\0';
555 return true;
556 }
557 }
558
559 ep[1] = '\0';
560 memmove(s, fp, ep-fp+2);
561 return ret;
562}
563
564/**
565 Trim the specified elements off the front and back of a string.
566**/
567
568bool trim_string(char *s,const char *front,const char *back)
569{
570 bool ret = false;
571 size_t front_len;
572 size_t back_len;
573 size_t len;
574
575 /* Ignore null or empty strings. */
576 if (!s || (s[0] == '\0'))
577 return false;
578
579 front_len = front? strlen(front) : 0;
580 back_len = back? strlen(back) : 0;
581
582 len = strlen(s);
583
584 if (front_len) {
585 while (len && strncmp(s, front, front_len)==0) {
586 /* Must use memmove here as src & dest can
587 * easily overlap. Found by valgrind. JRA. */
588 memmove(s, s+front_len, (len-front_len)+1);
589 len -= front_len;
590 ret=true;
591 }
592 }
593
594 if (back_len) {
595 while ((len >= back_len) &&
596 strncmp(s+len-back_len,back,back_len)==0) {
597 s[len-back_len]='\0';
598 len -= back_len;
599 ret=true;
600 }
601 }
602 return ret;
603}
604
605/**
606 Does a string have any uppercase chars in it?
607**/
608
609bool strhasupper(const char *s)
610{
611 smb_ucs2_t *tmp, *p;
612 bool ret;
613
614 if (push_ucs2_allocate(&tmp, s) == -1) {
615 return false;
616 }
617
618 for(p = tmp; *p != 0; p++) {
619 if(isupper_w(*p)) {
620 break;
621 }
622 }
623
624 ret = (*p != 0);
625 SAFE_FREE(tmp);
626 return ret;
627}
628
629/**
630 Does a string have any lowercase chars in it?
631**/
632
633bool strhaslower(const char *s)
634{
635 smb_ucs2_t *tmp, *p;
636 bool ret;
637
638 if (push_ucs2_allocate(&tmp, s) == -1) {
639 return false;
640 }
641
642 for(p = tmp; *p != 0; p++) {
643 if(islower_w(*p)) {
644 break;
645 }
646 }
647
648 ret = (*p != 0);
649 SAFE_FREE(tmp);
650 return ret;
651}
652
653/**
654 Find the number of 'c' chars in a string
655**/
656
657size_t count_chars(const char *s,char c)
658{
659 smb_ucs2_t *ptr;
660 int count;
661 smb_ucs2_t *alloc_tmpbuf = NULL;
662
663 if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
664 return 0;
665 }
666
667 for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
668 if(*ptr==UCS2_CHAR(c))
669 count++;
670
671 SAFE_FREE(alloc_tmpbuf);
672 return(count);
673}
674
675/**
676 Safe string copy into a known length string. maxlength does not
677 include the terminating zero.
678**/
679
680char *safe_strcpy_fn(const char *fn,
681 int line,
682 char *dest,
683 const char *src,
684 size_t maxlength)
685{
686 size_t len;
687
688 if (!dest) {
689 DEBUG(0,("ERROR: NULL dest in safe_strcpy, "
690 "called from [%s][%d]\n", fn, line));
691 return NULL;
692 }
693
694#ifdef DEVELOPER
695 clobber_region(fn,line,dest, maxlength+1);
696#endif
697
698 if (!src) {
699 *dest = 0;
700 return dest;
701 }
702
703 len = strnlen(src, maxlength+1);
704
705 if (len > maxlength) {
706 DEBUG(0,("ERROR: string overflow by "
707 "%lu (%lu - %lu) in safe_strcpy [%.50s]\n",
708 (unsigned long)(len-maxlength), (unsigned long)len,
709 (unsigned long)maxlength, src));
710 len = maxlength;
711 }
712
713 memmove(dest, src, len);
714 dest[len] = 0;
715 return dest;
716}
717
718/**
719 Safe string cat into a string. maxlength does not
720 include the terminating zero.
721**/
722char *safe_strcat_fn(const char *fn,
723 int line,
724 char *dest,
725 const char *src,
726 size_t maxlength)
727{
728 size_t src_len, dest_len;
729
730 if (!dest) {
731 DEBUG(0,("ERROR: NULL dest in safe_strcat, "
732 "called from [%s][%d]\n", fn, line));
733 return NULL;
734 }
735
736 if (!src)
737 return dest;
738
739 src_len = strnlen(src, maxlength + 1);
740 dest_len = strnlen(dest, maxlength + 1);
741
742#ifdef DEVELOPER
743 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
744#endif
745
746 if (src_len + dest_len > maxlength) {
747 DEBUG(0,("ERROR: string overflow by %d "
748 "in safe_strcat [%.50s]\n",
749 (int)(src_len + dest_len - maxlength), src));
750 if (maxlength > dest_len) {
751 memcpy(&dest[dest_len], src, maxlength - dest_len);
752 }
753 dest[maxlength] = 0;
754 return NULL;
755 }
756
757 memcpy(&dest[dest_len], src, src_len);
758 dest[dest_len + src_len] = 0;
759 return dest;
760}
761
762/**
763 Paranoid strcpy into a buffer of given length (includes terminating
764 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
765 and replaces with '_'. Deliberately does *NOT* check for multibyte
766 characters. Don't change it !
767**/
768
769char *alpha_strcpy_fn(const char *fn,
770 int line,
771 char *dest,
772 const char *src,
773 const char *other_safe_chars,
774 size_t maxlength)
775{
776 size_t len, i;
777
778#ifdef DEVELOPER
779 clobber_region(fn, line, dest, maxlength);
780#endif
781
782 if (!dest) {
783 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, "
784 "called from [%s][%d]\n", fn, line));
785 return NULL;
786 }
787
788 if (!src) {
789 *dest = 0;
790 return dest;
791 }
792
793 len = strlen(src);
794 if (len >= maxlength)
795 len = maxlength - 1;
796
797 if (!other_safe_chars)
798 other_safe_chars = "";
799
800 for(i = 0; i < len; i++) {
801 int val = (src[i] & 0xff);
802 if (isupper_ascii(val) || islower_ascii(val) ||
803 isdigit(val) || strchr_m(other_safe_chars, val))
804 dest[i] = src[i];
805 else
806 dest[i] = '_';
807 }
808
809 dest[i] = '\0';
810
811 return dest;
812}
813
814/**
815 Like strncpy but always null terminates. Make sure there is room!
816 The variable n should always be one less than the available size.
817**/
818char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
819{
820 char *d = dest;
821
822#ifdef DEVELOPER
823 clobber_region(fn, line, dest, n+1);
824#endif
825
826 if (!dest) {
827 DEBUG(0,("ERROR: NULL dest in StrnCpy, "
828 "called from [%s][%d]\n", fn, line));
829 return(NULL);
830 }
831
832 if (!src) {
833 *dest = 0;
834 return(dest);
835 }
836
837 while (n-- && (*d = *src)) {
838 d++;
839 src++;
840 }
841
842 *d = 0;
843 return(dest);
844}
845
846#if 0
847/**
848 Like strncpy but copies up to the character marker. always null terminates.
849 returns a pointer to the character marker in the source string (src).
850**/
851
852static char *strncpyn(char *dest, const char *src, size_t n, char c)
853{
854 char *p;
855 size_t str_len;
856
857#ifdef DEVELOPER
858 clobber_region(dest, n+1);
859#endif
860 p = strchr_m(src, c);
861 if (p == NULL) {
862 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
863 return NULL;
864 }
865
866 str_len = PTR_DIFF(p, src);
867 strncpy(dest, src, MIN(n, str_len));
868 dest[str_len] = '\0';
869
870 return p;
871}
872#endif
873
874/**
875 Routine to get hex characters and turn them into a 16 byte array.
876 the array can be variable length, and any non-hex-numeric
877 characters are skipped. "0xnn" or "0Xnn" is specially catered
878 for.
879
880 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
881
882**/
883
884size_t strhex_to_str(char *buf, size_t buf_len, const char *strhex, size_t strhex_len)
885{
886 size_t i;
887 size_t num_chars = 0;
888 unsigned char lonybble, hinybble;
889 const char *hexchars = "0123456789ABCDEF";
890 char *p1 = NULL, *p2 = NULL;
891
892 for (i = 0; i < strhex_len && strhex[i] != 0; i++) {
893 if (strnequal(hexchars, "0x", 2)) {
894 i++; /* skip two chars */
895 continue;
896 }
897
898 if (!(p1 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
899 break;
900
901 i++; /* next hex digit */
902
903 if (!(p2 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
904 break;
905
906 /* get the two nybbles */
907 hinybble = PTR_DIFF(p1, hexchars);
908 lonybble = PTR_DIFF(p2, hexchars);
909
910 if (num_chars >= buf_len) {
911 break;
912 }
913 buf[num_chars] = (hinybble << 4) | lonybble;
914 num_chars++;
915
916 p1 = NULL;
917 p2 = NULL;
918 }
919 return num_chars;
920}
921
922DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex)
923{
924 DATA_BLOB ret_blob;
925
926 if (mem_ctx != NULL)
927 ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
928 else
929 ret_blob = data_blob(NULL, strlen(strhex)/2+1);
930
931 ret_blob.length = strhex_to_str((char*)ret_blob.data,
932 ret_blob.length,
933 strhex,
934 strlen(strhex));
935
936 return ret_blob;
937}
938
939/**
940 * Routine to print a buffer as HEX digits, into an allocated string.
941 */
942
943char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
944{
945 int i;
946 char *hex_buffer;
947
948 hex_buffer = TALLOC_ARRAY(mem_ctx, char, (len*2)+1);
949
950 for (i = 0; i < len; i++)
951 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
952
953 return hex_buffer;
954}
955
956/**
957 Check if a string is part of a list.
958**/
959
960bool in_list(const char *s, const char *list, bool casesensitive)
961{
962 char *tok = NULL;
963 bool ret = false;
964 TALLOC_CTX *frame;
965
966 if (!list) {
967 return false;
968 }
969
970 frame = talloc_stackframe();
971 while (next_token_talloc(frame, &list, &tok,LIST_SEP)) {
972 if (casesensitive) {
973 if (strcmp(tok,s) == 0) {
974 ret = true;
975 break;
976 }
977 } else {
978 if (StrCaseCmp(tok,s) == 0) {
979 ret = true;
980 break;
981 }
982 }
983 }
984 TALLOC_FREE(frame);
985 return ret;
986}
987
988/* this is used to prevent lots of mallocs of size 1 */
989static const char null_string[] = "";
990
991/**
992 Set a string value, allocing the space for the string
993**/
994
995static bool string_init(char **dest,const char *src)
996{
997 size_t l;
998
999 if (!src)
1000 src = "";
1001
1002 l = strlen(src);
1003
1004 if (l == 0) {
1005 *dest = CONST_DISCARD(char*, null_string);
1006 } else {
1007 (*dest) = SMB_STRDUP(src);
1008 if ((*dest) == NULL) {
1009 DEBUG(0,("Out of memory in string_init\n"));
1010 return false;
1011 }
1012 }
1013 return(true);
1014}
1015
1016/**
1017 Free a string value.
1018**/
1019
1020void string_free(char **s)
1021{
1022 if (!s || !(*s))
1023 return;
1024 if (*s == null_string)
1025 *s = NULL;
1026 SAFE_FREE(*s);
1027}
1028
1029/**
1030 Set a string value, deallocating any existing space, and allocing the space
1031 for the string
1032**/
1033
1034bool string_set(char **dest,const char *src)
1035{
1036 string_free(dest);
1037 return(string_init(dest,src));
1038}
1039
1040/**
1041 Substitute a string for a pattern in another string. Make sure there is
1042 enough room!
1043
1044 This routine looks for pattern in s and replaces it with
1045 insert. It may do multiple replacements or just one.
1046
1047 Any of " ; ' $ or ` in the insert string are replaced with _
1048 if len==0 then the string cannot be extended. This is different from the old
1049 use of len==0 which was for no length checks to be done.
1050**/
1051
1052void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
1053 bool remove_unsafe_characters, bool replace_once,
1054 bool allow_trailing_dollar)
1055{
1056 char *p;
1057 ssize_t ls,lp,li, i;
1058
1059 if (!insert || !pattern || !*pattern || !s)
1060 return;
1061
1062 ls = (ssize_t)strlen(s);
1063 lp = (ssize_t)strlen(pattern);
1064 li = (ssize_t)strlen(insert);
1065
1066 if (len == 0)
1067 len = ls + 1; /* len is number of *bytes* */
1068
1069 while (lp <= ls && (p = strstr_m(s,pattern))) {
1070 if (ls + (li-lp) >= len) {
1071 DEBUG(0,("ERROR: string overflow by "
1072 "%d in string_sub(%.50s, %d)\n",
1073 (int)(ls + (li-lp) - len),
1074 pattern, (int)len));
1075 break;
1076 }
1077 if (li != lp) {
1078 memmove(p+li,p+lp,strlen(p+lp)+1);
1079 }
1080 for (i=0;i<li;i++) {
1081 switch (insert[i]) {
1082 case '`':
1083 case '"':
1084 case '\'':
1085 case ';':
1086 case '$':
1087 /* allow a trailing $
1088 * (as in machine accounts) */
1089 if (allow_trailing_dollar && (i == li - 1 )) {
1090 p[i] = insert[i];
1091 break;
1092 }
1093 case '%':
1094 case '\r':
1095 case '\n':
1096 if ( remove_unsafe_characters ) {
1097 p[i] = '_';
1098 /* yes this break should be here
1099 * since we want to fall throw if
1100 * not replacing unsafe chars */
1101 break;
1102 }
1103 default:
1104 p[i] = insert[i];
1105 }
1106 }
1107 s = p + li;
1108 ls += (li-lp);
1109
1110 if (replace_once)
1111 break;
1112 }
1113}
1114
1115void string_sub_once(char *s, const char *pattern,
1116 const char *insert, size_t len)
1117{
1118 string_sub2( s, pattern, insert, len, true, true, false );
1119}
1120
1121void string_sub(char *s,const char *pattern, const char *insert, size_t len)
1122{
1123 string_sub2( s, pattern, insert, len, true, false, false );
1124}
1125
1126void fstring_sub(char *s,const char *pattern,const char *insert)
1127{
1128 string_sub(s, pattern, insert, sizeof(fstring));
1129}
1130
1131/**
1132 Similar to string_sub2, but it will accept only allocated strings
1133 and may realloc them so pay attention at what you pass on no
1134 pointers inside strings, no const may be passed
1135 as string.
1136**/
1137
1138char *realloc_string_sub2(char *string,
1139 const char *pattern,
1140 const char *insert,
1141 bool remove_unsafe_characters,
1142 bool allow_trailing_dollar)
1143{
1144 char *p, *in;
1145 char *s;
1146 ssize_t ls,lp,li,ld, i;
1147
1148 if (!insert || !pattern || !*pattern || !string || !*string)
1149 return NULL;
1150
1151 s = string;
1152
1153 in = SMB_STRDUP(insert);
1154 if (!in) {
1155 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1156 return NULL;
1157 }
1158 ls = (ssize_t)strlen(s);
1159 lp = (ssize_t)strlen(pattern);
1160 li = (ssize_t)strlen(insert);
1161 ld = li - lp;
1162 for (i=0;i<li;i++) {
1163 switch (in[i]) {
1164 case '`':
1165 case '"':
1166 case '\'':
1167 case ';':
1168 case '$':
1169 /* allow a trailing $
1170 * (as in machine accounts) */
1171 if (allow_trailing_dollar && (i == li - 1 )) {
1172 break;
1173 }
1174 case '%':
1175 case '\r':
1176 case '\n':
1177 if ( remove_unsafe_characters ) {
1178 in[i] = '_';
1179 break;
1180 }
1181 default:
1182 /* ok */
1183 break;
1184 }
1185 }
1186
1187 while ((p = strstr_m(s,pattern))) {
1188 if (ld > 0) {
1189 int offset = PTR_DIFF(s,string);
1190 string = (char *)SMB_REALLOC(string, ls + ld + 1);
1191 if (!string) {
1192 DEBUG(0, ("realloc_string_sub: "
1193 "out of memory!\n"));
1194 SAFE_FREE(in);
1195 return NULL;
1196 }
1197 p = string + offset + (p - s);
1198 }
1199 if (li != lp) {
1200 memmove(p+li,p+lp,strlen(p+lp)+1);
1201 }
1202 memcpy(p, in, li);
1203 s = p + li;
1204 ls += ld;
1205 }
1206 SAFE_FREE(in);
1207 return string;
1208}
1209
1210char *realloc_string_sub(char *string,
1211 const char *pattern,
1212 const char *insert)
1213{
1214 return realloc_string_sub2(string, pattern, insert, true, false);
1215}
1216
1217/*
1218 * Internal guts of talloc_string_sub and talloc_all_string_sub.
1219 * talloc version of string_sub2.
1220 */
1221
1222char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
1223 const char *pattern,
1224 const char *insert,
1225 bool remove_unsafe_characters,
1226 bool replace_once,
1227 bool allow_trailing_dollar)
1228{
1229 char *p, *in;
1230 char *s;
1231 char *string;
1232 ssize_t ls,lp,li,ld, i;
1233
1234 if (!insert || !pattern || !*pattern || !src) {
1235 return NULL;
1236 }
1237
1238 string = talloc_strdup(mem_ctx, src);
1239 if (string == NULL) {
1240 DEBUG(0, ("talloc_string_sub2: "
1241 "talloc_strdup failed\n"));
1242 return NULL;
1243 }
1244
1245 s = string;
1246
1247 in = SMB_STRDUP(insert);
1248 if (!in) {
1249 DEBUG(0, ("talloc_string_sub2: ENOMEM\n"));
1250 return NULL;
1251 }
1252 ls = (ssize_t)strlen(s);
1253 lp = (ssize_t)strlen(pattern);
1254 li = (ssize_t)strlen(insert);
1255 ld = li - lp;
1256
1257 for (i=0;i<li;i++) {
1258 switch (in[i]) {
1259 case '`':
1260 case '"':
1261 case '\'':
1262 case ';':
1263 case '$':
1264 /* allow a trailing $
1265 * (as in machine accounts) */
1266 if (allow_trailing_dollar && (i == li - 1 )) {
1267 break;
1268 }
1269 case '%':
1270 case '\r':
1271 case '\n':
1272 if (remove_unsafe_characters) {
1273 in[i] = '_';
1274 break;
1275 }
1276 default:
1277 /* ok */
1278 break;
1279 }
1280 }
1281
1282 while ((p = strstr_m(s,pattern))) {
1283 if (ld > 0) {
1284 int offset = PTR_DIFF(s,string);
1285 string = (char *)TALLOC_REALLOC(mem_ctx, string,
1286 ls + ld + 1);
1287 if (!string) {
1288 DEBUG(0, ("talloc_string_sub: out of "
1289 "memory!\n"));
1290 SAFE_FREE(in);
1291 return NULL;
1292 }
1293 p = string + offset + (p - s);
1294 }
1295 if (li != lp) {
1296 memmove(p+li,p+lp,strlen(p+lp)+1);
1297 }
1298 memcpy(p, in, li);
1299 s = p + li;
1300 ls += ld;
1301
1302 if (replace_once) {
1303 break;
1304 }
1305 }
1306 SAFE_FREE(in);
1307 return string;
1308}
1309
1310/* Same as string_sub, but returns a talloc'ed string */
1311
1312char *talloc_string_sub(TALLOC_CTX *mem_ctx,
1313 const char *src,
1314 const char *pattern,
1315 const char *insert)
1316{
1317 return talloc_string_sub2(mem_ctx, src, pattern, insert,
1318 true, false, false);
1319}
1320
1321/**
1322 Similar to string_sub() but allows for any character to be substituted.
1323 Use with caution!
1324 if len==0 then the string cannot be extended. This is different from the old
1325 use of len==0 which was for no length checks to be done.
1326**/
1327
1328void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1329{
1330 char *p;
1331 ssize_t ls,lp,li;
1332
1333 if (!insert || !pattern || !s)
1334 return;
1335
1336 ls = (ssize_t)strlen(s);
1337 lp = (ssize_t)strlen(pattern);
1338 li = (ssize_t)strlen(insert);
1339
1340 if (!*pattern)
1341 return;
1342
1343 if (len == 0)
1344 len = ls + 1; /* len is number of *bytes* */
1345
1346 while (lp <= ls && (p = strstr_m(s,pattern))) {
1347 if (ls + (li-lp) >= len) {
1348 DEBUG(0,("ERROR: string overflow by "
1349 "%d in all_string_sub(%.50s, %d)\n",
1350 (int)(ls + (li-lp) - len),
1351 pattern, (int)len));
1352 break;
1353 }
1354 if (li != lp) {
1355 memmove(p+li,p+lp,strlen(p+lp)+1);
1356 }
1357 memcpy(p, insert, li);
1358 s = p + li;
1359 ls += (li-lp);
1360 }
1361}
1362
1363char *talloc_all_string_sub(TALLOC_CTX *ctx,
1364 const char *src,
1365 const char *pattern,
1366 const char *insert)
1367{
1368 return talloc_string_sub2(ctx, src, pattern, insert,
1369 false, false, false);
1370}
1371
1372/**
1373 Write an octal as a string.
1374**/
1375
1376char *octal_string(int i)
1377{
1378 char *result;
1379 if (i == -1) {
1380 result = talloc_strdup(talloc_tos(), "-1");
1381 }
1382 else {
1383 result = talloc_asprintf(talloc_tos(), "0%o", i);
1384 }
1385 SMB_ASSERT(result != NULL);
1386 return result;
1387}
1388
1389
1390/**
1391 Truncate a string at a specified length.
1392**/
1393
1394char *string_truncate(char *s, unsigned int length)
1395{
1396 if (s && strlen(s) > length)
1397 s[length] = 0;
1398 return s;
1399}
1400
1401/**
1402 Strchr and strrchr_m are very hard to do on general multi-byte strings.
1403 We convert via ucs2 for now.
1404**/
1405
1406char *strchr_m(const char *src, char c)
1407{
1408 smb_ucs2_t *ws = NULL;
1409 char *s2 = NULL;
1410 smb_ucs2_t *p;
1411 const char *s;
1412 char *ret;
1413
1414 /* characters below 0x3F are guaranteed to not appear in
1415 non-initial position in multi-byte charsets */
1416 if ((c & 0xC0) == 0) {
1417 return strchr(src, c);
1418 }
1419
1420 /* this is quite a common operation, so we want it to be
1421 fast. We optimise for the ascii case, knowing that all our
1422 supported multi-byte character sets are ascii-compatible
1423 (ie. they match for the first 128 chars) */
1424
1425 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1426 if (*s == c)
1427 return (char *)s;
1428 }
1429
1430 if (!*s)
1431 return NULL;
1432
1433#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1434 /* With compose characters we must restart from the beginning. JRA. */
1435 s = src;
1436#endif
1437
1438 if (push_ucs2_allocate(&ws, s)==(size_t)-1) {
1439 /* Wrong answer, but what can we do... */
1440 return strchr(src, c);
1441 }
1442 p = strchr_w(ws, UCS2_CHAR(c));
1443 if (!p) {
1444 SAFE_FREE(ws);
1445 return NULL;
1446 }
1447 *p = 0;
1448 if (pull_ucs2_allocate(&s2, ws)==(size_t)-1) {
1449 SAFE_FREE(ws);
1450 /* Wrong answer, but what can we do... */
1451 return strchr(src, c);
1452 }
1453 ret = (char *)(s+strlen(s2));
1454 SAFE_FREE(ws);
1455 SAFE_FREE(s2);
1456 return ret;
1457}
1458
1459char *strrchr_m(const char *s, char c)
1460{
1461 /* characters below 0x3F are guaranteed to not appear in
1462 non-initial position in multi-byte charsets */
1463 if ((c & 0xC0) == 0) {
1464 return strrchr(s, c);
1465 }
1466
1467 /* this is quite a common operation, so we want it to be
1468 fast. We optimise for the ascii case, knowing that all our
1469 supported multi-byte character sets are ascii-compatible
1470 (ie. they match for the first 128 chars). Also, in Samba
1471 we only search for ascii characters in 'c' and that
1472 in all mb character sets with a compound character
1473 containing c, if 'c' is not a match at position
1474 p, then p[-1] > 0x7f. JRA. */
1475
1476 {
1477 size_t len = strlen(s);
1478 const char *cp = s;
1479 bool got_mb = false;
1480
1481 if (len == 0)
1482 return NULL;
1483 cp += (len - 1);
1484 do {
1485 if (c == *cp) {
1486 /* Could be a match. Part of a multibyte ? */
1487 if ((cp > s) &&
1488 (((unsigned char)cp[-1]) & 0x80)) {
1489 /* Yep - go slow :-( */
1490 got_mb = true;
1491 break;
1492 }
1493 /* No - we have a match ! */
1494 return (char *)cp;
1495 }
1496 } while (cp-- != s);
1497 if (!got_mb)
1498 return NULL;
1499 }
1500
1501 /* String contained a non-ascii char. Slow path. */
1502 {
1503 smb_ucs2_t *ws = NULL;
1504 char *s2 = NULL;
1505 smb_ucs2_t *p;
1506 char *ret;
1507
1508 if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
1509 /* Wrong answer, but what can we do. */
1510 return strrchr(s, c);
1511 }
1512 p = strrchr_w(ws, UCS2_CHAR(c));
1513 if (!p) {
1514 SAFE_FREE(ws);
1515 return NULL;
1516 }
1517 *p = 0;
1518 if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
1519 SAFE_FREE(ws);
1520 /* Wrong answer, but what can we do. */
1521 return strrchr(s, c);
1522 }
1523 ret = (char *)(s+strlen(s2));
1524 SAFE_FREE(ws);
1525 SAFE_FREE(s2);
1526 return ret;
1527 }
1528}
1529
1530/***********************************************************************
1531 Return the equivalent of doing strrchr 'n' times - always going
1532 backwards.
1533***********************************************************************/
1534
1535char *strnrchr_m(const char *s, char c, unsigned int n)
1536{
1537 smb_ucs2_t *ws = NULL;
1538 char *s2 = NULL;
1539 smb_ucs2_t *p;
1540 char *ret;
1541
1542 if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
1543 /* Too hard to try and get right. */
1544 return NULL;
1545 }
1546 p = strnrchr_w(ws, UCS2_CHAR(c), n);
1547 if (!p) {
1548 SAFE_FREE(ws);
1549 return NULL;
1550 }
1551 *p = 0;
1552 if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
1553 SAFE_FREE(ws);
1554 /* Too hard to try and get right. */
1555 return NULL;
1556 }
1557 ret = (char *)(s+strlen(s2));
1558 SAFE_FREE(ws);
1559 SAFE_FREE(s2);
1560 return ret;
1561}
1562
1563/***********************************************************************
1564 strstr_m - We convert via ucs2 for now.
1565***********************************************************************/
1566
1567char *strstr_m(const char *src, const char *findstr)
1568{
1569 smb_ucs2_t *p;
1570 smb_ucs2_t *src_w, *find_w;
1571 const char *s;
1572 char *s2;
1573 char *retp;
1574
1575 size_t findstr_len = 0;
1576
1577 /* for correctness */
1578 if (!findstr[0]) {
1579 return (char*)src;
1580 }
1581
1582 /* Samba does single character findstr calls a *lot*. */
1583 if (findstr[1] == '\0')
1584 return strchr_m(src, *findstr);
1585
1586 /* We optimise for the ascii case, knowing that all our
1587 supported multi-byte character sets are ascii-compatible
1588 (ie. they match for the first 128 chars) */
1589
1590 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1591 if (*s == *findstr) {
1592 if (!findstr_len)
1593 findstr_len = strlen(findstr);
1594
1595 if (strncmp(s, findstr, findstr_len) == 0) {
1596 return (char *)s;
1597 }
1598 }
1599 }
1600
1601 if (!*s)
1602 return NULL;
1603
1604#if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1605 /* 'make check' fails unless we do this */
1606
1607 /* With compose characters we must restart from the beginning. JRA. */
1608 s = src;
1609#endif
1610
1611 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1612 DEBUG(0,("strstr_m: src malloc fail\n"));
1613 return NULL;
1614 }
1615
1616 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1617 SAFE_FREE(src_w);
1618 DEBUG(0,("strstr_m: find malloc fail\n"));
1619 return NULL;
1620 }
1621
1622 p = strstr_w(src_w, find_w);
1623
1624 if (!p) {
1625 SAFE_FREE(src_w);
1626 SAFE_FREE(find_w);
1627 return NULL;
1628 }
1629
1630 *p = 0;
1631 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1632 SAFE_FREE(src_w);
1633 SAFE_FREE(find_w);
1634 DEBUG(0,("strstr_m: dest malloc fail\n"));
1635 return NULL;
1636 }
1637 retp = (char *)(s+strlen(s2));
1638 SAFE_FREE(src_w);
1639 SAFE_FREE(find_w);
1640 SAFE_FREE(s2);
1641 return retp;
1642}
1643
1644/**
1645 Convert a string to lower case.
1646**/
1647
1648void strlower_m(char *s)
1649{
1650 size_t len;
1651 int errno_save;
1652
1653 /* this is quite a common operation, so we want it to be
1654 fast. We optimise for the ascii case, knowing that all our
1655 supported multi-byte character sets are ascii-compatible
1656 (ie. they match for the first 128 chars) */
1657
1658 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1659 *s = tolower_ascii((unsigned char)*s);
1660 s++;
1661 }
1662
1663 if (!*s)
1664 return;
1665
1666 /* I assume that lowercased string takes the same number of bytes
1667 * as source string even in UTF-8 encoding. (VIV) */
1668 len = strlen(s) + 1;
1669 errno_save = errno;
1670 errno = 0;
1671 unix_strlower(s,len,s,len);
1672 /* Catch mb conversion errors that may not terminate. */
1673 if (errno)
1674 s[len-1] = '\0';
1675 errno = errno_save;
1676}
1677
1678/**
1679 Convert a string to upper case.
1680**/
1681
1682void strupper_m(char *s)
1683{
1684 size_t len;
1685 int errno_save;
1686
1687 /* this is quite a common operation, so we want it to be
1688 fast. We optimise for the ascii case, knowing that all our
1689 supported multi-byte character sets are ascii-compatible
1690 (ie. they match for the first 128 chars) */
1691
1692 while (*s && !(((unsigned char)s[0]) & 0x80)) {
1693 *s = toupper_ascii_fast((unsigned char)*s);
1694 s++;
1695 }
1696
1697 if (!*s)
1698 return;
1699
1700 /* I assume that lowercased string takes the same number of bytes
1701 * as source string even in multibyte encoding. (VIV) */
1702 len = strlen(s) + 1;
1703 errno_save = errno;
1704 errno = 0;
1705 unix_strupper(s,len,s,len);
1706 /* Catch mb conversion errors that may not terminate. */
1707 if (errno)
1708 s[len-1] = '\0';
1709 errno = errno_save;
1710}
1711
1712/**
1713 Count the number of UCS2 characters in a string. Normally this will
1714 be the same as the number of bytes in a string for single byte strings,
1715 but will be different for multibyte.
1716**/
1717
1718size_t strlen_m(const char *s)
1719{
1720 size_t count = 0;
1721
1722 if (!s) {
1723 return 0;
1724 }
1725
1726 while (*s && !(((uint8_t)*s) & 0x80)) {
1727 s++;
1728 count++;
1729 }
1730
1731 if (!*s) {
1732 return count;
1733 }
1734
1735 while (*s) {
1736 size_t c_size;
1737 codepoint_t c = next_codepoint(s, &c_size);
1738 if (c < 0x10000) {
1739 /* Unicode char fits into 16 bits. */
1740 count += 1;
1741 } else {
1742 /* Double-width unicode char - 32 bits. */
1743 count += 2;
1744 }
1745 s += c_size;
1746 }
1747
1748 return count;
1749}
1750
1751/**
1752 Count the number of UCS2 characters in a string including the null
1753 terminator.
1754**/
1755
1756size_t strlen_m_term(const char *s)
1757{
1758 if (!s) {
1759 return 0;
1760 }
1761 return strlen_m(s) + 1;
1762}
1763
1764/*
1765 * Weird helper routine for the winreg pipe: If nothing is around, return 0,
1766 * if a string is there, include the terminator.
1767 */
1768
1769size_t strlen_m_term_null(const char *s)
1770{
1771 size_t len;
1772 if (!s) {
1773 return 0;
1774 }
1775 len = strlen_m(s);
1776 if (len == 0) {
1777 return 0;
1778 }
1779
1780 return len+1;
1781}
1782/**
1783 Return a RFC2254 binary string representation of a buffer.
1784 Used in LDAP filters.
1785 Caller must free.
1786**/
1787
1788char *binary_string_rfc2254(char *buf, int len)
1789{
1790 char *s;
1791 int i, j;
1792 const char *hex = "0123456789ABCDEF";
1793 s = (char *)SMB_MALLOC(len * 3 + 1);
1794 if (!s)
1795 return NULL;
1796 for (j=i=0;i<len;i++) {
1797 s[j] = '\\';
1798 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1799 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1800 j += 3;
1801 }
1802 s[j] = 0;
1803 return s;
1804}
1805
1806char *binary_string(char *buf, int len)
1807{
1808 char *s;
1809 int i, j;
1810 const char *hex = "0123456789ABCDEF";
1811 s = (char *)SMB_MALLOC(len * 2 + 1);
1812 if (!s)
1813 return NULL;
1814 for (j=i=0;i<len;i++) {
1815 s[j] = hex[((unsigned char)buf[i]) >> 4];
1816 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1817 j += 2;
1818 }
1819 s[j] = 0;
1820 return s;
1821}
1822
1823/**
1824 Just a typesafety wrapper for snprintf into a fstring.
1825**/
1826
1827int fstr_sprintf(fstring s, const char *fmt, ...)
1828{
1829 va_list ap;
1830 int ret;
1831
1832 va_start(ap, fmt);
1833 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1834 va_end(ap);
1835 return ret;
1836}
1837
1838/**
1839 List of Strings manipulation functions
1840**/
1841
1842#define S_LIST_ABS 16 /* List Allocation Block Size */
1843
1844char **str_list_make(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1845{
1846 char **list;
1847 const char *str;
1848 char *s;
1849 int num, lsize;
1850 char *tok;
1851
1852 if (!string || !*string)
1853 return NULL;
1854
1855 list = TALLOC_ARRAY(mem_ctx, char *, S_LIST_ABS+1);
1856 if (list == NULL) {
1857 return NULL;
1858 }
1859 lsize = S_LIST_ABS;
1860
1861 s = talloc_strdup(list, string);
1862 if (s == NULL) {
1863 DEBUG(0,("str_list_make: Unable to allocate memory"));
1864 TALLOC_FREE(list);
1865 return NULL;
1866 }
1867 if (!sep) sep = LIST_SEP;
1868
1869 num = 0;
1870 str = s;
1871
1872 while (next_token_talloc(list, &str, &tok, sep)) {
1873
1874 if (num == lsize) {
1875 char **tmp;
1876
1877 lsize += S_LIST_ABS;
1878
1879 tmp = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *,
1880 lsize + 1);
1881 if (tmp == NULL) {
1882 DEBUG(0,("str_list_make: "
1883 "Unable to allocate memory"));
1884 TALLOC_FREE(list);
1885 return NULL;
1886 }
1887
1888 list = tmp;
1889
1890 memset (&list[num], 0,
1891 ((sizeof(char**)) * (S_LIST_ABS +1)));
1892 }
1893
1894 list[num] = tok;
1895 num += 1;
1896 }
1897
1898 list[num] = NULL;
1899
1900 TALLOC_FREE(s);
1901 return list;
1902}
1903
1904bool str_list_copy(TALLOC_CTX *mem_ctx, char ***dest, const char **src)
1905{
1906 char **list;
1907 int i, num;
1908
1909 *dest = NULL;
1910 if (!src)
1911 return false;
1912
1913 num = 0;
1914 while (src[num] != NULL) {
1915 num += 1;
1916 }
1917
1918 list = TALLOC_ARRAY(mem_ctx, char *, num+1);
1919 if (list == NULL) {
1920 return false;
1921 }
1922
1923 for (i=0; i<num; i++) {
1924 list[i] = talloc_strdup(list, src[i]);
1925 if (list[i] == NULL) {
1926 TALLOC_FREE(list);
1927 return false;
1928 }
1929 }
1930 list[i] = NULL;
1931 *dest = list;
1932 return true;
1933}
1934
1935/**
1936 * Return true if all the elements of the list match exactly.
1937 **/
1938bool str_list_compare(char **list1, char **list2)
1939{
1940 int num;
1941
1942 if (!list1 || !list2)
1943 return (list1 == list2);
1944
1945 for (num = 0; list1[num]; num++) {
1946 if (!list2[num])
1947 return false;
1948 if (!strcsequal(list1[num], list2[num]))
1949 return false;
1950 }
1951 if (list2[num])
1952 return false; /* if list2 has more elements than list1 fail */
1953
1954 return true;
1955}
1956
1957/******************************************************************************
1958 *****************************************************************************/
1959
1960int str_list_count( const char **list )
1961{
1962 int i = 0;
1963
1964 if ( ! list )
1965 return 0;
1966
1967 /* count the number of list members */
1968
1969 for ( i=0; *list; i++, list++ );
1970
1971 return i;
1972}
1973
1974/******************************************************************************
1975 version of standard_sub_basic() for string lists; uses talloc_sub_basic()
1976 for the work
1977 *****************************************************************************/
1978
1979bool str_list_sub_basic( char **list, const char *smb_name,
1980 const char *domain_name )
1981{
1982 TALLOC_CTX *ctx = list;
1983 char *s, *tmpstr;
1984
1985 while ( *list ) {
1986 s = *list;
1987 tmpstr = talloc_sub_basic(ctx, smb_name, domain_name, s);
1988 if ( !tmpstr ) {
1989 DEBUG(0,("str_list_sub_basic: "
1990 "alloc_sub_basic() return NULL!\n"));
1991 return false;
1992 }
1993
1994 TALLOC_FREE(*list);
1995 *list = tmpstr;
1996
1997 list++;
1998 }
1999
2000 return true;
2001}
2002
2003/******************************************************************************
2004 substritute a specific pattern in a string list
2005 *****************************************************************************/
2006
2007bool str_list_substitute(char **list, const char *pattern, const char *insert)
2008{
2009 TALLOC_CTX *ctx = list;
2010 char *p, *s, *t;
2011 ssize_t ls, lp, li, ld, i, d;
2012
2013 if (!list)
2014 return false;
2015 if (!pattern)
2016 return false;
2017 if (!insert)
2018 return false;
2019
2020 lp = (ssize_t)strlen(pattern);
2021 li = (ssize_t)strlen(insert);
2022 ld = li -lp;
2023
2024 while (*list) {
2025 s = *list;
2026 ls = (ssize_t)strlen(s);
2027
2028 while ((p = strstr_m(s, pattern))) {
2029 t = *list;
2030 d = p -t;
2031 if (ld) {
2032 t = TALLOC_ARRAY(ctx, char, ls +ld +1);
2033 if (!t) {
2034 DEBUG(0,("str_list_substitute: "
2035 "Unable to allocate memory"));
2036 return false;
2037 }
2038 memcpy(t, *list, d);
2039 memcpy(t +d +li, p +lp, ls -d -lp +1);
2040 TALLOC_FREE(*list);
2041 *list = t;
2042 ls += ld;
2043 s = t +d +li;
2044 }
2045
2046 for (i = 0; i < li; i++) {
2047 switch (insert[i]) {
2048 case '`':
2049 case '"':
2050 case '\'':
2051 case ';':
2052 case '$':
2053 case '%':
2054 case '\r':
2055 case '\n':
2056 t[d +i] = '_';
2057 break;
2058 default:
2059 t[d +i] = insert[i];
2060 }
2061 }
2062 }
2063
2064 list++;
2065 }
2066
2067 return true;
2068}
2069
2070
2071#define IPSTR_LIST_SEP ","
2072#define IPSTR_LIST_CHAR ','
2073
2074/**
2075 * Add ip string representation to ipstr list. Used also
2076 * as part of @function ipstr_list_make
2077 *
2078 * @param ipstr_list pointer to string containing ip list;
2079 * MUST BE already allocated and IS reallocated if necessary
2080 * @param ipstr_size pointer to current size of ipstr_list (might be changed
2081 * as a result of reallocation)
2082 * @param ip IP address which is to be added to list
2083 * @return pointer to string appended with new ip and possibly
2084 * reallocated to new length
2085 **/
2086
2087static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
2088{
2089 char *new_ipstr = NULL;
2090 char addr_buf[INET6_ADDRSTRLEN];
2091 int ret;
2092
2093 /* arguments checking */
2094 if (!ipstr_list || !service) {
2095 return NULL;
2096 }
2097
2098 print_sockaddr(addr_buf,
2099 sizeof(addr_buf),
2100 &service->ss);
2101
2102 /* attempt to convert ip to a string and append colon separator to it */
2103 if (*ipstr_list) {
2104 if (service->ss.ss_family == AF_INET) {
2105 /* IPv4 */
2106 ret = asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list,
2107 IPSTR_LIST_SEP, addr_buf,
2108 service->port);
2109 } else {
2110 /* IPv6 */
2111 ret = asprintf(&new_ipstr, "%s%s[%s]:%d", *ipstr_list,
2112 IPSTR_LIST_SEP, addr_buf,
2113 service->port);
2114 }
2115 SAFE_FREE(*ipstr_list);
2116 } else {
2117 if (service->ss.ss_family == AF_INET) {
2118 /* IPv4 */
2119 ret = asprintf(&new_ipstr, "%s:%d", addr_buf,
2120 service->port);
2121 } else {
2122 /* IPv6 */
2123 ret = asprintf(&new_ipstr, "[%s]:%d", addr_buf,
2124 service->port);
2125 }
2126 }
2127 if (ret == -1) {
2128 return NULL;
2129 }
2130 *ipstr_list = new_ipstr;
2131 return *ipstr_list;
2132}
2133
2134/**
2135 * Allocate and initialise an ipstr list using ip adresses
2136 * passed as arguments.
2137 *
2138 * @param ipstr_list pointer to string meant to be allocated and set
2139 * @param ip_list array of ip addresses to place in the list
2140 * @param ip_count number of addresses stored in ip_list
2141 * @return pointer to allocated ip string
2142 **/
2143
2144char *ipstr_list_make(char **ipstr_list,
2145 const struct ip_service *ip_list,
2146 int ip_count)
2147{
2148 int i;
2149
2150 /* arguments checking */
2151 if (!ip_list || !ipstr_list) {
2152 return 0;
2153 }
2154
2155 *ipstr_list = NULL;
2156
2157 /* process ip addresses given as arguments */
2158 for (i = 0; i < ip_count; i++) {
2159 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2160 }
2161
2162 return (*ipstr_list);
2163}
2164
2165
2166/**
2167 * Parse given ip string list into array of ip addresses
2168 * (as ip_service structures)
2169 * e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
2170 *
2171 * @param ipstr ip string list to be parsed
2172 * @param ip_list pointer to array of ip addresses which is
2173 * allocated by this function and must be freed by caller
2174 * @return number of successfully parsed addresses
2175 **/
2176
2177int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
2178{
2179 TALLOC_CTX *frame;
2180 char *token_str = NULL;
2181 size_t count;
2182 int i;
2183
2184 if (!ipstr_list || !ip_list)
2185 return 0;
2186
2187 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2188 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2189 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n",
2190 (unsigned long)count));
2191 return 0;
2192 }
2193
2194 frame = talloc_stackframe();
2195 for ( i=0; next_token_talloc(frame, &ipstr_list, &token_str,
2196 IPSTR_LIST_SEP) && i<count; i++ ) {
2197 char *s = token_str;
2198 char *p = strrchr(token_str, ':');
2199
2200 if (p) {
2201 *p = 0;
2202 (*ip_list)[i].port = atoi(p+1);
2203 }
2204
2205 /* convert single token to ip address */
2206 if (token_str[0] == '[') {
2207 /* IPv6 address. */
2208 s++;
2209 p = strchr(token_str, ']');
2210 if (!p) {
2211 continue;
2212 }
2213 *p = '\0';
2214 }
2215 if (!interpret_string_addr(&(*ip_list)[i].ss,
2216 s,
2217 AI_NUMERICHOST)) {
2218 continue;
2219 }
2220 }
2221 TALLOC_FREE(frame);
2222 return count;
2223}
2224
2225/**
2226 * Safely free ip string list
2227 *
2228 * @param ipstr_list ip string list to be freed
2229 **/
2230
2231void ipstr_list_free(char* ipstr_list)
2232{
2233 SAFE_FREE(ipstr_list);
2234}
2235
2236/**
2237 Unescape a URL encoded string, in place.
2238**/
2239
2240void rfc1738_unescape(char *buf)
2241{
2242 char *p=buf;
2243
2244 while (p && *p && (p=strchr_m(p,'%'))) {
2245 int c1 = p[1];
2246 int c2 = p[2];
2247
2248 if (c1 >= '0' && c1 <= '9')
2249 c1 = c1 - '0';
2250 else if (c1 >= 'A' && c1 <= 'F')
2251 c1 = 10 + c1 - 'A';
2252 else if (c1 >= 'a' && c1 <= 'f')
2253 c1 = 10 + c1 - 'a';
2254 else {p++; continue;}
2255
2256 if (c2 >= '0' && c2 <= '9')
2257 c2 = c2 - '0';
2258 else if (c2 >= 'A' && c2 <= 'F')
2259 c2 = 10 + c2 - 'A';
2260 else if (c2 >= 'a' && c2 <= 'f')
2261 c2 = 10 + c2 - 'a';
2262 else {p++; continue;}
2263
2264 *p = (c1<<4) | c2;
2265
2266 memmove(p+1, p+3, strlen(p+3)+1);
2267 p++;
2268 }
2269}
2270
2271static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2272
2273/**
2274 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2275 **/
2276DATA_BLOB base64_decode_data_blob(const char *s)
2277{
2278 int bit_offset, byte_offset, idx, i, n;
2279 DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2280 unsigned char *d = decoded.data;
2281 char *p;
2282
2283 n=i=0;
2284
2285 while (*s && (p=strchr_m(b64,*s))) {
2286 idx = (int)(p - b64);
2287 byte_offset = (i*6)/8;
2288 bit_offset = (i*6)%8;
2289 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2290 if (bit_offset < 3) {
2291 d[byte_offset] |= (idx << (2-bit_offset));
2292 n = byte_offset+1;
2293 } else {
2294 d[byte_offset] |= (idx >> (bit_offset-2));
2295 d[byte_offset+1] = 0;
2296 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2297 n = byte_offset+2;
2298 }
2299 s++; i++;
2300 }
2301
2302 if ((n > 0) && (*s == '=')) {
2303 n -= 1;
2304 }
2305
2306 /* fix up length */
2307 decoded.length = n;
2308 return decoded;
2309}
2310
2311/**
2312 * Decode a base64 string in-place - wrapper for the above
2313 **/
2314void base64_decode_inplace(char *s)
2315{
2316 DATA_BLOB decoded = base64_decode_data_blob(s);
2317
2318 if ( decoded.length != 0 ) {
2319 memcpy(s, decoded.data, decoded.length);
2320
2321 /* null terminate */
2322 s[decoded.length] = '\0';
2323 } else {
2324 *s = '\0';
2325 }
2326
2327 data_blob_free(&decoded);
2328}
2329
2330/**
2331 * Encode a base64 string into a talloc()ed string caller to free.
2332 *
2333 * From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c
2334 * with adjustments
2335 **/
2336
2337char *base64_encode_data_blob(TALLOC_CTX *mem_ctx, DATA_BLOB data)
2338{
2339 int bits = 0;
2340 int char_count = 0;
2341 size_t out_cnt, len, output_len;
2342 char *result;
2343
2344 if (!data.length || !data.data)
2345 return NULL;
2346
2347 out_cnt = 0;
2348 len = data.length;
2349 output_len = data.length * 2 + 4; /* Account for closing bytes. 4 is
2350 * random but should be enough for
2351 * the = and \0 */
2352 result = TALLOC_ARRAY(mem_ctx, char, output_len); /* get us plenty of space */
2353 SMB_ASSERT(result != NULL);
2354
2355 while (len-- && out_cnt < (data.length * 2) - 5) {
2356 int c = (unsigned char) *(data.data++);
2357 bits += c;
2358 char_count++;
2359 if (char_count == 3) {
2360 result[out_cnt++] = b64[bits >> 18];
2361 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2362 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2363 result[out_cnt++] = b64[bits & 0x3f];
2364 bits = 0;
2365 char_count = 0;
2366 } else {
2367 bits <<= 8;
2368 }
2369 }
2370 if (char_count != 0) {
2371 bits <<= 16 - (8 * char_count);
2372 result[out_cnt++] = b64[bits >> 18];
2373 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2374 if (char_count == 1) {
2375 result[out_cnt++] = '=';
2376 result[out_cnt++] = '=';
2377 } else {
2378 result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2379 result[out_cnt++] = '=';
2380 }
2381 }
2382 result[out_cnt] = '\0'; /* terminate */
2383 return result;
2384}
2385
2386/* read a SMB_BIG_UINT from a string */
2387SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2388{
2389
2390 SMB_BIG_UINT val = -1;
2391 const char *p = nptr;
2392
2393 if (!p) {
2394 if (entptr) {
2395 *entptr = p;
2396 }
2397 return val;
2398 }
2399
2400 while (*p && isspace(*p))
2401 p++;
2402
2403#ifdef LARGE_SMB_OFF_T
2404 sscanf(p,"%llu",&val);
2405#else /* LARGE_SMB_OFF_T */
2406 sscanf(p,"%lu",&val);
2407#endif /* LARGE_SMB_OFF_T */
2408 if (entptr) {
2409 while (*p && isdigit(*p))
2410 p++;
2411 *entptr = p;
2412 }
2413
2414 return val;
2415}
2416
2417/* Convert a size specification to a count of bytes. We accept the following
2418 * suffixes:
2419 * bytes if there is no suffix
2420 * kK kibibytes
2421 * mM mebibytes
2422 * gG gibibytes
2423 * tT tibibytes
2424 * pP whatever the ISO name for petabytes is
2425 *
2426 * Returns 0 if the string can't be converted.
2427 */
2428SMB_OFF_T conv_str_size(const char * str)
2429{
2430 SMB_OFF_T lval;
2431 char * end;
2432
2433 if (str == NULL || *str == '\0') {
2434 return 0;
2435 }
2436
2437#ifdef HAVE_STRTOULL
2438 if (sizeof(SMB_OFF_T) == 8) {
2439 lval = strtoull(str, &end, 10 /* base */);
2440 } else {
2441 lval = strtoul(str, &end, 10 /* base */);
2442 }
2443#else
2444 lval = strtoul(str, &end, 10 /* base */);
2445#endif
2446
2447 if (end == NULL || end == str) {
2448 return 0;
2449 }
2450
2451 if (*end) {
2452 SMB_OFF_T lval_orig = lval;
2453
2454 if (strwicmp(end, "K") == 0) {
2455 lval *= (SMB_OFF_T)1024;
2456 } else if (strwicmp(end, "M") == 0) {
2457 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2458 } else if (strwicmp(end, "G") == 0) {
2459 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2460 (SMB_OFF_T)1024);
2461 } else if (strwicmp(end, "T") == 0) {
2462 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2463 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2464 } else if (strwicmp(end, "P") == 0) {
2465 lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2466 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2467 (SMB_OFF_T)1024);
2468 } else {
2469 return 0;
2470 }
2471
2472 /* Primitive attempt to detect wrapping on platforms with
2473 * 4-byte SMB_OFF_T. It's better to let the caller handle
2474 * a failure than some random number.
2475 */
2476 if (lval_orig <= lval) {
2477 return 0;
2478 }
2479 }
2480
2481 return lval;
2482}
2483
2484void string_append(char **left, const char *right)
2485{
2486 int new_len = strlen(right) + 1;
2487
2488 if (*left == NULL) {
2489 *left = (char *)SMB_MALLOC(new_len);
2490 *left[0] = '\0';
2491 } else {
2492 new_len += strlen(*left);
2493 *left = (char *)SMB_REALLOC(*left, new_len);
2494 }
2495
2496 if (*left == NULL) {
2497 return;
2498 }
2499
2500 safe_strcat(*left, right, new_len-1);
2501}
2502
2503bool add_string_to_array(TALLOC_CTX *mem_ctx,
2504 const char *str, const char ***strings,
2505 int *num)
2506{
2507 char *dup_str = talloc_strdup(mem_ctx, str);
2508
2509 *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings,
2510 const char *, (*num)+1);
2511
2512 if ((*strings == NULL) || (dup_str == NULL)) {
2513 *num = 0;
2514 return false;
2515 }
2516
2517 (*strings)[*num] = dup_str;
2518 *num += 1;
2519 return true;
2520}
2521
2522/* Append an sprintf'ed string. Double buffer size on demand. Usable without
2523 * error checking in between. The indiation that something weird happened is
2524 * string==NULL */
2525
2526void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2527 size_t *bufsize, const char *fmt, ...)
2528{
2529 va_list ap;
2530 char *newstr;
2531 int ret;
2532 bool increased;
2533
2534 /* len<0 is an internal marker that something failed */
2535 if (*len < 0)
2536 goto error;
2537
2538 if (*string == NULL) {
2539 if (*bufsize == 0)
2540 *bufsize = 128;
2541
2542 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2543 if (*string == NULL)
2544 goto error;
2545 }
2546
2547 va_start(ap, fmt);
2548 ret = vasprintf(&newstr, fmt, ap);
2549 va_end(ap);
2550
2551 if (ret < 0)
2552 goto error;
2553
2554 increased = false;
2555
2556 while ((*len)+ret >= *bufsize) {
2557 increased = true;
2558 *bufsize *= 2;
2559 if (*bufsize >= (1024*1024*256))
2560 goto error;
2561 }
2562
2563 if (increased) {
2564 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2565 *bufsize);
2566 if (*string == NULL) {
2567 goto error;
2568 }
2569 }
2570
2571 StrnCpy((*string)+(*len), newstr, ret);
2572 (*len) += ret;
2573 free(newstr);
2574 return;
2575
2576 error:
2577 *len = -1;
2578 *string = NULL;
2579}
2580
2581/*
2582 * asprintf into a string and strupper_m it after that.
2583 */
2584
2585int asprintf_strupper_m(char **strp, const char *fmt, ...)
2586{
2587 va_list ap;
2588 char *result;
2589 int ret;
2590
2591 va_start(ap, fmt);
2592 ret = vasprintf(&result, fmt, ap);
2593 va_end(ap);
2594
2595 if (ret == -1)
2596 return -1;
2597
2598 strupper_m(result);
2599 *strp = result;
2600 return ret;
2601}
2602
2603char *talloc_asprintf_strupper_m(TALLOC_CTX *t, const char *fmt, ...)
2604{
2605 va_list ap;
2606 char *ret;
2607
2608 va_start(ap, fmt);
2609 ret = talloc_vasprintf(t, fmt, ap);
2610 va_end(ap);
2611
2612 if (ret == NULL) {
2613 return NULL;
2614 }
2615 strupper_m(ret);
2616 return ret;
2617}
2618
2619/*
2620 Returns the substring from src between the first occurrence of
2621 the char "front" and the first occurence of the char "back".
2622 Mallocs the return string which must be freed. Not for use
2623 with wide character strings.
2624*/
2625char *sstring_sub(const char *src, char front, char back)
2626{
2627 char *temp1, *temp2, *temp3;
2628 ptrdiff_t len;
2629
2630 temp1 = strchr(src, front);
2631 if (temp1 == NULL) return NULL;
2632 temp2 = strchr(src, back);
2633 if (temp2 == NULL) return NULL;
2634 len = temp2 - temp1;
2635 if (len <= 0) return NULL;
2636 temp3 = (char*)SMB_MALLOC(len);
2637 if (temp3 == NULL) {
2638 DEBUG(1,("Malloc failure in sstring_sub\n"));
2639 return NULL;
2640 }
2641 memcpy(temp3, temp1+1, len-1);
2642 temp3[len-1] = '\0';
2643 return temp3;
2644}
2645
2646/********************************************************************
2647 Check a string for any occurrences of a specified list of invalid
2648 characters.
2649********************************************************************/
2650
2651bool validate_net_name( const char *name,
2652 const char *invalid_chars,
2653 int max_len)
2654{
2655 int i;
2656
2657 for ( i=0; i<max_len && name[i]; i++ ) {
2658 /* fail if strchr_m() finds one of the invalid characters */
2659 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2660 return false;
2661 }
2662 }
2663
2664 return true;
2665}
2666
2667
2668/**
2669return the number of bytes occupied by a buffer in ASCII format
2670the result includes the null termination
2671limited by 'n' bytes
2672**/
2673size_t ascii_len_n(const char *src, size_t n)
2674{
2675 size_t len;
2676
2677 len = strnlen(src, n);
2678 if (len+1 <= n) {
2679 len += 1;
2680 }
2681
2682 return len;
2683}
2684
2685/**
2686return the number of bytes occupied by a buffer in CH_UTF16 format
2687the result includes the null termination
2688**/
2689size_t utf16_len(const void *buf)
2690{
2691 size_t len;
2692
2693 for (len = 0; SVAL(buf,len); len += 2) ;
2694
2695 return len + 2;
2696}
2697
2698/**
2699return the number of bytes occupied by a buffer in CH_UTF16 format
2700the result includes the null termination
2701limited by 'n' bytes
2702**/
2703size_t utf16_len_n(const void *src, size_t n)
2704{
2705 size_t len;
2706
2707 for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
2708
2709 if (len+2 <= n) {
2710 len += 2;
2711 }
2712
2713 return len;
2714}
2715
2716/*******************************************************************
2717 Add a shell escape character '\' to any character not in a known list
2718 of characters. UNIX charset format.
2719*******************************************************************/
2720
2721#define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2722#define INSIDE_DQUOTE_LIST "$`\n\"\\"
2723
2724char *escape_shell_string(const char *src)
2725{
2726 size_t srclen = strlen(src);
2727 char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
2728 char *dest = ret;
2729 bool in_s_quote = false;
2730 bool in_d_quote = false;
2731 bool next_escaped = false;
2732
2733 if (!ret) {
2734 return NULL;
2735 }
2736
2737 while (*src) {
2738 size_t c_size;
2739 codepoint_t c = next_codepoint(src, &c_size);
2740
2741 if (c == INVALID_CODEPOINT) {
2742 SAFE_FREE(ret);
2743 return NULL;
2744 }
2745
2746 if (c_size > 1) {
2747 memcpy(dest, src, c_size);
2748 src += c_size;
2749 dest += c_size;
2750 next_escaped = false;
2751 continue;
2752 }
2753
2754 /*
2755 * Deal with backslash escaped state.
2756 * This only lasts for one character.
2757 */
2758
2759 if (next_escaped) {
2760 *dest++ = *src++;
2761 next_escaped = false;
2762 continue;
2763 }
2764
2765 /*
2766 * Deal with single quote state. The
2767 * only thing we care about is exiting
2768 * this state.
2769 */
2770
2771 if (in_s_quote) {
2772 if (*src == '\'') {
2773 in_s_quote = false;
2774 }
2775 *dest++ = *src++;
2776 continue;
2777 }
2778
2779 /*
2780 * Deal with double quote state. The most
2781 * complex state. We must cope with \, meaning
2782 * possibly escape next char (depending what it
2783 * is), ", meaning exit this state, and possibly
2784 * add an \ escape to any unprotected character
2785 * (listed in INSIDE_DQUOTE_LIST).
2786 */
2787
2788 if (in_d_quote) {
2789 if (*src == '\\') {
2790 /*
2791 * Next character might be escaped.
2792 * We have to peek. Inside double
2793 * quotes only INSIDE_DQUOTE_LIST
2794 * characters are escaped by a \.
2795 */
2796
2797 char nextchar;
2798
2799 c = next_codepoint(&src[1], &c_size);
2800 if (c == INVALID_CODEPOINT) {
2801 SAFE_FREE(ret);
2802 return NULL;
2803 }
2804 if (c_size > 1) {
2805 /*
2806 * Don't escape the next char.
2807 * Just copy the \.
2808 */
2809 *dest++ = *src++;
2810 continue;
2811 }
2812
2813 nextchar = src[1];
2814
2815 if (nextchar && strchr(INSIDE_DQUOTE_LIST,
2816 (int)nextchar)) {
2817 next_escaped = true;
2818 }
2819 *dest++ = *src++;
2820 continue;
2821 }
2822
2823 if (*src == '\"') {
2824 /* Exit double quote state. */
2825 in_d_quote = false;
2826 *dest++ = *src++;
2827 continue;
2828 }
2829
2830 /*
2831 * We know the character isn't \ or ",
2832 * so escape it if it's any of the other
2833 * possible unprotected characters.
2834 */
2835
2836 if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
2837 *dest++ = '\\';
2838 }
2839 *dest++ = *src++;
2840 continue;
2841 }
2842
2843 /*
2844 * From here to the end of the loop we're
2845 * not in the single or double quote state.
2846 */
2847
2848 if (*src == '\\') {
2849 /* Next character must be escaped. */
2850 next_escaped = true;
2851 *dest++ = *src++;
2852 continue;
2853 }
2854
2855 if (*src == '\'') {
2856 /* Go into single quote state. */
2857 in_s_quote = true;
2858 *dest++ = *src++;
2859 continue;
2860 }
2861
2862 if (*src == '\"') {
2863 /* Go into double quote state. */
2864 in_d_quote = true;
2865 *dest++ = *src++;
2866 continue;
2867 }
2868
2869 /* Check if we need to escape the character. */
2870
2871 if (!strchr(INCLUDE_LIST, (int)*src)) {
2872 *dest++ = '\\';
2873 }
2874 *dest++ = *src++;
2875 }
2876 *dest++ = '\0';
2877 return ret;
2878}
Note: See TracBrowser for help on using the repository browser.