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