1/* 2 Unix SMB/CIFS implementation. 3 Samba utility functions 4 Copyright (C) Andrew Tridgell 1992-2001 5 Copyright (C) Simo Sorce 2001 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. 19*/ 20 21#include "includes.h" 22#include "system/locale.h" 23 24struct smb_iconv_convenience *global_iconv_convenience = NULL; 25 26static inline struct smb_iconv_convenience *get_iconv_convenience(void) 27{ 28 if (global_iconv_convenience == NULL) 29 global_iconv_convenience = smb_iconv_convenience_init(talloc_autofree_context(), "ASCII", "UTF-8", true); 30 return global_iconv_convenience; 31} 32 33/** 34 Case insensitive string compararison 35**/ 36_PUBLIC_ int strcasecmp_m(const char *s1, const char *s2) 37{ 38 codepoint_t c1=0, c2=0; 39 size_t size1, size2; 40 struct smb_iconv_convenience *iconv_convenience = get_iconv_convenience(); 41 42 /* handle null ptr comparisons to simplify the use in qsort */ 43 if (s1 == s2) return 0; 44 if (s1 == NULL) return -1; 45 if (s2 == NULL) return 1; 46 47 while (*s1 && *s2) { 48 c1 = next_codepoint_convenience(iconv_convenience, s1, &size1); 49 c2 = next_codepoint_convenience(iconv_convenience, s2, &size2); 50 51 s1 += size1; 52 s2 += size2; 53 54 if (c1 == c2) { 55 continue; 56 } 57 58 if (c1 == INVALID_CODEPOINT || 59 c2 == INVALID_CODEPOINT) { 60 /* what else can we do?? */ 61 return strcasecmp(s1, s2); 62 } 63 64 if (toupper_m(c1) != toupper_m(c2)) { 65 return c1 - c2; 66 } 67 } 68 69 return *s1 - *s2; 70} 71 72/** 73 * Get the next token from a string, return False if none found. 74 * Handles double-quotes. 75 * 76 * Based on a routine by GJC@VILLAGE.COM. 77 * Extensively modified by Andrew.Tridgell@anu.edu.au 78 **/ 79_PUBLIC_ bool next_token(const char **ptr,char *buff, const char *sep, size_t bufsize) 80{ 81 const char *s; 82 bool quoted; 83 size_t len=1; 84 85 if (!ptr) 86 return false; 87 88 s = *ptr; 89 90 /* default to simple separators */ 91 if (!sep) 92 sep = " \t\n\r"; 93 94 /* find the first non sep char */ 95 while (*s && strchr_m(sep,*s)) 96 s++; 97 98 /* nothing left? */ 99 if (!*s) 100 return false; 101 102 /* copy over the token */ 103 for (quoted = false; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) { 104 if (*s == '\"') { 105 quoted = !quoted; 106 } else { 107 len++; 108 *buff++ = *s; 109 } 110 } 111 112 *ptr = (*s) ? s+1 : s; 113 *buff = 0; 114 115 return true; 116} 117 118/** 119 Case insensitive string compararison, length limited 120**/ 121_PUBLIC_ int strncasecmp_m(const char *s1, const char *s2, size_t n) 122{ 123 codepoint_t c1=0, c2=0; 124 size_t size1, size2; 125 struct smb_iconv_convenience *iconv_convenience = get_iconv_convenience(); 126 127 /* handle null ptr comparisons to simplify the use in qsort */ 128 if (s1 == s2) return 0; 129 if (s1 == NULL) return -1; 130 if (s2 == NULL) return 1; 131 132 while (*s1 && *s2 && n) { 133 n--; 134 135 c1 = next_codepoint_convenience(iconv_convenience, s1, &size1); 136 c2 = next_codepoint_convenience(iconv_convenience, s2, &size2); 137 138 s1 += size1; 139 s2 += size2; 140 141 if (c1 == c2) { 142 continue; 143 } 144 145 if (c1 == INVALID_CODEPOINT || 146 c2 == INVALID_CODEPOINT) { 147 /* what else can we do?? */ 148 return strcasecmp(s1, s2); 149 } 150 151 if (toupper_m(c1) != toupper_m(c2)) { 152 return c1 - c2; 153 } 154 } 155 156 if (n == 0) { 157 return 0; 158 } 159 160 return *s1 - *s2; 161} 162 163/** 164 * Compare 2 strings. 165 * 166 * @note The comparison is case-insensitive. 167 **/ 168_PUBLIC_ bool strequal_m(const char *s1, const char *s2) 169{ 170 return strcasecmp_m(s1,s2) == 0; 171} 172 173/** 174 Compare 2 strings (case sensitive). 175**/ 176_PUBLIC_ bool strcsequal_m(const char *s1,const char *s2) 177{ 178 if (s1 == s2) 179 return true; 180 if (!s1 || !s2) 181 return false; 182 183 return strcmp(s1,s2) == 0; 184} 185 186 187/** 188 String replace. 189 NOTE: oldc and newc must be 7 bit characters 190**/ 191_PUBLIC_ void string_replace_m(char *s, char oldc, char newc) 192{ 193 struct smb_iconv_convenience *ic = get_iconv_convenience(); 194 while (s && *s) { 195 size_t size; 196 codepoint_t c = next_codepoint_convenience(ic, s, &size); 197 if (c == oldc) { 198 *s = newc; 199 } 200 s += size; 201 } 202} 203 204/** 205 Paranoid strcpy into a buffer of given length (includes terminating 206 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars 207 and replaces with '_'. Deliberately does *NOT* check for multibyte 208 characters. Don't change it ! 209**/ 210 211_PUBLIC_ char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength) 212{ 213 size_t len, i; 214 215 if (maxlength == 0) { 216 /* can't fit any bytes at all! */ 217 return NULL; 218 } 219 220 if (!dest) { 221 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n")); 222 return NULL; 223 } 224 225 if (!src) { 226 *dest = 0; 227 return dest; 228 } 229 230 len = strlen(src); 231 if (len >= maxlength) 232 len = maxlength - 1; 233 234 if (!other_safe_chars) 235 other_safe_chars = ""; 236 237 for(i = 0; i < len; i++) { 238 int val = (src[i] & 0xff); 239 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val)) 240 dest[i] = src[i]; 241 else 242 dest[i] = '_'; 243 } 244 245 dest[i] = '\0'; 246 247 return dest; 248} 249 250/** 251 Count the number of UCS2 characters in a string. Normally this will 252 be the same as the number of bytes in a string for single byte strings, 253 but will be different for multibyte. 254**/ 255_PUBLIC_ size_t strlen_m(const char *s) 256{ 257 size_t count = 0; 258 struct smb_iconv_convenience *ic = get_iconv_convenience(); 259 260 if (!s) { 261 return 0; 262 } 263 264 while (*s && !(((uint8_t)*s) & 0x80)) { 265 s++; 266 count++; 267 } 268 269 if (!*s) { 270 return count; 271 } 272 273 while (*s) { 274 size_t c_size; 275 codepoint_t c = next_codepoint_convenience(ic, s, &c_size); 276 if (c < 0x10000) { 277 count += 1; 278 } else { 279 count += 2; 280 } 281 s += c_size; 282 } 283 284 return count; 285} 286 287/** 288 Work out the number of multibyte chars in a string, including the NULL 289 terminator. 290**/ 291_PUBLIC_ size_t strlen_m_term(const char *s) 292{ 293 if (!s) { 294 return 0; 295 } 296 297 return strlen_m(s) + 1; 298} 299 300/* 301 * Weird helper routine for the winreg pipe: If nothing is around, return 0, 302 * if a string is there, include the terminator. 303 */ 304 305_PUBLIC_ size_t strlen_m_term_null(const char *s) 306{ 307 size_t len; 308 if (!s) { 309 return 0; 310 } 311 len = strlen_m(s); 312 if (len == 0) { 313 return 0; 314 } 315 316 return len+1; 317} 318 319/** 320 Strchr and strrchr_m are a bit complex on general multi-byte strings. 321**/ 322_PUBLIC_ char *strchr_m(const char *s, char c) 323{ 324 struct smb_iconv_convenience *ic = get_iconv_convenience(); 325 if (s == NULL) { 326 return NULL; 327 } 328 /* characters below 0x3F are guaranteed to not appear in 329 non-initial position in multi-byte charsets */ 330 if ((c & 0xC0) == 0) { 331 return strchr(s, c); 332 } 333 334 while (*s) { 335 size_t size; 336 codepoint_t c2 = next_codepoint_convenience(ic, s, &size); 337 if (c2 == c) { 338 return discard_const_p(char, s); 339 } 340 s += size; 341 } 342 343 return NULL; 344} 345 346/** 347 * Multibyte-character version of strrchr 348 */ 349_PUBLIC_ char *strrchr_m(const char *s, char c) 350{ 351 struct smb_iconv_convenience *ic = get_iconv_convenience(); 352 char *ret = NULL; 353 354 if (s == NULL) { 355 return NULL; 356 } 357 358 /* characters below 0x3F are guaranteed to not appear in 359 non-initial position in multi-byte charsets */ 360 if ((c & 0xC0) == 0) { 361 return strrchr(s, c); 362 } 363 364 while (*s) { 365 size_t size; 366 codepoint_t c2 = next_codepoint_convenience(ic, s, &size); 367 if (c2 == c) { 368 ret = discard_const_p(char, s); 369 } 370 s += size; 371 } 372 373 return ret; 374} 375 376/** 377 return True if any (multi-byte) character is lower case 378*/ 379_PUBLIC_ bool strhaslower(const char *string) 380{ 381 struct smb_iconv_convenience *ic = get_iconv_convenience(); 382 while (*string) { 383 size_t c_size; 384 codepoint_t s; 385 codepoint_t t; 386 387 s = next_codepoint_convenience(ic, string, &c_size); 388 string += c_size; 389 390 t = toupper_m(s); 391 392 if (s != t) { 393 return true; /* that means it has lower case chars */ 394 } 395 } 396 397 return false; 398} 399 400/** 401 return True if any (multi-byte) character is upper case 402*/ 403_PUBLIC_ bool strhasupper(const char *string) 404{ 405 struct smb_iconv_convenience *ic = get_iconv_convenience(); 406 while (*string) { 407 size_t c_size; 408 codepoint_t s; 409 codepoint_t t; 410 411 s = next_codepoint_convenience(ic, string, &c_size); 412 string += c_size; 413 414 t = tolower_m(s); 415 416 if (s != t) { 417 return true; /* that means it has upper case chars */ 418 } 419 } 420 421 return false; 422} 423 424/** 425 Convert a string to lower case, allocated with talloc 426**/ 427_PUBLIC_ char *strlower_talloc(TALLOC_CTX *ctx, const char *src) 428{ 429 size_t size=0; 430 char *dest; 431 struct smb_iconv_convenience *iconv_convenience = get_iconv_convenience(); 432 433 /* this takes advantage of the fact that upper/lower can't 434 change the length of a character by more than 1 byte */ 435 dest = talloc_array(ctx, char, 2*(strlen(src))+1); 436 if (dest == NULL) { 437 return NULL; 438 } 439 440 while (*src) { 441 size_t c_size; 442 codepoint_t c = next_codepoint_convenience(iconv_convenience, src, &c_size); 443 src += c_size; 444 445 c = tolower_m(c); 446 447 c_size = push_codepoint_convenience(iconv_convenience, dest+size, c); 448 if (c_size == -1) { 449 talloc_free(dest); 450 return NULL; 451 } 452 size += c_size; 453 } 454 455 dest[size] = 0; 456 457 /* trim it so talloc_append_string() works */ 458 dest = talloc_realloc(ctx, dest, char, size+1); 459 460 talloc_set_name_const(dest, dest); 461 462 return dest; 463} 464 465/** 466 Convert a string to UPPER case, allocated with talloc 467 source length limited to n bytes 468**/ 469_PUBLIC_ char *strupper_talloc_n(TALLOC_CTX *ctx, const char *src, size_t n) 470{ 471 size_t size=0; 472 char *dest; 473 struct smb_iconv_convenience *iconv_convenience = get_iconv_convenience(); 474 475 if (!src) { 476 return NULL; 477 } 478 479 /* this takes advantage of the fact that upper/lower can't 480 change the length of a character by more than 1 byte */ 481 dest = talloc_array(ctx, char, 2*(n+1)); 482 if (dest == NULL) { 483 return NULL; 484 } 485 486 while (n-- && *src) { 487 size_t c_size; 488 codepoint_t c = next_codepoint_convenience(iconv_convenience, src, &c_size); 489 src += c_size; 490 491 c = toupper_m(c); 492 493 c_size = push_codepoint_convenience(iconv_convenience, dest+size, c); 494 if (c_size == -1) { 495 talloc_free(dest); 496 return NULL; 497 } 498 size += c_size; 499 } 500 501 dest[size] = 0; 502 503 /* trim it so talloc_append_string() works */ 504 dest = talloc_realloc(ctx, dest, char, size+1); 505 506 talloc_set_name_const(dest, dest); 507 508 return dest; 509} 510 511/** 512 Convert a string to UPPER case, allocated with talloc 513**/ 514_PUBLIC_ char *strupper_talloc(TALLOC_CTX *ctx, const char *src) 515{ 516 return strupper_talloc_n(ctx, src, src?strlen(src):0); 517} 518 519/** 520 talloc_strdup() a unix string to upper case. 521**/ 522_PUBLIC_ char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *src) 523{ 524 return strupper_talloc(ctx, src); 525} 526 527/** 528 Convert a string to lower case. 529**/ 530_PUBLIC_ void strlower_m(char *s) 531{ 532 char *d; 533 struct smb_iconv_convenience *iconv_convenience; 534 535 /* this is quite a common operation, so we want it to be 536 fast. We optimise for the ascii case, knowing that all our 537 supported multi-byte character sets are ascii-compatible 538 (ie. they match for the first 128 chars) */ 539 while (*s && !(((uint8_t)*s) & 0x80)) { 540 *s = tolower((uint8_t)*s); 541 s++; 542 } 543 544 if (!*s) 545 return; 546 547 iconv_convenience = get_iconv_convenience(); 548 549 d = s; 550 551 while (*s) { 552 size_t c_size, c_size2; 553 codepoint_t c = next_codepoint_convenience(iconv_convenience, s, &c_size); 554 c_size2 = push_codepoint_convenience(iconv_convenience, d, tolower_m(c)); 555 if (c_size2 > c_size) { 556 DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strlower_m\n", 557 c, tolower_m(c), (int)c_size, (int)c_size2)); 558 smb_panic("codepoint expansion in strlower_m\n"); 559 } 560 s += c_size; 561 d += c_size2; 562 } 563 *d = 0; 564} 565 566/** 567 Convert a string to UPPER case. 568**/ 569_PUBLIC_ void strupper_m(char *s) 570{ 571 char *d; 572 struct smb_iconv_convenience *iconv_convenience; 573 574 /* this is quite a common operation, so we want it to be 575 fast. We optimise for the ascii case, knowing that all our 576 supported multi-byte character sets are ascii-compatible 577 (ie. they match for the first 128 chars) */ 578 while (*s && !(((uint8_t)*s) & 0x80)) { 579 *s = toupper((uint8_t)*s); 580 s++; 581 } 582 583 if (!*s) 584 return; 585 586 iconv_convenience = get_iconv_convenience(); 587 588 d = s; 589 590 while (*s) { 591 size_t c_size, c_size2; 592 codepoint_t c = next_codepoint_convenience(iconv_convenience, s, &c_size); 593 c_size2 = push_codepoint_convenience(iconv_convenience, d, toupper_m(c)); 594 if (c_size2 > c_size) { 595 DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strupper_m\n", 596 c, toupper_m(c), (int)c_size, (int)c_size2)); 597 smb_panic("codepoint expansion in strupper_m\n"); 598 } 599 s += c_size; 600 d += c_size2; 601 } 602 *d = 0; 603} 604 605 606/** 607 Find the number of 'c' chars in a string 608**/ 609_PUBLIC_ size_t count_chars_m(const char *s, char c) 610{ 611 struct smb_iconv_convenience *ic = get_iconv_convenience(); 612 size_t count = 0; 613 614 while (*s) { 615 size_t size; 616 codepoint_t c2 = next_codepoint_convenience(ic, s, &size); 617 if (c2 == c) count++; 618 s += size; 619 } 620 621 return count; 622} 623 624 625/** 626 * Copy a string from a char* unix src to a dos codepage string destination. 627 * 628 * @return the number of bytes occupied by the string in the destination. 629 * 630 * @param flags can include 631 * <dl> 632 * <dt>STR_TERMINATE</dt> <dd>means include the null termination</dd> 633 * <dt>STR_UPPER</dt> <dd>means uppercase in the destination</dd> 634 * </dl> 635 * 636 * @param dest_len the maximum length in bytes allowed in the 637 * destination. If @p dest_len is -1 then no maximum is used. 638 **/ 639static ssize_t push_ascii(void *dest, const char *src, size_t dest_len, int flags) 640{ 641 size_t src_len; 642 ssize_t ret; 643 644 if (flags & STR_UPPER) { 645 char *tmpbuf = strupper_talloc(NULL, src); 646 if (tmpbuf == NULL) { 647 return -1; 648 } 649 ret = push_ascii(dest, tmpbuf, dest_len, flags & ~STR_UPPER); 650 talloc_free(tmpbuf); 651 return ret; 652 } 653 654 src_len = strlen(src); 655 656 if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII)) 657 src_len++; 658 659 return convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len, false); 660} 661 662/** 663 * Copy a string from a unix char* src to an ASCII destination, 664 * allocating a buffer using talloc(). 665 * 666 * @param dest always set at least to NULL 667 * 668 * @returns The number of bytes occupied by the string in the destination 669 * or -1 in case of error. 670 **/ 671_PUBLIC_ bool push_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src, size_t *converted_size) 672{ 673 size_t src_len = strlen(src)+1; 674 *dest = NULL; 675 return convert_string_talloc(ctx, CH_UNIX, CH_DOS, src, src_len, (void **)dest, converted_size, false); 676} 677 678 679/** 680 * Copy a string from a dos codepage source to a unix char* destination. 681 * 682 * The resulting string in "dest" is always null terminated. 683 * 684 * @param flags can have: 685 * <dl> 686 * <dt>STR_TERMINATE</dt> 687 * <dd>STR_TERMINATE means the string in @p src 688 * is null terminated, and src_len is ignored.</dd> 689 * </dl> 690 * 691 * @param src_len is the length of the source area in bytes. 692 * @returns the number of bytes occupied by the string in @p src. 693 **/ 694static ssize_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t src_len, int flags) 695{ 696 size_t ret; 697 698 if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII)) { 699 if (src_len == (size_t)-1) { 700 src_len = strlen((const char *)src) + 1; 701 } else { 702 size_t len = strnlen((const char *)src, src_len); 703 if (len < src_len) 704 len++; 705 src_len = len; 706 } 707 } 708 709 ret = convert_string(CH_DOS, CH_UNIX, src, src_len, dest, dest_len, false); 710 711 if (dest_len) 712 dest[MIN(ret, dest_len-1)] = 0; 713 714 return src_len; 715} 716 717/** 718 * Copy a string from a char* src to a unicode destination. 719 * 720 * @returns the number of bytes occupied by the string in the destination. 721 * 722 * @param flags can have: 723 * 724 * <dl> 725 * <dt>STR_TERMINATE <dd>means include the null termination. 726 * <dt>STR_UPPER <dd>means uppercase in the destination. 727 * <dt>STR_NOALIGN <dd>means don't do alignment. 728 * </dl> 729 * 730 * @param dest_len is the maximum length allowed in the 731 * destination. If dest_len is -1 then no maxiumum is used. 732 **/ 733static ssize_t push_ucs2(void *dest, const char *src, size_t dest_len, int flags) 734{ 735 size_t len=0; 736 size_t src_len = strlen(src); 737 size_t ret; 738 739 if (flags & STR_UPPER) { 740 char *tmpbuf = strupper_talloc(NULL, src); 741 if (tmpbuf == NULL) { 742 return -1; 743 } 744 ret = push_ucs2(dest, tmpbuf, dest_len, flags & ~STR_UPPER); 745 talloc_free(tmpbuf); 746 return ret; 747 } 748 749 if (flags & STR_TERMINATE) 750 src_len++; 751 752 if (ucs2_align(NULL, dest, flags)) { 753 *(char *)dest = 0; 754 dest = (void *)((char *)dest + 1); 755 if (dest_len) dest_len--; 756 len++; 757 } 758 759 /* ucs2 is always a multiple of 2 bytes */ 760 dest_len &= ~1; 761 762 ret = convert_string(CH_UNIX, CH_UTF16, src, src_len, dest, dest_len, false); 763 if (ret == (size_t)-1) { 764 return 0; 765 } 766 767 len += ret; 768 769 return len; 770} 771 772 773/** 774 * Copy a string from a unix char* src to a UCS2 destination, 775 * allocating a buffer using talloc(). 776 * 777 * @param dest always set at least to NULL 778 * 779 * @returns The number of bytes occupied by the string in the destination 780 * or -1 in case of error. 781 **/ 782_PUBLIC_ bool push_ucs2_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src, size_t *converted_size) 783{ 784 size_t src_len = strlen(src)+1; 785 *dest = NULL; 786 return convert_string_talloc(ctx, CH_UNIX, CH_UTF16, src, src_len, (void **)dest, converted_size, false); 787} 788 789 790/** 791 * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer using talloc 792 * 793 * @param dest always set at least to NULL 794 * 795 * @returns The number of bytes occupied by the string in the destination 796 **/ 797 798_PUBLIC_ bool push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src, size_t *converted_size) 799{ 800 size_t src_len = strlen(src)+1; 801 *dest = NULL; 802 return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len, (void **)dest, converted_size, false); 803} 804 805/** 806 Copy a string from a ucs2 source to a unix char* destination. 807 Flags can have: 808 STR_TERMINATE means the string in src is null terminated. 809 STR_NOALIGN means don't try to align. 810 if STR_TERMINATE is set then src_len is ignored if it is -1. 811 src_len is the length of the source area in bytes 812 Return the number of bytes occupied by the string in src. 813 The resulting string in "dest" is always null terminated. 814**/ 815 816static size_t pull_ucs2(char *dest, const void *src, size_t dest_len, size_t src_len, int flags) 817{ 818 size_t ret; 819 820 if (ucs2_align(NULL, src, flags)) { 821 src = (const void *)((const char *)src + 1); 822 if (src_len > 0) 823 src_len--; 824 } 825 826 if (flags & STR_TERMINATE) { 827 if (src_len == (size_t)-1) { 828 src_len = utf16_len(src); 829 } else { 830 src_len = utf16_len_n(src, src_len); 831 } 832 } 833 834 /* ucs2 is always a multiple of 2 bytes */ 835 if (src_len != (size_t)-1) 836 src_len &= ~1; 837 838 ret = convert_string(CH_UTF16, CH_UNIX, src, src_len, dest, dest_len, false); 839 if (dest_len) 840 dest[MIN(ret, dest_len-1)] = 0; 841 842 return src_len; 843} 844 845/** 846 * Copy a string from a ASCII src to a unix char * destination, allocating a buffer using talloc 847 * 848 * @param dest always set at least to NULL 849 * 850 * @returns The number of bytes occupied by the string in the destination 851 **/ 852 853_PUBLIC_ bool pull_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src, size_t *converted_size) 854{ 855 size_t src_len = strlen(src)+1; 856 *dest = NULL; 857 return convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len, (void **)dest, converted_size, false); 858} 859 860/** 861 * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer using talloc 862 * 863 * @param dest always set at least to NULL 864 * 865 * @returns The number of bytes occupied by the string in the destination 866 **/ 867 868_PUBLIC_ bool pull_ucs2_talloc(TALLOC_CTX *ctx, char **dest, const smb_ucs2_t *src, size_t *converted_size) 869{ 870 size_t src_len = utf16_len(src); 871 *dest = NULL; 872 return convert_string_talloc(ctx, CH_UTF16, CH_UNIX, src, src_len, (void **)dest, converted_size, false); 873} 874 875/** 876 * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc 877 * 878 * @param dest always set at least to NULL 879 * 880 * @returns The number of bytes occupied by the string in the destination 881 **/ 882 883_PUBLIC_ bool pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src, size_t *converted_size) 884{ 885 size_t src_len = strlen(src)+1; 886 *dest = NULL; 887 return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len, (void **)dest, converted_size, false); 888} 889 890/** 891 Copy a string from a char* src to a unicode or ascii 892 dos codepage destination choosing unicode or ascii based on the 893 flags in the SMB buffer starting at base_ptr. 894 Return the number of bytes occupied by the string in the destination. 895 flags can have: 896 STR_TERMINATE means include the null termination. 897 STR_UPPER means uppercase in the destination. 898 STR_ASCII use ascii even with unicode packet. 899 STR_NOALIGN means don't do alignment. 900 dest_len is the maximum length allowed in the destination. If dest_len 901 is -1 then no maxiumum is used. 902**/ 903 904_PUBLIC_ ssize_t push_string(void *dest, const char *src, size_t dest_len, int flags) 905{ 906 if (flags & STR_ASCII) { 907 return push_ascii(dest, src, dest_len, flags); 908 } else if (flags & STR_UNICODE) { 909 return push_ucs2(dest, src, dest_len, flags); 910 } else { 911 smb_panic("push_string requires either STR_ASCII or STR_UNICODE flag to be set"); 912 return -1; 913 } 914} 915 916 917/** 918 Copy a string from a unicode or ascii source (depending on 919 the packet flags) to a char* destination. 920 Flags can have: 921 STR_TERMINATE means the string in src is null terminated. 922 STR_UNICODE means to force as unicode. 923 STR_ASCII use ascii even with unicode packet. 924 STR_NOALIGN means don't do alignment. 925 if STR_TERMINATE is set then src_len is ignored is it is -1 926 src_len is the length of the source area in bytes. 927 Return the number of bytes occupied by the string in src. 928 The resulting string in "dest" is always null terminated. 929**/ 930 931_PUBLIC_ ssize_t pull_string(char *dest, const void *src, size_t dest_len, size_t src_len, int flags) 932{ 933 if (flags & STR_ASCII) { 934 return pull_ascii(dest, src, dest_len, src_len, flags); 935 } else if (flags & STR_UNICODE) { 936 return pull_ucs2(dest, src, dest_len, src_len, flags); 937 } else { 938 smb_panic("pull_string requires either STR_ASCII or STR_UNICODE flag to be set"); 939 return -1; 940 } 941} 942 943 944/** 945 * Convert string from one encoding to another, making error checking etc 946 * 947 * @param src pointer to source string (multibyte or singlebyte) 948 * @param srclen length of the source string in bytes 949 * @param dest pointer to destination string (multibyte or singlebyte) 950 * @param destlen maximal length allowed for string 951 * @returns the number of bytes occupied in the destination 952 **/ 953_PUBLIC_ size_t convert_string(charset_t from, charset_t to, 954 void const *src, size_t srclen, 955 void *dest, size_t destlen, 956 bool allow_badcharcnv) 957{ 958 size_t ret; 959 if (!convert_string_convenience(get_iconv_convenience(), from, to, 960 src, srclen, 961 dest, destlen, &ret, 962 allow_badcharcnv)) 963 return -1; 964 return ret; 965} 966 967/** 968 * Convert between character sets, allocating a new buffer using talloc for the result. 969 * 970 * @param srclen length of source buffer. 971 * @param dest always set at least to NULL 972 * @param converted_size Size in bytes of the converted string 973 * @note -1 is not accepted for srclen. 974 * 975 * @returns boolean indication whether the conversion succeeded 976 **/ 977 978_PUBLIC_ bool convert_string_talloc(TALLOC_CTX *ctx, 979 charset_t from, charset_t to, 980 void const *src, size_t srclen, 981 void *dest, size_t *converted_size, 982 bool allow_badcharcnv) 983{ 984 return convert_string_talloc_convenience(ctx, get_iconv_convenience(), 985 from, to, src, srclen, dest, 986 converted_size, 987 allow_badcharcnv); 988} 989 990 991_PUBLIC_ codepoint_t next_codepoint(const char *str, size_t *size) 992{ 993 return next_codepoint_convenience(get_iconv_convenience(), str, size); 994} 995 996_PUBLIC_ ssize_t push_codepoint(char *str, codepoint_t c) 997{ 998 return push_codepoint_convenience(get_iconv_convenience(), str, c); 999} 1000