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 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 2 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22*/ 23 24#include "includes.h" 25 26/** 27 * @file 28 * @brief String utilities. 29 **/ 30 31/** 32 * Get the next token from a string, return False if none found. 33 * Handles double-quotes. 34 * 35 * Based on a routine by GJC@VILLAGE.COM. 36 * Extensively modified by Andrew.Tridgell@anu.edu.au 37 **/ 38BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize) 39{ 40 char *s; 41 char *pbuf; 42 BOOL quoted; 43 size_t len=1; 44 45 if (!ptr) 46 return(False); 47 48 s = (char *)*ptr; 49 50 /* default to simple separators */ 51 if (!sep) 52 sep = " \t\n\r"; 53 54 /* find the first non sep char */ 55 while (*s && strchr_m(sep,*s)) 56 s++; 57 58 /* nothing left? */ 59 if (! *s) 60 return(False); 61 62 /* copy over the token */ 63 pbuf = buff; 64 for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) { 65 if ( *s == '\"' ) { 66 quoted = !quoted; 67 } else { 68 len++; 69 *pbuf++ = *s; 70 } 71 } 72 73 *ptr = (*s) ? s+1 : s; 74 *pbuf = 0; 75 76 return(True); 77} 78 79/** 80This is like next_token but is not re-entrant and "remembers" the first 81parameter so you can pass NULL. This is useful for user interface code 82but beware the fact that it is not re-entrant! 83**/ 84 85static const char *last_ptr=NULL; 86 87BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize) 88{ 89 BOOL ret; 90 if (!ptr) 91 ptr = &last_ptr; 92 93 ret = next_token(ptr, buff, sep, bufsize); 94 last_ptr = *ptr; 95 return ret; 96} 97 98static uint16 tmpbuf[sizeof(pstring)]; 99 100void set_first_token(char *ptr) 101{ 102 last_ptr = ptr; 103} 104 105/** 106 Convert list of tokens to array; dependent on above routine. 107 Uses last_ptr from above - bit of a hack. 108**/ 109 110char **toktocliplist(int *ctok, const char *sep) 111{ 112 char *s=(char *)last_ptr; 113 int ictok=0; 114 char **ret, **iret; 115 116 if (!sep) 117 sep = " \t\n\r"; 118 119 while(*s && strchr_m(sep,*s)) 120 s++; 121 122 /* nothing left? */ 123 if (!*s) 124 return(NULL); 125 126 do { 127 ictok++; 128 while(*s && (!strchr_m(sep,*s))) 129 s++; 130 while(*s && strchr_m(sep,*s)) 131 *s++=0; 132 } while(*s); 133 134 *ctok=ictok; 135 s=(char *)last_ptr; 136 137 if (!(ret=iret=SMB_MALLOC_ARRAY(char *,ictok+1))) 138 return NULL; 139 140 while(ictok--) { 141 *iret++=s; 142 if (ictok > 0) { 143 while(*s++) 144 ; 145 while(!*s) 146 s++; 147 } 148 } 149 150 ret[*ctok] = NULL; 151 return ret; 152} 153 154/** 155 * Case insensitive string compararison. 156 * 157 * iconv does not directly give us a way to compare strings in 158 * arbitrary unix character sets -- all we can is convert and then 159 * compare. This is expensive. 160 * 161 * As an optimization, we do a first pass that considers only the 162 * prefix of the strings that is entirely 7-bit. Within this, we 163 * check whether they have the same value. 164 * 165 * Hopefully this will often give the answer without needing to copy. 166 * In particular it should speed comparisons to literal ascii strings 167 * or comparisons of strings that are "obviously" different. 168 * 169 * If we find a non-ascii character we fall back to converting via 170 * iconv. 171 * 172 * This should never be slower than convering the whole thing, and 173 * often faster. 174 * 175 * A different optimization would be to compare for bitwise equality 176 * in the binary encoding. (It would be possible thought hairy to do 177 * both simultaneously.) But in that case if they turn out to be 178 * different, we'd need to restart the whole thing. 179 * 180 * Even better is to implement strcasecmp for each encoding and use a 181 * function pointer. 182 **/ 183int StrCaseCmp(const char *s, const char *t) 184{ 185 186 const char * ps, * pt; 187 size_t size; 188 smb_ucs2_t *buffer_s, *buffer_t; 189 int ret; 190 191 for (ps = s, pt = t; ; ps++, pt++) { 192 char us, ut; 193 194 if (!*ps && !*pt) 195 return 0; /* both ended */ 196 else if (!*ps) 197 return -1; /* s is a prefix */ 198 else if (!*pt) 199 return +1; /* t is a prefix */ 200 else if ((*ps & 0x80) || (*pt & 0x80)) 201 /* not ascii anymore, do it the hard way from here on in */ 202 break; 203 204 us = toupper(*ps); 205 ut = toupper(*pt); 206 if (us == ut) 207 continue; 208 else if (us < ut) 209 return -1; 210 else if (us > ut) 211 return +1; 212 } 213 214 size = push_ucs2_allocate(&buffer_s, s); 215 if (size == (size_t)-1) { 216 return strcmp(s, t); 217 /* Not quite the right answer, but finding the right one 218 under this failure case is expensive, and it's pretty close */ 219 } 220 221 size = push_ucs2_allocate(&buffer_t, t); 222 if (size == (size_t)-1) { 223 SAFE_FREE(buffer_s); 224 return strcmp(s, t); 225 /* Not quite the right answer, but finding the right one 226 under this failure case is expensive, and it's pretty close */ 227 } 228 229 ret = strcasecmp_w(buffer_s, buffer_t); 230 SAFE_FREE(buffer_s); 231 SAFE_FREE(buffer_t); 232 return ret; 233} 234 235 236/** 237 Case insensitive string compararison, length limited. 238**/ 239int StrnCaseCmp(const char *s, const char *t, size_t n) 240{ 241 pstring buf1, buf2; 242 unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1)); 243 unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2)); 244 return strncmp(buf1,buf2,n); 245} 246 247/** 248 * Compare 2 strings. 249 * 250 * @note The comparison is case-insensitive. 251 **/ 252BOOL strequal(const char *s1, const char *s2) 253{ 254 if (s1 == s2) 255 return(True); 256 if (!s1 || !s2) 257 return(False); 258 259 return(StrCaseCmp(s1,s2)==0); 260} 261 262/** 263 * Compare 2 strings up to and including the nth char. 264 * 265 * @note The comparison is case-insensitive. 266 **/ 267BOOL strnequal(const char *s1,const char *s2,size_t n) 268{ 269 if (s1 == s2) 270 return(True); 271 if (!s1 || !s2 || !n) 272 return(False); 273 274 return(StrnCaseCmp(s1,s2,n)==0); 275} 276 277/** 278 Compare 2 strings (case sensitive). 279**/ 280 281BOOL strcsequal(const char *s1,const char *s2) 282{ 283 if (s1 == s2) 284 return(True); 285 if (!s1 || !s2) 286 return(False); 287 288 return(strcmp(s1,s2)==0); 289} 290 291/** 292Do a case-insensitive, whitespace-ignoring string compare. 293**/ 294 295int strwicmp(const char *psz1, const char *psz2) 296{ 297 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */ 298 /* appropriate value. */ 299 if (psz1 == psz2) 300 return (0); 301 else if (psz1 == NULL) 302 return (-1); 303 else if (psz2 == NULL) 304 return (1); 305 306 /* sync the strings on first non-whitespace */ 307 while (1) { 308 while (isspace((int)*psz1)) 309 psz1++; 310 while (isspace((int)*psz2)) 311 psz2++; 312 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' 313 || *psz2 == '\0') 314 break; 315 psz1++; 316 psz2++; 317 } 318 return (*psz1 - *psz2); 319} 320 321 322/** 323 Convert a string to upper case, but don't modify it. 324**/ 325 326char *strupper_static(const char *s) 327{ 328 static pstring str; 329 330 pstrcpy(str, s); 331 strupper_m(str); 332 333 return str; 334} 335 336/** 337 Convert a string to "normal" form. 338**/ 339 340void strnorm(char *s, int case_default) 341{ 342 if (case_default == CASE_UPPER) 343 strupper_m(s); 344 else 345 strlower_m(s); 346} 347 348/** 349 Check if a string is in "normal" case. 350**/ 351 352BOOL strisnormal(const char *s, int case_default) 353{ 354 if (case_default == CASE_UPPER) 355 return(!strhaslower(s)); 356 357 return(!strhasupper(s)); 358} 359 360 361/** 362 String replace. 363 NOTE: oldc and newc must be 7 bit characters 364**/ 365 366void string_replace(pstring s,char oldc,char newc) 367{ 368 unsigned char *p; 369 370 /* this is quite a common operation, so we want it to be 371 fast. We optimise for the ascii case, knowing that all our 372 supported multi-byte character sets are ascii-compatible 373 (ie. they match for the first 128 chars) */ 374 375 for (p = (unsigned char *)s; *p; p++) { 376 if (*p & 0x80) /* mb string - slow path. */ 377 break; 378 if (*p == oldc) 379 *p = newc; 380 } 381 382 if (!*p) 383 return; 384 385 /* Slow (mb) path. */ 386#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS 387 /* With compose characters we must restart from the beginning. JRA. */ 388 p = s; 389#endif 390 push_ucs2(NULL, tmpbuf, p, sizeof(tmpbuf), STR_TERMINATE); 391 string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc)); 392 pull_ucs2(NULL, p, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE); 393} 394 395/** 396 Skip past some strings in a buffer. 397**/ 398 399char *skip_string(char *buf,size_t n) 400{ 401 while (n--) 402 buf += strlen(buf) + 1; 403 return(buf); 404} 405 406/** 407 Count the number of characters in a string. Normally this will 408 be the same as the number of bytes in a string for single byte strings, 409 but will be different for multibyte. 410**/ 411 412size_t str_charnum(const char *s) 413{ 414 uint16 tmpbuf2[sizeof(pstring)]; 415 push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE); 416 return strlen_w(tmpbuf2); 417} 418 419/** 420 Count the number of characters in a string. Normally this will 421 be the same as the number of bytes in a string for single byte strings, 422 but will be different for multibyte. 423**/ 424 425size_t str_ascii_charnum(const char *s) 426{ 427 pstring tmpbuf2; 428 push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE); 429 return strlen(tmpbuf2); 430} 431 432BOOL trim_char(char *s,char cfront,char cback) 433{ 434 BOOL ret = False; 435 char *ep; 436 char *fp = s; 437 438 /* Ignore null or empty strings. */ 439 if (!s || (s[0] == '\0')) 440 return False; 441 442 if (cfront) { 443 while (*fp && *fp == cfront) 444 fp++; 445 if (!*fp) { 446 /* We ate the string. */ 447 s[0] = '\0'; 448 return True; 449 } 450 if (fp != s) 451 ret = True; 452 } 453 454 ep = fp + strlen(fp) - 1; 455 if (cback) { 456 /* Attempt ascii only. Bail for mb strings. */ 457 while ((ep >= fp) && (*ep == cback)) { 458 ret = True; 459 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) { 460 /* Could be mb... bail back to tim_string. */ 461 char fs[2], bs[2]; 462 if (cfront) { 463 fs[0] = cfront; 464 fs[1] = '\0'; 465 } 466 bs[0] = cback; 467 bs[1] = '\0'; 468 return trim_string(s, cfront ? fs : NULL, bs); 469 } else { 470 ep--; 471 } 472 } 473 if (ep < fp) { 474 /* We ate the string. */ 475 s[0] = '\0'; 476 return True; 477 } 478 } 479 480 ep[1] = '\0'; 481 memmove(s, fp, ep-fp+2); 482 return ret; 483} 484 485/** 486 Trim the specified elements off the front and back of a string. 487**/ 488 489BOOL trim_string(char *s,const char *front,const char *back) 490{ 491 BOOL ret = False; 492 size_t front_len; 493 size_t back_len; 494 size_t len; 495 496 /* Ignore null or empty strings. */ 497 if (!s || (s[0] == '\0')) 498 return False; 499 500 front_len = front? strlen(front) : 0; 501 back_len = back? strlen(back) : 0; 502 503 len = strlen(s); 504 505 if (front_len) { 506 while (len && strncmp(s, front, front_len)==0) { 507 /* Must use memmove here as src & dest can 508 * easily overlap. Found by valgrind. JRA. */ 509 memmove(s, s+front_len, (len-front_len)+1); 510 len -= front_len; 511 ret=True; 512 } 513 } 514 515 if (back_len) { 516 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) { 517 s[len-back_len]='\0'; 518 len -= back_len; 519 ret=True; 520 } 521 } 522 return ret; 523} 524 525/** 526 Does a string have any uppercase chars in it? 527**/ 528 529BOOL strhasupper(const char *s) 530{ 531 smb_ucs2_t *ptr; 532 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE); 533 for(ptr=tmpbuf;*ptr;ptr++) 534 if(isupper_w(*ptr)) 535 return True; 536 return(False); 537} 538 539/** 540 Does a string have any lowercase chars in it? 541**/ 542 543BOOL strhaslower(const char *s) 544{ 545 smb_ucs2_t *ptr; 546 push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE); 547 for(ptr=tmpbuf;*ptr;ptr++) 548 if(islower_w(*ptr)) 549 return True; 550 return(False); 551} 552 553/** 554 Find the number of 'c' chars in a string 555**/ 556 557size_t count_chars(const char *s,char c) 558{ 559 smb_ucs2_t *ptr; 560 int count; 561 smb_ucs2_t *alloc_tmpbuf = NULL; 562 563 if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) { 564 return 0; 565 } 566 567 for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++) 568 if(*ptr==UCS2_CHAR(c)) 569 count++; 570 571 SAFE_FREE(alloc_tmpbuf); 572 return(count); 573} 574 575/** 576 Safe string copy into a known length string. maxlength does not 577 include the terminating zero. 578**/ 579 580char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength) 581{ 582 size_t len; 583 584 if (!dest) { 585 DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line)); 586 return NULL; 587 } 588 589#ifdef DEVELOPER 590 clobber_region(fn,line,dest, maxlength+1); 591#endif 592 593 if (!src) { 594 *dest = 0; 595 return dest; 596 } 597 598 len = strnlen(src, maxlength+1); 599 600 if (len > maxlength) { 601 DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n", 602 (unsigned long)(len-maxlength), (unsigned long)len, 603 (unsigned long)maxlength, src)); 604 len = maxlength; 605 } 606 607 memmove(dest, src, len); 608 dest[len] = 0; 609 return dest; 610} 611 612/** 613 Safe string cat into a string. maxlength does not 614 include the terminating zero. 615**/ 616char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength) 617{ 618 size_t src_len, dest_len; 619 620 if (!dest) { 621 DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line)); 622 return NULL; 623 } 624 625 if (!src) 626 return dest; 627 628 src_len = strnlen(src, maxlength + 1); 629 dest_len = strnlen(dest, maxlength + 1); 630 631#ifdef DEVELOPER 632 clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len); 633#endif 634 635 if (src_len + dest_len > maxlength) { 636 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n", 637 (int)(src_len + dest_len - maxlength), src)); 638 if (maxlength > dest_len) { 639 memcpy(&dest[dest_len], src, maxlength - dest_len); 640 } 641 dest[maxlength] = 0; 642 return NULL; 643 } 644 645 memcpy(&dest[dest_len], src, src_len); 646 dest[dest_len + src_len] = 0; 647 return dest; 648} 649 650/** 651 Paranoid strcpy into a buffer of given length (includes terminating 652 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars 653 and replaces with '_'. Deliberately does *NOT* check for multibyte 654 characters. Don't change it ! 655**/ 656char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength) 657{ 658 size_t len, i; 659 660#ifdef DEVELOPER 661 clobber_region(fn, line, dest, maxlength); 662#endif 663 664 if (!dest) { 665 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line)); 666 return NULL; 667 } 668 669 if (!src) { 670 *dest = 0; 671 return dest; 672 } 673 674 len = strlen(src); 675 if (len >= maxlength) 676 len = maxlength - 1; 677 678 if (!other_safe_chars) 679 other_safe_chars = ""; 680 681 for(i = 0; i < len; i++) { 682 int val = (src[i] & 0xff); 683 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val)) 684 dest[i] = src[i]; 685 else 686 dest[i] = '_'; 687 } 688 689 dest[i] = '\0'; 690 691 return dest; 692} 693 694/** 695 Like strncpy but always null terminates. Make sure there is room! 696 The variable n should always be one less than the available size. 697**/ 698char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n) 699{ 700 char *d = dest; 701 702#ifdef DEVELOPER 703 clobber_region(fn, line, dest, n+1); 704#endif 705 706 if (!dest) { 707 DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line)); 708 return(NULL); 709 } 710 711 if (!src) { 712 *dest = 0; 713 return(dest); 714 } 715 716 while (n-- && (*d = *src)) { 717 d++; 718 src++; 719 } 720 721 *d = 0; 722 return(dest); 723} 724 725#if 0 726/** 727 Like strncpy but copies up to the character marker. always null terminates. 728 returns a pointer to the character marker in the source string (src). 729**/ 730 731static char *strncpyn(char *dest, const char *src, size_t n, char c) 732{ 733 char *p; 734 size_t str_len; 735 736#ifdef DEVELOPER 737 clobber_region(dest, n+1); 738#endif 739 p = strchr_m(src, c); 740 if (p == NULL) { 741 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c)); 742 return NULL; 743 } 744 745 str_len = PTR_DIFF(p, src); 746 strncpy(dest, src, MIN(n, str_len)); 747 dest[str_len] = '\0'; 748 749 return p; 750} 751#endif 752 753/** 754 Routine to get hex characters and turn them into a 16 byte array. 755 the array can be variable length, and any non-hex-numeric 756 characters are skipped. "0xnn" or "0Xnn" is specially catered 757 for. 758 759 valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n" 760 761**/ 762 763size_t strhex_to_str(char *p, size_t len, const char *strhex) 764{ 765 size_t i; 766 size_t num_chars = 0; 767 unsigned char lonybble, hinybble; 768 const char *hexchars = "0123456789ABCDEF"; 769 char *p1 = NULL, *p2 = NULL; 770 771 for (i = 0; i < len && strhex[i] != 0; i++) { 772 if (strnequal(hexchars, "0x", 2)) { 773 i++; /* skip two chars */ 774 continue; 775 } 776 777 if (!(p1 = strchr_m(hexchars, toupper(strhex[i])))) 778 break; 779 780 i++; /* next hex digit */ 781 782 if (!(p2 = strchr_m(hexchars, toupper(strhex[i])))) 783 break; 784 785 /* get the two nybbles */ 786 hinybble = PTR_DIFF(p1, hexchars); 787 lonybble = PTR_DIFF(p2, hexchars); 788 789 p[num_chars] = (hinybble << 4) | lonybble; 790 num_chars++; 791 792 p1 = NULL; 793 p2 = NULL; 794 } 795 return num_chars; 796} 797 798DATA_BLOB strhex_to_data_blob(const char *strhex) 799{ 800 DATA_BLOB ret_blob = data_blob(NULL, strlen(strhex)/2+1); 801 802 ret_blob.length = strhex_to_str(ret_blob.data, 803 strlen(strhex), 804 strhex); 805 806 return ret_blob; 807} 808 809/** 810 * Routine to print a buffer as HEX digits, into an allocated string. 811 */ 812 813void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer) 814{ 815 int i; 816 char *hex_buffer; 817 818 *out_hex_buffer = SMB_XMALLOC_ARRAY(char, (len*2)+1); 819 hex_buffer = *out_hex_buffer; 820 821 for (i = 0; i < len; i++) 822 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]); 823} 824 825/** 826 Check if a string is part of a list. 827**/ 828 829BOOL in_list(char *s,char *list,BOOL casesensitive) 830{ 831 pstring tok; 832 const char *p=list; 833 834 if (!list) 835 return(False); 836 837 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) { 838 if (casesensitive) { 839 if (strcmp(tok,s) == 0) 840 return(True); 841 } else { 842 if (StrCaseCmp(tok,s) == 0) 843 return(True); 844 } 845 } 846 return(False); 847} 848 849/* this is used to prevent lots of mallocs of size 1 */ 850static char *null_string = NULL; 851 852/** 853 Set a string value, allocing the space for the string 854**/ 855 856static BOOL string_init(char **dest,const char *src) 857{ 858 size_t l; 859 if (!src) 860 src = ""; 861 862 l = strlen(src); 863 864 if (l == 0) { 865 if (!null_string) { 866 if((null_string = (char *)SMB_MALLOC(1)) == NULL) { 867 DEBUG(0,("string_init: malloc fail for null_string.\n")); 868 return False; 869 } 870 *null_string = 0; 871 } 872 *dest = null_string; 873 } else { 874 (*dest) = SMB_STRDUP(src); 875 if ((*dest) == NULL) { 876 DEBUG(0,("Out of memory in string_init\n")); 877 return False; 878 } 879 } 880 return(True); 881} 882 883/** 884 Free a string value. 885**/ 886 887void string_free(char **s) 888{ 889 if (!s || !(*s)) 890 return; 891 if (*s == null_string) 892 *s = NULL; 893 SAFE_FREE(*s); 894} 895 896/** 897 Set a string value, deallocating any existing space, and allocing the space 898 for the string 899**/ 900 901BOOL string_set(char **dest,const char *src) 902{ 903 string_free(dest); 904 return(string_init(dest,src)); 905} 906 907/** 908 Substitute a string for a pattern in another string. Make sure there is 909 enough room! 910 911 This routine looks for pattern in s and replaces it with 912 insert. It may do multiple replacements. 913 914 Any of " ; ' $ or ` in the insert string are replaced with _ 915 if len==0 then the string cannot be extended. This is different from the old 916 use of len==0 which was for no length checks to be done. 917**/ 918 919void string_sub(char *s,const char *pattern, const char *insert, size_t len) 920{ 921 char *p; 922 ssize_t ls,lp,li, i; 923 924 if (!insert || !pattern || !*pattern || !s) 925 return; 926 927 ls = (ssize_t)strlen(s); 928 lp = (ssize_t)strlen(pattern); 929 li = (ssize_t)strlen(insert); 930 931 if (len == 0) 932 len = ls + 1; /* len is number of *bytes* */ 933 934 while (lp <= ls && (p = strstr_m(s,pattern))) { 935 if (ls + (li-lp) >= len) { 936 DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", 937 (int)(ls + (li-lp) - len), 938 pattern, (int)len)); 939 break; 940 } 941 if (li != lp) { 942 memmove(p+li,p+lp,strlen(p+lp)+1); 943 } 944 for (i=0;i<li;i++) { 945 switch (insert[i]) { 946 case '`': 947 case '"': 948 case '\'': 949 case ';': 950 case '$': 951 case '%': 952 case '\r': 953 case '\n': 954 p[i] = '_'; 955 break; 956 default: 957 p[i] = insert[i]; 958 } 959 } 960 s = p + li; 961 ls += (li-lp); 962 } 963} 964 965void fstring_sub(char *s,const char *pattern,const char *insert) 966{ 967 string_sub(s, pattern, insert, sizeof(fstring)); 968} 969 970void pstring_sub(char *s,const char *pattern,const char *insert) 971{ 972 string_sub(s, pattern, insert, sizeof(pstring)); 973} 974 975/** 976 Similar to string_sub, but it will accept only allocated strings 977 and may realloc them so pay attention at what you pass on no 978 pointers inside strings, no pstrings or const may be passed 979 as string. 980**/ 981 982char *realloc_string_sub(char *string, const char *pattern, const char *insert) 983{ 984 char *p, *in; 985 char *s; 986 ssize_t ls,lp,li,ld, i; 987 988 if (!insert || !pattern || !*pattern || !string || !*string) 989 return NULL; 990 991 s = string; 992 993 in = SMB_STRDUP(insert); 994 if (!in) { 995 DEBUG(0, ("realloc_string_sub: out of memory!\n")); 996 return NULL; 997 } 998 ls = (ssize_t)strlen(s); 999 lp = (ssize_t)strlen(pattern); 1000 li = (ssize_t)strlen(insert); 1001 ld = li - lp; 1002 for (i=0;i<li;i++) { 1003 switch (in[i]) { 1004 case '`': 1005 case '"': 1006 case '\'': 1007 case ';': 1008 case '$': 1009 case '%': 1010 case '\r': 1011 case '\n': 1012 in[i] = '_'; 1013 default: 1014 /* ok */ 1015 break; 1016 } 1017 } 1018 1019 while ((p = strstr_m(s,pattern))) { 1020 if (ld > 0) { 1021 int offset = PTR_DIFF(s,string); 1022 char *t = SMB_REALLOC(string, ls + ld + 1); 1023 if (!t) { 1024 DEBUG(0, ("realloc_string_sub: out of memory!\n")); 1025 SAFE_FREE(in); 1026 return NULL; 1027 } 1028 string = t; 1029 p = t + offset + (p - s); 1030 } 1031 if (li != lp) { 1032 memmove(p+li,p+lp,strlen(p+lp)+1); 1033 } 1034 memcpy(p, in, li); 1035 s = p + li; 1036 ls += ld; 1037 } 1038 SAFE_FREE(in); 1039 return string; 1040} 1041 1042/** 1043 Similar to string_sub() but allows for any character to be substituted. 1044 Use with caution! 1045 if len==0 then the string cannot be extended. This is different from the old 1046 use of len==0 which was for no length checks to be done. 1047**/ 1048 1049void all_string_sub(char *s,const char *pattern,const char *insert, size_t len) 1050{ 1051 char *p; 1052 ssize_t ls,lp,li; 1053 1054 if (!insert || !pattern || !s) 1055 return; 1056 1057 ls = (ssize_t)strlen(s); 1058 lp = (ssize_t)strlen(pattern); 1059 li = (ssize_t)strlen(insert); 1060 1061 if (!*pattern) 1062 return; 1063 1064 if (len == 0) 1065 len = ls + 1; /* len is number of *bytes* */ 1066 1067 while (lp <= ls && (p = strstr_m(s,pattern))) { 1068 if (ls + (li-lp) >= len) { 1069 DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", 1070 (int)(ls + (li-lp) - len), 1071 pattern, (int)len)); 1072 break; 1073 } 1074 if (li != lp) { 1075 memmove(p+li,p+lp,strlen(p+lp)+1); 1076 } 1077 memcpy(p, insert, li); 1078 s = p + li; 1079 ls += (li-lp); 1080 } 1081} 1082 1083/** 1084 Similar to all_string_sub but for unicode strings. 1085 Return a new allocated unicode string. 1086 similar to string_sub() but allows for any character to be substituted. 1087 Use with caution! 1088**/ 1089 1090static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern, 1091 const smb_ucs2_t *insert) 1092{ 1093 smb_ucs2_t *r, *rp; 1094 const smb_ucs2_t *sp; 1095 size_t lr, lp, li, lt; 1096 1097 if (!insert || !pattern || !*pattern || !s) 1098 return NULL; 1099 1100 lt = (size_t)strlen_w(s); 1101 lp = (size_t)strlen_w(pattern); 1102 li = (size_t)strlen_w(insert); 1103 1104 if (li > lp) { 1105 const smb_ucs2_t *st = s; 1106 int ld = li - lp; 1107 while ((sp = strstr_w(st, pattern))) { 1108 st = sp + lp; 1109 lt += ld; 1110 } 1111 } 1112 1113 r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1); 1114 if (!r) { 1115 DEBUG(0, ("all_string_sub_w: out of memory!\n")); 1116 return NULL; 1117 } 1118 1119 while ((sp = strstr_w(s, pattern))) { 1120 memcpy(rp, s, (sp - s)); 1121 rp += ((sp - s) / sizeof(smb_ucs2_t)); 1122 memcpy(rp, insert, (li * sizeof(smb_ucs2_t))); 1123 s = sp + lp; 1124 rp += li; 1125 } 1126 lr = ((rp - r) / sizeof(smb_ucs2_t)); 1127 if (lr < lt) { 1128 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t))); 1129 rp += (lt - lr); 1130 } 1131 *rp = 0; 1132 1133 return r; 1134} 1135 1136smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern, 1137 const char *insert) 1138{ 1139 wpstring p, i; 1140 1141 if (!insert || !pattern || !s) 1142 return NULL; 1143 push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE); 1144 push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE); 1145 return all_string_sub_w(s, p, i); 1146} 1147 1148#if 0 1149/** 1150 Splits out the front and back at a separator. 1151**/ 1152 1153static void split_at_last_component(char *path, char *front, char sep, char *back) 1154{ 1155 char *p = strrchr_m(path, sep); 1156 1157 if (p != NULL) 1158 *p = 0; 1159 1160 if (front != NULL) 1161 pstrcpy(front, path); 1162 1163 if (p != NULL) { 1164 if (back != NULL) 1165 pstrcpy(back, p+1); 1166 *p = '\\'; 1167 } else { 1168 if (back != NULL) 1169 back[0] = 0; 1170 } 1171} 1172#endif 1173 1174/** 1175 Write an octal as a string. 1176**/ 1177 1178const char *octal_string(int i) 1179{ 1180 static char ret[64]; 1181 if (i == -1) 1182 return "-1"; 1183 slprintf(ret, sizeof(ret)-1, "0%o", i); 1184 return ret; 1185} 1186 1187 1188/** 1189 Truncate a string at a specified length. 1190**/ 1191 1192char *string_truncate(char *s, unsigned int length) 1193{ 1194 if (s && strlen(s) > length) 1195 s[length] = 0; 1196 return s; 1197} 1198 1199/** 1200 Strchr and strrchr_m are very hard to do on general multi-byte strings. 1201 We convert via ucs2 for now. 1202**/ 1203 1204char *strchr_m(const char *src, char c) 1205{ 1206 wpstring ws; 1207 pstring s2; 1208 smb_ucs2_t *p; 1209 const char *s; 1210 1211 /* characters below 0x3F are guaranteed to not appear in 1212 non-initial position in multi-byte charsets */ 1213 if ((c & 0xC0) == 0) { 1214 return strchr(src, c); 1215 } 1216 1217 /* this is quite a common operation, so we want it to be 1218 fast. We optimise for the ascii case, knowing that all our 1219 supported multi-byte character sets are ascii-compatible 1220 (ie. they match for the first 128 chars) */ 1221 1222 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) { 1223 if (*s == c) 1224 return (char *)s; 1225 } 1226 1227 if (!*s) 1228 return NULL; 1229 1230#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS 1231 /* With compose characters we must restart from the beginning. JRA. */ 1232 s = src; 1233#endif 1234 1235 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE); 1236 p = strchr_w(ws, UCS2_CHAR(c)); 1237 if (!p) 1238 return NULL; 1239 *p = 0; 1240 pull_ucs2_pstring(s2, ws); 1241 return (char *)(s+strlen(s2)); 1242} 1243 1244char *strrchr_m(const char *s, char c) 1245{ 1246 /* characters below 0x3F are guaranteed to not appear in 1247 non-initial position in multi-byte charsets */ 1248 if ((c & 0xC0) == 0) { 1249 return strrchr(s, c); 1250 } 1251 1252 /* this is quite a common operation, so we want it to be 1253 fast. We optimise for the ascii case, knowing that all our 1254 supported multi-byte character sets are ascii-compatible 1255 (ie. they match for the first 128 chars). Also, in Samba 1256 we only search for ascii characters in 'c' and that 1257 in all mb character sets with a compound character 1258 containing c, if 'c' is not a match at position 1259 p, then p[-1] > 0x7f. JRA. */ 1260 1261 { 1262 size_t len = strlen(s); 1263 const char *cp = s; 1264 BOOL got_mb = False; 1265 1266 if (len == 0) 1267 return NULL; 1268 cp += (len - 1); 1269 do { 1270 if (c == *cp) { 1271 /* Could be a match. Part of a multibyte ? */ 1272 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) { 1273 /* Yep - go slow :-( */ 1274 got_mb = True; 1275 break; 1276 } 1277 /* No - we have a match ! */ 1278 return (char *)cp; 1279 } 1280 } while (cp-- != s); 1281 if (!got_mb) 1282 return NULL; 1283 } 1284 1285 /* String contained a non-ascii char. Slow path. */ 1286 { 1287 wpstring ws; 1288 pstring s2; 1289 smb_ucs2_t *p; 1290 1291 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE); 1292 p = strrchr_w(ws, UCS2_CHAR(c)); 1293 if (!p) 1294 return NULL; 1295 *p = 0; 1296 pull_ucs2_pstring(s2, ws); 1297 return (char *)(s+strlen(s2)); 1298 } 1299} 1300 1301/*********************************************************************** 1302 Return the equivalent of doing strrchr 'n' times - always going 1303 backwards. 1304***********************************************************************/ 1305 1306char *strnrchr_m(const char *s, char c, unsigned int n) 1307{ 1308 wpstring ws; 1309 pstring s2; 1310 smb_ucs2_t *p; 1311 1312 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE); 1313 p = strnrchr_w(ws, UCS2_CHAR(c), n); 1314 if (!p) 1315 return NULL; 1316 *p = 0; 1317 pull_ucs2_pstring(s2, ws); 1318 return (char *)(s+strlen(s2)); 1319} 1320 1321/*********************************************************************** 1322 strstr_m - We convert via ucs2 for now. 1323***********************************************************************/ 1324 1325char *strstr_m(const char *src, const char *findstr) 1326{ 1327 smb_ucs2_t *p; 1328 smb_ucs2_t *src_w, *find_w; 1329 const char *s; 1330 char *s2; 1331 char *retp; 1332 1333 size_t findstr_len = 0; 1334 1335 /* for correctness */ 1336 if (!findstr[0]) { 1337 return src; 1338 } 1339 1340 /* Samba does single character findstr calls a *lot*. */ 1341 if (findstr[1] == '\0') 1342 return strchr_m(src, *findstr); 1343 1344 /* We optimise for the ascii case, knowing that all our 1345 supported multi-byte character sets are ascii-compatible 1346 (ie. they match for the first 128 chars) */ 1347 1348 for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) { 1349 if (*s == *findstr) { 1350 if (!findstr_len) 1351 findstr_len = strlen(findstr); 1352 1353 if (strncmp(s, findstr, findstr_len) == 0) { 1354 return (char *)s; 1355 } 1356 } 1357 } 1358 1359 if (!*s) 1360 return NULL; 1361 1362#if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */ 1363 /* 'make check' fails unless we do this */ 1364 1365 /* With compose characters we must restart from the beginning. JRA. */ 1366 s = src; 1367#endif 1368 1369 if (push_ucs2_allocate(&src_w, src) == (size_t)-1) { 1370 DEBUG(0,("strstr_m: src malloc fail\n")); 1371 return NULL; 1372 } 1373 1374 if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) { 1375 SAFE_FREE(src_w); 1376 DEBUG(0,("strstr_m: find malloc fail\n")); 1377 return NULL; 1378 } 1379 1380 p = strstr_w(src_w, find_w); 1381 1382 if (!p) { 1383 SAFE_FREE(src_w); 1384 SAFE_FREE(find_w); 1385 return NULL; 1386 } 1387 1388 *p = 0; 1389 if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) { 1390 SAFE_FREE(src_w); 1391 SAFE_FREE(find_w); 1392 DEBUG(0,("strstr_m: dest malloc fail\n")); 1393 return NULL; 1394 } 1395 retp = (char *)(s+strlen(s2)); 1396 SAFE_FREE(src_w); 1397 SAFE_FREE(find_w); 1398 SAFE_FREE(s2); 1399 return retp; 1400} 1401 1402/** 1403 Convert a string to lower case. 1404**/ 1405 1406void strlower_m(char *s) 1407{ 1408 size_t len; 1409 int errno_save; 1410 1411 /* this is quite a common operation, so we want it to be 1412 fast. We optimise for the ascii case, knowing that all our 1413 supported multi-byte character sets are ascii-compatible 1414 (ie. they match for the first 128 chars) */ 1415 1416 while (*s && !(((unsigned char)s[0]) & 0x80)) { 1417 *s = tolower((unsigned char)*s); 1418 s++; 1419 } 1420 1421 if (!*s) 1422 return; 1423 1424 /* I assume that lowercased string takes the same number of bytes 1425 * as source string even in UTF-8 encoding. (VIV) */ 1426 len = strlen(s) + 1; 1427 errno_save = errno; 1428 errno = 0; 1429 unix_strlower(s,len,s,len); 1430 /* Catch mb conversion errors that may not terminate. */ 1431 if (errno) 1432 s[len-1] = '\0'; 1433 errno = errno_save; 1434} 1435 1436/** 1437 Convert a string to upper case. 1438**/ 1439 1440void strupper_m(char *s) 1441{ 1442 size_t len; 1443 int errno_save; 1444 1445 /* this is quite a common operation, so we want it to be 1446 fast. We optimise for the ascii case, knowing that all our 1447 supported multi-byte character sets are ascii-compatible 1448 (ie. they match for the first 128 chars) */ 1449 1450 while (*s && !(((unsigned char)s[0]) & 0x80)) { 1451 *s = toupper((unsigned char)*s); 1452 s++; 1453 } 1454 1455 if (!*s) 1456 return; 1457 1458 /* I assume that lowercased string takes the same number of bytes 1459 * as source string even in multibyte encoding. (VIV) */ 1460 len = strlen(s) + 1; 1461 errno_save = errno; 1462 errno = 0; 1463 unix_strupper(s,len,s,len); 1464 /* Catch mb conversion errors that may not terminate. */ 1465 if (errno) 1466 s[len-1] = '\0'; 1467 errno = errno_save; 1468} 1469 1470/** 1471 Return a RFC2254 binary string representation of a buffer. 1472 Used in LDAP filters. 1473 Caller must free. 1474**/ 1475 1476char *binary_string(char *buf, int len) 1477{ 1478 char *s; 1479 int i, j; 1480 const char *hex = "0123456789ABCDEF"; 1481 s = SMB_MALLOC(len * 3 + 1); 1482 if (!s) 1483 return NULL; 1484 for (j=i=0;i<len;i++) { 1485 s[j] = '\\'; 1486 s[j+1] = hex[((unsigned char)buf[i]) >> 4]; 1487 s[j+2] = hex[((unsigned char)buf[i]) & 0xF]; 1488 j += 3; 1489 } 1490 s[j] = 0; 1491 return s; 1492} 1493 1494/** 1495 Just a typesafety wrapper for snprintf into a pstring. 1496**/ 1497 1498 int pstr_sprintf(pstring s, const char *fmt, ...) 1499{ 1500 va_list ap; 1501 int ret; 1502 1503 va_start(ap, fmt); 1504 ret = vsnprintf(s, PSTRING_LEN, fmt, ap); 1505 va_end(ap); 1506 return ret; 1507} 1508 1509 1510/** 1511 Just a typesafety wrapper for snprintf into a fstring. 1512**/ 1513 1514int fstr_sprintf(fstring s, const char *fmt, ...) 1515{ 1516 va_list ap; 1517 int ret; 1518 1519 va_start(ap, fmt); 1520 ret = vsnprintf(s, FSTRING_LEN, fmt, ap); 1521 va_end(ap); 1522 return ret; 1523} 1524 1525 1526#if !defined(HAVE_STRNDUP) || defined(BROKEN_STRNDUP) 1527/** 1528 Some platforms don't have strndup. 1529**/ 1530#if defined(PARANOID_MALLOC_CHECKER) 1531#undef strndup 1532#endif 1533 1534 char *strndup(const char *s, size_t n) 1535{ 1536 char *ret; 1537 1538 n = strnlen(s, n); 1539 ret = SMB_MALLOC(n+1); 1540 if (!ret) 1541 return NULL; 1542 memcpy(ret, s, n); 1543 ret[n] = 0; 1544 1545 return ret; 1546} 1547 1548#if defined(PARANOID_MALLOC_CHECKER) 1549#define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY 1550#endif 1551 1552#endif 1553 1554#if !defined(HAVE_STRNLEN) || defined(BROKEN_STRNLEN) 1555/** 1556 Some platforms don't have strnlen 1557**/ 1558 1559 size_t strnlen(const char *s, size_t n) 1560{ 1561 size_t i; 1562 for (i=0; i<n && s[i] != '\0'; i++) 1563 /* noop */ ; 1564 return i; 1565} 1566#endif 1567 1568/** 1569 List of Strings manipulation functions 1570**/ 1571 1572#define S_LIST_ABS 16 /* List Allocation Block Size */ 1573 1574char **str_list_make(const char *string, const char *sep) 1575{ 1576 char **list, **rlist; 1577 const char *str; 1578 char *s; 1579 int num, lsize; 1580 pstring tok; 1581 1582 if (!string || !*string) 1583 return NULL; 1584 s = SMB_STRDUP(string); 1585 if (!s) { 1586 DEBUG(0,("str_list_make: Unable to allocate memory")); 1587 return NULL; 1588 } 1589 if (!sep) sep = LIST_SEP; 1590 1591 num = lsize = 0; 1592 list = NULL; 1593 1594 str = s; 1595 while (next_token(&str, tok, sep, sizeof(tok))) { 1596 if (num == lsize) { 1597 lsize += S_LIST_ABS; 1598 rlist = SMB_REALLOC_ARRAY(list, char *, lsize +1); 1599 if (!rlist) { 1600 DEBUG(0,("str_list_make: Unable to allocate memory")); 1601 str_list_free(&list); 1602 SAFE_FREE(s); 1603 return NULL; 1604 } else 1605 list = rlist; 1606 memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1))); 1607 } 1608 1609 list[num] = SMB_STRDUP(tok); 1610 if (!list[num]) { 1611 DEBUG(0,("str_list_make: Unable to allocate memory")); 1612 str_list_free(&list); 1613 SAFE_FREE(s); 1614 return NULL; 1615 } 1616 1617 num++; 1618 } 1619 1620 SAFE_FREE(s); 1621 return list; 1622} 1623 1624BOOL str_list_copy(char ***dest, const char **src) 1625{ 1626 char **list, **rlist; 1627 int num, lsize; 1628 1629 *dest = NULL; 1630 if (!src) 1631 return False; 1632 1633 num = lsize = 0; 1634 list = NULL; 1635 1636 while (src[num]) { 1637 if (num == lsize) { 1638 lsize += S_LIST_ABS; 1639 rlist = SMB_REALLOC_ARRAY(list, char *, lsize +1); 1640 if (!rlist) { 1641 DEBUG(0,("str_list_copy: Unable to re-allocate memory")); 1642 str_list_free(&list); 1643 return False; 1644 } else 1645 list = rlist; 1646 memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1))); 1647 } 1648 1649 list[num] = SMB_STRDUP(src[num]); 1650 if (!list[num]) { 1651 DEBUG(0,("str_list_copy: Unable to allocate memory")); 1652 str_list_free(&list); 1653 return False; 1654 } 1655 1656 num++; 1657 } 1658 1659 *dest = list; 1660 return True; 1661} 1662 1663/** 1664 * Return true if all the elements of the list match exactly. 1665 **/ 1666BOOL str_list_compare(char **list1, char **list2) 1667{ 1668 int num; 1669 1670 if (!list1 || !list2) 1671 return (list1 == list2); 1672 1673 for (num = 0; list1[num]; num++) { 1674 if (!list2[num]) 1675 return False; 1676 if (!strcsequal(list1[num], list2[num])) 1677 return False; 1678 } 1679 if (list2[num]) 1680 return False; /* if list2 has more elements than list1 fail */ 1681 1682 return True; 1683} 1684 1685void str_list_free(char ***list) 1686{ 1687 char **tlist; 1688 1689 if (!list || !*list) 1690 return; 1691 tlist = *list; 1692 for(; *tlist; tlist++) 1693 SAFE_FREE(*tlist); 1694 SAFE_FREE(*list); 1695} 1696 1697/****************************************************************************** 1698 version of standard_sub_basic() for string lists; uses alloc_sub_basic() 1699 for the work 1700 *****************************************************************************/ 1701 1702BOOL str_list_sub_basic( char **list, const char *smb_name ) 1703{ 1704 char *s, *tmpstr; 1705 1706 while ( *list ) { 1707 s = *list; 1708 tmpstr = alloc_sub_basic(smb_name, s); 1709 if ( !tmpstr ) { 1710 DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n")); 1711 return False; 1712 } 1713 1714 SAFE_FREE(*list); 1715 *list = tmpstr; 1716 1717 list++; 1718 } 1719 1720 return True; 1721} 1722 1723/****************************************************************************** 1724 substritute a specific pattern in a string list 1725 *****************************************************************************/ 1726 1727BOOL str_list_substitute(char **list, const char *pattern, const char *insert) 1728{ 1729 char *p, *s, *t; 1730 ssize_t ls, lp, li, ld, i, d; 1731 1732 if (!list) 1733 return False; 1734 if (!pattern) 1735 return False; 1736 if (!insert) 1737 return False; 1738 1739 lp = (ssize_t)strlen(pattern); 1740 li = (ssize_t)strlen(insert); 1741 ld = li -lp; 1742 1743 while (*list) { 1744 s = *list; 1745 ls = (ssize_t)strlen(s); 1746 1747 while ((p = strstr_m(s, pattern))) { 1748 t = *list; 1749 d = p -t; 1750 if (ld) { 1751 t = (char *) SMB_MALLOC(ls +ld +1); 1752 if (!t) { 1753 DEBUG(0,("str_list_substitute: Unable to allocate memory")); 1754 return False; 1755 } 1756 memcpy(t, *list, d); 1757 memcpy(t +d +li, p +lp, ls -d -lp +1); 1758 SAFE_FREE(*list); 1759 *list = t; 1760 ls += ld; 1761 s = t +d +li; 1762 } 1763 1764 for (i = 0; i < li; i++) { 1765 switch (insert[i]) { 1766 case '`': 1767 case '"': 1768 case '\'': 1769 case ';': 1770 case '$': 1771 case '%': 1772 case '\r': 1773 case '\n': 1774 t[d +i] = '_'; 1775 break; 1776 default: 1777 t[d +i] = insert[i]; 1778 } 1779 } 1780 } 1781 1782 1783 list++; 1784 } 1785 1786 return True; 1787} 1788 1789 1790#define IPSTR_LIST_SEP "," 1791#define IPSTR_LIST_CHAR ',' 1792 1793/** 1794 * Add ip string representation to ipstr list. Used also 1795 * as part of @function ipstr_list_make 1796 * 1797 * @param ipstr_list pointer to string containing ip list; 1798 * MUST BE already allocated and IS reallocated if necessary 1799 * @param ipstr_size pointer to current size of ipstr_list (might be changed 1800 * as a result of reallocation) 1801 * @param ip IP address which is to be added to list 1802 * @return pointer to string appended with new ip and possibly 1803 * reallocated to new length 1804 **/ 1805 1806char* ipstr_list_add(char** ipstr_list, const struct ip_service *service) 1807{ 1808 char* new_ipstr = NULL; 1809 1810 /* arguments checking */ 1811 if (!ipstr_list || !service) return NULL; 1812 1813 /* attempt to convert ip to a string and append colon separator to it */ 1814 if (*ipstr_list) { 1815 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP, 1816 inet_ntoa(service->ip), service->port); 1817 SAFE_FREE(*ipstr_list); 1818 } else { 1819 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port); 1820 } 1821 *ipstr_list = new_ipstr; 1822 return *ipstr_list; 1823} 1824 1825 1826/** 1827 * Allocate and initialise an ipstr list using ip adresses 1828 * passed as arguments. 1829 * 1830 * @param ipstr_list pointer to string meant to be allocated and set 1831 * @param ip_list array of ip addresses to place in the list 1832 * @param ip_count number of addresses stored in ip_list 1833 * @return pointer to allocated ip string 1834 **/ 1835 1836char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count) 1837{ 1838 int i; 1839 1840 /* arguments checking */ 1841 if (!ip_list && !ipstr_list) return 0; 1842 1843 *ipstr_list = NULL; 1844 1845 /* process ip addresses given as arguments */ 1846 for (i = 0; i < ip_count; i++) 1847 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]); 1848 1849 return (*ipstr_list); 1850} 1851 1852 1853/** 1854 * Parse given ip string list into array of ip addresses 1855 * (as ip_service structures) 1856 * e.g. 192.168.1.100:389,192.168.1.78, ... 1857 * 1858 * @param ipstr ip string list to be parsed 1859 * @param ip_list pointer to array of ip addresses which is 1860 * allocated by this function and must be freed by caller 1861 * @return number of succesfully parsed addresses 1862 **/ 1863 1864int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list) 1865{ 1866 fstring token_str; 1867 size_t count; 1868 int i; 1869 1870 if (!ipstr_list || !ip_list) 1871 return 0; 1872 1873 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1; 1874 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) { 1875 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count)); 1876 return 0; 1877 } 1878 1879 for ( i=0; 1880 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count; 1881 i++ ) 1882 { 1883 struct in_addr addr; 1884 unsigned port = 0; 1885 char *p = strchr(token_str, ':'); 1886 1887 if (p) { 1888 *p = 0; 1889 port = atoi(p+1); 1890 } 1891 1892 /* convert single token to ip address */ 1893 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE ) 1894 break; 1895 1896 (*ip_list)[i].ip = addr; 1897 (*ip_list)[i].port = port; 1898 } 1899 1900 return count; 1901} 1902 1903 1904/** 1905 * Safely free ip string list 1906 * 1907 * @param ipstr_list ip string list to be freed 1908 **/ 1909 1910void ipstr_list_free(char* ipstr_list) 1911{ 1912 SAFE_FREE(ipstr_list); 1913} 1914 1915 1916/** 1917 Unescape a URL encoded string, in place. 1918**/ 1919 1920void rfc1738_unescape(char *buf) 1921{ 1922 char *p=buf; 1923 1924 while (p && *p && (p=strchr_m(p,'%'))) { 1925 int c1 = p[1]; 1926 int c2 = p[2]; 1927 1928 if (c1 >= '0' && c1 <= '9') 1929 c1 = c1 - '0'; 1930 else if (c1 >= 'A' && c1 <= 'F') 1931 c1 = 10 + c1 - 'A'; 1932 else if (c1 >= 'a' && c1 <= 'f') 1933 c1 = 10 + c1 - 'a'; 1934 else {p++; continue;} 1935 1936 if (c2 >= '0' && c2 <= '9') 1937 c2 = c2 - '0'; 1938 else if (c2 >= 'A' && c2 <= 'F') 1939 c2 = 10 + c2 - 'A'; 1940 else if (c2 >= 'a' && c2 <= 'f') 1941 c2 = 10 + c2 - 'a'; 1942 else {p++; continue;} 1943 1944 *p = (c1<<4) | c2; 1945 1946 memmove(p+1, p+3, strlen(p+3)+1); 1947 p++; 1948 } 1949} 1950 1951static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 1952 1953/** 1954 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm 1955 **/ 1956DATA_BLOB base64_decode_data_blob(const char *s) 1957{ 1958 int bit_offset, byte_offset, idx, i, n; 1959 DATA_BLOB decoded = data_blob(s, strlen(s)+1); 1960 unsigned char *d = decoded.data; 1961 char *p; 1962 1963 n=i=0; 1964 1965 while (*s && (p=strchr_m(b64,*s))) { 1966 idx = (int)(p - b64); 1967 byte_offset = (i*6)/8; 1968 bit_offset = (i*6)%8; 1969 d[byte_offset] &= ~((1<<(8-bit_offset))-1); 1970 if (bit_offset < 3) { 1971 d[byte_offset] |= (idx << (2-bit_offset)); 1972 n = byte_offset+1; 1973 } else { 1974 d[byte_offset] |= (idx >> (bit_offset-2)); 1975 d[byte_offset+1] = 0; 1976 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF; 1977 n = byte_offset+2; 1978 } 1979 s++; i++; 1980 } 1981 1982 if ((n > 0) && (*s == '=')) { 1983 n -= 1; 1984 } 1985 1986 /* fix up length */ 1987 decoded.length = n; 1988 return decoded; 1989} 1990 1991/** 1992 * Decode a base64 string in-place - wrapper for the above 1993 **/ 1994void base64_decode_inplace(char *s) 1995{ 1996 DATA_BLOB decoded = base64_decode_data_blob(s); 1997 1998 if ( decoded.length != 0 ) { 1999 memcpy(s, decoded.data, decoded.length); 2000 2001 /* null terminate */ 2002 s[decoded.length] = '\0'; 2003 } else { 2004 *s = '\0'; 2005 } 2006 2007 data_blob_free(&decoded); 2008} 2009 2010/** 2011 * Encode a base64 string into a malloc()ed string caller to free. 2012 * 2013 *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments 2014 **/ 2015char * base64_encode_data_blob(DATA_BLOB data) 2016{ 2017 int bits = 0; 2018 int char_count = 0; 2019 size_t out_cnt, len, output_len; 2020 char *result; 2021 2022 if (!data.length || !data.data) 2023 return NULL; 2024 2025 out_cnt = 0; 2026 len = data.length; 2027 output_len = data.length * 2; 2028 result = SMB_MALLOC(output_len); /* get us plenty of space */ 2029 2030 while (len-- && out_cnt < (data.length * 2) - 5) { 2031 int c = (unsigned char) *(data.data++); 2032 bits += c; 2033 char_count++; 2034 if (char_count == 3) { 2035 result[out_cnt++] = b64[bits >> 18]; 2036 result[out_cnt++] = b64[(bits >> 12) & 0x3f]; 2037 result[out_cnt++] = b64[(bits >> 6) & 0x3f]; 2038 result[out_cnt++] = b64[bits & 0x3f]; 2039 bits = 0; 2040 char_count = 0; 2041 } else { 2042 bits <<= 8; 2043 } 2044 } 2045 if (char_count != 0) { 2046 bits <<= 16 - (8 * char_count); 2047 result[out_cnt++] = b64[bits >> 18]; 2048 result[out_cnt++] = b64[(bits >> 12) & 0x3f]; 2049 if (char_count == 1) { 2050 result[out_cnt++] = '='; 2051 result[out_cnt++] = '='; 2052 } else { 2053 result[out_cnt++] = b64[(bits >> 6) & 0x3f]; 2054 result[out_cnt++] = '='; 2055 } 2056 } 2057 result[out_cnt] = '\0'; /* terminate */ 2058 return result; 2059} 2060 2061/* read a SMB_BIG_UINT from a string */ 2062SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr) 2063{ 2064 2065 SMB_BIG_UINT val = -1; 2066 const char *p = nptr; 2067 2068 while (p && *p && isspace(*p)) 2069 p++; 2070#ifdef LARGE_SMB_OFF_T 2071 sscanf(p,"%llu",&val); 2072#else /* LARGE_SMB_OFF_T */ 2073 sscanf(p,"%lu",&val); 2074#endif /* LARGE_SMB_OFF_T */ 2075 if (entptr) { 2076 while (p && *p && isdigit(*p)) 2077 p++; 2078 *entptr = p; 2079 } 2080 2081 return val; 2082} 2083 2084void string_append(char **left, const char *right) 2085{ 2086 int new_len = strlen(right) + 1; 2087 2088 if (*left == NULL) { 2089 *left = SMB_MALLOC(new_len); 2090 *left[0] = '\0'; 2091 } else { 2092 new_len += strlen(*left); 2093 *left = SMB_REALLOC(*left, new_len); 2094 } 2095 2096 if (*left == NULL) 2097 return; 2098 2099 safe_strcat(*left, right, new_len-1); 2100} 2101 2102BOOL add_string_to_array(TALLOC_CTX *mem_ctx, 2103 const char *str, const char ***strings, 2104 int *num) 2105{ 2106 char *dup_str = talloc_strdup(mem_ctx, str); 2107 2108 *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1); 2109 2110 if ((*strings == NULL) || (dup_str == NULL)) 2111 return False; 2112 2113 (*strings)[*num] = dup_str; 2114 *num += 1; 2115 return True; 2116} 2117