source: vendor/3.5.0/source3/lib/util_str.c

Last change on this file was 414, checked in by Herwig Bauernfeind, 15 years ago

Samba 3.5.0: Initial import

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